(window["webpackJsonp"] = window["webpackJsonp"] || []).push([["commons~FlexDesign~admin~ampai~client"],{

/***/ "./client/project/import-project.pug":
/***/ (function(module, exports, __webpack_require__) {

var pug = __webpack_require__("./node_modules/pug-runtime/index.js");

function template(locals) {var pug_html = "", pug_mixins = {}, pug_interp;pug_html = pug_html + "\u003Cdiv class=\"modal fade\" id=\"modal-import-project\" role=\"dialog\" tabindex=\"-1\"\u003E\u003Cdiv class=\"modal-dialog\"\u003E\u003Cdiv class=\"modal-content\"\u003E\u003Cdiv class=\"modal-header\"\u003E\u003Cbutton class=\"close\" data-dismiss=\"modal\" aria-label=\"close\"\u003E\u003Cspan aria-hidden=\"true\"\u003E&times;\u003C\u002Fspan\u003E\u003C\u002Fbutton\u003E\u003Ch4 class=\"modal-title\"\u003EImport Project  (.zip or .json file)\u003C\u002Fh4\u003E\u003Csmall\u003E\u003Cspan class=\"label label-danger\"\u003E\u003C\u002Fspan\u003E\u003C\u002Fsmall\u003E\u003C\u002Fdiv\u003E\u003Cdiv class=\"modal-body\"\u003E\u003Cform class=\"param-form form-horizontal\" id=\"import\"\u003E\u003Cdiv class=\"form-group form-group-sm\"\u003E\u003Clabel class=\"col-sm-4 control-label\" for=\"Project Name\" title=\"\"\u003EProject Name\u003C\u002Flabel\u003E\u003Cdiv class=\"col-sm-8\"\u003E\u003Cinput class=\"form-control\" id=\"project-name\" onchange=\"amp.ProjectManager.checkProjectName(this)\" value=\"\"\u003E\u003C\u002Fdiv\u003E\u003C\u002Fdiv\u003E\u003Cdiv class=\"form-group form-group-sm\"\u003E\u003Cdiv class=\"col-sm-12\"\u003E\u003Cinput class=\"filestyle form-control\" type=\"file\" accept=\".zip,.json\" data-classbutton=\"btn btn-primary\" data-input=\"false\" data-classicon=\"icon-plus\"\u003E\u003C\u002Fdiv\u003E\u003C\u002Fdiv\u003E\u003C\u002Fform\u003E\u003C\u002Fdiv\u003E\u003Cdiv class=\"modal-footer\"\u003E\u003Cbutton class=\"btn btn-default\" data-dismiss=\"modal\"\u003ECreate\u003C\u002Fbutton\u003E\u003C\u002Fdiv\u003E\u003C\u002Fdiv\u003E\u003C\u002Fdiv\u003E\u003C\u002Fdiv\u003E";;return pug_html;};
module.exports = template;

/***/ }),

/***/ "./client/project/manage-projects.pug":
/***/ (function(module, exports, __webpack_require__) {

var pug = __webpack_require__("./node_modules/pug-runtime/index.js");

function template(locals) {var pug_html = "", pug_mixins = {}, pug_interp;pug_html = pug_html + "\u003Cdiv class=\"modal fade\" id=\"manage-projects\" role=\"dialog\" tabindex=\"-1\" style=\"overflow:hidden\"\u003E\u003Cdiv class=\"modal-dialog\" role=\"document\"\u003E\u003Cdiv class=\"modal-content\"\u003E\u003Cdiv class=\"modal-header\"\u003E\u003Cbutton class=\"close\" data-dismiss=\"modal\" aria-label=\"close\"\u003E\u003Cspan aria-hidden=\"true\"\u003E&times;\u003C\u002Fspan\u003E\u003C\u002Fbutton\u003E\u003Ch4 class=\"modal-title\"\u003EManage Projects\u003C\u002Fh4\u003E\u003Csmall\u003E\u003Cspan class=\"label label-danger\"\u003E\u003C\u002Fspan\u003E\u003C\u002Fsmall\u003E\u003C\u002Fdiv\u003E\u003Cdiv class=\"modal-body\"\u003E\u003Cdiv id=\"projects-grid\" style=\"width:100%;height:400px\"\u003E\u003C\u002Fdiv\u003E\u003C\u002Fdiv\u003E\u003Cdiv class=\"modal-footer\"\u003E\u003Cbutton class=\"btn btn-default\" data-dismiss=\"modal\"\u003ECancel\u003C\u002Fbutton\u003E\u003Cbutton class=\"btn btn-primary\" data-dismiss=\"modal\"\u003ESave\u003C\u002Fbutton\u003E\u003C\u002Fdiv\u003E\u003C\u002Fdiv\u003E\u003C\u002Fdiv\u003E\u003C\u002Fdiv\u003E";;return pug_html;};
module.exports = template;

/***/ }),

/***/ "./client/project/modular-project.pug":
/***/ (function(module, exports, __webpack_require__) {

var pug = __webpack_require__("./node_modules/pug-runtime/index.js");

function template(locals) {var pug_html = "", pug_mixins = {}, pug_interp;pug_html = pug_html + "\u003Cdiv class=\"modal fade\" id=\"modal-saveAs-project\" role=\"dialog\" tabindex=\"-1\"\u003E\u003Cdiv class=\"modal-dialog\"\u003E\u003Cdiv class=\"modal-content\"\u003E\u003Cdiv class=\"modal-header\"\u003E\u003Cbutton class=\"close\" data-dismiss=\"modal\" aria-label=\"close\"\u003E\u003Cspan aria-hidden=\"true\"\u003E&times;\u003C\u002Fspan\u003E\u003C\u002Fbutton\u003E\u003Ch4 class=\"modal-title\"\u003EModule\u003C\u002Fh4\u003E\u003Csmall\u003E\u003Cspan class=\"label label-danger\"\u003E\u003C\u002Fspan\u003E\u003C\u002Fsmall\u003E\u003C\u002Fdiv\u003E\u003Cdiv class=\"modal-body\"\u003E\u003Cform class=\"param-form form-horizontal\" id=\"saveAs\"\u003E\u003Cdiv class=\"form-group form-group-sm\"\u003E\u003Clabel class=\"col-sm-4 control-label\" for=\"Module Name\" title=\"\"\u003EModule Name\u003C\u002Flabel\u003E\u003Cdiv class=\"col-sm-4\"\u003E\u003Cinput class=\"form-control\" id=\"project-name\" onchange=\"amp.ProjectManager.checkProjectName(this)\" value=\"\"\u003E\u003C\u002Fdiv\u003E\u003C\u002Fdiv\u003E\u003C\u002Fform\u003E\u003C\u002Fdiv\u003E\u003Cdiv class=\"modal-footer\"\u003E\u003Cbutton class=\"btn btn-default\" data-dismiss=\"modal\"\u003ECreate\u003C\u002Fbutton\u003E\u003C\u002Fdiv\u003E\u003C\u002Fdiv\u003E\u003C\u002Fdiv\u003E\u003C\u002Fdiv\u003E";;return pug_html;};
module.exports = template;

/***/ }),

/***/ "./client/project/new-project.pug":
/***/ (function(module, exports, __webpack_require__) {

var pug = __webpack_require__("./node_modules/pug-runtime/index.js");

function template(locals) {var pug_html = "", pug_mixins = {}, pug_interp;pug_html = pug_html + "\u003Cdiv class=\"modal fade\" id=\"modal-new-project\" role=\"dialog\" tabindex=\"-1\"\u003E\u003Cdiv class=\"modal-dialog\"\u003E\u003Cdiv class=\"modal-content\"\u003E\u003Cdiv class=\"modal-header\"\u003E\u003Cbutton class=\"close\" data-dismiss=\"modal\" aria-label=\"close\"\u003E\u003Cspan aria-hidden=\"true\"\u003E&times;\u003C\u002Fspan\u003E\u003C\u002Fbutton\u003E\u003Ch4 class=\"modal-title\"\u003ECreate new project\u003C\u002Fh4\u003E\u003Csmall\u003E\u003Cspan class=\"label label-danger\"\u003E\u003C\u002Fspan\u003E\u003C\u002Fsmall\u003E\u003C\u002Fdiv\u003E\u003Cdiv class=\"modal-body\"\u003E\u003Cform class=\"param-form form-horizontal\" id=\"new-project\"\u003E\u003Cdiv class=\"form-group form-group-sm\"\u003E\u003Clabel class=\"col-sm-4 control-label\" for=\"Project Name\"\u003EProject Name\u003C\u002Flabel\u003E\u003Cdiv class=\"col-sm-8\"\u003E\u003Cinput class=\"form-control\" id=\"project-name\" onchange=\"amp.ProjectManager.checkProjectName(this)\"\u003E\u003C\u002Fdiv\u003E\u003C\u002Fdiv\u003E\u003C\u002Fform\u003E\u003C\u002Fdiv\u003E\u003Cdiv class=\"modal-footer\"\u003E\u003Cbutton class=\"btn btn-default\" data-dismiss=\"modal\"\u003ECreate\u003C\u002Fbutton\u003E\u003C\u002Fdiv\u003E\u003C\u002Fdiv\u003E\u003C\u002Fdiv\u003E\u003C\u002Fdiv\u003E";;return pug_html;};
module.exports = template;

/***/ }),

/***/ "./client/project/project-manager.js":
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* WEBPACK VAR INJECTION */(function(Buffer) {/* harmony import */ var _babel_runtime_helpers_typeof__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./node_modules/@babel/runtime/helpers/typeof.js");
/* harmony import */ var _babel_runtime_helpers_typeof__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_typeof__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./node_modules/@babel/runtime/helpers/asyncToGenerator.js");
/* harmony import */ var _babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_1__);
/* harmony import */ var _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__("./node_modules/@babel/runtime/regenerator/index.js");
/* harmony import */ var _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2__);
/* harmony import */ var lodash__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__("./node_modules/lodash/lodash.js");
/* harmony import */ var lodash__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(lodash__WEBPACK_IMPORTED_MODULE_3__);
/* harmony import */ var qgraph__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__("./node_modules/qgraph/lib/qgraph.js");
/* harmony import */ var qgraph__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(qgraph__WEBPACK_IMPORTED_MODULE_4__);
/* harmony import */ var debug__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__("./node_modules/debug/src/browser.js");
/* harmony import */ var debug__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(debug__WEBPACK_IMPORTED_MODULE_5__);
/* harmony import */ var jszip__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__("./node_modules/jszip/dist/jszip.min.js");
/* harmony import */ var jszip__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(jszip__WEBPACK_IMPORTED_MODULE_6__);
/* harmony import */ var file_saver__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__("./node_modules/file-saver/dist/FileSaver.min.js");
/* harmony import */ var file_saver__WEBPACK_IMPORTED_MODULE_7___default = /*#__PURE__*/__webpack_require__.n(file_saver__WEBPACK_IMPORTED_MODULE_7__);
/* harmony import */ var _utils_common__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__("./client/utils/common.js");
/* harmony import */ var _new_project_pug__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__("./client/project/new-project.pug");
/* harmony import */ var _new_project_pug__WEBPACK_IMPORTED_MODULE_9___default = /*#__PURE__*/__webpack_require__.n(_new_project_pug__WEBPACK_IMPORTED_MODULE_9__);
/* harmony import */ var _import_project_pug__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__("./client/project/import-project.pug");
/* harmony import */ var _import_project_pug__WEBPACK_IMPORTED_MODULE_10___default = /*#__PURE__*/__webpack_require__.n(_import_project_pug__WEBPACK_IMPORTED_MODULE_10__);
/* harmony import */ var _saveAs_project_pug__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__("./client/project/saveAs-project.pug");
/* harmony import */ var _saveAs_project_pug__WEBPACK_IMPORTED_MODULE_11___default = /*#__PURE__*/__webpack_require__.n(_saveAs_project_pug__WEBPACK_IMPORTED_MODULE_11__);
/* harmony import */ var _modular_project_pug__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__("./client/project/modular-project.pug");
/* harmony import */ var _modular_project_pug__WEBPACK_IMPORTED_MODULE_12___default = /*#__PURE__*/__webpack_require__.n(_modular_project_pug__WEBPACK_IMPORTED_MODULE_12__);
/* harmony import */ var _manage_projects_pug__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__("./client/project/manage-projects.pug");
/* harmony import */ var _manage_projects_pug__WEBPACK_IMPORTED_MODULE_13___default = /*#__PURE__*/__webpack_require__.n(_manage_projects_pug__WEBPACK_IMPORTED_MODULE_13__);
/* harmony import */ var _settings_pug__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__("./client/project/settings.pug");
/* harmony import */ var _settings_pug__WEBPACK_IMPORTED_MODULE_14___default = /*#__PURE__*/__webpack_require__.n(_settings_pug__WEBPACK_IMPORTED_MODULE_14__);
/* harmony import */ var _project__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__("./client/project/project.js");
/* harmony import */ var Components_component_manager__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__("./components/component-manager.js");
/* harmony import */ var Components_packages_package_manager__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__("./components/packages/package-manager.js");
/* harmony import */ var _screens_screen_manager__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__("./client/screens/screen-manager.js");
/* harmony import */ var Client_bom__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__("./client/bom.js");
/* harmony import */ var Components_utils_event_bus__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__("./components/utils/event-bus.js");
/* harmony import */ var Components_parameters_clock__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__("./components/parameters/clock.js");
/* harmony import */ var Components_utils_versions__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__("./components/utils/versions.js");


function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }





















var debug = debug__WEBPACK_IMPORTED_MODULE_5___default()('project:manager');
var toolBarColoums = [{
  field: 'order',
  caption: 'order',
  size: '45px',
  sortable: true,
  resizable: true,
  render: 'int',
  editable: {
    type: 'int'
  }
}, {
  field: 'name',
  caption: 'Project Name',
  sortable: true,
  size: '100%',
  editable: {
    type: 'text'
  }
}, {
  field: 'device',
  caption: 'Device',
  sortable: false,
  size: '100px'
}, {
  field: 'modification_time',
  caption: 'Modified Date',
  sortable: true,
  size: '100px',
  render: 'date',
  attr: 'align=right'
}, {
  field: 'creation_time',
  caption: 'Creation Date',
  sortable: true,
  size: '100px',
  render: 'date',
  attr: 'align=right'
}];
/* harmony default export */ __webpack_exports__["default"] = ({
  checkProjectName: function checkProjectName(input, exclude, projects, userID) {
    if (!projects) {
      projects = window.projects;
    }
    if (!lodash__WEBPACK_IMPORTED_MODULE_3___default.a.isString(input)) {
      input = $(input).val();
    }
    // remove ' ' in project name
    input = input.replace(/ /g, '_');
    if (lodash__WEBPACK_IMPORTED_MODULE_3___default.a.isUndefined(exclude) || lodash__WEBPACK_IMPORTED_MODULE_3___default.a.isNull(exclude)) {
      exclude = -1;
    }
    var valid = true;
    projects.forEach(function (p, i) {
      if (i !== exclude && p.name === input && (!userID || !p.userID || p.userID === userID)) {
        valid = false;
        return false;
      }
    });
    return valid;
  },
  refreshProjectsMenu: function refreshProjectsMenu() {
    var releasever = Components_utils_versions__WEBPACK_IMPORTED_MODULE_22__["default"].release;
    var buf = new qgraph__WEBPACK_IMPORTED_MODULE_4___default.a.StringBuffer();
    var ul = $('#openMenu > ul');
    // for modular
    var deleteProjects = [];
    var deleteProjectNames = '';
    if (projects.length > 0) {
      projects.forEach(function (project) {
        if (project && project.config && !project.config.modular) {
          buf.append('<li><a href="javascript:amp.ProjectManager.loadProject(').append(project.projectID).append(')"><span class="menu-text">').append(project.name).append('</span></a></li>');
        } else {
          // for modular: need to remove this project
          if (project.projectID) {
            deleteProjects.push(project.projectID);
            deleteProjectNames = deleteProjectNames + ' ' + project.name;
          }
        }
      });
    } else {
      buf.append('<li class="disabled"><a href="javascript:void(0);"><span class="menu-text">No project available</span></a></li>');
    }
    ul.html(buf.toString());

    // update example and device options depends on platform
    var divs = $('.exampver'); // control examples
    var pdivs = $('.platformver'); // control device platform
    var deviceVer = 'A';
    var updatedone = false;
    if (!releasever) {
      if (project && project.device) {
        deviceVer = project.device.version;
      } else {
        lodash__WEBPACK_IMPORTED_MODULE_3___default.a.forEach(divs, function (ind) {
          // control examples
          var div = $(ind);
          var parent = div.parent();
          parent.show();
        });
        lodash__WEBPACK_IMPORTED_MODULE_3___default.a.forEach(pdivs, function (ind) {
          // control device platform
          var div = $(ind);
          var parent = div.parent();
          parent.show();
        });
        updatedone = true;
      }
    }
    if (!updatedone) {
      lodash__WEBPACK_IMPORTED_MODULE_3___default.a.forEach(divs, function (ind) {
        // control examples
        var div = $(ind);
        var foldername = div.text();
        var usingfolder = false;
        if (foldername === 'Platform ' + deviceVer) {
          usingfolder = true;
        }
        var parent = div.parent();
        if (usingfolder) {
          parent.show();
        } else {
          parent.hide();
        }
      });
      lodash__WEBPACK_IMPORTED_MODULE_3___default.a.forEach(pdivs, function (ind) {
        // control device platform
        var div = $(ind);
        var foldername = div.text();
        var usingfolder = false;
        if (foldername.startsWith('Platform ' + deviceVer)) {
          usingfolder = true;
        } else if (foldername.startsWith('Convert Platform To')) {
          var convertDevice = 'C';
          if (deviceVer === 'B') {
            convertDevice = 'C';
          } else if (deviceVer === 'C') {
            convertDevice = 'B';
          }
          $('#nav-ConvertPlatform' + convertDevice).show();
          $('#nav-ConvertPlatform' + deviceVer).hide();
          usingfolder = true;
        }
        var parent = div.parent();
        if (usingfolder) {
          parent.show();
        } else {
          parent.hide();
        }
      });
    }
    // in the furure, it can be controled by role 'Andapt'
    $('#designExamples').show();
    if (!window.project) {
      $('#saveMenu').addClass('disabled');
      $('#saveAsMenu').addClass('disabled');
      $('#exportMenu').addClass('disabled');
      $('#closeMenu').addClass('disabled');
    } else if (window.guestProject) {
      $('#openMenu').addClass('disabled');
      $('#examplesMenu').addClass('disabled');
      $('#createProjectMenu').addClass('disabled');
      $('#manageProjectMenu').addClass('disabled');
      $('#saveMenu').addClass('disabled');
      $('#saveAsMenu').addClass('disabled');
      $('#importMenu').addClass('disabled');
      $('#exportMenu').removeClass('disabled');
      $('#closeMenu').addClass('disabled');
      $('#manageAccountMenu').addClass('disabled');
      $('#userIdMenu').addClass('disabled');
      $('#changePwdMenu').addClass('disabled');
      $('#adminMenu').addClass('disabled');
      $('#signOutMenu').addClass('disabled');
    } else {
      $('#saveMenu').removeClass('disabled');
      $('#saveAsMenu').removeClass('disabled');
      $('#exportMenu').removeClass('disabled');
      $('#closeMenu').removeClass('disabled');
    }
    if (project) {
      $('#project_name').text(project.name);
    } else {
      $('#project_name').text('Projects');
    }
    if (deleteProjects.length) {
      // for modular: remove these projects from database and projects
      // showModalDialog('Warning', 'Delete some temporary projects(' + deleteProjectNames + ')')
      this.deleteProjects(deleteProjects);
    }
  },
  saveUserConfig: function saveUserConfig(config) {
    return _babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_1___default()(/*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.mark(function _callee() {
      return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.wrap(function _callee$(_context) {
        while (1) switch (_context.prev = _context.next) {
          case 0:
            if (!config) {
              config = user;
            }
            _context.next = 3;
            return Object(_utils_common__WEBPACK_IMPORTED_MODULE_8__["sendCommand"])('/project', {
              method: 'saveUserConfig',
              config: config
            });
          case 3:
          case "end":
            return _context.stop();
        }
      }, _callee);
    }))();
  },
  getModifiedProjectName: function getModifiedProjectName(name, exclude, projects, userID) {
    var index = 1;
    var newName = name;
    while (!this.checkProjectName(newName, exclude, projects, userID)) {
      newName = name + '_' + index;
      index++;
    }
    return newName;
  },
  getFile: function getFile(file, download) {
    return _babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_1___default()(/*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.mark(function _callee2() {
      var data, viewid, dataToDl, blob, url, a, displaystr, fileDialog;
      return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.wrap(function _callee2$(_context2) {
        while (1) switch (_context2.prev = _context2.next) {
          case 0:
            viewid = file;
            viewid = viewid.replace('$', '');
            viewid = 'view_' + viewid;
            if (!(file === '$bom')) {
              _context2.next = 7;
              break;
            }
            data = {
              name: 'globalbom.csv',
              data: Client_bom__WEBPACK_IMPORTED_MODULE_19__["default"].getGlobalBoMCSV(project.chip)
            };
            _context2.next = 16;
            break;
          case 7:
            if (!(file === 'project')) {
              _context2.next = 11;
              break;
            }
            data = project.chip.toConfigString();
            _context2.next = 16;
            break;
          case 11:
            _context2.next = 13;
            return Object(_utils_common__WEBPACK_IMPORTED_MODULE_8__["sendCommand"])('/project', {
              method: 'getFile',
              projectId: project.projectID,
              chipName: project.chip.name,
              projectName: project.name,
              file: file
            });
          case 13:
            data = _context2.sent;
            if (data.success) {
              _context2.next = 16;
              break;
            }
            return _context2.abrupt("return");
          case 16:
            if (download) {
              if (file === 'project') {
                qgraph__WEBPACK_IMPORTED_MODULE_4___default.a.DomUtils.downloadFile(project.name + '.ini', 'data:attachment/text,' + encodeURIComponent(data));
              } else if (file === '$bit') {
                dataToDl = Buffer.from(data.data, 'base64'); // qg.DomUtils.downloadFile(data.name, 'data:application/octet-stream,' + dataToDl)
                blob = new Blob([dataToDl], {
                  type: 'application/octet-stream'
                });
                url = URL.createObjectURL(blob);
                a = document.createElement('a');
                a.href = url;
                a.download = data.name;
                document.body.appendChild(a);
                a.click();
                document.body.removeChild(a);
                URL.revokeObjectURL(url);
              } else {
                qgraph__WEBPACK_IMPORTED_MODULE_4___default.a.DomUtils.downloadFile(data.name, 'data:attachment/text,' + encodeURIComponent(data.data));
              }
              if (file === '$checksum') {
                // after downloaded, display checksum of hex file
                displaystr = data.data.substr(0, data.data.indexOf('START'));
                $('#checksum').text(' ' + displaystr);
              }
            } else {
              fileDialog = $('#file-dialog');
              if (fileDialog.length === 0) {
                fileDialog = $(Object(_utils_common__WEBPACK_IMPORTED_MODULE_8__["createModalDialog"])('log-dialog', 'modal-lg'));
                fileDialog.find('.modal-body').html('<textarea style="width:100%;height:300px;overflow-x:hidden;overflow-y:auto" id="' + viewid + '" ></textarea>');
                $('body').append(fileDialog);
              }
              fileDialog.modal({
                show: false,
                keyboard: false,
                backdrop: 'static'
              });
              if (file === 'project') {
                fileDialog.find('.modal-header h4').text('Project Config');
                fileDialog.find('.modal-body textarea').text(data);
              } else {
                fileDialog.find('.modal-header h4').text(data.name);
                fileDialog.find('.modal-body textarea').text(data.data);
              }
              fileDialog.modal('show');
            }
          case 17:
          case "end":
            return _context2.stop();
        }
      }, _callee2);
    }))();
  },
  uploadFile: function uploadFile(fileName) {
    var form = new qgraph__WEBPACK_IMPORTED_MODULE_4___default.a.StringBuffer();
    form.append('<form><input type="file"/></form>');
    form = $(qgraph__WEBPACK_IMPORTED_MODULE_4___default.a.DomUtils.createElementByString(form.toString()));
    var input = form.find('input[type="file"]');
    input.change(function () {
      var file = this.files[0];
      var reader = new FileReader();
      reader.onload = /*#__PURE__*/_babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_1___default()(/*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.mark(function _callee3() {
        var data;
        return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.wrap(function _callee3$(_context3) {
          while (1) switch (_context3.prev = _context3.next) {
            case 0:
              _context3.next = 2;
              return Object(_utils_common__WEBPACK_IMPORTED_MODULE_8__["sendCommand"])('/project', {
                method: 'upload',
                fileName: fileName,
                file: '' + reader.result,
                projectId: project.projectID,
                chipName: project.chip.name,
                projectName: project.name
              });
            case 2:
              data = _context3.sent;
              if (data.success) {
                // showModalDialog('File Uploaded')
                $('#' + fileName.slice(1) + 'Uploaded').show();
              } else {
                Object(_utils_common__WEBPACK_IMPORTED_MODULE_8__["showModalDialog"])('File Upload Failed!!');
              }
            case 4:
            case "end":
              return _context3.stop();
          }
        }, _callee3);
      }));
      reader.readAsText(file);
    });
    input.click();
  },
  confirmCreate: function confirmCreate(grid) {
    var _this = this;
    return new Promise(function (resolve) {
      var selections = grid.getSelection();
      var msg = 'Are you sure you want to create ' + selections.length + ' new projects?';
      Object(_utils_common__WEBPACK_IMPORTED_MODULE_8__["showConfirm"])(msg, null, {
        name: 'Duplicate',
        className: 'btn-danger'
      }, /*#__PURE__*/function () {
        var _ref2 = _babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_1___default()(/*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.mark(function _callee4(confirm) {
          var copiedProjects, names;
          return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.wrap(function _callee4$(_context4) {
            while (1) switch (_context4.prev = _context4.next) {
              case 0:
                if (!confirm) {
                  _context4.next = 7;
                  break;
                }
                copiedProjects = [];
                names = lodash__WEBPACK_IMPORTED_MODULE_3___default.a.map(grid.records, function (r) {
                  return {
                    name: r.changes && r.changes.name ? r.changes.name : r.name,
                    userID: r.userID
                  };
                });
                selections.forEach(function (recid) {
                  var record;
                  var newName;
                  record = lodash__WEBPACK_IMPORTED_MODULE_3___default.a.find(grid.records, {
                    recid: recid
                  });
                  newName = _this.getModifiedProjectName(record.name, null, names);
                  copiedProjects.push({
                    projectID: 'N' + record.recid,
                    name: newName,
                    config: record.config ? lodash__WEBPACK_IMPORTED_MODULE_3___default.a.cloneDeep(record.config) : null,
                    userID: record.userID
                  });
                  names.push({
                    name: newName,
                    userID: record.userID
                  });
                });
                _context4.next = 6;
                return _this.createProjects(copiedProjects);
              case 6:
                resolve(true);
              case 7:
                resolve(false);
              case 8:
              case "end":
                return _context4.stop();
            }
          }, _callee4);
        }));
        return function (_x) {
          return _ref2.apply(this, arguments);
        };
      }());
    });
  },
  createNew: function createNew() {
    var _this2 = this;
    $('#nav-ConvertPlatformC').hide();
    $('#nav-ConvertPlatformB').hide();
    var dialog = $(_new_project_pug__WEBPACK_IMPORTED_MODULE_9___default()());
    $('body').append(dialog);
    Object(_utils_common__WEBPACK_IMPORTED_MODULE_8__["setDialogButtonAction"])(dialog, 'Create', /*#__PURE__*/function () {
      var _ref3 = _babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_1___default()(/*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.mark(function _callee5(event) {
        var input, nValid, name, validNameExp, _yield$sendCommand, success, data;
        return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.wrap(function _callee5$(_context5) {
          while (1) switch (_context5.prev = _context5.next) {
            case 0:
              input = dialog.find('input');
              nValid = false;
              name = $(input).val();
              validNameExp = /^[A-Z_][0-9A-Z_]*$/i;
              nValid = validNameExp.test(name);
              if (nValid) {
                _context5.next = 10;
                break;
              }
              if ($(input).val().match(/^\d/)) {
                dialog.find('.modal-header small span').text('Project name can not start with number');
              } else {
                dialog.find('.modal-header small span').text('Project name ONLY includes A..Z, a..z, 0..9, _');
              }
              event.stopPropagation();
              _context5.next = 26;
              break;
            case 10:
              if (_this2.checkProjectName(input[0])) {
                _context5.next = 15;
                break;
              }
              dialog.find('.modal-header small span').text('Project name has been taken');
              event.stopPropagation();
              _context5.next = 26;
              break;
            case 15:
              _context5.next = 17;
              return Object(_utils_common__WEBPACK_IMPORTED_MODULE_8__["sendCommand"])('/project', {
                method: 'new',
                name: input.val()
              });
            case 17:
              _yield$sendCommand = _context5.sent;
              success = _yield$sendCommand.success;
              data = _yield$sendCommand.data;
              if (success) {
                _context5.next = 22;
                break;
              }
              return _context5.abrupt("return");
            case 22:
              if (data) {
                _context5.next = 24;
                break;
              }
              return _context5.abrupt("return");
            case 24:
              projects.push(data);
              _this2.loadProject(data.projectID, true);
            case 26:
            case "end":
              return _context5.stop();
          }
        }, _callee5);
      }));
      return function (_x2) {
        return _ref3.apply(this, arguments);
      };
    }(), true);
  },
  createProjects: function createProjects(projs) {
    var _this3 = this;
    return _babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_1___default()(/*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.mark(function _callee6() {
      var max, batch, _yield$sendCommand2, success, data;
      return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.wrap(function _callee6$(_context6) {
        while (1) switch (_context6.prev = _context6.next) {
          case 0:
            // If there are too many projects, we need to break it up so as to avoid payload too large error.
            max = 10;
            if (!(projs.length > max)) {
              _context6.next = 6;
              break;
            }
            batch = projs.splice(0, max);
            _context6.next = 5;
            return _this3.createProjects(batch);
          case 5:
            return _context6.abrupt("return", _this3.createProjects(projs));
          case 6:
            if (!(projs.length > 0)) {
              _context6.next = 15;
              break;
            }
            _context6.next = 9;
            return Object(_utils_common__WEBPACK_IMPORTED_MODULE_8__["sendCommand"])('/project', {
              method: 'createProjects',
              projects: projs
            });
          case 9:
            _yield$sendCommand2 = _context6.sent;
            success = _yield$sendCommand2.success;
            data = _yield$sendCommand2.data;
            if (success) {
              _context6.next = 14;
              break;
            }
            return _context6.abrupt("return");
          case 14:
            projs.forEach(function (p, i) {
              p.projectID = data.id + i;
              p.modification_time = data.modification_time;
              p.creation_time = data.creation_time;
              if (!p.userID) {
                projects.push(p);
              }
            });
          case 15:
          case "end":
            return _context6.stop();
        }
      }, _callee6);
    }))();
  },
  diffFiles: function diffFiles(f1, f2) {
    function lookForSameLine(line, file, index, count) {
      var maxDiff = 10;
      for (var i = index; i < count; i++) {
        if (i - index > maxDiff) {
          return count;
        }
        ;
        if (file[i].trim() === line.trim()) {
          return i;
        }
        ;
      }
      ;
      return count;
    }
    ;
    var index1 = 0;
    var index2 = 0;
    var result = [];
    var diff = false;
    var count1 = f1.length;
    var count2 = f2.length;
    while (index1 < count1 && index2 < count2) {
      var line1 = f1[index1].trim();
      var line2 = f2[index2].trim();
      if (line1 === line2) {
        result.push(line1);
        index1++;
        index2++;
      } else {
        diff = true;
        var next1 = lookForSameLine(line2, f1, index1, count1);
        var next2 = lookForSameLine(line1, f2, index2, count2);
        if (next1 === count1 && next2 === count2) {
          next1 = index1 + 1;
          next2 = index2 + 1;
        } else if (next2 === count2) {
          next2 = index2;
        } else if (next1 === count1) {
          next1 = index1;
        } else {
          if (next1 - index1 < next2 - index2) {
            next2 = index2;
          } else {
            next1 = index1;
          }
          ;
        }
        ;
        for (var i = index1; i < next1; i++) {
          result.push('+++ ' + f1[i]);
        }
        ;
        for (var _i = index2; _i < next2; _i++) {
          result.push('--- ' + f2[_i]);
        }
        ;
        index1 = next1;
        index2 = next2;
      }
    }
    return [diff, result];
  },
  // this function only for cypress testing
  deleteAllProjects: function deleteAllProjects() {
    return _babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_1___default()(/*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.mark(function _callee7() {
      var selections, _yield$sendCommand3, success;
      return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.wrap(function _callee7$(_context7) {
        while (1) switch (_context7.prev = _context7.next) {
          case 0:
            selections = projects.map(function (p) {
              return p.projectID;
            });
            if (selections) {
              _context7.next = 3;
              break;
            }
            return _context7.abrupt("return");
          case 3:
            _context7.next = 5;
            return Object(_utils_common__WEBPACK_IMPORTED_MODULE_8__["sendCommand"])('/project', {
              method: 'deleteProjects',
              projects: selections
            });
          case 5:
            _yield$sendCommand3 = _context7.sent;
            success = _yield$sendCommand3.success;
            if (success) {
              _context7.next = 9;
              break;
            }
            return _context7.abrupt("return");
          case 9:
            if (projects) {
              lodash__WEBPACK_IMPORTED_MODULE_3___default.a.remove(projects, function (p) {
                return selections.indexOf(p.projectID) >= 0;
              });
            }
          case 10:
          case "end":
            return _context7.stop();
        }
      }, _callee7);
    }))();
  },
  changeVersionForTest: function changeVersionForTest(platform, compType, compVersion) {
    var _this4 = this;
    return _babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_1___default()(/*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.mark(function _callee8() {
      var deviceName, parts, comp;
      return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.wrap(function _callee8$(_context8) {
        while (1) switch (_context8.prev = _context8.next) {
          case 0:
            deviceName = project.config.chips[0].device;
            if (deviceName) {
              // in case, it is a old webamp project
              deviceName = deviceName.replace('S', '');
              parts = deviceName.match(/^AmP(\d+)D([A|B|C]?)(\d)(.*)$/);
              if (platform === 'A') platform = ''; // 'A' is default
              deviceName = 'AmP' + parts[1] + 'D' + platform + parts[3] + parts[4];
              project.config.chips[0].device = deviceName;
            }
            project.config.chips[0].components.forEach(function (c) {
              c.version = compVersion;
            });
            comp = Components_component_manager__WEBPACK_IMPORTED_MODULE_16__["default"].newComponent(compType, project.chip);
            _this4.clearProject(true);
            project = new _project__WEBPACK_IMPORTED_MODULE_15__["default"](project);
            project.selected = comp;
            _this4.validateConnections();
            _this4.refreshProjectsMenu();
          case 9:
          case "end":
            return _context8.stop();
        }
      }, _callee8);
    }))();
  },
  cleanLegacy: function cleanLegacy(chip) {
    if (chip.autoConnections) {
      // Clean legacy tristate in autoConnection
      // let tristates = chip.ios['TriState']
      // let removeAutoConnTriS = []
      // for (const el of chip.autoConnections) {
      //   if (el.portName.includes('triState')) {
      //     let portNameArr = el.portName.split('_')
      //     if (!tristates.includes(parseInt(portNameArr[portNameArr.length - 1]))) removeAutoConnTriS.push(el.portName)
      //   }
      // }
      // chip.autoConnections = chip.autoConnections.filter(el => !removeAutoConnTriS.includes(el.portName))

      var simpleChipJSON = function simpleChipJSON(chip) {
        // stringify an object, avoiding circular structures (_chip)
        var simpleObject = {};
        for (var prop in chip) {
          if (!chip.hasOwnProperty(prop)) continue;
          if (_babel_runtime_helpers_typeof__WEBPACK_IMPORTED_MODULE_0___default()(chip[prop]) === 'object') continue;
          if (typeof chip[prop] === 'function') continue;
          simpleObject[prop] = chip[prop];
        }
        return JSON.stringify(simpleObject);
      };

      // Clean legacy tristate in autoConnection by parsing all data
      var chipAsString = simpleChipJSON(chip);
      var triStatesToDelete = [];
      var _iterator = _createForOfIteratorHelper(chip.autoConnections),
        _step;
      try {
        for (_iterator.s(); !(_step = _iterator.n()).done;) {
          var _el = _step.value;
          // If array length after split is <= 2, it is NOT being used.
          if (_el.portName.includes('triState') && chipAsString.split(_el.portName).length <= 2) triStatesToDelete.push(_el.portName);
        }
      } catch (err) {
        _iterator.e(err);
      } finally {
        _iterator.f();
      }
      chip.autoConnections = chip.autoConnections.filter(function (el) {
        return !triStatesToDelete.includes(el.portName);
      });

      // Clean fixed wires in autoConnections
      var listOfFixedConn = [];
      for (var el in chip.connections) {
        listOfFixedConn.push(chip.connections[el]);
      }
      chip.autoConnections = chip.autoConnections.filter(function (el) {
        return !listOfFixedConn.includes(el.portName);
      });
    }
  },
  // TODO: should be able to load in memory project, instead of going to server every time.
  loadProject: function loadProject(id, validateParams) {
    var _this5 = this;
    debug('loadProject - id: %s', id);
    var idNum = id;
    if (lodash__WEBPACK_IMPORTED_MODULE_3___default.a.isString(id)) {
      idNum = parseInt(id);
    }
    var jump = "yes";
    this.confirmSave(/*#__PURE__*/_babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_1___default()(/*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.mark(function _callee9() {
      var _yield$sendCommand4, success, data, deviceName, revision, parts, chip, screen, isNumber;
      return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.wrap(function _callee9$(_context9) {
        while (1) switch (_context9.prev = _context9.next) {
          case 0:
            _context9.next = 2;
            return Object(_utils_common__WEBPACK_IMPORTED_MODULE_8__["sendCommand"])('/project', {
              method: 'load',
              id: id
            });
          case 2:
            _yield$sendCommand4 = _context9.sent;
            success = _yield$sendCommand4.success;
            data = _yield$sendCommand4.data;
            if (success) {
              _context9.next = 7;
              break;
            }
            return _context9.abrupt("return");
          case 7:
            if (data) {
              _context9.next = 9;
              break;
            }
            return _context9.abrupt("return");
          case 9:
            if (!(jump === 'yes')) {
              _context9.next = 20;
              break;
            }
            if (!(Object.keys(data.config).length > 0)) {
              _context9.next = 20;
              break;
            }
            // check if component is revision A or B
            deviceName = data.config.chips[0].device;
            if (!deviceName) {
              _context9.next = 20;
              break;
            }
            // in case, it is a old webamp project
            deviceName = deviceName.replace('S', '');
            revision = 'A';
            parts = deviceName.match(/^AmP(\d+)D([A|B|C]?)(\d)(.*)$/);
            if (parts[2].length > 0) {
              revision = parts[2];
            }
            if (!(revision === 'A')) {
              _context9.next = 20;
              break;
            }
            // redirect to A platform
            window.location.replace("https://webamp.andapt.com" + "/projects/".concat(id));
            return _context9.abrupt("return");
          case 20:
            _this5.clearProject(true);
            lodash__WEBPACK_IMPORTED_MODULE_3___default.a.remove(projects, function (p) {
              return p.projectID === idNum;
            });
            user.superMode = false;
            projects.unshift(data);
            project = new _project__WEBPACK_IMPORTED_MODULE_15__["default"](data);
            chip = project.chip;
            if (validateParams) {
              chip.components.forEach(function (c) {
                c.validateParams();
              });
              chip.digitals.forEach(function (c) {
                c.validateParams();
              });
            }
            if (chip.currentStage === 'tuning') {
              chip.currentStage = 'design';
            }
            // Clean legacy autoConnections
            _this5.cleanLegacy(chip);
            // chip.updateOldLDOComponent()
            screen = _screens_screen_manager__WEBPACK_IMPORTED_MODULE_18__["default"].getScreen('design');
            if (screen && screen.initialized) {
              // considering possible platform changed, need to re build categories
              screen.buildCategories();
              screen.showThermal = false; // make sure it is not in thermal page when loaded
              screen.showComponents = true;
              screen.showConnections = true;
              screen.refresh();
            }
            screen.enableBtns();
            _this5.refreshProjectsMenu();
            project.dirty = false;
            Components_utils_event_bus__WEBPACK_IMPORTED_MODULE_20__["default"].$emit('projectLoaded');
            if (!chip.verilogLibVersions) {
              chip['verilogLibVersions'] = 'Production';
            }
            isNumber = false;
            if (chip.VIN) {
              isNumber = lodash__WEBPACK_IMPORTED_MODULE_3___default.a.isNumber(chip.VIN);
            }
            if (!isNumber) {
              if (screen) {
                screen.handleVIN();
              }
            }
          case 39:
          case "end":
            return _context9.stop();
        }
      }, _callee9);
    })));
  },
  // Load guest project
  loadGuestProject: function loadGuestProject(id, validateParams) {
    var _this6 = this;
    debug('loadGuestProject - id: %s', id);
    var idNum = id;
    if (lodash__WEBPACK_IMPORTED_MODULE_3___default.a.isString(id)) {
      idNum = parseInt(id);
    }
    var jump = "yes";
    this.confirmSave(/*#__PURE__*/_babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_1___default()(/*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.mark(function _callee10() {
      var data, chip, screen, isNumber;
      return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.wrap(function _callee10$(_context10) {
        while (1) switch (_context10.prev = _context10.next) {
          case 0:
            projects.push(window.guestProject);
            data = window.guestProject;
            _this6.clearProject(true);
            lodash__WEBPACK_IMPORTED_MODULE_3___default.a.remove(projects, function (p) {
              return p.projectID === idNum;
            });
            user.superMode = false;
            projects.unshift(data);
            project = new _project__WEBPACK_IMPORTED_MODULE_15__["default"](data);
            chip = project.chip;
            if (validateParams) {
              chip.components.forEach(function (c) {
                c.validateParams();
              });
              chip.digitals.forEach(function (c) {
                c.validateParams();
              });
            }
            if (chip.currentStage === 'tuning') {
              chip.currentStage = 'design';
            }
            // Clean legacy autoConnections
            _this6.cleanLegacy(chip);
            // chip.updateOldLDOComponent()
            screen = _screens_screen_manager__WEBPACK_IMPORTED_MODULE_18__["default"].getScreen('design');
            if (screen && screen.initialized) {
              // considering possible platform changed, need to re build categories
              screen.buildCategories();
              screen.showThermal = false; // make sure it is not in thermal page when loaded
              screen.showComponents = true;
              screen.showConnections = true;
              screen.refresh();
            }
            screen.enableBtns();
            _this6.refreshProjectsMenu();
            project.dirty = false;
            Components_utils_event_bus__WEBPACK_IMPORTED_MODULE_20__["default"].$emit('projectLoaded');
            if (!chip.verilogLibVersions) {
              chip['verilogLibVersions'] = 'Production';
            }
            isNumber = false;
            if (chip.VIN) {
              isNumber = lodash__WEBPACK_IMPORTED_MODULE_3___default.a.isNumber(chip.VIN);
            }
            if (!isNumber) {
              if (screen) {
                screen.handleVIN();
              }
            }
          case 21:
          case "end":
            return _context10.stop();
        }
      }, _callee10);
    })));
  },
  convertPlatformForProject: function convertPlatformForProject(newPlatform, buildCategories) {
    var _this7 = this;
    return _babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_1___default()(/*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.mark(function _callee11() {
      var validateParams, chip, platFormVersion, parts, versionFound, failedComps, fc, newDeviceName, screen;
      return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.wrap(function _callee11$(_context11) {
        while (1) switch (_context11.prev = _context11.next) {
          case 0:
            if (lodash__WEBPACK_IMPORTED_MODULE_3___default.a.isUndefined(buildCategories)) buildCategories = true;
            debug('convertPlatformForProject - newPlatform: %s', newPlatform);
            validateParams = true;
            chip = project.chip; // change device
            platFormVersion = 'B';
            parts = chip.device.name.match(/^AmP(\d+)D([A|B|C]?)(\d)(.*)$/);
            if (parts[2].length > 0) {
              platFormVersion = parts[2];
            }
            if (platFormVersion !== newPlatform) {
              platFormVersion = newPlatform;
            }
            // check all component version existed in newPlatform, if not, report a convert failed.
            versionFound = true;
            failedComps = [];
            project.config.chips[0].components.forEach(function (c) {
              var version = Components_component_manager__WEBPACK_IMPORTED_MODULE_16__["default"].getDefaultVersion(c, c.type, newPlatform, chip, true)[1];
              if (version === undefined) {
                var comp = chip.components.find(function (x) {
                  return x.id === c.id;
                });
                var typeConvert = comp.config.typeConvert;
                if (!typeConvert) {
                  versionFound = false;
                  failedComps.push('component' + c.id + ' ' + c.type);
                }
              }
            });
            project.config.chips[0].digitals.forEach(function (c) {
              var version = Components_component_manager__WEBPACK_IMPORTED_MODULE_16__["default"].getDefaultVersion(c, c.type, newPlatform, chip, true)[1];
              if (version === undefined) {
                versionFound = false;
                failedComps.push('component' + c.id + ' ' + c.type);
              }
            });
            if (versionFound) {
              _context11.next = 16;
              break;
            }
            fc = failedComps.join();
            Object(_utils_common__WEBPACK_IMPORTED_MODULE_8__["showModalDialog"])('Convert Failed', 'these component(s)(' + fc + ') cannot be converted and convert action failed');
            return _context11.abrupt("return");
          case 16:
            // start convert action
            // if (platFormVersion === 'A') platFormVersion = ''// 'A' is default
            newDeviceName = 'AmP' + parts[1] + 'D' + platFormVersion + parts[3] + parts[4];
            chip.device = newDeviceName;
            project.config.chips[0].device = newDeviceName;

            // change component version
            project.config.chips[0].components.forEach(function (c) {
              var compVer = '_1_0';
              var compType = c.type;
              var idx = c.type.indexOf('_');
              if (idx > 0) {
                // separating type and version
                compVer = c.type.substring(idx + 2, c.type.length);
                compType = c.type.substring(0, idx);
              }
              var comp = chip.components.find(function (x) {
                return x.id === c.id;
              });
              var typeConvert = comp.config.typeConvert;
              // if (newPlatform === 'B') {
              if (typeConvert) {
                if (typeConvert[1] === 'any') {
                  c.version = 'B' + compVer;
                } else {
                  c.version = typeConvert[1];
                }
                c.type = typeConvert[0];
              } else {
                c.version = Components_component_manager__WEBPACK_IMPORTED_MODULE_16__["default"].getDefaultVersion(c, c.type, newPlatform, chip, true)[1];
                c.type = compType;
              }
              // } else {
              //  c.version = ComponentManager.getDefaultVersion(c, c.type, newPlatform, chip, true)[1]
              //  c.type = compType
              // }
            });
            project.config.chips[0].digitals.forEach(function (c) {
              c.version = Components_component_manager__WEBPACK_IMPORTED_MODULE_16__["default"].getDefaultVersion(c, c.type, newPlatform, chip, true)[1];
            });
            // rebuild project
            project.chips.components = project.config.chips[0].components;
            project.chips.digitals = project.config.chips[0].digitals;
            _this7.clearProject(true);
            lodash__WEBPACK_IMPORTED_MODULE_3___default.a.remove(projects, function (p) {
              return p.projectID === project.projectID;
            });
            projects.unshift(project);
            project = new _project__WEBPACK_IMPORTED_MODULE_15__["default"](project);
            _context11.next = 29;
            return _this7.saveProject();
          case 29:
            chip = project.chip;
            if (validateParams) {
              chip.components.forEach(function (c) {
                c.validateParams();
              });
              chip.digitals.forEach(function (c) {
                c.validateParams();
              });
            }
            /* if (process.env.JUMP_ENABLE === 'yes') {
              if (newPlatform === 'A') {
                let id = project.projectID
                // redirect to A platform
                window.location.replace(process.env.REVISION_A_URL + `/projects/${id}`)
                return
              }
            } */
            if (chip.currentStage === 'tuning') {
              chip.currentStage = 'design';
            }
            // chip.updateOldLDOComponent()
            if (buildCategories) {
              screen = _screens_screen_manager__WEBPACK_IMPORTED_MODULE_18__["default"].getScreen('design');
              if (screen && screen.initialized) {
                // considering possible platform changed, need to re build categories
                screen.buildCategories();
                screen.refresh();
              }
            }
            // chip.updateOldLDOComponent()
            _this7.refreshProjectsMenu();
            // EventBus.$emit('projectLoaded')
          case 34:
          case "end":
            return _context11.stop();
        }
      }, _callee11);
    }))();
  },
  clearProject: function clearProject(checkDirty) {
    debug('clearProject');
    var check = checkDirty;
    if (lodash__WEBPACK_IMPORTED_MODULE_3___default.a.isUndefined(checkDirty)) check = false;
    if (project) {
      if (!check) project.dirty = false;
      // TODO: use event instead
      $('#topUploaded').hide();
      $('#paramUploaded').hide();
      $('#implUploaded').hide();
      $('#pcfUploaded').hide();
      _screens_screen_manager__WEBPACK_IMPORTED_MODULE_18__["default"].reset();
    }
  },
  confirmSave: function confirmSave(callback) {
    var _this8 = this;
    if (!project || !project.dirty) {
      if (callback) callback();
      return;
    }
    Object(_utils_common__WEBPACK_IMPORTED_MODULE_8__["showConfirm"])('Do you want to save the current project?', {
      name: 'No',
      className: 'btn-danger'
    }, {
      name: 'Yes',
      className: 'btn-success'
    }, /*#__PURE__*/function () {
      var _ref6 = _babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_1___default()(/*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.mark(function _callee12(confirm) {
        return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.wrap(function _callee12$(_context12) {
          while (1) switch (_context12.prev = _context12.next) {
            case 0:
              if (!confirm) {
                _context12.next = 3;
                break;
              }
              _context12.next = 3;
              return _this8.saveProject();
            case 3:
              if (callback) callback();
            case 4:
            case "end":
              return _context12.stop();
          }
        }, _callee12);
      }));
      return function (_x3) {
        return _ref6.apply(this, arguments);
      };
    }());
  },
  keepTdc: function keepTdc() {
    var chip = project.chip;
    chip.components.forEach(function (c) {
      if (c.tdc) {
        var comp = project.config.chips[0].components.find(function (p) {
          return p.id === c.id;
        });
        if (comp) {
          comp.tdc = c.tdc;
        }
      }
    });
    project.config.chips[0].TA = chip.TA;
  },
  saveProject: function saveProject() {
    var _this9 = this;
    return _babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_1___default()(/*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.mark(function _callee13() {
      return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.wrap(function _callee13$(_context13) {
        while (1) switch (_context13.prev = _context13.next) {
          case 0:
            if (project) {
              _context13.next = 2;
              break;
            }
            return _context13.abrupt("return");
          case 2:
            _context13.prev = 2;
            Object(_utils_common__WEBPACK_IMPORTED_MODULE_8__["showBusy"])(true, 'Saving...');
            _this9.keepTdc();
            _context13.next = 7;
            return _this9.saveProjects();
          case 7:
            Object(_utils_common__WEBPACK_IMPORTED_MODULE_8__["hideBusy"])();
            project.dirty = false;
            _context13.next = 14;
            break;
          case 11:
            _context13.prev = 11;
            _context13.t0 = _context13["catch"](2);
            return _context13.abrupt("return", Object(_utils_common__WEBPACK_IMPORTED_MODULE_8__["showModalDialog"])('Error', _context13.t0.message));
          case 14:
          case "end":
            return _context13.stop();
        }
      }, _callee13, null, [[2, 11]]);
    }))();
  },
  // batch operations
  saveProjects: function saveProjects(projects) {
    var _this10 = this;
    return _babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_1___default()(/*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.mark(function _callee14() {
      var max, batch;
      return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.wrap(function _callee14$(_context14) {
        while (1) switch (_context14.prev = _context14.next) {
          case 0:
            if (!projects) {
              projects = [{
                projectID: project.projectID,
                config: project.config,
                name: project.name
              }];
            }
            if (!Array.isArray(projects)) projects = [projects];

            // If there are too many projects, we need to break it up so as to avoid payload too large error.
            max = 10;
            if (!(projects.length > max)) {
              _context14.next = 8;
              break;
            }
            batch = projects.splice(0, max);
            _context14.next = 7;
            return _this10.saveProjects(batch);
          case 7:
            return _context14.abrupt("return", _this10.saveProjects(projects));
          case 8:
            if (!(projects.length > 0)) {
              _context14.next = 11;
              break;
            }
            _context14.next = 11;
            return Object(_utils_common__WEBPACK_IMPORTED_MODULE_8__["sendCommand"])('/project', {
              method: 'saveProjects',
              projects: projects
            });
          case 11:
          case "end":
            return _context14.stop();
        }
      }, _callee14);
    }))();
  },
  confirmDelete: function confirmDelete(selections) {
    var _this11 = this;
    if (!selections) {
      selections = project ? [project.projectID] : null;
    }
    if (!selections) return;
    var msg = 'Are you sure you want to delete these projects?';
    if (selections.length === 1 && typeof project !== 'undefined' && project && (lodash__WEBPACK_IMPORTED_MODULE_3___default.a.isObject(selections[0]) ? selections[0].id === project.projectID : selections[0] === project.projectID)) {
      msg = 'Are you sure you want to delete this project?';
    }
    return new Promise(function (resolve) {
      Object(_utils_common__WEBPACK_IMPORTED_MODULE_8__["showConfirm"])(msg, null, {
        name: 'Delete',
        className: 'btn-danger'
      }, /*#__PURE__*/function () {
        var _ref7 = _babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_1___default()(/*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.mark(function _callee15(confirm) {
          return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.wrap(function _callee15$(_context15) {
            while (1) switch (_context15.prev = _context15.next) {
              case 0:
                if (!confirm) {
                  _context15.next = 4;
                  break;
                }
                _context15.next = 3;
                return _this11.deleteProjects(selections);
              case 3:
                return _context15.abrupt("return", resolve(true));
              case 4:
                resolve(false);
              case 5:
              case "end":
                return _context15.stop();
            }
          }, _callee15);
        }));
        return function (_x4) {
          return _ref7.apply(this, arguments);
        };
      }());
    });
  },
  deleteProject: function deleteProject(showConfirm) {
    var _this12 = this;
    return _babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_1___default()(/*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.mark(function _callee16() {
      var deleted;
      return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.wrap(function _callee16$(_context16) {
        while (1) switch (_context16.prev = _context16.next) {
          case 0:
            if (!project) {
              _context16.next = 16;
              break;
            }
            if (lodash__WEBPACK_IMPORTED_MODULE_3___default.a.isUndefined(showConfirm)) {
              showConfirm = true;
            }
            if (!showConfirm) {
              _context16.next = 10;
              break;
            }
            _context16.next = 5;
            return _this12.confirmDelete([project.projectID]);
          case 5:
            deleted = _context16.sent;
            if (deleted) {
              _context16.next = 8;
              break;
            }
            return _context16.abrupt("return");
          case 8:
            _context16.next = 12;
            break;
          case 10:
            _context16.next = 12;
            return _this12.deleteProjects([project.projectID]);
          case 12:
            _this12.clearProject();
            project = null;
            _this12.refreshProjectsMenu();
            _screens_screen_manager__WEBPACK_IMPORTED_MODULE_18__["default"].showScreen();
          case 16:
          case "end":
            return _context16.stop();
        }
      }, _callee16);
    }))();
  },
  deleteProjects: function deleteProjects(selections) {
    return _babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_1___default()(/*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.mark(function _callee17() {
      var _yield$sendCommand5, success;
      return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.wrap(function _callee17$(_context17) {
        while (1) switch (_context17.prev = _context17.next) {
          case 0:
            if (selections) {
              _context17.next = 2;
              break;
            }
            return _context17.abrupt("return");
          case 2:
            _context17.next = 4;
            return Object(_utils_common__WEBPACK_IMPORTED_MODULE_8__["sendCommand"])('/project', {
              method: 'deleteProjects',
              projects: selections
            });
          case 4:
            _yield$sendCommand5 = _context17.sent;
            success = _yield$sendCommand5.success;
            if (success) {
              _context17.next = 8;
              break;
            }
            return _context17.abrupt("return");
          case 8:
            if (projects) {
              lodash__WEBPACK_IMPORTED_MODULE_3___default.a.remove(projects, function (p) {
                return selections.indexOf(p.projectID) >= 0;
              });
            }
          case 9:
          case "end":
            return _context17.stop();
        }
      }, _callee17);
    }))();
  },
  changeDevice: function changeDevice(deviceName) {
    var _this13 = this;
    return _babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_1___default()(/*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.mark(function _callee18() {
      var chip, id, revision, parts, screen, newDeviceConfig;
      return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.wrap(function _callee18$(_context18) {
        while (1) switch (_context18.prev = _context18.next) {
          case 0:
            chip = project.chip;
            if (chip.device) {
              _context18.next = 19;
              break;
            }
            chip.device = deviceName;
            if (!deviceName) {
              _context18.next = 14;
              break;
            }
            // in case, it is a old webamp project
            // deviceName = deviceName.replace('S', '')
            id = project.projectID;
            revision = 'A';
            parts = deviceName.match(/^AmP(\d+)D([A|B|C]?)(\d)(.*)$/);
            if (parts[2].length > 0) {
              revision = parts[2];
            }
            if (false) {}
            if (!(revision === 'A')) {
              _context18.next = 14;
              break;
            }
            _context18.next = 12;
            return _this13.saveProject();
          case 12:
            // redirect to A platform
            window.location.replace("https://webamp.andapt.com" + "/projects/".concat(id));
            return _context18.abrupt("return");
          case 14:
            // chosen platform, need to re-build Categories
            screen = _screens_screen_manager__WEBPACK_IMPORTED_MODULE_18__["default"].getScreen('design');
            if (screen && screen.initialized) {
              // considering possible platform changed, need to re build categories
              screen.buildCategories();
              screen.refresh();
            }
            _this13.refreshProjectsMenu();
            _context18.next = 25;
            break;
          case 19:
            if (!(chip.device.name !== deviceName)) {
              _context18.next = 25;
              break;
            }
            newDeviceConfig = Components_packages_package_manager__WEBPACK_IMPORTED_MODULE_17__["default"].devices.find(function (device) {
              return device.name === deviceName;
            });
            if (!(chip.device.mosfets !== newDeviceConfig.mosfets)) {
              _context18.next = 24;
              break;
            }
            Object(_utils_common__WEBPACK_IMPORTED_MODULE_8__["showModalDialog"])('Warning', 'Can not migrate to device with different mosfets');
            return _context18.abrupt("return");
          case 24:
            Object(_utils_common__WEBPACK_IMPORTED_MODULE_8__["showConfirm"])("Do you want to migrate from ".concat(chip.device.name, " to ").concat(deviceName, " ?"), {
              name: 'No',
              className: 'btn-danger'
            }, {
              name: 'Yes',
              className: 'btn-success'
            }, function (confirm) {
              if (confirm) {
                Object(_utils_common__WEBPACK_IMPORTED_MODULE_8__["showBusy"])(true, 'Changing Device...');
                chip.device = deviceName;
                Object(_utils_common__WEBPACK_IMPORTED_MODULE_8__["hideBusy"])();
                _this13.refreshProjectsMenu();
              }
            });
          case 25:
          case "end":
            return _context18.stop();
        }
      }, _callee18);
    }))();
  },
  "import": function _import() {
    var _this14 = this;
    var dialog = $(_import_project_pug__WEBPACK_IMPORTED_MODULE_10___default()());
    $('body').append(dialog);
    var importedProject;
    $(dialog.find('input')[1]).on('change', function () {
      var inFileName = this.files[0].name;
      var reader = new FileReader();
      reader.onload = /*#__PURE__*/function () {
        var _ref8 = _babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_1___default()(/*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.mark(function _callee19(fle) {
          var jsonContent, zip, jsonName, device, err;
          return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.wrap(function _callee19$(_context19) {
            while (1) switch (_context19.prev = _context19.next) {
              case 0:
                if (!inFileName.endsWith('.zip')) {
                  _context19.next = 11;
                  break;
                }
                _context19.next = 3;
                return jszip__WEBPACK_IMPORTED_MODULE_6___default.a.loadAsync(fle.target.result);
              case 3:
                zip = _context19.sent;
                jsonName = Object.keys(zip.files).find(function (fName) {
                  return fName.endsWith('.json');
                });
                if (!jsonName) {
                  _context19.next = 9;
                  break;
                }
                _context19.next = 8;
                return zip.file(jsonName).async('string');
              case 8:
                jsonContent = _context19.sent;
              case 9:
                _context19.next = 12;
                break;
              case 11:
                jsonContent = reader.result;
              case 12:
                _context19.prev = 12;
                importedProject = JSON.parse(jsonContent);
                device = importedProject.config.chips[0].device;
                if (!(!device || device.includes('QF74'))) {
                  _context19.next = 18;
                  break;
                }
                err = 'Package in project file is unsupported: ' + device;
                throw err;
              case 18:
                _context19.next = 23;
                break;
              case 20:
                _context19.prev = 20;
                _context19.t0 = _context19["catch"](12);
                Object(_utils_common__WEBPACK_IMPORTED_MODULE_8__["showModalDialog"])('Import Failed', 'Project file might be corrupted or unsupported.<br><br>' + 'Please choose a new file or zip.<br><br> ' + _context19.t0);
              case 23:
                $(dialog.find('input')[0]).val(importedProject.name);
              case 24:
              case "end":
                return _context19.stop();
            }
          }, _callee19, null, [[12, 20]]);
        }));
        return function (_x5) {
          return _ref8.apply(this, arguments);
        };
      }();
      if (inFileName.endsWith('.zip')) {
        reader.readAsArrayBuffer(this.files[0]);
      } else {
        reader.readAsText(this.files[0]);
      }
    });
    Object(_utils_common__WEBPACK_IMPORTED_MODULE_8__["setDialogButtonAction"])(dialog, 'Import', /*#__PURE__*/function () {
      var _ref9 = _babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_1___default()(/*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.mark(function _callee20(event) {
        var inputs, name, nValid, validNameExp, _yield$sendCommand6, success, data;
        return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.wrap(function _callee20$(_context20) {
          while (1) switch (_context20.prev = _context20.next) {
            case 0:
              inputs = dialog.find('input');
              name = $(inputs).val();
              _context20.prev = 2;
              if (importedProject) {
                _context20.next = 6;
                break;
              }
              event.stopPropagation();
              return _context20.abrupt("return", $(dialog.find('small')).append('<span class="label label-danger">Please specify a file.</span>'));
            case 6:
              if ($(inputs[0]).val().trim() === '') {
                $(inputs[0]).val(importedProject.name);
                name = importedProject.name;
              }
              nValid = false;
              validNameExp = /^[A-Z_][0-9A-Z_]*$/i;
              nValid = validNameExp.test(name);
              if (nValid) {
                _context20.next = 15;
                break;
              }
              event.stopPropagation();
              return _context20.abrupt("return", dialog.find('.modal-header small span').text('Project name ONLY includes A..Z, a..z, 0..9, _'));
            case 15:
              if (_this14.checkProjectName(inputs[0])) {
                _context20.next = 18;
                break;
              }
              event.stopPropagation();
              return _context20.abrupt("return", dialog.find('.modal-header small span').text('Project name has been taken'));
            case 18:
              _context20.next = 20;
              return Object(_utils_common__WEBPACK_IMPORTED_MODULE_8__["sendCommand"])('/project', {
                method: 'new',
                name: $(inputs[0]).val().trim(),
                config: JSON.stringify(importedProject.config)
              });
            case 20:
              _yield$sendCommand6 = _context20.sent;
              success = _yield$sendCommand6.success;
              data = _yield$sendCommand6.data;
              if (success) {
                _context20.next = 25;
                break;
              }
              return _context20.abrupt("return");
            case 25:
              if (data) {
                _context20.next = 27;
                break;
              }
              return _context20.abrupt("return");
            case 27:
              projects.push(data);
              _this14.loadProject(data.projectID, false);
              _context20.next = 34;
              break;
            case 31:
              _context20.prev = 31;
              _context20.t0 = _context20["catch"](2);
              Object(_utils_common__WEBPACK_IMPORTED_MODULE_8__["showModalDialog"])('Import Failed', 'Project file might be corrupted.');
            case 34:
            case "end":
              return _context20.stop();
          }
        }, _callee20, null, [[2, 31]]);
      }));
      return function (_x6) {
        return _ref9.apply(this, arguments);
      };
    }(), true);
  },
  getUserID: function getUserID() {
    var showinfo = 'UserID: ' + user.userID.toString();
    if (project) {
      showinfo = showinfo + '   ProjectID: ' + project.projectID;
    }
    Object(_utils_common__WEBPACK_IMPORTED_MODULE_8__["showModalDialog"])('User ID', showinfo);
  },
  // TODO: this could be refactored. Don't need to get file and then send back.
  importExample: function importExample(name) {
    var _this15 = this;
    return _babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_1___default()(/*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.mark(function _callee21() {
      var _yield$sendCommand7, success, data, config, nameArr, projectName, _yield$sendCommand8;
      return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.wrap(function _callee21$(_context21) {
        while (1) switch (_context21.prev = _context21.next) {
          case 0:
            _context21.next = 2;
            return Object(_utils_common__WEBPACK_IMPORTED_MODULE_8__["sendCommand"])('/project', {
              method: 'getFile',
              file: 'examples/' + name + '.json'
            });
          case 2:
            _yield$sendCommand7 = _context21.sent;
            success = _yield$sendCommand7.success;
            data = _yield$sendCommand7.data;
            if (success) {
              _context21.next = 7;
              break;
            }
            return _context21.abrupt("return");
          case 7:
            config = JSON.parse(data).config;
            nameArr = name.split('/');
            name = nameArr[nameArr.length - 1]; // get rid of the directory name.
            projectName = _this15.getModifiedProjectName(name);
            _context21.next = 13;
            return Object(_utils_common__WEBPACK_IMPORTED_MODULE_8__["sendCommand"])('/project', {
              method: 'new',
              name: projectName,
              config: JSON.stringify(config)
            });
          case 13:
            _yield$sendCommand8 = _context21.sent;
            success = _yield$sendCommand8.success;
            data = _yield$sendCommand8.data;
            if (success) {
              _context21.next = 18;
              break;
            }
            return _context21.abrupt("return");
          case 18:
            if (data) {
              _context21.next = 20;
              break;
            }
            return _context21.abrupt("return");
          case 20:
            projects.push(data);
            _this15.loadProject(data.projectID, false);
          case 22:
          case "end":
            return _context21.stop();
        }
      }, _callee21);
    }))();
  },
  importWebAdapterProduct: function importWebAdapterProduct(type) {
    var _arguments = arguments,
      _this16 = this;
    return _babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_1___default()(/*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.mark(function _callee22() {
      var mode, _yield$sendCommand9, success, data, projectName, _yield$sendCommand10;
      return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.wrap(function _callee22$(_context22) {
        while (1) switch (_context22.prev = _context22.next) {
          case 0:
            mode = _arguments.length > 1 && _arguments[1] !== undefined ? _arguments[1] : 'Time';
            _context22.next = 3;
            return Object(_utils_common__WEBPACK_IMPORTED_MODULE_8__["sendCommand"])('/webadapter', {
              method: 'getProduct',
              type: type
            });
          case 3:
            _yield$sendCommand9 = _context22.sent;
            success = _yield$sendCommand9.success;
            data = _yield$sendCommand9.data;
            if (success) {
              _context22.next = 8;
              break;
            }
            return _context22.abrupt("return");
          case 8:
            data.config.chips[0].type = type;
            projectName = _this16.getModifiedProjectName(type); // create new project with data
            _context22.next = 12;
            return Object(_utils_common__WEBPACK_IMPORTED_MODULE_8__["sendCommand"])('/project', {
              method: 'new',
              name: projectName,
              config: JSON.stringify(data.config)
            });
          case 12:
            _yield$sendCommand10 = _context22.sent;
            success = _yield$sendCommand10.success;
            data = _yield$sendCommand10.data;
            if (success) {
              _context22.next = 17;
              break;
            }
            return _context22.abrupt("return");
          case 17:
            if (data) {
              _context22.next = 19;
              break;
            }
            return _context22.abrupt("return");
          case 19:
            projects.push(data);
            _this16.loadProject(data.projectID, false);
          case 21:
          case "end":
            return _context22.stop();
        }
      }, _callee22);
    }))();
  },
  "export": function _export() {
    return _babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_1___default()(/*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.mark(function _callee23() {
      var fileFormts, zip, formatDt, tsToString, tsSuffix, zipSuffix, i, data, nameStrs, dataToZip;
      return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.wrap(function _callee23$(_context23) {
        while (1) switch (_context23.prev = _context23.next) {
          case 0:
            if (project) {
              _context23.next = 2;
              break;
            }
            return _context23.abrupt("return");
          case 2:
            fileFormts = ['$hax', '$hex', '$bit'];
            zip = new jszip__WEBPACK_IMPORTED_MODULE_6___default.a();
            formatDt = function formatDt(t) {
              t = t < 10 ? '0' + t : t;
              return t;
            };
            tsToString = function tsToString(ts) {
              var tsString = ts.getFullYear() + '_' + formatDt(ts.getMonth() + 1) + '_' + formatDt(ts.getDate());
              tsString += '_' + formatDt(ts.getHours()) + formatDt(ts.getMinutes());
              return tsString;
            }; // Add files bin, hax, hex to zip
            zipSuffix = '';
            if (!project.tsp) {
              _context23.next = 26;
              break;
            }
            tsSuffix = tsToString(project.tsp);
            i = 0;
          case 10:
            if (!(i < fileFormts.length)) {
              _context23.next = 26;
              break;
            }
            _context23.next = 13;
            return Object(_utils_common__WEBPACK_IMPORTED_MODULE_8__["sendCommand"])('/project', {
              method: 'getFile',
              projectId: project.projectID,
              chipName: project.chip.name,
              projectName: project.name,
              file: fileFormts[i]
            }, false);
          case 13:
            data = _context23.sent;
            if (!(data && data.success)) {
              _context23.next = 23;
              break;
            }
            nameStrs = data.name.split('.');
            zipSuffix = '_' + tsSuffix;
            dataToZip = data.data;
            if (!fileFormts[i].includes('bit')) {
              _context23.next = 22;
              break;
            }
            _context23.next = 21;
            return Buffer.from(data.data, 'base64');
          case 21:
            dataToZip = _context23.sent;
          case 22:
            zip.file(nameStrs[0] + zipSuffix + '.' + nameStrs[1], dataToZip);
          case 23:
            i++;
            _context23.next = 10;
            break;
          case 26:
            // Add project's json to zip
            tsSuffix = tsToString(new Date());
            zip.file(project.name + '_' + tsSuffix + '.json', JSON.stringify(project.toJson(), null, '\t'));

            // Generate zip and prompt 'save as'
            zip.generateAsync({
              type: 'blob',
              compression: 'DEFLATE',
              compressionOptions: {
                level: 9
              }
            }).then(function (blob) {
              Object(file_saver__WEBPACK_IMPORTED_MODULE_7__["saveAs"])(blob, project.name + zipSuffix + '.zip');
            });

            // const downloadLink = document.createElement('a')
            // downloadLink.href = 'data:attachment/text,' + encodeURIComponent(JSON.stringify(project.toJson(), null, '\t'))
            // downloadLink.target = '_blank'
            // downloadLink.download = project.name + '.json'
            // downloadLink.style = 'display:none'
            // $('body').append(downloadLink)
            // downloadLink.click()
            // downloadLink.parentNode.removeChild(downloadLink)
          case 29:
          case "end":
            return _context23.stop();
        }
      }, _callee23);
    }))();
  },
  exportProjects: function exportProjects(projects) {
    if (!projects) projects = project ? [project] : null;
    if (!projects) return;
    var downloadLink = document.createElement('a');
    downloadLink.target = '_blank';
    downloadLink.style = 'display:none';
    $('body').append(downloadLink);
    var properties = ['projectID', 'userID', 'name', 'config', 'creation_time', 'modification_time'];
    var clone;
    projects.forEach(function (project) {
      clone = JSON.parse(JSON.stringify(project));
      lodash__WEBPACK_IMPORTED_MODULE_3___default.a.forEach(clone, function (value, name) {
        if (properties.indexOf(name) < 0) {
          delete clone[name];
        }
      });
      downloadLink.href = 'data:attachment/text,' + encodeURIComponent(JSON.stringify(clone));
      downloadLink.download = clone.name + '.json';
      downloadLink.click();
    });
    downloadLink.parentNode.removeChild(downloadLink);
  },
  cleanUPConnections: function cleanUPConnections(chip, WireConns) {
    // handle local connections
    var deletedWires = [];
    Object.keys(WireConns).forEach(function (wireName) {
      if (wireName !== 'GPIO' && wireName !== 'VCC' && wireName !== 'GND' && !(chip.autoConnections && lodash__WEBPACK_IMPORTED_MODULE_3___default.a.find(chip.autoConnections, {
        portName: wireName
      }) && !Object.values(chip.connections).includes(wireName))) {
        var conns = WireConns[wireName];
        if (conns.length <= 1) {
          // check if this wire connecting to specific GPIO
          var gpio = false;
          if (chip.connections) {
            gpio = lodash__WEBPACK_IMPORTED_MODULE_3___default.a.findKey(chip.connections, function (e) {
              return e === wireName;
            });
          }
          if (!gpio) {
            // this local wire only connect one point, removed it
            deletedWires.push(wireName);
            for (var i = 0; i < conns.length; i++) {
              var conn = conns[i];
              var compid = conn.comp;
              var portname = conn.port;
              var component = project.chip.findComponentById(compid);
              delete component.connections[portname];
              console.log('removed local connection(s) at port(' + portname + ') wire(' + wireName + ') comp id( ' + compid + ')\n');
            }
          }
        }
      }
    });
    // handle global connections
    var keepGlobalConns = {};
    Object.keys(chip.connections).forEach(function (gpio) {
      var wire = chip.connections[gpio];
      if (!deletedWires.includes(wire)) {
        keepGlobalConns[gpio] = wire;
      } else {
        console.log('removed global connection at GPIO(' + gpio + ') wire( ' + wire + ')\n');
      }
    });
    // global connections has been clean up
    chip.connections = keepGlobalConns;
  },
  getWiresConnections: function getWiresConnections(chip, comp, WireConns) {
    // find all valid wires that occur in component connections
    Object.keys(comp.connections).forEach(function (port) {
      var wireName = comp.connections[port];
      var keep = true;
      if (wireName !== 'GPIO' && wireName !== 'VCC' && wireName !== 'GND' && chip.autoConnections && lodash__WEBPACK_IMPORTED_MODULE_3___default.a.find(chip.autoConnections, {
        portName: wireName
      }) && !Object.values(chip.connections).includes(wireName)) {
        // check port existed for local connection
        var foundport = false;
        comp.ports.forEach(function (pt) {
          if (pt.name === port) {
            foundport = true;
          }
        });
        if (!foundport) {
          // need to remove this local connection
          delete comp.connections[port];
          console.log('removed local connection at port(' + port + ') wire(' + wireName + ') comp id( ' + comp.id + ')\n');
          keep = false;
        }
      }
      if (keep) {
        var wire = {};
        wire['port'] = port;
        wire['comp'] = comp.id;
        if (!WireConns[wireName]) {
          var conns = [];
          conns.push(wire);
          WireConns[wireName] = conns;
        } else {
          WireConns[wireName].push(wire);
        }
      }
    });
    return WireConns;
  },
  validateConnections: function validateConnections() {
    var projectFile = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
    var that = this;
    var chip = projectFile ? projectFile.chip : project.chip;
    var WireConns = {};
    chip.components.forEach(function (c) {
      WireConns = that.getWiresConnections(chip, c, WireConns);
    });
    chip.digitals.forEach(function (c) {
      WireConns = that.getWiresConnections(chip, c, WireConns);
    });
    chip.LDOS.forEach(function (c) {
      WireConns = that.getWiresConnections(chip, c, WireConns);
    });
    that.cleanUPConnections(chip, WireConns);
  },
  setComponentVersionUtil: function setComponentVersionUtil(compId, compType, compSubType) {
    var checkPorts = function checkPorts(portName, component) {
      var ports = component.ports;
      var found = false;
      ports.forEach(function (port) {
        if (port.name === portName) {
          found = true;
          return true;
        }
      });
      return found;
    };
    var checkWireName = function checkWireName(wireN) {
      var found = false;
      chip.components.forEach(function (cp) {
        Object.keys(cp.connections).forEach(function (port) {
          var wireName = cp.connections[port];
          if (wireN === wireName) {
            found = true;
            return true;
          }
        });
      });
      return found;
    };
    var comp = Components_component_manager__WEBPACK_IMPORTED_MODULE_16__["default"].newComponent(compType, project.chip, compSubType);
    comp.version = compSubType;
    this.clearProject(true);
    project = new _project__WEBPACK_IMPORTED_MODULE_15__["default"](project);
    project.selected = comp;
    this.validateConnections();
    var chip = project.chip;
    // replace comp by compId
    chip.components.forEach(function (cp) {
      if (cp.id === compId) {
        // update type, config and update parameters init
        cp.version = compSubType;
        cp.config = comp.config;
        cp.initComp();

        // check port and connections
        var gpios = [];
        Object.keys(cp.connections).forEach(function (port) {
          var wireName = cp.connections[port];
          var found = checkPorts(port, comp);
          if (!found) {
            // no port found
            if (wireName !== 'GPIO') {
              var aFound = checkWireName(wireName);
              if (!aFound) {
                // this wireName only have one port connect to gpio, need to be deleted
                Object.keys(chip.connections).forEach(function (gpio) {
                  var wireN = chip.connections[gpio];
                  if (wireN === wireName) {
                    // record this gpio
                    gpios.push(gpio);
                    return true;
                  }
                });
              }
            }
          }
        });
        if (gpios.length > 0) {
          // removed these connections from chip.connections
          gpios.forEach(function (gpio) {
            delete chip.connections[gpio];
          });
        }
      }
    });
    chip.digitals.forEach(function (cp) {
      if (cp.id === compId) {
        // update type, config and update parameters init
        cp.version = compSubType;
        cp.config = comp.config;
        cp.initComp();

        // check port and connections
        var gpios = [];
        Object.keys(cp.connections).forEach(function (port) {
          var wireName = cp.connections[port];
          var found = checkPorts(port, comp);
          if (!found) {
            // no port found
            if (wireName !== 'GPIO') {
              var aFound = checkWireName(wireName);
              if (!aFound) {
                // this wireName only have one port connect to gpio, need to be deleted
                Object.keys(chip.connections).forEach(function (gpio) {
                  var wireN = chip.connections[gpio];
                  if (wireN === wireName) {
                    // record this gpio
                    gpios.push(gpio);
                    return true;
                  }
                });
              }
            }
          }
        });
        if (gpios.length > 0) {
          // removed these connections from chip.connections
          gpios.forEach(function (gpio) {
            delete chip.connections[gpio];
          });
        }
      }
    });
    if (chip.currentStage === 'tuning') {
      chip.currentStage = 'design';
    }
    var screen = _screens_screen_manager__WEBPACK_IMPORTED_MODULE_18__["default"].getScreen('design');
    if (screen && screen.initialized) {
      // considering possible platform changed, need to re build categories
      screen.buildCategories();
      screen.refresh();
    }
    // EventBus.$emit('projectLoaded')
  },
  setVerilogLibVersion: function setVerilogLibVersion(el) {
    var chip = project.chip;
    chip.verilogLibVersions = $(el).val();
  },
  settings: function settings() {
    var chip = project.chip;

    // TODO: kind of like a hack now
    var dialog = $(_settings_pug__WEBPACK_IMPORTED_MODULE_14___default()());
    $('body').append(dialog);
    var modal = $('#modal-settings-form');
    $(modal).on('hidden.bs.modal', function () {
      // this.setDirty(true)
      if (_screens_screen_manager__WEBPACK_IMPORTED_MODULE_18__["default"].currentScreen.name === 'tuning') {
        _screens_screen_manager__WEBPACK_IMPORTED_MODULE_18__["default"].currentScreen.refreshParameterForm(false);
      }
      _screens_screen_manager__WEBPACK_IMPORTED_MODULE_18__["default"].refresh();
    });
    $('#modal-settings-form').modal({
      show: false,
      keyboard: false,
      backdrop: 'static'
    });
    $('#modal-settings-form #clocksTab').html(Object(Components_parameters_clock__WEBPACK_IMPORTED_MODULE_21__["buildClockForm"])(chip));
    $('#modal-settings-form #platformBoMTab').html(Client_bom__WEBPACK_IMPORTED_MODULE_19__["default"].getPlatformBoMHTML(chip));
    $('#modal-settings-form').modal('show');
    var ver = 'Production';
    if (chip.verilogLibVersions) {
      ver = chip.verilogLibVersions;
    }
    $('#verilogLibrary-versions').val(ver);
    $('#settingsbtn').click(function () {
      Object(Components_parameters_clock__WEBPACK_IMPORTED_MODULE_21__["VerifyCompClock"])(chip);
    });
    $(modal).draggable({
      handle: '.modal-header, .modal-footer'
    });
  },
  signout: function signout() {
    this.confirmSave(function () {
      setTimeout(function () {
        Object(_utils_common__WEBPACK_IMPORTED_MODULE_8__["redirect"])('login');
      }, 50);
    });
  },
  getManagementToolbar: function getManagementToolbar(callback) {
    var items = [];
    var that = this;
    if (user.isAdmin()) {
      items.push({
        type: 'button',
        id: 'execute',
        caption: 'Script',
        icon: 'fa fa-code'
      });
    }
    items.push({
      type: 'button',
      id: 'duplicate',
      caption: 'Duplicate',
      icon: 'fa fa-copy'
    });
    items.push({
      type: 'button',
      id: 'export',
      caption: 'Export',
      icon: 'fa fa-cloud-download'
    });
    return {
      items: items,
      onClick: function () {
        var _onClick = _babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_1___default()(/*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.mark(function _callee25(target, event) {
          var grid, selection, dialog, html, _projects, record;
          return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.wrap(function _callee25$(_context25) {
            while (1) switch (_context25.prev = _context25.next) {
              case 0:
                grid = this.owner;
                selection = grid.getSelection();
                _context25.t0 = target;
                _context25.next = _context25.t0 === 'execute' ? 5 : _context25.t0 === 'duplicate' ? 14 : _context25.t0 === 'export' ? 18 : 23;
                break;
              case 5:
                if (!(selection.length === 0)) {
                  _context25.next = 7;
                  break;
                }
                return _context25.abrupt("return");
              case 7:
                dialog = $(Object(_utils_common__WEBPACK_IMPORTED_MODULE_8__["createModalDialog"])('execute-script', 'modal-sm'));
                dialog.find('.modal-header h4').text('Enter Script');
                html = '<textarea class="form-control" rows="5" style="font:12px \'Courier\'"></textarea>';
                dialog.find('.modal-body').html(html);
                $('body').append(dialog);
                Object(_utils_common__WEBPACK_IMPORTED_MODULE_8__["setDialogButtonAction"])(dialog, 'Execute', function () {
                  var script = dialog.find('textarea').val();
                  var record;
                  var f = function f(script) {
                    // var config = this.config
                    eval(script);
                  };
                  try {
                    selection.forEach(function (recid) {
                      record = grid.records.find(function (r) {
                        return r.recid === recid;
                      });
                      if (record) {
                        f.call(record, script);
                        if (!record.changes) {
                          record.changes = {};
                        }
                        record.changes.name = record.name;
                        record.changes.config = record.config;
                      }
                    });
                    grid.refresh();
                  } catch (e) {
                    debug(e);
                  }
                });
                return _context25.abrupt("return");
              case 14:
                if (!(selection.length === 0)) {
                  _context25.next = 16;
                  break;
                }
                return _context25.abrupt("return");
              case 16:
                Object(_utils_common__WEBPACK_IMPORTED_MODULE_8__["showConfirm"])('Are you sure you want to create ' + selection.length + ' new projects?', null, {
                  name: 'Duplicate',
                  className: 'btn-danger'
                }, /*#__PURE__*/function () {
                  var _ref10 = _babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_1___default()(/*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.mark(function _callee24(confirm) {
                    var copiedProjects, names;
                    return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.wrap(function _callee24$(_context24) {
                      while (1) switch (_context24.prev = _context24.next) {
                        case 0:
                          if (!confirm) {
                            _context24.next = 7;
                            break;
                          }
                          copiedProjects = [];
                          names = grid.records.map(function (r) {
                            return {
                              name: r.changes && r.changes.name ? r.changes.name : r.name,
                              userID: r.userID
                            };
                          });
                          selection.forEach(function (recid) {
                            var record = grid.records.find(function (r) {
                              return r.recid === recid;
                            });
                            var newName = that.getModifiedProjectName(record.name, null, names);
                            copiedProjects.push({
                              projectID: 'N' + record.recid,
                              name: newName,
                              config: record.config ? lodash__WEBPACK_IMPORTED_MODULE_3___default.a.cloneDeep(record.config) : null,
                              userID: record.userID
                            });
                            names.push({
                              name: newName,
                              userID: record.userID
                            });
                          });
                          _context24.next = 6;
                          return that.createProjects(copiedProjects);
                        case 6:
                          callback(grid, target, copiedProjects);
                        case 7:
                        case "end":
                          return _context24.stop();
                      }
                    }, _callee24);
                  }));
                  return function (_x9) {
                    return _ref10.apply(this, arguments);
                  };
                }());
                return _context25.abrupt("return");
              case 18:
                if (!(selection.length === 0)) {
                  _context25.next = 20;
                  break;
                }
                return _context25.abrupt("return");
              case 20:
                _projects = [];
                selection.forEach(function (recid) {
                  record = grid.records.find(function (r) {
                    return r.recid === recid;
                  });
                  _projects.push(record);
                });
                that.exportProjects(_projects);
              case 23:
              case "end":
                return _context25.stop();
            }
          }, _callee25, this);
        }));
        function onClick(_x7, _x8) {
          return _onClick.apply(this, arguments);
        }
        return onClick;
      }()
    };
  },
  manageProjects: function manageProjects() {
    var _this17 = this;
    var that = this;
    var getRecords = function getRecords() {
      return projects.map(function (p) {
        var order = user.projectorder.indexOf(p.projectID) + 1;
        var adevice = p.config ? p.config.device : null;
        if (p.config && p.config.chips) {
          adevice = lodash__WEBPACK_IMPORTED_MODULE_3___default.a.map(p.config.chips, 'device').join();
        }
        return {
          recid: p.projectID,
          name: p.name,
          modification_time: p.modification_time,
          creation_time: p.creation_time,
          device: adevice,
          config: p.config,
          order: order
        };
      });
    };
    var dialog = $(_manage_projects_pug__WEBPACK_IMPORTED_MODULE_13___default()());
    $('body').append(dialog);
    if (!w2ui['projects-grid']) {
      $('#projects-grid').w2grid({
        name: 'projects-grid',
        width: '100%',
        height: '100%',
        show: {
          toolbar: true,
          footer: true,
          toolbarDelete: true,
          columnHeaders: true,
          selectColumn: true
        },
        multiSelect: true,
        reorderRows: false,
        toolbar: this.getManagementToolbar(function (grid, action, data) {
          if (action === 'duplicate') {
            data.forEach(function (p) {
              var adevice = p.config ? p.config.device : null;
              if (p.config && p.config.chips) {
                adevice = lodash__WEBPACK_IMPORTED_MODULE_3___default.a.map(p.config.chips, 'device').join();
              }
              grid.records.push({
                recid: p.projectID,
                name: p.name,
                modification_time: p.modification_time,
                device: adevice,
                config: p.config
              });
            });
            grid.total = grid.records.length;
            grid.selectNone();
            grid.refresh();
            _this17.refreshProjectsMenu();
          }
        }),
        columns: toolBarColoums,
        onChange: function onChange(event) {
          if (event.column === 0) {
            event.preventDefault();
            if (this.records[event.index].order >= event.value_new) {
              this.records[event.index].order = event.value_new - 0.5;
            } else {
              this.records[event.index].order = event.value_new + 0.5;
            }
            this.sort('order', 'asc');
            lodash__WEBPACK_IMPORTED_MODULE_3___default.a.forEach(this.records, function (p, index) {
              p.order = index + 1;
            });
            this.refresh();
          } else if (event.column === 1) {
            var names = lodash__WEBPACK_IMPORTED_MODULE_3___default.a.map(this.records, function (r) {
              return {
                name: r.changes && r.changes.name ? r.changes.name : r.name
              };
            });
            var modifyName = event.value_new;
            // check modifyName leagal
            var validNameExp = /^[A-Z_][0-9A-Z_]*$/i;
            var nValid = validNameExp.test(modifyName);
            if (!nValid) {
              // report a error
              if (modifyName.match(/^\d/)) {
                Object(_utils_common__WEBPACK_IMPORTED_MODULE_8__["showModalDialog"])('Rename Failed', 'Project name can not start with number.');
              } else {
                Object(_utils_common__WEBPACK_IMPORTED_MODULE_8__["showModalDialog"])('Rename Failed', 'Project name ONLY includes A..Z, a..z, 0..9, _');
              }
              // grid refresh
              var grid = w2ui['projects-grid'];
              this.records = getRecords();
              grid.refresh();
            } else {
              event.value_new = that.getModifiedProjectName(modifyName, event.index, names);
            }
          }
        },
        onDelete: function () {
          var _onDelete = _babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_1___default()(/*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.mark(function _callee26(event) {
            var grid, selected, data;
            return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.wrap(function _callee26$(_context26) {
              while (1) switch (_context26.prev = _context26.next) {
                case 0:
                  event.force = true;
                  event.preventDefault();
                  grid = w2ui['projects-grid'];
                  selected = grid.getSelection();
                  if (!(selected.length > 0)) {
                    _context26.next = 9;
                    break;
                  }
                  _context26.next = 7;
                  return that.confirmDelete(selected);
                case 7:
                  data = _context26.sent;
                  if (data) {
                    if (project && selected.indexOf(project.projectID) >= 0) {
                      that.clearProject();
                      project = null;
                      _screens_screen_manager__WEBPACK_IMPORTED_MODULE_18__["default"].showScreen();
                    }
                    this.records = getRecords();
                    this.total = this.records.length;
                    grid.selectNone();
                    grid.refresh();
                    that.refreshProjectsMenu();
                    Object(_utils_common__WEBPACK_IMPORTED_MODULE_8__["showModalDialog"])('Success', 'Projects deleted.');
                  }
                case 9:
                case "end":
                  return _context26.stop();
              }
            }, _callee26, this);
          }));
          function onDelete(_x10) {
            return _onDelete.apply(this, arguments);
          }
          return onDelete;
        }()
      });
      var content = dialog.find('.modal-content');
      content.resizable({});
      content.on('resize', function (event, ui) {
        dialog.find('#projects-grid').css('height', ui.size.height - 151 + 'px');
        w2ui['projects-grid'].resize();
        w2ui['projects-grid'].refresh();
      });
      dialog.find('.modal-dialog').draggable({
        handle: '.modal-header'
      });
    }
    Object(_utils_common__WEBPACK_IMPORTED_MODULE_8__["setDialogButtonAction"])(dialog, null, /*#__PURE__*/function () {
      var _ref11 = _babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_1___default()(/*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.mark(function _callee27(event) {
        var grid, changes, changedProjects, reload, records, order;
        return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.wrap(function _callee27$(_context27) {
          while (1) switch (_context27.prev = _context27.next) {
            case 0:
              grid = w2ui['projects-grid'];
              changes = grid.getChanges();
              changedProjects = [];
              reload = false;
              records = getRecords();
              changes.forEach(function (change) {
                if (change.config === undefined) {
                  records.forEach(function (rec) {
                    if (rec.recid === change.recid) {
                      change.config = rec.config;
                    }
                  });
                }
                changedProjects.push({
                  projectID: change.recid,
                  name: change.name,
                  config: change.config
                });
                if (change.config && project && change.recid === project.projectID) {
                  reload = true;
                }
              });
              Object(_utils_common__WEBPACK_IMPORTED_MODULE_8__["showBusy"])(true, 'Updating Projects...');
              _context27.next = 9;
              return that.saveProjects(changedProjects);
            case 9:
              Object(_utils_common__WEBPACK_IMPORTED_MODULE_8__["hideBusy"])();
              // update projects for these project in changedProjects
              changedProjects.forEach(function (prj) {
                var projectTemp = projects.find(function (p) {
                  return p.projectID === prj.projectID;
                });
                projectTemp.name = prj.name;
              });
              order = user.projectorder;
              projects.sort(function (a, b) {
                return order.indexOf(a.projectID) - order.indexOf(b.projectID);
              });
              that.refreshProjectsMenu();
              if (reload) {
                _this17.loadProject(project.projectID, false);
              }
              Object(_utils_common__WEBPACK_IMPORTED_MODULE_8__["showModalDialog"])('Success', 'Projects saved.');
            case 16:
            case "end":
              return _context27.stop();
          }
        }, _callee27);
      }));
      return function (_x11) {
        return _ref11.apply(this, arguments);
      };
    }(), true);
    dialog.on('hidden.bs.modal', /*#__PURE__*/_babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_1___default()(/*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.mark(function _callee28() {
      var records, order;
      return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.wrap(function _callee28$(_context28) {
        while (1) switch (_context28.prev = _context28.next) {
          case 0:
            // showBusy(true, "Updating Projects orders...");
            if (user.projectOrder) {
              delete user.projectOrder;
            }
            records = w2ui['projects-grid'].records;
            order = lodash__WEBPACK_IMPORTED_MODULE_3___default.a.map(records, 'recid');
            user.projectorder = order;
            if (user.config) {
              // save projectorder to user DB
              user.config.projectorder = order;
            }
            _context28.next = 7;
            return _this17.saveUserConfig(user);
          case 7:
            // hideBusy()
            // sort user.project based on order in config
            projects.sort(function (a, b) {
              return order.indexOf(a.projectID) - order.indexOf(b.projectID);
            });
            _this17.refreshProjectsMenu();
            // EventBus.$emit('projectLoaded')
            w2ui['projects-grid'].destroy();
            // $('#project_name').text('Projects')
          case 10:
          case "end":
            return _context28.stop();
        }
      }, _callee28);
    })));
    dialog.on('shown.bs.modal', function () {
      var grid = w2ui['projects-grid'];
      grid.resize();
      grid.records = getRecords();
      grid.sort('order', 'asc');
      grid.records.forEach(function (p, index) {
        p.order = index + 1;
      });
      w2ui['projects-grid'].refresh();
    });
  },
  close: function close() {
    var _this18 = this;
    if (!project) return;
    this.confirmSave(/*#__PURE__*/_babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_1___default()(/*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.mark(function _callee29() {
      var _yield$sendCommand11, success, data;
      return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.wrap(function _callee29$(_context29) {
        while (1) switch (_context29.prev = _context29.next) {
          case 0:
            _context29.next = 2;
            return Object(_utils_common__WEBPACK_IMPORTED_MODULE_8__["sendCommand"])('/project', {
              method: 'closeProject',
              id: project.projectID
            });
          case 2:
            _yield$sendCommand11 = _context29.sent;
            success = _yield$sendCommand11.success;
            data = _yield$sendCommand11.data;
            if (success) {
              _context29.next = 7;
              break;
            }
            return _context29.abrupt("return");
          case 7:
            if (data) {
              _context29.next = 9;
              break;
            }
            return _context29.abrupt("return");
          case 9:
            _this18.clearProject();
            project = null;
            _this18.refreshProjectsMenu();
            _screens_screen_manager__WEBPACK_IMPORTED_MODULE_18__["default"].showScreen();
          case 13:
          case "end":
            return _context29.stop();
        }
      }, _callee29);
    })));
  },
  saveAs: function saveAs() {
    var _this19 = this;
    if (!project) return;
    var dialog = $(_saveAs_project_pug__WEBPACK_IMPORTED_MODULE_11___default()());
    $('body').append(dialog);
    Object(_utils_common__WEBPACK_IMPORTED_MODULE_8__["setDialogButtonAction"])(dialog, 'Save', /*#__PURE__*/function () {
      var _ref14 = _babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_1___default()(/*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.mark(function _callee30(event) {
        var input, nValid, name, validNameExp, _yield$sendCommand12, success, data;
        return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.wrap(function _callee30$(_context30) {
          while (1) switch (_context30.prev = _context30.next) {
            case 0:
              input = dialog.find('input');
              nValid = false;
              name = $(input).val();
              validNameExp = /^[A-Z_][0-9A-Z_]*$/i;
              nValid = validNameExp.test(name);
              if (nValid) {
                _context30.next = 10;
                break;
              }
              if ($(input).val().match(/^\d/)) {
                dialog.find('.modal-header small span').text('Project name can not start with number');
              } else {
                dialog.find('.modal-header small span').text('Project name ONLY includes A..Z, a..z, 0..9, _');
              }
              event.stopPropagation();
              _context30.next = 27;
              break;
            case 10:
              if (_this19.checkProjectName(input[0])) {
                _context30.next = 15;
                break;
              }
              dialog.find('.modal-header small span').text('Project name has been taken');
              event.stopPropagation();
              _context30.next = 27;
              break;
            case 15:
              _context30.next = 17;
              return Object(_utils_common__WEBPACK_IMPORTED_MODULE_8__["sendCommand"])('/project', {
                method: 'new',
                name: input.val(),
                config: JSON.stringify(project.config)
              });
            case 17:
              _yield$sendCommand12 = _context30.sent;
              success = _yield$sendCommand12.success;
              data = _yield$sendCommand12.data;
              if (success) {
                _context30.next = 22;
                break;
              }
              return _context30.abrupt("return");
            case 22:
              if (data) {
                _context30.next = 24;
                break;
              }
              return _context30.abrupt("return");
            case 24:
              projects.push(data);
              _this19.refreshProjectsMenu();
              _this19.loadProject(data.projectID, false);
            case 27:
            case "end":
              return _context30.stop();
          }
        }, _callee30);
      }));
      return function (_x12) {
        return _ref14.apply(this, arguments);
      };
    }(), true);
  },
  createModular: function createModular() {
    var _this20 = this;
    if (!project) return;
    var dialog = $(_modular_project_pug__WEBPACK_IMPORTED_MODULE_12___default()());
    $('body').append(dialog);
    var checkName = function checkName(mName) {
      if (project.config.customComponents) {
        if (lodash__WEBPACK_IMPORTED_MODULE_3___default.a.find(project.config.customComponents, {
          id: 'custom_' + mName
        })) {
          return false;
        }
      }
      return true;
    };
    Object(_utils_common__WEBPACK_IMPORTED_MODULE_8__["setDialogButtonAction"])(dialog, 'Create Module', /*#__PURE__*/function () {
      var _ref15 = _babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_1___default()(/*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.mark(function _callee31(event) {
        var input, nValid, name, validNameExp;
        return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.wrap(function _callee31$(_context31) {
          while (1) switch (_context31.prev = _context31.next) {
            case 0:
              input = dialog.find('input');
              nValid = false;
              name = $(input).val();
              validNameExp = /^[A-Z_][0-9A-Z_]*$/i;
              nValid = validNameExp.test(name);
              if (!nValid) {
                if (name.match(/^\d/)) {
                  dialog.find('.modal-header small span').text('Modular name can not start with number');
                } else {
                  dialog.find('.modal-header small span').text('Modular name ONLY includes A..Z, a..z, 0..9, _');
                }
                event.stopPropagation();
              } else if (!checkName(name)) {
                dialog.find('.modal-header small span').text('Modular name has been taken');
                event.stopPropagation();
              } else {
                _this20.importDefaultModular(name);
              }
            case 6:
            case "end":
              return _context31.stop();
          }
        }, _callee31);
      }));
      return function (_x13) {
        return _ref15.apply(this, arguments);
      };
    }(), true);
  },
  getModularPorts: function getModularPorts() {
    var _this21 = this;
    var chip = project.chip;
    var expPorts = [];
    var WireConns = {};
    chip.digitals.forEach(function (c) {
      WireConns = _this21.getWiresConnections(chip, c, WireConns);
    });
    Object.keys(WireConns).forEach(function (wireName) {
      if (wireName !== 'GPIO' && wireName !== 'VCC' && wireName !== 'GND') {
        var conns = WireConns[wireName];
        // check if this wire connecting to specific GPIO
        var gpio = false;
        if (chip.connections) {
          gpio = lodash__WEBPACK_IMPORTED_MODULE_3___default.a.findKey(chip.connections, function (e) {
            return e === wireName;
          });
        }
        if (gpio) {
          var displayWireName = '';
          var pkg = chip.device["package"];
          if (pkg.modularPinMap.length > 0) {
            var _pkg = chip.device["package"];
            var index = lodash__WEBPACK_IMPORTED_MODULE_3___default.a.findIndex(_pkg.modularPinMap, {
              pinName: gpio
            });
            if (index >= 0) {
              displayWireName = _pkg.modularPinMap[index].pinDisplayName;
            }
          }
          // this is a wire connecting to GPIO, get its direction
          var _loop = function _loop() {
            var conn = conns[i];
            var compid = conn.comp;
            var portname = conn.port;
            if (displayWireName.length === 0) displayWireName = 'C' + compid + portname;
            var component = project.chip.findComponentById(compid);
            var ports = component.ports;
            ports.forEach(function (port) {
              if (port.name === portname) {
                var wireIndex = lodash__WEBPACK_IMPORTED_MODULE_3___default.a.findIndex(expPorts, {
                  wire: wireName
                });
                if (wireIndex === -1) {
                  expPorts.push({
                    wire: wireName,
                    name: displayWireName,
                    type: port.type
                  });
                }
                return true;
              }
            });
          };
          for (var i = 0; i < conns.length; i++) {
            _loop();
          }
        }
      }
    });
    return expPorts;
  },
  deleteModular: function deleteModular() {
    var _this22 = this;
    return _babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_1___default()(/*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.mark(function _callee32() {
      var prjId, component, customComps, modularPinMap;
      return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.wrap(function _callee32$(_context32) {
        while (1) switch (_context32.prev = _context32.next) {
          case 0:
            // delete modular project
            prjId = project.origProjectId;
            _context32.next = 3;
            return _this22.deleteProjects([project.projectID]);
          case 3:
            // back to original project
            component = null;
            customComps = null;
            modularPinMap = null;
            _this22.loadModProject(prjId, component, customComps, modularPinMap, true);
          case 7:
          case "end":
            return _context32.stop();
        }
      }, _callee32);
    }))();
  },
  loadModular: function loadModular(inNetlist, origProjectId, topName) {
    var _this23 = this;
    return _babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_1___default()(/*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.mark(function _callee33() {
      var netlist, name, _yield$sendCommand13, success, data, config, portsmap, projectName, customComps, datan;
      return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.wrap(function _callee33$(_context33) {
        while (1) switch (_context33.prev = _context33.next) {
          case 0:
            netlist = inNetlist;
            if (lodash__WEBPACK_IMPORTED_MODULE_3___default.a.isString(inNetlist)) {
              netlist = JSON.parse(inNetlist);
            }
            name = 'defaultModular';
            _context33.next = 5;
            return Object(_utils_common__WEBPACK_IMPORTED_MODULE_8__["sendCommand"])('/project', {
              method: 'getFile',
              file: 'files/' + name + '.json'
            });
          case 5:
            _yield$sendCommand13 = _context33.sent;
            success = _yield$sendCommand13.success;
            data = _yield$sendCommand13.data;
            if (success) {
              _context33.next = 10;
              break;
            }
            return _context33.abrupt("return");
          case 10:
            config = JSON.parse(data).config;
            config.chips[0].connections = netlist.conns;
            config.chips[0].digitals = netlist.comps;
            portsmap = netlist.portsmap;
            projectName = topName;
            customComps = null;
            _context33.next = 18;
            return Object(_utils_common__WEBPACK_IMPORTED_MODULE_8__["sendCommand"])('/project', {
              method: 'new',
              name: projectName,
              config: JSON.stringify(config)
            });
          case 18:
            datan = _context33.sent;
            if (datan) {
              _context33.next = 21;
              break;
            }
            return _context33.abrupt("return");
          case 21:
            if (datan.success) {
              _context33.next = 23;
              break;
            }
            return _context33.abrupt("return");
          case 23:
            projects.push(datan);
            _this23.loadModProject(datan.data.projectID, origProjectId, customComps, portsmap, false);
          case 25:
          case "end":
            return _context33.stop();
        }
      }, _callee33);
    }))();
  },
  addModular: function addModular() {
    var _this24 = this;
    return _babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_1___default()(/*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.mark(function _callee34() {
      var achip, pkg, modName, ports, component, portsmap, components, aCompConfigs, chip, aComponents, chipName, moduleNetList, data, prjId, customComps, modularPinMap;
      return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.wrap(function _callee34$(_context34) {
        while (1) switch (_context34.prev = _context34.next) {
          case 0:
            // get ports description
            achip = project.chip;
            pkg = achip.device["package"];
            modName = project.name;
            ports = _this24.getModularPorts();
            component = {
              'id': 'custom_' + modName,
              'topName': modName,
              'type': 'modular',
              'version': '',
              'function': 'Custom Component',
              'verilog': '',
              'fets': 1,
              'digital': true,
              'style': {
                'fill': '#bfe5ff',
                'stroke': '#005189'
              },
              ports: []
            };
            portsmap = [];
            ports.forEach(function (port) {
              component.ports.push({
                name: port.name,
                type: port.type,
                align: port.type === 'output' ? 'right' : 'left',
                description: 'Custom Port'
              });
              if (pkg.modularPinMap.length > 0) {
                var index = lodash__WEBPACK_IMPORTED_MODULE_3___default.a.findIndex(pkg.modularPinMap, {
                  pinDisplayName: port.name
                });
                if (index >= 0) {
                  portsmap.push(pkg.modularPinMap[index]);
                }
              }
            });
            components = {};
            aCompConfigs = [];
            achip.digitals.forEach(function (comp) {
              if (comp.category === 'Supervisor') {
                components[comp.type] = comp.config.verilog.top_name;
                var compConfig = comp.config;
                var c = {
                  name: comp.name,
                  config: compConfig
                };
                aCompConfigs.push(c);
              }
            });
            chip = project.config.chips[0];
            aComponents = [];
            chip.digitals.forEach(function (comp) {
              var info = Components_component_manager__WEBPACK_IMPORTED_MODULE_16__["default"].components[comp.type];
              if (info.category === 'Supervisor') {
                comp.verilogTopName = components[comp.type];
                var configComp = lodash__WEBPACK_IMPORTED_MODULE_3___default.a.find(aCompConfigs, {
                  name: comp.name
                });
                if (configComp) {
                  var aComp = comp;
                  aComp.config = configComp.config;
                  aComponents.push(aComp);
                }
              }
            });
            chipName = chip.name;
            moduleNetList = {
              conns: chip.connections,
              portsmap: portsmap,
              comps: aComponents
            };
            component['netlist'] = moduleNetList; // JSON.stringify(moduleNetList, null, '\t')
            if (project.dirty) component['dirty'] = true;
            _context34.next = 19;
            return Object(_utils_common__WEBPACK_IMPORTED_MODULE_8__["sendCommand"])('/project', {
              method: 'genCustomVerilog',
              data: {
                id: project.origProjectId,
                topName: modName,
                ports: ports,
                chipname: chipName,
                netlist: moduleNetList
              }
            });
          case 19:
            data = _context34.sent;
            if (data.success) {
              component.verilog = data.data;
              // delete component.netlist
            } else {
              component = null;
            }

            // delete modular project
            prjId = project.origProjectId;
            _context34.next = 24;
            return _this24.deleteProjects([project.projectID]);
          case 24:
            // back to original project
            customComps = null;
            modularPinMap = null;
            _this24.loadModProject(prjId, component, customComps, modularPinMap, true);
          case 27:
          case "end":
            return _context34.stop();
        }
      }, _callee34);
    }))();
  },
  importDefaultModular: function importDefaultModular(pName) {
    var _this25 = this;
    return _babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_1___default()(/*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.mark(function _callee35() {
      var origProjectId, customComps, name, _yield$sendCommand14, success, data, modularPinMap, config, projectName, _yield$sendCommand15;
      return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.wrap(function _callee35$(_context35) {
        while (1) switch (_context35.prev = _context35.next) {
          case 0:
            origProjectId = project.projectID;
            customComps = null;
            if (project.config.customComponents) {
              customComps = project.config.customComponents;
            }
            name = 'defaultModular';
            _context35.next = 6;
            return Object(_utils_common__WEBPACK_IMPORTED_MODULE_8__["sendCommand"])('/project', {
              method: 'getFile',
              file: 'files/' + name + '.json'
            });
          case 6:
            _yield$sendCommand14 = _context35.sent;
            success = _yield$sendCommand14.success;
            data = _yield$sendCommand14.data;
            if (success) {
              _context35.next = 11;
              break;
            }
            return _context35.abrupt("return");
          case 11:
            modularPinMap = null;
            config = JSON.parse(data).config;
            projectName = pName;
            _context35.next = 16;
            return Object(_utils_common__WEBPACK_IMPORTED_MODULE_8__["sendCommand"])('/project', {
              method: 'new',
              name: projectName,
              config: JSON.stringify(config)
            });
          case 16:
            _yield$sendCommand15 = _context35.sent;
            success = _yield$sendCommand15.success;
            data = _yield$sendCommand15.data;
            if (success) {
              _context35.next = 21;
              break;
            }
            return _context35.abrupt("return");
          case 21:
            if (data) {
              _context35.next = 23;
              break;
            }
            return _context35.abrupt("return");
          case 23:
            projects.push(data);
            _this25.loadModProject(data.projectID, origProjectId, customComps, modularPinMap, false);
          case 25:
          case "end":
            return _context35.stop();
        }
      }, _callee35);
    }))();
  },
  loadModProject: function loadModProject(id, inData, customComps, modularPinMap, normalProject) {
    var _this26 = this;
    return _babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_1___default()(/*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.mark(function _callee36() {
      var idNum, _yield$sendCommand16, success, data, chip, component, index, screen, pkg, isNumber;
      return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default.a.wrap(function _callee36$(_context36) {
        while (1) switch (_context36.prev = _context36.next) {
          case 0:
            debug('loadModProject - id: %s', id);
            idNum = id;
            if (lodash__WEBPACK_IMPORTED_MODULE_3___default.a.isString(id)) {
              idNum = parseInt(id);
            }
            _context36.next = 5;
            return _this26.saveProject();
          case 5:
            _context36.next = 7;
            return Object(_utils_common__WEBPACK_IMPORTED_MODULE_8__["sendCommand"])('/project', {
              method: 'load',
              id: id
            });
          case 7:
            _yield$sendCommand16 = _context36.sent;
            success = _yield$sendCommand16.success;
            data = _yield$sendCommand16.data;
            if (success) {
              _context36.next = 12;
              break;
            }
            return _context36.abrupt("return");
          case 12:
            if (data) {
              _context36.next = 14;
              break;
            }
            return _context36.abrupt("return");
          case 14:
            _this26.clearProject(true);
            lodash__WEBPACK_IMPORTED_MODULE_3___default.a.remove(projects, function (p) {
              return p.projectID === idNum;
            });
            user.superMode = false;
            projects.unshift(data);
            project = new _project__WEBPACK_IMPORTED_MODULE_15__["default"](data);
            chip = project.chip;
            project.config.modular = true;
            if (normalProject) {
              // this is a normal project (original project of modular)
              if (inData) {
                component = inData;
                if (!project.config.customComponents) {
                  project.config.customComponents = [];
                }
                index = lodash__WEBPACK_IMPORTED_MODULE_3___default.a.findIndex(project.config.customComponents, {
                  id: component.id
                });
                if (index < 0) {
                  if (component.dirty) {
                    delete component.dirty;
                  }
                  project.config.customComponents.push(component);
                } else {
                  project.config.customComponents.splice(index, 1, component);
                  if (component.dirty) {
                    delete component.dirty;
                    chip.digitals.forEach(function (cp) {
                      if (cp.type === component.id) {
                        Object(_utils_common__WEBPACK_IMPORTED_MODULE_8__["showModalDialog"])('Warning', 'modular(' + component.topName + ') changed, please removed ' + cp.name + 'and do again');
                        return false;
                      }
                    });
                  }
                }
              }
              if (project.config.modular) delete project.config.modular;
              if (project.customComps) delete project.customComps;
            } else {
              // this is a project for modular
              project.origProjectId = inData;
              if (customComps) project.customComps = customComps;
            }
            screen = _screens_screen_manager__WEBPACK_IMPORTED_MODULE_18__["default"].getScreen('design');
            if (normalProject) {
              // this is a normal project (original project of modular)
              screen.buildCategories();
              screen.enableBtns();
            } else {
              // this is a project for modular
              screen.buildModCategories();
              screen.disableBtns();
            }
            if (modularPinMap && Array.isArray(modularPinMap) && modularPinMap.length) {
              pkg = chip.device["package"];
              pkg.modularPinMap = modularPinMap;
            }
            screen.showThermal = false; // make sure it is not in thermal page when loaded
            screen.showComponents = true;
            screen.showConnections = true;
            screen.refresh();
            _this26.refreshProjectsMenu();
            Components_utils_event_bus__WEBPACK_IMPORTED_MODULE_20__["default"].$emit('projectLoaded');
            if (!chip.verilogLibVersions) {
              chip['verilogLibVersions'] = 'Production';
            }
            isNumber = false;
            if (chip.VIN) {
              isNumber = lodash__WEBPACK_IMPORTED_MODULE_3___default.a.isNumber(chip.VIN);
            }
            if (!isNumber) {
              if (screen) {
                screen.handleVIN();
              }
            }
          case 35:
          case "end":
            return _context36.stop();
        }
      }, _callee36);
    }))();
  }
});
/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__("./node_modules/buffer/index.js").Buffer))

/***/ }),

/***/ "./client/project/saveAs-project.pug":
/***/ (function(module, exports, __webpack_require__) {

var pug = __webpack_require__("./node_modules/pug-runtime/index.js");

function template(locals) {var pug_html = "", pug_mixins = {}, pug_interp;pug_html = pug_html + "\u003Cdiv class=\"modal fade\" id=\"modal-saveAs-project\" role=\"dialog\" tabindex=\"-1\"\u003E\u003Cdiv class=\"modal-dialog\"\u003E\u003Cdiv class=\"modal-content\"\u003E\u003Cdiv class=\"modal-header\"\u003E\u003Cbutton class=\"close\" data-dismiss=\"modal\" aria-label=\"close\"\u003E\u003Cspan aria-hidden=\"true\"\u003E&times;\u003C\u002Fspan\u003E\u003C\u002Fbutton\u003E\u003Ch4 class=\"modal-title\"\u003ESave As\u003C\u002Fh4\u003E\u003Csmall\u003E\u003Cspan class=\"label label-danger\"\u003E\u003C\u002Fspan\u003E\u003C\u002Fsmall\u003E\u003C\u002Fdiv\u003E\u003Cdiv class=\"modal-body\"\u003E\u003Cform class=\"param-form form-horizontal\" id=\"saveAs\"\u003E\u003Cdiv class=\"form-group form-group-sm\"\u003E\u003Clabel class=\"col-sm-4 control-label\" for=\"Project Name\" title=\"\"\u003EProject Name\u003C\u002Flabel\u003E\u003Cdiv class=\"col-sm-4\"\u003E\u003Cinput class=\"form-control\" id=\"project-name\" onchange=\"amp.ProjectManager.checkProjectName(this)\" value=\"\"\u003E\u003C\u002Fdiv\u003E\u003C\u002Fdiv\u003E\u003C\u002Fform\u003E\u003C\u002Fdiv\u003E\u003Cdiv class=\"modal-footer\"\u003E\u003Cbutton class=\"btn btn-default\" data-dismiss=\"modal\"\u003ECreate\u003C\u002Fbutton\u003E\u003C\u002Fdiv\u003E\u003C\u002Fdiv\u003E\u003C\u002Fdiv\u003E\u003C\u002Fdiv\u003E";;return pug_html;};
module.exports = template;

/***/ }),

/***/ "./client/project/settings.pug":
/***/ (function(module, exports, __webpack_require__) {

var pug = __webpack_require__("./node_modules/pug-runtime/index.js");

function template(locals) {var pug_html = "", pug_mixins = {}, pug_interp;pug_html = pug_html + "\u003Cdiv class=\"modal fade\" id=\"modal-settings-form\" role=\"dialog\" tabindex=\"-1\"\u003E\u003Cdiv class=\"modal-dialog modal-lg\"\u003E\u003Cdiv class=\"modal-content\" style=\"overflow:auto;resize:both\"\u003E\u003Cdiv class=\"modal-header\"\u003E\u003Cbutton class=\"close\" data-dismiss=\"modal\" aria-label=\"close\"\u003E\u003Cspan aria-hidden=\"true\"\u003E&times;\u003C\u002Fspan\u003E\u003C\u002Fbutton\u003E\u003Ch4 class=\"modal-title\"\u003EProject Settings\u003C\u002Fh4\u003E\u003Csmall\u003E\u003C\u002Fsmall\u003E\u003C\u002Fdiv\u003E\u003Cdiv class=\"modal-body\"\u003E\u003Cdiv\u003E\u003Cul class=\"nav nav-tabs\" role=\"tablist\"\u003E\u003Cli class=\"active\" role=\"presentation\"\u003E\u003Ca href=\"#clocksTab\" aria-controls=\"clocksTab\" role=\"tab\" data-toggle=\"tab\"\u003EClock\u003C\u002Fa\u003E\u003C\u002Fli\u003E\u003Cli role=\"presentation\"\u003E\u003Ca href=\"#platformBoMTab\" aria-controls=\"platformBoMTab\" role=\"tab\" data-toggle=\"tab\"\u003EPlatform BoM\u003C\u002Fa\u003E\u003C\u002Fli\u003E\u003Cli role=\"presentation\"\u003E\u003Ca href=\"#verilogVersionsTab\" aria-controls=\"#verilogVersionsTab\" role=\"tab\" data-toggle=\"tab\"\u003E Verilog Library Versions\u003C\u002Fa\u003E\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cdiv class=\"tab-content\"\u003E\u003Cdiv class=\"tab-pane fade in active\" id=\"clocksTab\" role=\"tabpanel\"\u003E\u003C\u002Fdiv\u003E\u003Cdiv class=\"tab-pane fade\" id=\"platformBoMTab\" role=\"tabpanel\" style=\"overflow-x:auto;overflow-y:auto\"\u003E\u003C\u002Fdiv\u003E\u003Cdiv class=\"tab-pane fade\" id=\"verilogVersionsTab\" role=\"tabpanel\" style=\"overflow-x:auto;overflow-y:auto\"\u003E\u003Cdiv class=\"container-fluid\" style=\"overflow-y:auto;height:100%;\"\u003E\u003Cdiv class=\"row\"\u003E&nbsp;\u003C\u002Fdiv\u003E\u003Cdiv class=\"row\"\u003E\u003Cdiv class=\"col-md-12\"\u003E\u003Ctable class=\"table table-bordered table-striped\"\u003E\u003C\u002Ftable\u003E\u003Ctbody\u003E\u003Ctr\u003E\u003Ctd\u003EVersion\u003C\u002Ftd\u003E\u003Ctd\u003E\u003Cdiv class=\"form-inline\"\u003E\u003Cselect class=\"form-control\" id=\"verilogLibrary-versions\" style=\"width:20%\" onchange=\"amp.ProjectManager.setVerilogLibVersion(this)\"\u003E\u003Coption value=\"Production\" selected\u003EProduction\u003C\u002Foption\u003E\u003Coption value=\"Alpha\"\u003EAlpha\u003C\u002Foption\u003E\u003Coption value=\"Beta\"\u003EBeta\u003C\u002Foption\u003E\u003C\u002Fselect\u003E\u003C\u002Fdiv\u003E\u003C\u002Ftd\u003E\u003C\u002Ftr\u003E\u003C\u002Ftbody\u003E\u003C\u002Fdiv\u003E\u003C\u002Fdiv\u003E\u003C\u002Fdiv\u003E\u003C\u002Fdiv\u003E\u003C\u002Fdiv\u003E\u003C\u002Fdiv\u003E\u003C\u002Fdiv\u003E\u003Cdiv class=\"modal-footer\"\u003E\u003Cbutton class=\"btn btn-default\" id=\"settingsbtn\" data-dismiss=\"modal\"\u003EOk\u003C\u002Fbutton\u003E\u003C\u002Fdiv\u003E\u003C\u002Fdiv\u003E\u003C\u002Fdiv\u003E\u003C\u002Fdiv\u003E";;return pug_html;};
module.exports = template;

/***/ })

}]);
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tbW9uc35GbGV4RGVzaWdufmFkbWlufmFtcGFpfmNsaWVudC5jaHVuay5qcyIsInNvdXJjZXMiOlsiL2hvbWUvZWMyLXVzZXIvRGVjXzA2XzIwMjQvd2ViYW1wMS9jbGllbnQvcHJvamVjdC9pbXBvcnQtcHJvamVjdC5wdWciLCIvaG9tZS9lYzItdXNlci9EZWNfMDZfMjAyNC93ZWJhbXAxL2NsaWVudC9wcm9qZWN0L21hbmFnZS1wcm9qZWN0cy5wdWciLCIvaG9tZS9lYzItdXNlci9EZWNfMDZfMjAyNC93ZWJhbXAxL2NsaWVudC9wcm9qZWN0L21vZHVsYXItcHJvamVjdC5wdWciLCIvaG9tZS9lYzItdXNlci9EZWNfMDZfMjAyNC93ZWJhbXAxL2NsaWVudC9wcm9qZWN0L25ldy1wcm9qZWN0LnB1ZyIsIi9ob21lL2VjMi11c2VyL0RlY18wNl8yMDI0L3dlYmFtcDEvY2xpZW50L3Byb2plY3QvcHJvamVjdC1tYW5hZ2VyLmpzIiwiL2hvbWUvZWMyLXVzZXIvRGVjXzA2XzIwMjQvd2ViYW1wMS9jbGllbnQvcHJvamVjdC9zYXZlQXMtcHJvamVjdC5wdWciLCIvaG9tZS9lYzItdXNlci9EZWNfMDZfMjAyNC93ZWJhbXAxL2NsaWVudC9wcm9qZWN0L3NldHRpbmdzLnB1ZyJdLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgcHVnID0gcmVxdWlyZShcIiEuLi8uLi9ub2RlX21vZHVsZXMvcHVnLXJ1bnRpbWUvaW5kZXguanNcIik7XG5cbmZ1bmN0aW9uIHRlbXBsYXRlKGxvY2Fscykge3ZhciBwdWdfaHRtbCA9IFwiXCIsIHB1Z19taXhpbnMgPSB7fSwgcHVnX2ludGVycDtwdWdfaHRtbCA9IHB1Z19odG1sICsgXCJcXHUwMDNDZGl2IGNsYXNzPVxcXCJtb2RhbCBmYWRlXFxcIiBpZD1cXFwibW9kYWwtaW1wb3J0LXByb2plY3RcXFwiIHJvbGU9XFxcImRpYWxvZ1xcXCIgdGFiaW5kZXg9XFxcIi0xXFxcIlxcdTAwM0VcXHUwMDNDZGl2IGNsYXNzPVxcXCJtb2RhbC1kaWFsb2dcXFwiXFx1MDAzRVxcdTAwM0NkaXYgY2xhc3M9XFxcIm1vZGFsLWNvbnRlbnRcXFwiXFx1MDAzRVxcdTAwM0NkaXYgY2xhc3M9XFxcIm1vZGFsLWhlYWRlclxcXCJcXHUwMDNFXFx1MDAzQ2J1dHRvbiBjbGFzcz1cXFwiY2xvc2VcXFwiIGRhdGEtZGlzbWlzcz1cXFwibW9kYWxcXFwiIGFyaWEtbGFiZWw9XFxcImNsb3NlXFxcIlxcdTAwM0VcXHUwMDNDc3BhbiBhcmlhLWhpZGRlbj1cXFwidHJ1ZVxcXCJcXHUwMDNFJnRpbWVzO1xcdTAwM0NcXHUwMDJGc3BhblxcdTAwM0VcXHUwMDNDXFx1MDAyRmJ1dHRvblxcdTAwM0VcXHUwMDNDaDQgY2xhc3M9XFxcIm1vZGFsLXRpdGxlXFxcIlxcdTAwM0VJbXBvcnQgUHJvamVjdCAgKC56aXAgb3IgLmpzb24gZmlsZSlcXHUwMDNDXFx1MDAyRmg0XFx1MDAzRVxcdTAwM0NzbWFsbFxcdTAwM0VcXHUwMDNDc3BhbiBjbGFzcz1cXFwibGFiZWwgbGFiZWwtZGFuZ2VyXFxcIlxcdTAwM0VcXHUwMDNDXFx1MDAyRnNwYW5cXHUwMDNFXFx1MDAzQ1xcdTAwMkZzbWFsbFxcdTAwM0VcXHUwMDNDXFx1MDAyRmRpdlxcdTAwM0VcXHUwMDNDZGl2IGNsYXNzPVxcXCJtb2RhbC1ib2R5XFxcIlxcdTAwM0VcXHUwMDNDZm9ybSBjbGFzcz1cXFwicGFyYW0tZm9ybSBmb3JtLWhvcml6b250YWxcXFwiIGlkPVxcXCJpbXBvcnRcXFwiXFx1MDAzRVxcdTAwM0NkaXYgY2xhc3M9XFxcImZvcm0tZ3JvdXAgZm9ybS1ncm91cC1zbVxcXCJcXHUwMDNFXFx1MDAzQ2xhYmVsIGNsYXNzPVxcXCJjb2wtc20tNCBjb250cm9sLWxhYmVsXFxcIiBmb3I9XFxcIlByb2plY3QgTmFtZVxcXCIgdGl0bGU9XFxcIlxcXCJcXHUwMDNFUHJvamVjdCBOYW1lXFx1MDAzQ1xcdTAwMkZsYWJlbFxcdTAwM0VcXHUwMDNDZGl2IGNsYXNzPVxcXCJjb2wtc20tOFxcXCJcXHUwMDNFXFx1MDAzQ2lucHV0IGNsYXNzPVxcXCJmb3JtLWNvbnRyb2xcXFwiIGlkPVxcXCJwcm9qZWN0LW5hbWVcXFwiIG9uY2hhbmdlPVxcXCJhbXAuUHJvamVjdE1hbmFnZXIuY2hlY2tQcm9qZWN0TmFtZSh0aGlzKVxcXCIgdmFsdWU9XFxcIlxcXCJcXHUwMDNFXFx1MDAzQ1xcdTAwMkZkaXZcXHUwMDNFXFx1MDAzQ1xcdTAwMkZkaXZcXHUwMDNFXFx1MDAzQ2RpdiBjbGFzcz1cXFwiZm9ybS1ncm91cCBmb3JtLWdyb3VwLXNtXFxcIlxcdTAwM0VcXHUwMDNDZGl2IGNsYXNzPVxcXCJjb2wtc20tMTJcXFwiXFx1MDAzRVxcdTAwM0NpbnB1dCBjbGFzcz1cXFwiZmlsZXN0eWxlIGZvcm0tY29udHJvbFxcXCIgdHlwZT1cXFwiZmlsZVxcXCIgYWNjZXB0PVxcXCIuemlwLC5qc29uXFxcIiBkYXRhLWNsYXNzYnV0dG9uPVxcXCJidG4gYnRuLXByaW1hcnlcXFwiIGRhdGEtaW5wdXQ9XFxcImZhbHNlXFxcIiBkYXRhLWNsYXNzaWNvbj1cXFwiaWNvbi1wbHVzXFxcIlxcdTAwM0VcXHUwMDNDXFx1MDAyRmRpdlxcdTAwM0VcXHUwMDNDXFx1MDAyRmRpdlxcdTAwM0VcXHUwMDNDXFx1MDAyRmZvcm1cXHUwMDNFXFx1MDAzQ1xcdTAwMkZkaXZcXHUwMDNFXFx1MDAzQ2RpdiBjbGFzcz1cXFwibW9kYWwtZm9vdGVyXFxcIlxcdTAwM0VcXHUwMDNDYnV0dG9uIGNsYXNzPVxcXCJidG4gYnRuLWRlZmF1bHRcXFwiIGRhdGEtZGlzbWlzcz1cXFwibW9kYWxcXFwiXFx1MDAzRUNyZWF0ZVxcdTAwM0NcXHUwMDJGYnV0dG9uXFx1MDAzRVxcdTAwM0NcXHUwMDJGZGl2XFx1MDAzRVxcdTAwM0NcXHUwMDJGZGl2XFx1MDAzRVxcdTAwM0NcXHUwMDJGZGl2XFx1MDAzRVxcdTAwM0NcXHUwMDJGZGl2XFx1MDAzRVwiOztyZXR1cm4gcHVnX2h0bWw7fTtcbm1vZHVsZS5leHBvcnRzID0gdGVtcGxhdGU7IiwidmFyIHB1ZyA9IHJlcXVpcmUoXCIhLi4vLi4vbm9kZV9tb2R1bGVzL3B1Zy1ydW50aW1lL2luZGV4LmpzXCIpO1xuXG5mdW5jdGlvbiB0ZW1wbGF0ZShsb2NhbHMpIHt2YXIgcHVnX2h0bWwgPSBcIlwiLCBwdWdfbWl4aW5zID0ge30sIHB1Z19pbnRlcnA7cHVnX2h0bWwgPSBwdWdfaHRtbCArIFwiXFx1MDAzQ2RpdiBjbGFzcz1cXFwibW9kYWwgZmFkZVxcXCIgaWQ9XFxcIm1hbmFnZS1wcm9qZWN0c1xcXCIgcm9sZT1cXFwiZGlhbG9nXFxcIiB0YWJpbmRleD1cXFwiLTFcXFwiIHN0eWxlPVxcXCJvdmVyZmxvdzpoaWRkZW5cXFwiXFx1MDAzRVxcdTAwM0NkaXYgY2xhc3M9XFxcIm1vZGFsLWRpYWxvZ1xcXCIgcm9sZT1cXFwiZG9jdW1lbnRcXFwiXFx1MDAzRVxcdTAwM0NkaXYgY2xhc3M9XFxcIm1vZGFsLWNvbnRlbnRcXFwiXFx1MDAzRVxcdTAwM0NkaXYgY2xhc3M9XFxcIm1vZGFsLWhlYWRlclxcXCJcXHUwMDNFXFx1MDAzQ2J1dHRvbiBjbGFzcz1cXFwiY2xvc2VcXFwiIGRhdGEtZGlzbWlzcz1cXFwibW9kYWxcXFwiIGFyaWEtbGFiZWw9XFxcImNsb3NlXFxcIlxcdTAwM0VcXHUwMDNDc3BhbiBhcmlhLWhpZGRlbj1cXFwidHJ1ZVxcXCJcXHUwMDNFJnRpbWVzO1xcdTAwM0NcXHUwMDJGc3BhblxcdTAwM0VcXHUwMDNDXFx1MDAyRmJ1dHRvblxcdTAwM0VcXHUwMDNDaDQgY2xhc3M9XFxcIm1vZGFsLXRpdGxlXFxcIlxcdTAwM0VNYW5hZ2UgUHJvamVjdHNcXHUwMDNDXFx1MDAyRmg0XFx1MDAzRVxcdTAwM0NzbWFsbFxcdTAwM0VcXHUwMDNDc3BhbiBjbGFzcz1cXFwibGFiZWwgbGFiZWwtZGFuZ2VyXFxcIlxcdTAwM0VcXHUwMDNDXFx1MDAyRnNwYW5cXHUwMDNFXFx1MDAzQ1xcdTAwMkZzbWFsbFxcdTAwM0VcXHUwMDNDXFx1MDAyRmRpdlxcdTAwM0VcXHUwMDNDZGl2IGNsYXNzPVxcXCJtb2RhbC1ib2R5XFxcIlxcdTAwM0VcXHUwMDNDZGl2IGlkPVxcXCJwcm9qZWN0cy1ncmlkXFxcIiBzdHlsZT1cXFwid2lkdGg6MTAwJTtoZWlnaHQ6NDAwcHhcXFwiXFx1MDAzRVxcdTAwM0NcXHUwMDJGZGl2XFx1MDAzRVxcdTAwM0NcXHUwMDJGZGl2XFx1MDAzRVxcdTAwM0NkaXYgY2xhc3M9XFxcIm1vZGFsLWZvb3RlclxcXCJcXHUwMDNFXFx1MDAzQ2J1dHRvbiBjbGFzcz1cXFwiYnRuIGJ0bi1kZWZhdWx0XFxcIiBkYXRhLWRpc21pc3M9XFxcIm1vZGFsXFxcIlxcdTAwM0VDYW5jZWxcXHUwMDNDXFx1MDAyRmJ1dHRvblxcdTAwM0VcXHUwMDNDYnV0dG9uIGNsYXNzPVxcXCJidG4gYnRuLXByaW1hcnlcXFwiIGRhdGEtZGlzbWlzcz1cXFwibW9kYWxcXFwiXFx1MDAzRVNhdmVcXHUwMDNDXFx1MDAyRmJ1dHRvblxcdTAwM0VcXHUwMDNDXFx1MDAyRmRpdlxcdTAwM0VcXHUwMDNDXFx1MDAyRmRpdlxcdTAwM0VcXHUwMDNDXFx1MDAyRmRpdlxcdTAwM0VcXHUwMDNDXFx1MDAyRmRpdlxcdTAwM0VcIjs7cmV0dXJuIHB1Z19odG1sO307XG5tb2R1bGUuZXhwb3J0cyA9IHRlbXBsYXRlOyIsInZhciBwdWcgPSByZXF1aXJlKFwiIS4uLy4uL25vZGVfbW9kdWxlcy9wdWctcnVudGltZS9pbmRleC5qc1wiKTtcblxuZnVuY3Rpb24gdGVtcGxhdGUobG9jYWxzKSB7dmFyIHB1Z19odG1sID0gXCJcIiwgcHVnX21peGlucyA9IHt9LCBwdWdfaW50ZXJwO3B1Z19odG1sID0gcHVnX2h0bWwgKyBcIlxcdTAwM0NkaXYgY2xhc3M9XFxcIm1vZGFsIGZhZGVcXFwiIGlkPVxcXCJtb2RhbC1zYXZlQXMtcHJvamVjdFxcXCIgcm9sZT1cXFwiZGlhbG9nXFxcIiB0YWJpbmRleD1cXFwiLTFcXFwiXFx1MDAzRVxcdTAwM0NkaXYgY2xhc3M9XFxcIm1vZGFsLWRpYWxvZ1xcXCJcXHUwMDNFXFx1MDAzQ2RpdiBjbGFzcz1cXFwibW9kYWwtY29udGVudFxcXCJcXHUwMDNFXFx1MDAzQ2RpdiBjbGFzcz1cXFwibW9kYWwtaGVhZGVyXFxcIlxcdTAwM0VcXHUwMDNDYnV0dG9uIGNsYXNzPVxcXCJjbG9zZVxcXCIgZGF0YS1kaXNtaXNzPVxcXCJtb2RhbFxcXCIgYXJpYS1sYWJlbD1cXFwiY2xvc2VcXFwiXFx1MDAzRVxcdTAwM0NzcGFuIGFyaWEtaGlkZGVuPVxcXCJ0cnVlXFxcIlxcdTAwM0UmdGltZXM7XFx1MDAzQ1xcdTAwMkZzcGFuXFx1MDAzRVxcdTAwM0NcXHUwMDJGYnV0dG9uXFx1MDAzRVxcdTAwM0NoNCBjbGFzcz1cXFwibW9kYWwtdGl0bGVcXFwiXFx1MDAzRU1vZHVsZVxcdTAwM0NcXHUwMDJGaDRcXHUwMDNFXFx1MDAzQ3NtYWxsXFx1MDAzRVxcdTAwM0NzcGFuIGNsYXNzPVxcXCJsYWJlbCBsYWJlbC1kYW5nZXJcXFwiXFx1MDAzRVxcdTAwM0NcXHUwMDJGc3BhblxcdTAwM0VcXHUwMDNDXFx1MDAyRnNtYWxsXFx1MDAzRVxcdTAwM0NcXHUwMDJGZGl2XFx1MDAzRVxcdTAwM0NkaXYgY2xhc3M9XFxcIm1vZGFsLWJvZHlcXFwiXFx1MDAzRVxcdTAwM0Nmb3JtIGNsYXNzPVxcXCJwYXJhbS1mb3JtIGZvcm0taG9yaXpvbnRhbFxcXCIgaWQ9XFxcInNhdmVBc1xcXCJcXHUwMDNFXFx1MDAzQ2RpdiBjbGFzcz1cXFwiZm9ybS1ncm91cCBmb3JtLWdyb3VwLXNtXFxcIlxcdTAwM0VcXHUwMDNDbGFiZWwgY2xhc3M9XFxcImNvbC1zbS00IGNvbnRyb2wtbGFiZWxcXFwiIGZvcj1cXFwiTW9kdWxlIE5hbWVcXFwiIHRpdGxlPVxcXCJcXFwiXFx1MDAzRU1vZHVsZSBOYW1lXFx1MDAzQ1xcdTAwMkZsYWJlbFxcdTAwM0VcXHUwMDNDZGl2IGNsYXNzPVxcXCJjb2wtc20tNFxcXCJcXHUwMDNFXFx1MDAzQ2lucHV0IGNsYXNzPVxcXCJmb3JtLWNvbnRyb2xcXFwiIGlkPVxcXCJwcm9qZWN0LW5hbWVcXFwiIG9uY2hhbmdlPVxcXCJhbXAuUHJvamVjdE1hbmFnZXIuY2hlY2tQcm9qZWN0TmFtZSh0aGlzKVxcXCIgdmFsdWU9XFxcIlxcXCJcXHUwMDNFXFx1MDAzQ1xcdTAwMkZkaXZcXHUwMDNFXFx1MDAzQ1xcdTAwMkZkaXZcXHUwMDNFXFx1MDAzQ1xcdTAwMkZmb3JtXFx1MDAzRVxcdTAwM0NcXHUwMDJGZGl2XFx1MDAzRVxcdTAwM0NkaXYgY2xhc3M9XFxcIm1vZGFsLWZvb3RlclxcXCJcXHUwMDNFXFx1MDAzQ2J1dHRvbiBjbGFzcz1cXFwiYnRuIGJ0bi1kZWZhdWx0XFxcIiBkYXRhLWRpc21pc3M9XFxcIm1vZGFsXFxcIlxcdTAwM0VDcmVhdGVcXHUwMDNDXFx1MDAyRmJ1dHRvblxcdTAwM0VcXHUwMDNDXFx1MDAyRmRpdlxcdTAwM0VcXHUwMDNDXFx1MDAyRmRpdlxcdTAwM0VcXHUwMDNDXFx1MDAyRmRpdlxcdTAwM0VcXHUwMDNDXFx1MDAyRmRpdlxcdTAwM0VcIjs7cmV0dXJuIHB1Z19odG1sO307XG5tb2R1bGUuZXhwb3J0cyA9IHRlbXBsYXRlOyIsInZhciBwdWcgPSByZXF1aXJlKFwiIS4uLy4uL25vZGVfbW9kdWxlcy9wdWctcnVudGltZS9pbmRleC5qc1wiKTtcblxuZnVuY3Rpb24gdGVtcGxhdGUobG9jYWxzKSB7dmFyIHB1Z19odG1sID0gXCJcIiwgcHVnX21peGlucyA9IHt9LCBwdWdfaW50ZXJwO3B1Z19odG1sID0gcHVnX2h0bWwgKyBcIlxcdTAwM0NkaXYgY2xhc3M9XFxcIm1vZGFsIGZhZGVcXFwiIGlkPVxcXCJtb2RhbC1uZXctcHJvamVjdFxcXCIgcm9sZT1cXFwiZGlhbG9nXFxcIiB0YWJpbmRleD1cXFwiLTFcXFwiXFx1MDAzRVxcdTAwM0NkaXYgY2xhc3M9XFxcIm1vZGFsLWRpYWxvZ1xcXCJcXHUwMDNFXFx1MDAzQ2RpdiBjbGFzcz1cXFwibW9kYWwtY29udGVudFxcXCJcXHUwMDNFXFx1MDAzQ2RpdiBjbGFzcz1cXFwibW9kYWwtaGVhZGVyXFxcIlxcdTAwM0VcXHUwMDNDYnV0dG9uIGNsYXNzPVxcXCJjbG9zZVxcXCIgZGF0YS1kaXNtaXNzPVxcXCJtb2RhbFxcXCIgYXJpYS1sYWJlbD1cXFwiY2xvc2VcXFwiXFx1MDAzRVxcdTAwM0NzcGFuIGFyaWEtaGlkZGVuPVxcXCJ0cnVlXFxcIlxcdTAwM0UmdGltZXM7XFx1MDAzQ1xcdTAwMkZzcGFuXFx1MDAzRVxcdTAwM0NcXHUwMDJGYnV0dG9uXFx1MDAzRVxcdTAwM0NoNCBjbGFzcz1cXFwibW9kYWwtdGl0bGVcXFwiXFx1MDAzRUNyZWF0ZSBuZXcgcHJvamVjdFxcdTAwM0NcXHUwMDJGaDRcXHUwMDNFXFx1MDAzQ3NtYWxsXFx1MDAzRVxcdTAwM0NzcGFuIGNsYXNzPVxcXCJsYWJlbCBsYWJlbC1kYW5nZXJcXFwiXFx1MDAzRVxcdTAwM0NcXHUwMDJGc3BhblxcdTAwM0VcXHUwMDNDXFx1MDAyRnNtYWxsXFx1MDAzRVxcdTAwM0NcXHUwMDJGZGl2XFx1MDAzRVxcdTAwM0NkaXYgY2xhc3M9XFxcIm1vZGFsLWJvZHlcXFwiXFx1MDAzRVxcdTAwM0Nmb3JtIGNsYXNzPVxcXCJwYXJhbS1mb3JtIGZvcm0taG9yaXpvbnRhbFxcXCIgaWQ9XFxcIm5ldy1wcm9qZWN0XFxcIlxcdTAwM0VcXHUwMDNDZGl2IGNsYXNzPVxcXCJmb3JtLWdyb3VwIGZvcm0tZ3JvdXAtc21cXFwiXFx1MDAzRVxcdTAwM0NsYWJlbCBjbGFzcz1cXFwiY29sLXNtLTQgY29udHJvbC1sYWJlbFxcXCIgZm9yPVxcXCJQcm9qZWN0IE5hbWVcXFwiXFx1MDAzRVByb2plY3QgTmFtZVxcdTAwM0NcXHUwMDJGbGFiZWxcXHUwMDNFXFx1MDAzQ2RpdiBjbGFzcz1cXFwiY29sLXNtLThcXFwiXFx1MDAzRVxcdTAwM0NpbnB1dCBjbGFzcz1cXFwiZm9ybS1jb250cm9sXFxcIiBpZD1cXFwicHJvamVjdC1uYW1lXFxcIiBvbmNoYW5nZT1cXFwiYW1wLlByb2plY3RNYW5hZ2VyLmNoZWNrUHJvamVjdE5hbWUodGhpcylcXFwiXFx1MDAzRVxcdTAwM0NcXHUwMDJGZGl2XFx1MDAzRVxcdTAwM0NcXHUwMDJGZGl2XFx1MDAzRVxcdTAwM0NcXHUwMDJGZm9ybVxcdTAwM0VcXHUwMDNDXFx1MDAyRmRpdlxcdTAwM0VcXHUwMDNDZGl2IGNsYXNzPVxcXCJtb2RhbC1mb290ZXJcXFwiXFx1MDAzRVxcdTAwM0NidXR0b24gY2xhc3M9XFxcImJ0biBidG4tZGVmYXVsdFxcXCIgZGF0YS1kaXNtaXNzPVxcXCJtb2RhbFxcXCJcXHUwMDNFQ3JlYXRlXFx1MDAzQ1xcdTAwMkZidXR0b25cXHUwMDNFXFx1MDAzQ1xcdTAwMkZkaXZcXHUwMDNFXFx1MDAzQ1xcdTAwMkZkaXZcXHUwMDNFXFx1MDAzQ1xcdTAwMkZkaXZcXHUwMDNFXFx1MDAzQ1xcdTAwMkZkaXZcXHUwMDNFXCI7O3JldHVybiBwdWdfaHRtbDt9O1xubW9kdWxlLmV4cG9ydHMgPSB0ZW1wbGF0ZTsiLCJpbXBvcnQgXyBmcm9tICdsb2Rhc2gnXG5pbXBvcnQgcWcgZnJvbSAncWdyYXBoJ1xuaW1wb3J0IGNyZWF0ZURlYnVnIGZyb20gJ2RlYnVnJ1xuaW1wb3J0IEpTWmlwIGZyb20gJ2pzemlwJ1xuaW1wb3J0IHsgc2F2ZUFzIH0gZnJvbSAnZmlsZS1zYXZlcidcblxuaW1wb3J0IHsgc2V0RGlhbG9nQnV0dG9uQWN0aW9uLCBzaG93TW9kYWxEaWFsb2csIHJlZGlyZWN0LCBjcmVhdGVNb2RhbERpYWxvZywgc2hvd0NvbmZpcm0sIHNlbmRDb21tYW5kLCBzaG93QnVzeSwgaGlkZUJ1c3kgfSBmcm9tICcuLi91dGlscy9jb21tb24nXG5pbXBvcnQgdGVtcGxhdGVOZXdQcm9qZWN0IGZyb20gJy4vbmV3LXByb2plY3QucHVnJ1xuaW1wb3J0IHRlbXBsYXRlSW1wb3J0UHJvamVjdCBmcm9tICcuL2ltcG9ydC1wcm9qZWN0LnB1ZydcbmltcG9ydCB0ZW1wbGF0ZVNhdmVBc1Byb2plY3QgZnJvbSAnLi9zYXZlQXMtcHJvamVjdC5wdWcnXG5pbXBvcnQgdGVtcGxhdGVNb2R1bGFyUHJvamVjdCBmcm9tICcuL21vZHVsYXItcHJvamVjdC5wdWcnXG5pbXBvcnQgdGVtcGxhdGVNYW5hZ2VQcm9qZWN0cyBmcm9tICcuL21hbmFnZS1wcm9qZWN0cy5wdWcnXG5pbXBvcnQgdGVtcGxhdGVQcm9qZWN0U2V0dGluZ3MgZnJvbSAnLi9zZXR0aW5ncy5wdWcnXG5pbXBvcnQgUHJvamVjdCBmcm9tICcuL3Byb2plY3QnXG5pbXBvcnQgQ29tcG9uZW50TWFuYWdlciBmcm9tICdDb21wb25lbnRzL2NvbXBvbmVudC1tYW5hZ2VyJ1xuaW1wb3J0IFBhY2thZ2VNYW5hZ2VyIGZyb20gJ0NvbXBvbmVudHMvcGFja2FnZXMvcGFja2FnZS1tYW5hZ2VyJ1xuaW1wb3J0IFNjcmVlbk1hbmFnZXIgZnJvbSAnLi4vc2NyZWVucy9zY3JlZW4tbWFuYWdlcidcbmltcG9ydCBCb01BUEkgZnJvbSAnQ2xpZW50L2JvbSdcbmltcG9ydCBFdmVudEJ1cyBmcm9tICdDb21wb25lbnRzL3V0aWxzL2V2ZW50LWJ1cydcbmltcG9ydCB7IGJ1aWxkQ2xvY2tGb3JtLCBWZXJpZnlDb21wQ2xvY2sgfSBmcm9tICdDb21wb25lbnRzL3BhcmFtZXRlcnMvY2xvY2snXG5pbXBvcnQgVmVyc2lvbnMgZnJvbSAnQ29tcG9uZW50cy91dGlscy92ZXJzaW9ucydcblxuY29uc3QgZGVidWcgPSBjcmVhdGVEZWJ1ZygncHJvamVjdDptYW5hZ2VyJylcblxuY29uc3QgdG9vbEJhckNvbG91bXMgPSBbXG4gIHtcbiAgICBmaWVsZDogJ29yZGVyJyxcbiAgICBjYXB0aW9uOiAnb3JkZXInLFxuICAgIHNpemU6ICc0NXB4JyxcbiAgICBzb3J0YWJsZTogdHJ1ZSxcbiAgICByZXNpemFibGU6IHRydWUsXG4gICAgcmVuZGVyOiAnaW50JyxcbiAgICBlZGl0YWJsZToge1xuICAgICAgdHlwZTogJ2ludCcsXG4gICAgfSxcbiAgfSxcbiAge1xuICAgIGZpZWxkOiAnbmFtZScsXG4gICAgY2FwdGlvbjogJ1Byb2plY3QgTmFtZScsXG4gICAgc29ydGFibGU6IHRydWUsXG4gICAgc2l6ZTogJzEwMCUnLFxuICAgIGVkaXRhYmxlOiB7XG4gICAgICB0eXBlOiAndGV4dCcsXG4gICAgfSxcbiAgfSxcbiAge1xuICAgIGZpZWxkOiAnZGV2aWNlJyxcbiAgICBjYXB0aW9uOiAnRGV2aWNlJyxcbiAgICBzb3J0YWJsZTogZmFsc2UsXG4gICAgc2l6ZTogJzEwMHB4JyxcbiAgfSxcbiAge1xuICAgIGZpZWxkOiAnbW9kaWZpY2F0aW9uX3RpbWUnLFxuICAgIGNhcHRpb246ICdNb2RpZmllZCBEYXRlJyxcbiAgICBzb3J0YWJsZTogdHJ1ZSxcbiAgICBzaXplOiAnMTAwcHgnLFxuICAgIHJlbmRlcjogJ2RhdGUnLFxuICAgIGF0dHI6ICdhbGlnbj1yaWdodCcsXG4gIH0sXG4gIHtcbiAgICBmaWVsZDogJ2NyZWF0aW9uX3RpbWUnLFxuICAgIGNhcHRpb246ICdDcmVhdGlvbiBEYXRlJyxcbiAgICBzb3J0YWJsZTogdHJ1ZSxcbiAgICBzaXplOiAnMTAwcHgnLFxuICAgIHJlbmRlcjogJ2RhdGUnLFxuICAgIGF0dHI6ICdhbGlnbj1yaWdodCcsXG4gIH0sXG5dXG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgY2hlY2tQcm9qZWN0TmFtZSAoaW5wdXQsIGV4Y2x1ZGUsIHByb2plY3RzLCB1c2VySUQpIHtcbiAgICBpZiAoIXByb2plY3RzKSB7XG4gICAgICBwcm9qZWN0cyA9IHdpbmRvdy5wcm9qZWN0c1xuICAgIH1cbiAgICBpZiAoIV8uaXNTdHJpbmcoaW5wdXQpKSB7XG4gICAgICBpbnB1dCA9ICQoaW5wdXQpLnZhbCgpXG4gICAgfVxuICAgIC8vIHJlbW92ZSAnICcgaW4gcHJvamVjdCBuYW1lXG4gICAgaW5wdXQgPSBpbnB1dC5yZXBsYWNlKC8gL2csICdfJylcbiAgICBpZiAoXy5pc1VuZGVmaW5lZChleGNsdWRlKSB8fCBfLmlzTnVsbChleGNsdWRlKSkge1xuICAgICAgZXhjbHVkZSA9IC0xXG4gICAgfVxuICAgIGxldCB2YWxpZCA9IHRydWVcbiAgICBwcm9qZWN0cy5mb3JFYWNoKGZ1bmN0aW9uIChwLCBpKSB7XG4gICAgICBpZiAoaSAhPT0gZXhjbHVkZSAmJiBwLm5hbWUgPT09IGlucHV0ICYmICghdXNlcklEIHx8ICFwLnVzZXJJRCB8fCBwLnVzZXJJRCA9PT0gdXNlcklEKSkge1xuICAgICAgICB2YWxpZCA9IGZhbHNlXG4gICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgfVxuICAgIH0pXG4gICAgcmV0dXJuIHZhbGlkXG4gIH0sXG5cbiAgcmVmcmVzaFByb2plY3RzTWVudSAoKSB7XG4gICAgbGV0IHJlbGVhc2V2ZXIgPSBWZXJzaW9ucy5yZWxlYXNlXG4gICAgbGV0IGJ1ZiA9IG5ldyBxZy5TdHJpbmdCdWZmZXIoKVxuICAgIGxldCB1bCA9ICQoJyNvcGVuTWVudSA+IHVsJylcbiAgICAvLyBmb3IgbW9kdWxhclxuICAgIGxldCBkZWxldGVQcm9qZWN0cyA9IFtdXG4gICAgbGV0IGRlbGV0ZVByb2plY3ROYW1lcyA9ICcnXG5cbiAgICBpZiAocHJvamVjdHMubGVuZ3RoID4gMCkge1xuICAgICAgcHJvamVjdHMuZm9yRWFjaCgocHJvamVjdCkgPT4ge1xuICAgICAgICBpZiAocHJvamVjdCAmJiBwcm9qZWN0LmNvbmZpZyAmJiAhcHJvamVjdC5jb25maWcubW9kdWxhcikge1xuICAgICAgICAgIGJ1Zi5hcHBlbmQoJzxsaT48YSBocmVmPVwiamF2YXNjcmlwdDphbXAuUHJvamVjdE1hbmFnZXIubG9hZFByb2plY3QoJykuYXBwZW5kKHByb2plY3QucHJvamVjdElEKS5hcHBlbmQoJylcIj48c3BhbiBjbGFzcz1cIm1lbnUtdGV4dFwiPicpLmFwcGVuZChwcm9qZWN0Lm5hbWUpLmFwcGVuZCgnPC9zcGFuPjwvYT48L2xpPicpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gZm9yIG1vZHVsYXI6IG5lZWQgdG8gcmVtb3ZlIHRoaXMgcHJvamVjdFxuICAgICAgICAgIGlmIChwcm9qZWN0LnByb2plY3RJRCkge1xuICAgICAgICAgICAgZGVsZXRlUHJvamVjdHMucHVzaChwcm9qZWN0LnByb2plY3RJRClcbiAgICAgICAgICAgIGRlbGV0ZVByb2plY3ROYW1lcyA9IGRlbGV0ZVByb2plY3ROYW1lcyArICcgJyArIHByb2plY3QubmFtZVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSlcbiAgICB9IGVsc2Uge1xuICAgICAgYnVmLmFwcGVuZCgnPGxpIGNsYXNzPVwiZGlzYWJsZWRcIj48YSBocmVmPVwiamF2YXNjcmlwdDp2b2lkKDApO1wiPjxzcGFuIGNsYXNzPVwibWVudS10ZXh0XCI+Tm8gcHJvamVjdCBhdmFpbGFibGU8L3NwYW4+PC9hPjwvbGk+JylcbiAgICB9XG5cbiAgICB1bC5odG1sKGJ1Zi50b1N0cmluZygpKVxuXG4gICAgLy8gdXBkYXRlIGV4YW1wbGUgYW5kIGRldmljZSBvcHRpb25zIGRlcGVuZHMgb24gcGxhdGZvcm1cbiAgICBsZXQgZGl2cyA9ICQoJy5leGFtcHZlcicpIC8vIGNvbnRyb2wgZXhhbXBsZXNcbiAgICBsZXQgcGRpdnMgPSAkKCcucGxhdGZvcm12ZXInKSAvLyBjb250cm9sIGRldmljZSBwbGF0Zm9ybVxuICAgIGxldCBkZXZpY2VWZXIgPSAnQSdcbiAgICBsZXQgdXBkYXRlZG9uZSA9IGZhbHNlXG4gICAgaWYgKCFyZWxlYXNldmVyKSB7XG4gICAgICBpZiAocHJvamVjdCAmJiBwcm9qZWN0LmRldmljZSkge1xuICAgICAgICBkZXZpY2VWZXIgPSBwcm9qZWN0LmRldmljZS52ZXJzaW9uXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBfLmZvckVhY2goZGl2cywgZnVuY3Rpb24gKGluZCkgeyAvLyBjb250cm9sIGV4YW1wbGVzXG4gICAgICAgICAgbGV0IGRpdiA9ICQoaW5kKVxuICAgICAgICAgIGxldCBwYXJlbnQgPSBkaXYucGFyZW50KClcbiAgICAgICAgICBwYXJlbnQuc2hvdygpXG4gICAgICAgIH0pXG4gICAgICAgIF8uZm9yRWFjaChwZGl2cywgZnVuY3Rpb24gKGluZCkgeyAvLyBjb250cm9sIGRldmljZSBwbGF0Zm9ybVxuICAgICAgICAgIGxldCBkaXYgPSAkKGluZClcbiAgICAgICAgICBsZXQgcGFyZW50ID0gZGl2LnBhcmVudCgpXG4gICAgICAgICAgcGFyZW50LnNob3coKVxuICAgICAgICB9KVxuICAgICAgICB1cGRhdGVkb25lID0gdHJ1ZVxuICAgICAgfVxuICAgIH1cbiAgICBpZiAoIXVwZGF0ZWRvbmUpIHtcbiAgICAgIF8uZm9yRWFjaChkaXZzLCBmdW5jdGlvbiAoaW5kKSB7IC8vIGNvbnRyb2wgZXhhbXBsZXNcbiAgICAgICAgbGV0IGRpdiA9ICQoaW5kKVxuICAgICAgICBsZXQgZm9sZGVybmFtZSA9IGRpdi50ZXh0KClcbiAgICAgICAgbGV0IHVzaW5nZm9sZGVyID0gZmFsc2VcbiAgICAgICAgaWYgKGZvbGRlcm5hbWUgPT09ICdQbGF0Zm9ybSAnICsgZGV2aWNlVmVyKSB7XG4gICAgICAgICAgdXNpbmdmb2xkZXIgPSB0cnVlXG4gICAgICAgIH1cbiAgICAgICAgbGV0IHBhcmVudCA9IGRpdi5wYXJlbnQoKVxuICAgICAgICBpZiAodXNpbmdmb2xkZXIpIHtcbiAgICAgICAgICBwYXJlbnQuc2hvdygpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcGFyZW50LmhpZGUoKVxuICAgICAgICB9XG4gICAgICB9KVxuICAgICAgXy5mb3JFYWNoKHBkaXZzLCBmdW5jdGlvbiAoaW5kKSB7IC8vIGNvbnRyb2wgZGV2aWNlIHBsYXRmb3JtXG4gICAgICAgIGxldCBkaXYgPSAkKGluZClcbiAgICAgICAgbGV0IGZvbGRlcm5hbWUgPSBkaXYudGV4dCgpXG4gICAgICAgIGxldCB1c2luZ2ZvbGRlciA9IGZhbHNlXG4gICAgICAgIGlmIChmb2xkZXJuYW1lLnN0YXJ0c1dpdGgoJ1BsYXRmb3JtICcgKyBkZXZpY2VWZXIpKSB7XG4gICAgICAgICAgdXNpbmdmb2xkZXIgPSB0cnVlXG4gICAgICAgIH0gZWxzZSBpZiAoZm9sZGVybmFtZS5zdGFydHNXaXRoKCdDb252ZXJ0IFBsYXRmb3JtIFRvJykpIHtcbiAgICAgICAgICBsZXQgY29udmVydERldmljZSA9ICdDJ1xuICAgICAgICAgIGlmIChkZXZpY2VWZXIgPT09ICdCJykge1xuICAgICAgICAgICAgY29udmVydERldmljZSA9ICdDJ1xuICAgICAgICAgIH0gZWxzZSBpZiAoZGV2aWNlVmVyID09PSAnQycpIHtcbiAgICAgICAgICAgIGNvbnZlcnREZXZpY2UgPSAnQidcbiAgICAgICAgICB9XG4gICAgICAgICAgJCgnI25hdi1Db252ZXJ0UGxhdGZvcm0nICsgY29udmVydERldmljZSkuc2hvdygpXG4gICAgICAgICAgJCgnI25hdi1Db252ZXJ0UGxhdGZvcm0nICsgZGV2aWNlVmVyKS5oaWRlKClcbiAgICAgICAgICB1c2luZ2ZvbGRlciA9IHRydWVcbiAgICAgICAgfVxuICAgICAgICBsZXQgcGFyZW50ID0gZGl2LnBhcmVudCgpXG4gICAgICAgIGlmICh1c2luZ2ZvbGRlcikge1xuICAgICAgICAgIHBhcmVudC5zaG93KClcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBwYXJlbnQuaGlkZSgpXG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgfVxuICAgIC8vIGluIHRoZSBmdXJ1cmUsIGl0IGNhbiBiZSBjb250cm9sZWQgYnkgcm9sZSAnQW5kYXB0J1xuICAgICQoJyNkZXNpZ25FeGFtcGxlcycpLnNob3coKVxuICAgIGlmICghd2luZG93LnByb2plY3QpIHtcbiAgICAgICQoJyNzYXZlTWVudScpLmFkZENsYXNzKCdkaXNhYmxlZCcpXG4gICAgICAkKCcjc2F2ZUFzTWVudScpLmFkZENsYXNzKCdkaXNhYmxlZCcpXG4gICAgICAkKCcjZXhwb3J0TWVudScpLmFkZENsYXNzKCdkaXNhYmxlZCcpXG4gICAgICAkKCcjY2xvc2VNZW51JykuYWRkQ2xhc3MoJ2Rpc2FibGVkJylcbiAgICB9IGVsc2UgaWYgKHdpbmRvdy5ndWVzdFByb2plY3QpIHtcbiAgICAgICQoJyNvcGVuTWVudScpLmFkZENsYXNzKCdkaXNhYmxlZCcpXG4gICAgICAkKCcjZXhhbXBsZXNNZW51JykuYWRkQ2xhc3MoJ2Rpc2FibGVkJylcbiAgICAgICQoJyNjcmVhdGVQcm9qZWN0TWVudScpLmFkZENsYXNzKCdkaXNhYmxlZCcpXG4gICAgICAkKCcjbWFuYWdlUHJvamVjdE1lbnUnKS5hZGRDbGFzcygnZGlzYWJsZWQnKVxuICAgICAgJCgnI3NhdmVNZW51JykuYWRkQ2xhc3MoJ2Rpc2FibGVkJylcbiAgICAgICQoJyNzYXZlQXNNZW51JykuYWRkQ2xhc3MoJ2Rpc2FibGVkJylcbiAgICAgICQoJyNpbXBvcnRNZW51JykuYWRkQ2xhc3MoJ2Rpc2FibGVkJylcbiAgICAgICQoJyNleHBvcnRNZW51JykucmVtb3ZlQ2xhc3MoJ2Rpc2FibGVkJylcbiAgICAgICQoJyNjbG9zZU1lbnUnKS5hZGRDbGFzcygnZGlzYWJsZWQnKVxuICAgICAgJCgnI21hbmFnZUFjY291bnRNZW51JykuYWRkQ2xhc3MoJ2Rpc2FibGVkJylcbiAgICAgICQoJyN1c2VySWRNZW51JykuYWRkQ2xhc3MoJ2Rpc2FibGVkJylcbiAgICAgICQoJyNjaGFuZ2VQd2RNZW51JykuYWRkQ2xhc3MoJ2Rpc2FibGVkJylcbiAgICAgICQoJyNhZG1pbk1lbnUnKS5hZGRDbGFzcygnZGlzYWJsZWQnKVxuICAgICAgJCgnI3NpZ25PdXRNZW51JykuYWRkQ2xhc3MoJ2Rpc2FibGVkJylcbiAgICB9IGVsc2Uge1xuICAgICAgJCgnI3NhdmVNZW51JykucmVtb3ZlQ2xhc3MoJ2Rpc2FibGVkJylcbiAgICAgICQoJyNzYXZlQXNNZW51JykucmVtb3ZlQ2xhc3MoJ2Rpc2FibGVkJylcbiAgICAgICQoJyNleHBvcnRNZW51JykucmVtb3ZlQ2xhc3MoJ2Rpc2FibGVkJylcbiAgICAgICQoJyNjbG9zZU1lbnUnKS5yZW1vdmVDbGFzcygnZGlzYWJsZWQnKVxuICAgIH1cblxuICAgIGlmIChwcm9qZWN0KSB7XG4gICAgICAkKCcjcHJvamVjdF9uYW1lJykudGV4dChwcm9qZWN0Lm5hbWUpXG4gICAgfSBlbHNlIHtcbiAgICAgICQoJyNwcm9qZWN0X25hbWUnKS50ZXh0KCdQcm9qZWN0cycpXG4gICAgfVxuICAgIGlmIChkZWxldGVQcm9qZWN0cy5sZW5ndGgpIHtcbiAgICAgIC8vIGZvciBtb2R1bGFyOiByZW1vdmUgdGhlc2UgcHJvamVjdHMgZnJvbSBkYXRhYmFzZSBhbmQgcHJvamVjdHNcbiAgICAgIC8vIHNob3dNb2RhbERpYWxvZygnV2FybmluZycsICdEZWxldGUgc29tZSB0ZW1wb3JhcnkgcHJvamVjdHMoJyArIGRlbGV0ZVByb2plY3ROYW1lcyArICcpJylcbiAgICAgIHRoaXMuZGVsZXRlUHJvamVjdHMoZGVsZXRlUHJvamVjdHMpXG4gICAgfVxuICB9LFxuXG4gIGFzeW5jIHNhdmVVc2VyQ29uZmlnIChjb25maWcpIHtcbiAgICBpZiAoIWNvbmZpZykge1xuICAgICAgY29uZmlnID0gdXNlclxuICAgIH1cbiAgICBhd2FpdCBzZW5kQ29tbWFuZCgnL3Byb2plY3QnLCB7IG1ldGhvZDogJ3NhdmVVc2VyQ29uZmlnJywgY29uZmlnOiBjb25maWcgfSlcbiAgfSxcblxuICBnZXRNb2RpZmllZFByb2plY3ROYW1lIChuYW1lLCBleGNsdWRlLCBwcm9qZWN0cywgdXNlcklEKSB7XG4gICAgbGV0IGluZGV4ID0gMVxuICAgIGxldCBuZXdOYW1lID0gbmFtZVxuICAgIHdoaWxlICghdGhpcy5jaGVja1Byb2plY3ROYW1lKG5ld05hbWUsIGV4Y2x1ZGUsIHByb2plY3RzLCB1c2VySUQpKSB7XG4gICAgICBuZXdOYW1lID0gbmFtZSArICdfJyArIGluZGV4XG4gICAgICBpbmRleCsrXG4gICAgfVxuICAgIHJldHVybiBuZXdOYW1lXG4gIH0sXG5cbiAgYXN5bmMgZ2V0RmlsZSAoZmlsZSwgZG93bmxvYWQpIHtcbiAgICBsZXQgZGF0YVxuICAgIGxldCB2aWV3aWQgPSBmaWxlXG4gICAgdmlld2lkID0gdmlld2lkLnJlcGxhY2UoJyQnLCAnJylcbiAgICB2aWV3aWQgPSAndmlld18nICsgdmlld2lkXG4gICAgaWYgKGZpbGUgPT09ICckYm9tJykge1xuICAgICAgZGF0YSA9IHsgbmFtZTogJ2dsb2JhbGJvbS5jc3YnLCBkYXRhOiBCb01BUEkuZ2V0R2xvYmFsQm9NQ1NWKHByb2plY3QuY2hpcCkgfVxuICAgIH0gZWxzZSBpZiAoZmlsZSA9PT0gJ3Byb2plY3QnKSB7XG4gICAgICBkYXRhID0gcHJvamVjdC5jaGlwLnRvQ29uZmlnU3RyaW5nKClcbiAgICB9IGVsc2Uge1xuICAgICAgZGF0YSA9IGF3YWl0IHNlbmRDb21tYW5kKCcvcHJvamVjdCcsIHtcbiAgICAgICAgbWV0aG9kOiAnZ2V0RmlsZScsXG4gICAgICAgIHByb2plY3RJZDogcHJvamVjdC5wcm9qZWN0SUQsXG4gICAgICAgIGNoaXBOYW1lOiBwcm9qZWN0LmNoaXAubmFtZSxcbiAgICAgICAgcHJvamVjdE5hbWU6IHByb2plY3QubmFtZSxcbiAgICAgICAgZmlsZSxcbiAgICAgIH0pXG4gICAgICBpZiAoIWRhdGEuc3VjY2VzcykgcmV0dXJuXG4gICAgfVxuICAgIGlmIChkb3dubG9hZCkge1xuICAgICAgaWYgKGZpbGUgPT09ICdwcm9qZWN0Jykge1xuICAgICAgICBxZy5Eb21VdGlscy5kb3dubG9hZEZpbGUocHJvamVjdC5uYW1lICsgJy5pbmknLCAnZGF0YTphdHRhY2htZW50L3RleHQsJyArIGVuY29kZVVSSUNvbXBvbmVudChkYXRhKSlcbiAgICAgIH0gZWxzZSBpZiAoZmlsZSA9PT0gJyRiaXQnKSB7XG4gICAgICAgIGxldCBkYXRhVG9EbCA9IEJ1ZmZlci5mcm9tKGRhdGEuZGF0YSwgJ2Jhc2U2NCcpXG4gICAgICAgIC8vIHFnLkRvbVV0aWxzLmRvd25sb2FkRmlsZShkYXRhLm5hbWUsICdkYXRhOmFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbSwnICsgZGF0YVRvRGwpXG4gICAgICAgIGxldCBibG9iID0gbmV3IEJsb2IgKFtkYXRhVG9EbF0sIHsgdHlwZTogJ2FwcGxpY2F0aW9uL29jdGV0LXN0cmVhbScgfSlcbiAgICAgICAgbGV0IHVybCA9ICBVUkwuY3JlYXRlT2JqZWN0VVJMKGJsb2IpXG4gICAgICAgIGxldCBhID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYScpXG4gICAgICAgIGEuaHJlZiA9IHVybFxuICAgICAgICBhLmRvd25sb2FkID0gZGF0YS5uYW1lXG4gICAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoYSlcbiAgICAgICAgYS5jbGljaygpXG4gICAgICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQoYSlcbiAgICAgICAgVVJMLnJldm9rZU9iamVjdFVSTCh1cmwpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBxZy5Eb21VdGlscy5kb3dubG9hZEZpbGUoZGF0YS5uYW1lLCAnZGF0YTphdHRhY2htZW50L3RleHQsJyArIGVuY29kZVVSSUNvbXBvbmVudChkYXRhLmRhdGEpKVxuICAgICAgfVxuXG4gICAgICBpZiAoZmlsZSA9PT0gJyRjaGVja3N1bScpIHtcbiAgICAgICAgLy8gYWZ0ZXIgZG93bmxvYWRlZCwgZGlzcGxheSBjaGVja3N1bSBvZiBoZXggZmlsZVxuICAgICAgICBsZXQgZGlzcGxheXN0ciA9IGRhdGEuZGF0YS5zdWJzdHIoMCwgZGF0YS5kYXRhLmluZGV4T2YoJ1NUQVJUJykpXG4gICAgICAgICQoJyNjaGVja3N1bScpLnRleHQoJyAnICsgZGlzcGxheXN0cilcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIGZpbGVEaWFsb2cgPSAkKCcjZmlsZS1kaWFsb2cnKVxuICAgICAgaWYgKGZpbGVEaWFsb2cubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIGZpbGVEaWFsb2cgPSAkKGNyZWF0ZU1vZGFsRGlhbG9nKCdsb2ctZGlhbG9nJywgJ21vZGFsLWxnJykpXG4gICAgICAgIGZpbGVEaWFsb2cuZmluZCgnLm1vZGFsLWJvZHknKS5odG1sKCc8dGV4dGFyZWEgc3R5bGU9XCJ3aWR0aDoxMDAlO2hlaWdodDozMDBweDtvdmVyZmxvdy14OmhpZGRlbjtvdmVyZmxvdy15OmF1dG9cIiBpZD1cIicgKyB2aWV3aWQgKyAnXCIgPjwvdGV4dGFyZWE+JylcbiAgICAgICAgJCgnYm9keScpLmFwcGVuZChmaWxlRGlhbG9nKVxuICAgICAgfVxuICAgICAgZmlsZURpYWxvZy5tb2RhbCh7XG4gICAgICAgIHNob3c6IGZhbHNlLFxuICAgICAgICBrZXlib2FyZDogZmFsc2UsXG4gICAgICAgIGJhY2tkcm9wOiAnc3RhdGljJyxcbiAgICAgIH0pXG4gICAgICBpZiAoZmlsZSA9PT0gJ3Byb2plY3QnKSB7XG4gICAgICAgIGZpbGVEaWFsb2cuZmluZCgnLm1vZGFsLWhlYWRlciBoNCcpLnRleHQoJ1Byb2plY3QgQ29uZmlnJylcbiAgICAgICAgZmlsZURpYWxvZy5maW5kKCcubW9kYWwtYm9keSB0ZXh0YXJlYScpLnRleHQoZGF0YSlcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGZpbGVEaWFsb2cuZmluZCgnLm1vZGFsLWhlYWRlciBoNCcpLnRleHQoZGF0YS5uYW1lKVxuICAgICAgICBmaWxlRGlhbG9nLmZpbmQoJy5tb2RhbC1ib2R5IHRleHRhcmVhJykudGV4dChkYXRhLmRhdGEpXG4gICAgICB9XG4gICAgICBmaWxlRGlhbG9nLm1vZGFsKCdzaG93JylcbiAgICB9XG4gIH0sXG5cbiAgdXBsb2FkRmlsZSAoZmlsZU5hbWUpIHtcbiAgICBsZXQgZm9ybSA9IG5ldyBxZy5TdHJpbmdCdWZmZXIoKVxuICAgIGZvcm0uYXBwZW5kKCc8Zm9ybT48aW5wdXQgdHlwZT1cImZpbGVcIi8+PC9mb3JtPicpXG4gICAgZm9ybSA9ICQocWcuRG9tVXRpbHMuY3JlYXRlRWxlbWVudEJ5U3RyaW5nKGZvcm0udG9TdHJpbmcoKSkpXG4gICAgbGV0IGlucHV0ID0gZm9ybS5maW5kKCdpbnB1dFt0eXBlPVwiZmlsZVwiXScpXG4gICAgaW5wdXQuY2hhbmdlKGZ1bmN0aW9uICgpIHtcbiAgICAgIGxldCBmaWxlID0gdGhpcy5maWxlc1swXVxuICAgICAgY29uc3QgcmVhZGVyID0gbmV3IEZpbGVSZWFkZXIoKVxuICAgICAgcmVhZGVyLm9ubG9hZCA9IGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgZGF0YSA9IGF3YWl0IHNlbmRDb21tYW5kKCcvcHJvamVjdCcsIHtcbiAgICAgICAgICBtZXRob2Q6ICd1cGxvYWQnLFxuICAgICAgICAgIGZpbGVOYW1lOiBmaWxlTmFtZSxcbiAgICAgICAgICBmaWxlOiAnJyArIHJlYWRlci5yZXN1bHQsXG4gICAgICAgICAgcHJvamVjdElkOiBwcm9qZWN0LnByb2plY3RJRCxcbiAgICAgICAgICBjaGlwTmFtZTogcHJvamVjdC5jaGlwLm5hbWUsXG4gICAgICAgICAgcHJvamVjdE5hbWU6IHByb2plY3QubmFtZSxcbiAgICAgICAgfSlcbiAgICAgICAgaWYgKGRhdGEuc3VjY2Vzcykge1xuICAgICAgICAgIC8vIHNob3dNb2RhbERpYWxvZygnRmlsZSBVcGxvYWRlZCcpXG4gICAgICAgICAgJCgnIycgKyBmaWxlTmFtZS5zbGljZSgxKSArICdVcGxvYWRlZCcpLnNob3coKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHNob3dNb2RhbERpYWxvZygnRmlsZSBVcGxvYWQgRmFpbGVkISEnKVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZWFkZXIucmVhZEFzVGV4dChmaWxlKVxuICAgIH0pXG4gICAgaW5wdXQuY2xpY2soKVxuICB9LFxuXG4gIGNvbmZpcm1DcmVhdGUgKGdyaWQpIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgIGxldCBzZWxlY3Rpb25zID0gZ3JpZC5nZXRTZWxlY3Rpb24oKVxuICAgICAgbGV0IG1zZyA9ICdBcmUgeW91IHN1cmUgeW91IHdhbnQgdG8gY3JlYXRlICcgKyBzZWxlY3Rpb25zLmxlbmd0aCArICcgbmV3IHByb2plY3RzPydcbiAgICAgIHNob3dDb25maXJtKG1zZywgbnVsbCxcbiAgICAgICAgeyBuYW1lOiAnRHVwbGljYXRlJywgY2xhc3NOYW1lOiAnYnRuLWRhbmdlcicgfSxcbiAgICAgICAgYXN5bmMgY29uZmlybSA9PiB7XG4gICAgICAgICAgaWYgKGNvbmZpcm0pIHtcbiAgICAgICAgICAgIGxldCBjb3BpZWRQcm9qZWN0cyA9IFtdXG4gICAgICAgICAgICBsZXQgbmFtZXMgPSBfLm1hcChncmlkLnJlY29yZHMsIGZ1bmN0aW9uIChyKSB7XG4gICAgICAgICAgICAgIHJldHVybiB7IG5hbWU6IHIuY2hhbmdlcyAmJiByLmNoYW5nZXMubmFtZSA/IHIuY2hhbmdlcy5uYW1lIDogci5uYW1lLCB1c2VySUQ6IHIudXNlcklEIH1cbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICBzZWxlY3Rpb25zLmZvckVhY2gocmVjaWQgPT4ge1xuICAgICAgICAgICAgICBsZXQgcmVjb3JkXG4gICAgICAgICAgICAgIGxldCBuZXdOYW1lXG4gICAgICAgICAgICAgIHJlY29yZCA9IF8uZmluZChncmlkLnJlY29yZHMsIHsgcmVjaWQgfSlcbiAgICAgICAgICAgICAgbmV3TmFtZSA9IHRoaXMuZ2V0TW9kaWZpZWRQcm9qZWN0TmFtZShyZWNvcmQubmFtZSwgbnVsbCwgbmFtZXMpXG4gICAgICAgICAgICAgIGNvcGllZFByb2plY3RzLnB1c2goeyBwcm9qZWN0SUQ6ICdOJyArIHJlY29yZC5yZWNpZCwgbmFtZTogbmV3TmFtZSwgY29uZmlnOiByZWNvcmQuY29uZmlnID8gXy5jbG9uZURlZXAocmVjb3JkLmNvbmZpZykgOiBudWxsLCB1c2VySUQ6IHJlY29yZC51c2VySUQgfSlcbiAgICAgICAgICAgICAgbmFtZXMucHVzaCh7IG5hbWU6IG5ld05hbWUsIHVzZXJJRDogcmVjb3JkLnVzZXJJRCB9KVxuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuY3JlYXRlUHJvamVjdHMoY29waWVkUHJvamVjdHMpXG4gICAgICAgICAgICByZXNvbHZlKHRydWUpXG4gICAgICAgICAgfVxuICAgICAgICAgIHJlc29sdmUoZmFsc2UpXG4gICAgICAgIH0pXG4gICAgfSlcbiAgfSxcblxuICBjcmVhdGVOZXcgKCkge1xuICAgICQoJyNuYXYtQ29udmVydFBsYXRmb3JtQycpLmhpZGUoKVxuICAgICQoJyNuYXYtQ29udmVydFBsYXRmb3JtQicpLmhpZGUoKVxuICAgIGNvbnN0IGRpYWxvZyA9ICQodGVtcGxhdGVOZXdQcm9qZWN0KCkpXG4gICAgJCgnYm9keScpLmFwcGVuZChkaWFsb2cpXG4gICAgc2V0RGlhbG9nQnV0dG9uQWN0aW9uKGRpYWxvZywgJ0NyZWF0ZScsIGFzeW5jIChldmVudCkgPT4ge1xuICAgICAgbGV0IGlucHV0ID0gZGlhbG9nLmZpbmQoJ2lucHV0JylcbiAgICAgIGxldCBuVmFsaWQgPSBmYWxzZVxuICAgICAgbGV0IG5hbWUgPSAkKGlucHV0KS52YWwoKVxuICAgICAgbGV0IHZhbGlkTmFtZUV4cCA9IC9eW0EtWl9dWzAtOUEtWl9dKiQvaVxuICAgICAgblZhbGlkID0gdmFsaWROYW1lRXhwLnRlc3QobmFtZSlcbiAgICAgIGlmICghblZhbGlkKSB7XG4gICAgICAgIGlmICgkKGlucHV0KS52YWwoKS5tYXRjaCgvXlxcZC8pKSB7XG4gICAgICAgICAgZGlhbG9nLmZpbmQoJy5tb2RhbC1oZWFkZXIgc21hbGwgc3BhbicpLnRleHQoJ1Byb2plY3QgbmFtZSBjYW4gbm90IHN0YXJ0IHdpdGggbnVtYmVyJylcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBkaWFsb2cuZmluZCgnLm1vZGFsLWhlYWRlciBzbWFsbCBzcGFuJykudGV4dCgnUHJvamVjdCBuYW1lIE9OTFkgaW5jbHVkZXMgQS4uWiwgYS4ueiwgMC4uOSwgXycpXG4gICAgICAgIH1cbiAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcbiAgICAgIH0gZWxzZSBpZiAoIXRoaXMuY2hlY2tQcm9qZWN0TmFtZShpbnB1dFswXSkpIHtcbiAgICAgICAgZGlhbG9nLmZpbmQoJy5tb2RhbC1oZWFkZXIgc21hbGwgc3BhbicpLnRleHQoJ1Byb2plY3QgbmFtZSBoYXMgYmVlbiB0YWtlbicpXG4gICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCB7IHN1Y2Nlc3MsIGRhdGEgfSA9IGF3YWl0IHNlbmRDb21tYW5kKCcvcHJvamVjdCcsIHsgbWV0aG9kOiAnbmV3JywgbmFtZTogaW5wdXQudmFsKCkgfSlcbiAgICAgICAgaWYgKCFzdWNjZXNzKSByZXR1cm5cbiAgICAgICAgaWYgKCFkYXRhKSByZXR1cm5cbiAgICAgICAgcHJvamVjdHMucHVzaChkYXRhKVxuICAgICAgICB0aGlzLmxvYWRQcm9qZWN0KGRhdGEucHJvamVjdElELCB0cnVlKVxuICAgICAgfVxuICAgIH0sIHRydWUpXG4gIH0sXG5cbiAgYXN5bmMgY3JlYXRlUHJvamVjdHMgIChwcm9qcykge1xuICAgIC8vIElmIHRoZXJlIGFyZSB0b28gbWFueSBwcm9qZWN0cywgd2UgbmVlZCB0byBicmVhayBpdCB1cCBzbyBhcyB0byBhdm9pZCBwYXlsb2FkIHRvbyBsYXJnZSBlcnJvci5cbiAgICBjb25zdCBtYXggPSAxMFxuICAgIGlmIChwcm9qcy5sZW5ndGggPiBtYXgpIHtcbiAgICAgIGNvbnN0IGJhdGNoID0gcHJvanMuc3BsaWNlKDAsIG1heClcbiAgICAgIGF3YWl0IHRoaXMuY3JlYXRlUHJvamVjdHMoYmF0Y2gpXG4gICAgICByZXR1cm4gdGhpcy5jcmVhdGVQcm9qZWN0cyhwcm9qcylcbiAgICB9XG5cbiAgICBpZiAocHJvanMubGVuZ3RoID4gMCkge1xuICAgICAgbGV0IHsgc3VjY2VzcywgZGF0YSB9ID0gYXdhaXQgc2VuZENvbW1hbmQoJy9wcm9qZWN0JywgeyBtZXRob2Q6ICdjcmVhdGVQcm9qZWN0cycsIHByb2plY3RzOiBwcm9qcyB9KVxuICAgICAgaWYgKCFzdWNjZXNzKSByZXR1cm5cbiAgICAgIHByb2pzLmZvckVhY2goKHAsIGkpID0+IHtcbiAgICAgICAgcC5wcm9qZWN0SUQgPSBkYXRhLmlkICsgaVxuICAgICAgICBwLm1vZGlmaWNhdGlvbl90aW1lID0gZGF0YS5tb2RpZmljYXRpb25fdGltZVxuICAgICAgICBwLmNyZWF0aW9uX3RpbWUgPSBkYXRhLmNyZWF0aW9uX3RpbWVcbiAgICAgICAgaWYgKCFwLnVzZXJJRCkge1xuICAgICAgICAgIHByb2plY3RzLnB1c2gocClcbiAgICAgICAgfVxuICAgICAgfSlcbiAgICB9XG4gIH0sXG5cbiAgZGlmZkZpbGVzIChmMSwgZjIpIHtcbiAgICBmdW5jdGlvbiBsb29rRm9yU2FtZUxpbmUgKGxpbmUsIGZpbGUsIGluZGV4LCBjb3VudCkge1xuICAgICAgY29uc3QgbWF4RGlmZiA9IDEwXG4gICAgICBmb3IgKGxldCBpID0gaW5kZXg7IGkgPCBjb3VudDsgaSsrKSB7XG4gICAgICAgIGlmICgoaSAtIGluZGV4KSA+IG1heERpZmYpIHtcbiAgICAgICAgICByZXR1cm4gKGNvdW50KVxuICAgICAgICB9O1xuICAgICAgICBpZiAoZmlsZVtpXS50cmltKCkgPT09IGxpbmUudHJpbSgpKSB7XG4gICAgICAgICAgcmV0dXJuIChpKVxuICAgICAgICB9O1xuICAgICAgfTtcbiAgICAgIHJldHVybiAoY291bnQpXG4gICAgfTtcblxuICAgIGxldCBpbmRleDEgPSAwXG4gICAgbGV0IGluZGV4MiA9IDBcbiAgICBsZXQgcmVzdWx0ID0gW11cbiAgICBsZXQgZGlmZiA9IGZhbHNlXG4gICAgbGV0IGNvdW50MSA9IGYxLmxlbmd0aFxuICAgIGxldCBjb3VudDIgPSBmMi5sZW5ndGhcbiAgICB3aGlsZSAoaW5kZXgxIDwgY291bnQxICYmIGluZGV4MiA8IGNvdW50Mikge1xuICAgICAgbGV0IGxpbmUxID0gZjFbaW5kZXgxXS50cmltKClcbiAgICAgIGxldCBsaW5lMiA9IGYyW2luZGV4Ml0udHJpbSgpXG4gICAgICBpZiAobGluZTEgPT09IGxpbmUyKSB7XG4gICAgICAgIHJlc3VsdC5wdXNoKGxpbmUxKVxuICAgICAgICBpbmRleDErK1xuICAgICAgICBpbmRleDIrK1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZGlmZiA9IHRydWVcbiAgICAgICAgbGV0IG5leHQxID0gbG9va0ZvclNhbWVMaW5lKGxpbmUyLCBmMSwgaW5kZXgxLCBjb3VudDEpXG4gICAgICAgIGxldCBuZXh0MiA9IGxvb2tGb3JTYW1lTGluZShsaW5lMSwgZjIsIGluZGV4MiwgY291bnQyKVxuICAgICAgICBpZiAobmV4dDEgPT09IGNvdW50MSAmJiBuZXh0MiA9PT0gY291bnQyKSB7XG4gICAgICAgICAgbmV4dDEgPSBpbmRleDEgKyAxXG4gICAgICAgICAgbmV4dDIgPSBpbmRleDIgKyAxXG4gICAgICAgIH0gZWxzZSBpZiAobmV4dDIgPT09IGNvdW50Mikge1xuICAgICAgICAgIG5leHQyID0gaW5kZXgyXG4gICAgICAgIH0gZWxzZSBpZiAobmV4dDEgPT09IGNvdW50MSkge1xuICAgICAgICAgIG5leHQxID0gaW5kZXgxXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaWYgKChuZXh0MSAtIGluZGV4MSkgPCAobmV4dDIgLSBpbmRleDIpKSB7XG4gICAgICAgICAgICBuZXh0MiA9IGluZGV4MlxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBuZXh0MSA9IGluZGV4MVxuICAgICAgICAgIH07XG4gICAgICAgIH07XG5cbiAgICAgICAgZm9yIChsZXQgaSA9IGluZGV4MTsgaSA8IG5leHQxOyBpKyspIHtcbiAgICAgICAgICByZXN1bHQucHVzaCgnKysrICcgKyBmMVtpXSlcbiAgICAgICAgfTtcbiAgICAgICAgZm9yIChsZXQgaSA9IGluZGV4MjsgaSA8IG5leHQyOyBpKyspIHtcbiAgICAgICAgICByZXN1bHQucHVzaCgnLS0tICcgKyBmMltpXSlcbiAgICAgICAgfTtcbiAgICAgICAgaW5kZXgxID0gbmV4dDFcbiAgICAgICAgaW5kZXgyID0gbmV4dDJcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIFtkaWZmLCByZXN1bHRdXG4gIH0sXG5cbiAgLy8gdGhpcyBmdW5jdGlvbiBvbmx5IGZvciBjeXByZXNzIHRlc3RpbmdcbiAgYXN5bmMgZGVsZXRlQWxsUHJvamVjdHMgKCkge1xuICAgIGxldCBzZWxlY3Rpb25zID0gcHJvamVjdHMubWFwKHAgPT4geyByZXR1cm4gcC5wcm9qZWN0SUQgfSlcbiAgICBpZiAoIXNlbGVjdGlvbnMpIHJldHVyblxuICAgIGNvbnN0IHsgc3VjY2VzcyB9ID0gYXdhaXQgc2VuZENvbW1hbmQoJy9wcm9qZWN0JywgeyBtZXRob2Q6ICdkZWxldGVQcm9qZWN0cycsIHByb2plY3RzOiBzZWxlY3Rpb25zIH0pXG4gICAgaWYgKCFzdWNjZXNzKSByZXR1cm5cbiAgICBpZiAocHJvamVjdHMpIHtcbiAgICAgIF8ucmVtb3ZlKHByb2plY3RzLCBwID0+IHtcbiAgICAgICAgcmV0dXJuIHNlbGVjdGlvbnMuaW5kZXhPZihwLnByb2plY3RJRCkgPj0gMFxuICAgICAgfSlcbiAgICB9XG4gIH0sXG5cbiAgYXN5bmMgY2hhbmdlVmVyc2lvbkZvclRlc3QgKHBsYXRmb3JtLCBjb21wVHlwZSwgY29tcFZlcnNpb24pIHtcbiAgICBsZXQgZGV2aWNlTmFtZSA9IHByb2plY3QuY29uZmlnLmNoaXBzWzBdLmRldmljZVxuICAgIGlmIChkZXZpY2VOYW1lKSB7XG4gICAgICAvLyBpbiBjYXNlLCBpdCBpcyBhIG9sZCB3ZWJhbXAgcHJvamVjdFxuICAgICAgZGV2aWNlTmFtZSA9IGRldmljZU5hbWUucmVwbGFjZSgnUycsICcnKVxuICAgICAgbGV0IHBhcnRzID0gZGV2aWNlTmFtZS5tYXRjaCgvXkFtUChcXGQrKUQoW0F8QnxDXT8pKFxcZCkoLiopJC8pXG4gICAgICBpZiAocGxhdGZvcm0gPT09ICdBJykgcGxhdGZvcm0gPSAnJy8vICdBJyBpcyBkZWZhdWx0XG4gICAgICBkZXZpY2VOYW1lID0gJ0FtUCcgKyBwYXJ0c1sxXSArICdEJyArIHBsYXRmb3JtICsgcGFydHNbM10gKyBwYXJ0c1s0XVxuICAgICAgcHJvamVjdC5jb25maWcuY2hpcHNbMF0uZGV2aWNlID0gZGV2aWNlTmFtZVxuICAgIH1cbiAgICBwcm9qZWN0LmNvbmZpZy5jaGlwc1swXS5jb21wb25lbnRzLmZvckVhY2goYyA9PiB7XG4gICAgICBjLnZlcnNpb24gPSBjb21wVmVyc2lvblxuICAgIH0pXG4gICAgbGV0IGNvbXAgPSBDb21wb25lbnRNYW5hZ2VyLm5ld0NvbXBvbmVudChjb21wVHlwZSwgcHJvamVjdC5jaGlwKVxuICAgIHRoaXMuY2xlYXJQcm9qZWN0KHRydWUpXG4gICAgcHJvamVjdCA9IG5ldyBQcm9qZWN0KHByb2plY3QpXG4gICAgcHJvamVjdC5zZWxlY3RlZCA9IGNvbXBcbiAgICB0aGlzLnZhbGlkYXRlQ29ubmVjdGlvbnMoKVxuICAgIHRoaXMucmVmcmVzaFByb2plY3RzTWVudSgpXG4gIH0sXG5cbiAgY2xlYW5MZWdhY3kgKGNoaXApIHtcbiAgICBpZiAoY2hpcC5hdXRvQ29ubmVjdGlvbnMpIHtcbiAgICAgIC8vIENsZWFuIGxlZ2FjeSB0cmlzdGF0ZSBpbiBhdXRvQ29ubmVjdGlvblxuICAgICAgLy8gbGV0IHRyaXN0YXRlcyA9IGNoaXAuaW9zWydUcmlTdGF0ZSddXG4gICAgICAvLyBsZXQgcmVtb3ZlQXV0b0Nvbm5UcmlTID0gW11cbiAgICAgIC8vIGZvciAoY29uc3QgZWwgb2YgY2hpcC5hdXRvQ29ubmVjdGlvbnMpIHtcbiAgICAgIC8vICAgaWYgKGVsLnBvcnROYW1lLmluY2x1ZGVzKCd0cmlTdGF0ZScpKSB7XG4gICAgICAvLyAgICAgbGV0IHBvcnROYW1lQXJyID0gZWwucG9ydE5hbWUuc3BsaXQoJ18nKVxuICAgICAgLy8gICAgIGlmICghdHJpc3RhdGVzLmluY2x1ZGVzKHBhcnNlSW50KHBvcnROYW1lQXJyW3BvcnROYW1lQXJyLmxlbmd0aCAtIDFdKSkpIHJlbW92ZUF1dG9Db25uVHJpUy5wdXNoKGVsLnBvcnROYW1lKVxuICAgICAgLy8gICB9XG4gICAgICAvLyB9XG4gICAgICAvLyBjaGlwLmF1dG9Db25uZWN0aW9ucyA9IGNoaXAuYXV0b0Nvbm5lY3Rpb25zLmZpbHRlcihlbCA9PiAhcmVtb3ZlQXV0b0Nvbm5UcmlTLmluY2x1ZGVzKGVsLnBvcnROYW1lKSlcblxuICAgICAgY29uc3Qgc2ltcGxlQ2hpcEpTT04gPSAoY2hpcCkgPT4ge1xuICAgICAgICAvLyBzdHJpbmdpZnkgYW4gb2JqZWN0LCBhdm9pZGluZyBjaXJjdWxhciBzdHJ1Y3R1cmVzIChfY2hpcClcbiAgICAgICAgdmFyIHNpbXBsZU9iamVjdCA9IHt9XG4gICAgICAgIGZvciAobGV0IHByb3AgaW4gY2hpcCkge1xuICAgICAgICAgIGlmICghY2hpcC5oYXNPd25Qcm9wZXJ0eShwcm9wKSkgY29udGludWVcbiAgICAgICAgICBpZiAodHlwZW9mIGNoaXBbcHJvcF0gPT09ICdvYmplY3QnKSBjb250aW51ZVxuICAgICAgICAgIGlmICh0eXBlb2YgY2hpcFtwcm9wXSA9PT0gJ2Z1bmN0aW9uJykgY29udGludWVcbiAgICAgICAgICBzaW1wbGVPYmplY3RbcHJvcF0gPSBjaGlwW3Byb3BdXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHNpbXBsZU9iamVjdClcbiAgICAgIH1cblxuICAgICAgLy8gQ2xlYW4gbGVnYWN5IHRyaXN0YXRlIGluIGF1dG9Db25uZWN0aW9uIGJ5IHBhcnNpbmcgYWxsIGRhdGFcbiAgICAgIGxldCBjaGlwQXNTdHJpbmcgPSBzaW1wbGVDaGlwSlNPTihjaGlwKVxuICAgICAgbGV0IHRyaVN0YXRlc1RvRGVsZXRlID0gW11cbiAgICAgIGZvciAoY29uc3QgZWwgb2YgY2hpcC5hdXRvQ29ubmVjdGlvbnMpIHtcbiAgICAgICAgLy8gSWYgYXJyYXkgbGVuZ3RoIGFmdGVyIHNwbGl0IGlzIDw9IDIsIGl0IGlzIE5PVCBiZWluZyB1c2VkLlxuICAgICAgICBpZiAoZWwucG9ydE5hbWUuaW5jbHVkZXMoJ3RyaVN0YXRlJykgJiYgY2hpcEFzU3RyaW5nLnNwbGl0KGVsLnBvcnROYW1lKS5sZW5ndGggPD0gMikgdHJpU3RhdGVzVG9EZWxldGUucHVzaChlbC5wb3J0TmFtZSlcbiAgICAgIH1cbiAgICAgIGNoaXAuYXV0b0Nvbm5lY3Rpb25zID0gY2hpcC5hdXRvQ29ubmVjdGlvbnMuZmlsdGVyKGVsID0+ICF0cmlTdGF0ZXNUb0RlbGV0ZS5pbmNsdWRlcyhlbC5wb3J0TmFtZSkpXG5cbiAgICAgIC8vIENsZWFuIGZpeGVkIHdpcmVzIGluIGF1dG9Db25uZWN0aW9uc1xuICAgICAgbGV0IGxpc3RPZkZpeGVkQ29ubiA9IFtdXG4gICAgICBmb3IgKGNvbnN0IGVsIGluIGNoaXAuY29ubmVjdGlvbnMpIHtcbiAgICAgICAgbGlzdE9mRml4ZWRDb25uLnB1c2goY2hpcC5jb25uZWN0aW9uc1tlbF0pXG4gICAgICB9XG4gICAgICBjaGlwLmF1dG9Db25uZWN0aW9ucyA9IGNoaXAuYXV0b0Nvbm5lY3Rpb25zLmZpbHRlcihlbCA9PiAhbGlzdE9mRml4ZWRDb25uLmluY2x1ZGVzKGVsLnBvcnROYW1lKSlcbiAgICB9XG4gIH0sXG5cbiAgLy8gVE9ETzogc2hvdWxkIGJlIGFibGUgdG8gbG9hZCBpbiBtZW1vcnkgcHJvamVjdCwgaW5zdGVhZCBvZiBnb2luZyB0byBzZXJ2ZXIgZXZlcnkgdGltZS5cbiAgbG9hZFByb2plY3QgKGlkLCB2YWxpZGF0ZVBhcmFtcykge1xuICAgIGRlYnVnKCdsb2FkUHJvamVjdCAtIGlkOiAlcycsIGlkKVxuICAgIGxldCBpZE51bSA9IGlkXG4gICAgaWYgKF8uaXNTdHJpbmcoaWQpKSB7XG4gICAgICBpZE51bSA9IHBhcnNlSW50KGlkKVxuICAgIH1cbiAgICBsZXQganVtcCA9IHByb2Nlc3MuZW52LkpVTVBfRU5BQkxFXG4gICAgdGhpcy5jb25maXJtU2F2ZShhc3luYyAoKSA9PiB7XG4gICAgICAvLyBjaGVjayBpZiBjb21wb25lbnQgaXMgcmV2aXNpb24gQSBvciBCXG4gICAgICBjb25zdCB7IHN1Y2Nlc3MsIGRhdGEgfSA9IGF3YWl0IHNlbmRDb21tYW5kKCcvcHJvamVjdCcsIHsgbWV0aG9kOiAnbG9hZCcsIGlkIH0pXG4gICAgICBpZiAoIXN1Y2Nlc3MpIHJldHVyblxuICAgICAgaWYgKCFkYXRhKSByZXR1cm5cbiAgICAgIGlmIChqdW1wID09PSAneWVzJykge1xuICAgICAgICBpZiAoT2JqZWN0LmtleXMoKGRhdGEuY29uZmlnKSkubGVuZ3RoID4gMCkge1xuICAgICAgICAgIC8vIGNoZWNrIGlmIGNvbXBvbmVudCBpcyByZXZpc2lvbiBBIG9yIEJcbiAgICAgICAgICBsZXQgZGV2aWNlTmFtZSA9IGRhdGEuY29uZmlnLmNoaXBzWzBdLmRldmljZVxuICAgICAgICAgIGlmIChkZXZpY2VOYW1lKSB7XG4gICAgICAgICAgICAvLyBpbiBjYXNlLCBpdCBpcyBhIG9sZCB3ZWJhbXAgcHJvamVjdFxuICAgICAgICAgICAgZGV2aWNlTmFtZSA9IGRldmljZU5hbWUucmVwbGFjZSgnUycsICcnKVxuICAgICAgICAgICAgbGV0IHJldmlzaW9uID0gJ0EnXG4gICAgICAgICAgICBsZXQgcGFydHMgPSBkZXZpY2VOYW1lLm1hdGNoKC9eQW1QKFxcZCspRChbQXxCfENdPykoXFxkKSguKikkLylcbiAgICAgICAgICAgIGlmIChwYXJ0c1syXS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgIHJldmlzaW9uID0gcGFydHNbMl1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChyZXZpc2lvbiA9PT0gJ0EnKSB7XG4gICAgICAgICAgICAgIC8vIHJlZGlyZWN0IHRvIEEgcGxhdGZvcm1cbiAgICAgICAgICAgICAgd2luZG93LmxvY2F0aW9uLnJlcGxhY2UocHJvY2Vzcy5lbnYuUkVWSVNJT05fQV9VUkwgKyBgL3Byb2plY3RzLyR7aWR9YClcbiAgICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICB0aGlzLmNsZWFyUHJvamVjdCh0cnVlKVxuICAgICAgXy5yZW1vdmUocHJvamVjdHMsIHAgPT4gcC5wcm9qZWN0SUQgPT09IGlkTnVtKVxuICAgICAgdXNlci5zdXBlck1vZGUgPSBmYWxzZVxuICAgICAgcHJvamVjdHMudW5zaGlmdChkYXRhKVxuICAgICAgcHJvamVjdCA9IG5ldyBQcm9qZWN0KGRhdGEpXG4gICAgICBjb25zdCBjaGlwID0gcHJvamVjdC5jaGlwXG4gICAgICBpZiAodmFsaWRhdGVQYXJhbXMpIHtcbiAgICAgICAgY2hpcC5jb21wb25lbnRzLmZvckVhY2goYyA9PiB7XG4gICAgICAgICAgYy52YWxpZGF0ZVBhcmFtcygpXG4gICAgICAgIH0pXG4gICAgICAgIGNoaXAuZGlnaXRhbHMuZm9yRWFjaChjID0+IHtcbiAgICAgICAgICBjLnZhbGlkYXRlUGFyYW1zKClcbiAgICAgICAgfSlcbiAgICAgIH1cbiAgICAgIGlmIChjaGlwLmN1cnJlbnRTdGFnZSA9PT0gJ3R1bmluZycpIHtcbiAgICAgICAgY2hpcC5jdXJyZW50U3RhZ2UgPSAnZGVzaWduJ1xuICAgICAgfVxuICAgICAgLy8gQ2xlYW4gbGVnYWN5IGF1dG9Db25uZWN0aW9uc1xuICAgICAgdGhpcy5jbGVhbkxlZ2FjeShjaGlwKVxuICAgICAgLy8gY2hpcC51cGRhdGVPbGRMRE9Db21wb25lbnQoKVxuICAgICAgbGV0IHNjcmVlbiA9IFNjcmVlbk1hbmFnZXIuZ2V0U2NyZWVuKCdkZXNpZ24nKVxuICAgICAgaWYgKHNjcmVlbiAmJiBzY3JlZW4uaW5pdGlhbGl6ZWQpIHtcbiAgICAgICAgLy8gY29uc2lkZXJpbmcgcG9zc2libGUgcGxhdGZvcm0gY2hhbmdlZCwgbmVlZCB0byByZSBidWlsZCBjYXRlZ29yaWVzXG4gICAgICAgIHNjcmVlbi5idWlsZENhdGVnb3JpZXMoKVxuICAgICAgICBzY3JlZW4uc2hvd1RoZXJtYWwgPSBmYWxzZSAvLyBtYWtlIHN1cmUgaXQgaXMgbm90IGluIHRoZXJtYWwgcGFnZSB3aGVuIGxvYWRlZFxuICAgICAgICBzY3JlZW4uc2hvd0NvbXBvbmVudHMgPSB0cnVlXG4gICAgICAgIHNjcmVlbi5zaG93Q29ubmVjdGlvbnMgPSB0cnVlXG4gICAgICAgIHNjcmVlbi5yZWZyZXNoKClcbiAgICAgIH1cbiAgICAgIHNjcmVlbi5lbmFibGVCdG5zKClcbiAgICAgIHRoaXMucmVmcmVzaFByb2plY3RzTWVudSgpXG4gICAgICBwcm9qZWN0LmRpcnR5ID0gZmFsc2VcbiAgICAgIEV2ZW50QnVzLiRlbWl0KCdwcm9qZWN0TG9hZGVkJylcbiAgICAgIGlmICghY2hpcC52ZXJpbG9nTGliVmVyc2lvbnMpIHtcbiAgICAgICAgY2hpcFsndmVyaWxvZ0xpYlZlcnNpb25zJ10gPSAnUHJvZHVjdGlvbidcbiAgICAgIH1cbiAgICAgIGxldCBpc051bWJlciA9IGZhbHNlXG4gICAgICBpZiAoY2hpcC5WSU4pIHtcbiAgICAgICAgaXNOdW1iZXIgPSBfLmlzTnVtYmVyKGNoaXAuVklOKVxuICAgICAgfVxuICAgICAgaWYgKCFpc051bWJlcikge1xuICAgICAgICBpZiAoc2NyZWVuKSB7XG4gICAgICAgICAgc2NyZWVuLmhhbmRsZVZJTigpXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KVxuICB9LFxuXG4gIC8vIExvYWQgZ3Vlc3QgcHJvamVjdFxuICBsb2FkR3Vlc3RQcm9qZWN0IChpZCwgdmFsaWRhdGVQYXJhbXMpIHtcbiAgICBkZWJ1ZygnbG9hZEd1ZXN0UHJvamVjdCAtIGlkOiAlcycsIGlkKVxuICAgIGxldCBpZE51bSA9IGlkXG4gICAgaWYgKF8uaXNTdHJpbmcoaWQpKSB7XG4gICAgICBpZE51bSA9IHBhcnNlSW50KGlkKVxuICAgIH1cbiAgICBsZXQganVtcCA9IHByb2Nlc3MuZW52LkpVTVBfRU5BQkxFXG4gICAgdGhpcy5jb25maXJtU2F2ZShhc3luYyAoKSA9PiB7XG4gICAgICBwcm9qZWN0cy5wdXNoKHdpbmRvdy5ndWVzdFByb2plY3QpXG4gICAgICBsZXQgZGF0YSA9IHdpbmRvdy5ndWVzdFByb2plY3RcbiAgICAgIHRoaXMuY2xlYXJQcm9qZWN0KHRydWUpXG4gICAgICBfLnJlbW92ZShwcm9qZWN0cywgcCA9PiBwLnByb2plY3RJRCA9PT0gaWROdW0pXG4gICAgICB1c2VyLnN1cGVyTW9kZSA9IGZhbHNlXG4gICAgICBwcm9qZWN0cy51bnNoaWZ0KGRhdGEpXG4gICAgICBwcm9qZWN0ID0gbmV3IFByb2plY3QoZGF0YSlcbiAgICAgIGNvbnN0IGNoaXAgPSBwcm9qZWN0LmNoaXBcbiAgICAgIGlmICh2YWxpZGF0ZVBhcmFtcykge1xuICAgICAgICBjaGlwLmNvbXBvbmVudHMuZm9yRWFjaChjID0+IHtcbiAgICAgICAgICBjLnZhbGlkYXRlUGFyYW1zKClcbiAgICAgICAgfSlcbiAgICAgICAgY2hpcC5kaWdpdGFscy5mb3JFYWNoKGMgPT4ge1xuICAgICAgICAgIGMudmFsaWRhdGVQYXJhbXMoKVxuICAgICAgICB9KVxuICAgICAgfVxuICAgICAgaWYgKGNoaXAuY3VycmVudFN0YWdlID09PSAndHVuaW5nJykge1xuICAgICAgICBjaGlwLmN1cnJlbnRTdGFnZSA9ICdkZXNpZ24nXG4gICAgICB9XG4gICAgICAvLyBDbGVhbiBsZWdhY3kgYXV0b0Nvbm5lY3Rpb25zXG4gICAgICB0aGlzLmNsZWFuTGVnYWN5KGNoaXApXG4gICAgICAvLyBjaGlwLnVwZGF0ZU9sZExET0NvbXBvbmVudCgpXG4gICAgICBsZXQgc2NyZWVuID0gU2NyZWVuTWFuYWdlci5nZXRTY3JlZW4oJ2Rlc2lnbicpXG4gICAgICBpZiAoc2NyZWVuICYmIHNjcmVlbi5pbml0aWFsaXplZCkge1xuICAgICAgICAvLyBjb25zaWRlcmluZyBwb3NzaWJsZSBwbGF0Zm9ybSBjaGFuZ2VkLCBuZWVkIHRvIHJlIGJ1aWxkIGNhdGVnb3JpZXNcbiAgICAgICAgc2NyZWVuLmJ1aWxkQ2F0ZWdvcmllcygpXG4gICAgICAgIHNjcmVlbi5zaG93VGhlcm1hbCA9IGZhbHNlIC8vIG1ha2Ugc3VyZSBpdCBpcyBub3QgaW4gdGhlcm1hbCBwYWdlIHdoZW4gbG9hZGVkXG4gICAgICAgIHNjcmVlbi5zaG93Q29tcG9uZW50cyA9IHRydWVcbiAgICAgICAgc2NyZWVuLnNob3dDb25uZWN0aW9ucyA9IHRydWVcbiAgICAgICAgc2NyZWVuLnJlZnJlc2goKVxuICAgICAgfVxuICAgICAgc2NyZWVuLmVuYWJsZUJ0bnMoKVxuICAgICAgdGhpcy5yZWZyZXNoUHJvamVjdHNNZW51KClcbiAgICAgIHByb2plY3QuZGlydHkgPSBmYWxzZVxuICAgICAgRXZlbnRCdXMuJGVtaXQoJ3Byb2plY3RMb2FkZWQnKVxuICAgICAgaWYgKCFjaGlwLnZlcmlsb2dMaWJWZXJzaW9ucykge1xuICAgICAgICBjaGlwWyd2ZXJpbG9nTGliVmVyc2lvbnMnXSA9ICdQcm9kdWN0aW9uJ1xuICAgICAgfVxuICAgICAgbGV0IGlzTnVtYmVyID0gZmFsc2VcbiAgICAgIGlmIChjaGlwLlZJTikge1xuICAgICAgICBpc051bWJlciA9IF8uaXNOdW1iZXIoY2hpcC5WSU4pXG4gICAgICB9XG4gICAgICBpZiAoIWlzTnVtYmVyKSB7XG4gICAgICAgIGlmIChzY3JlZW4pIHtcbiAgICAgICAgICBzY3JlZW4uaGFuZGxlVklOKClcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pXG4gIH0sXG5cbiAgYXN5bmMgY29udmVydFBsYXRmb3JtRm9yUHJvamVjdCAobmV3UGxhdGZvcm0sIGJ1aWxkQ2F0ZWdvcmllcykge1xuICAgIGlmIChfLmlzVW5kZWZpbmVkKGJ1aWxkQ2F0ZWdvcmllcykpIGJ1aWxkQ2F0ZWdvcmllcyA9IHRydWVcbiAgICBkZWJ1ZygnY29udmVydFBsYXRmb3JtRm9yUHJvamVjdCAtIG5ld1BsYXRmb3JtOiAlcycsIG5ld1BsYXRmb3JtKVxuICAgIGxldCB2YWxpZGF0ZVBhcmFtcyA9IHRydWVcbiAgICBsZXQgY2hpcCA9IHByb2plY3QuY2hpcFxuICAgIC8vIGNoYW5nZSBkZXZpY2VcbiAgICBsZXQgcGxhdEZvcm1WZXJzaW9uID0gJ0InXG4gICAgbGV0IHBhcnRzID0gY2hpcC5kZXZpY2UubmFtZS5tYXRjaCgvXkFtUChcXGQrKUQoW0F8QnxDXT8pKFxcZCkoLiopJC8pXG4gICAgaWYgKHBhcnRzWzJdLmxlbmd0aCA+IDApIHtcbiAgICAgIHBsYXRGb3JtVmVyc2lvbiA9IHBhcnRzWzJdXG4gICAgfVxuICAgIGlmIChwbGF0Rm9ybVZlcnNpb24gIT09IG5ld1BsYXRmb3JtKSB7XG4gICAgICBwbGF0Rm9ybVZlcnNpb24gPSBuZXdQbGF0Zm9ybVxuICAgIH1cbiAgICAvLyBjaGVjayBhbGwgY29tcG9uZW50IHZlcnNpb24gZXhpc3RlZCBpbiBuZXdQbGF0Zm9ybSwgaWYgbm90LCByZXBvcnQgYSBjb252ZXJ0IGZhaWxlZC5cbiAgICBsZXQgdmVyc2lvbkZvdW5kID0gdHJ1ZVxuICAgIGxldCBmYWlsZWRDb21wcyA9IFtdXG4gICAgcHJvamVjdC5jb25maWcuY2hpcHNbMF0uY29tcG9uZW50cy5mb3JFYWNoKGMgPT4ge1xuICAgICAgbGV0IHZlcnNpb24gPSBDb21wb25lbnRNYW5hZ2VyLmdldERlZmF1bHRWZXJzaW9uKGMsIGMudHlwZSwgbmV3UGxhdGZvcm0sIGNoaXAsIHRydWUpWzFdXG4gICAgICBpZiAodmVyc2lvbiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGxldCBjb21wID0gY2hpcC5jb21wb25lbnRzLmZpbmQoeCA9PiB4LmlkID09PSBjLmlkKVxuICAgICAgICBsZXQgdHlwZUNvbnZlcnQgPSBjb21wLmNvbmZpZy50eXBlQ29udmVydFxuICAgICAgICBpZiAoIXR5cGVDb252ZXJ0KSB7XG4gICAgICAgICAgdmVyc2lvbkZvdW5kID0gZmFsc2VcbiAgICAgICAgICBmYWlsZWRDb21wcy5wdXNoKCdjb21wb25lbnQnICsgYy5pZCArICcgJyArIGMudHlwZSlcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pXG4gICAgcHJvamVjdC5jb25maWcuY2hpcHNbMF0uZGlnaXRhbHMuZm9yRWFjaChjID0+IHtcbiAgICAgIGxldCB2ZXJzaW9uID0gQ29tcG9uZW50TWFuYWdlci5nZXREZWZhdWx0VmVyc2lvbihjLCBjLnR5cGUsIG5ld1BsYXRmb3JtLCBjaGlwLCB0cnVlKVsxXVxuICAgICAgaWYgKHZlcnNpb24gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICB2ZXJzaW9uRm91bmQgPSBmYWxzZVxuICAgICAgICBmYWlsZWRDb21wcy5wdXNoKCdjb21wb25lbnQnICsgYy5pZCArICcgJyArIGMudHlwZSlcbiAgICAgIH1cbiAgICB9KVxuICAgIGlmICghdmVyc2lvbkZvdW5kKSB7XG4gICAgICBsZXQgZmMgPSBmYWlsZWRDb21wcy5qb2luKClcbiAgICAgIHNob3dNb2RhbERpYWxvZygnQ29udmVydCBGYWlsZWQnLCAndGhlc2UgY29tcG9uZW50KHMpKCcgKyBmYyArICcpIGNhbm5vdCBiZSBjb252ZXJ0ZWQgYW5kIGNvbnZlcnQgYWN0aW9uIGZhaWxlZCcpXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICAvLyBzdGFydCBjb252ZXJ0IGFjdGlvblxuICAgIC8vIGlmIChwbGF0Rm9ybVZlcnNpb24gPT09ICdBJykgcGxhdEZvcm1WZXJzaW9uID0gJycvLyAnQScgaXMgZGVmYXVsdFxuICAgIGxldCBuZXdEZXZpY2VOYW1lID0gJ0FtUCcgKyBwYXJ0c1sxXSArICdEJyArIHBsYXRGb3JtVmVyc2lvbiArIHBhcnRzWzNdICsgcGFydHNbNF1cbiAgICBjaGlwLmRldmljZSA9IG5ld0RldmljZU5hbWVcbiAgICBwcm9qZWN0LmNvbmZpZy5jaGlwc1swXS5kZXZpY2UgPSBuZXdEZXZpY2VOYW1lXG5cbiAgICAvLyBjaGFuZ2UgY29tcG9uZW50IHZlcnNpb25cbiAgICBwcm9qZWN0LmNvbmZpZy5jaGlwc1swXS5jb21wb25lbnRzLmZvckVhY2goYyA9PiB7XG4gICAgICBsZXQgY29tcFZlciA9ICdfMV8wJ1xuICAgICAgbGV0IGNvbXBUeXBlID0gYy50eXBlXG4gICAgICBsZXQgaWR4ID0gYy50eXBlLmluZGV4T2YoJ18nKVxuICAgICAgaWYgKGlkeCA+IDApIHtcbiAgICAgICAgLy8gc2VwYXJhdGluZyB0eXBlIGFuZCB2ZXJzaW9uXG4gICAgICAgIGNvbXBWZXIgPSBjLnR5cGUuc3Vic3RyaW5nKGlkeCArIDIsIGMudHlwZS5sZW5ndGgpXG4gICAgICAgIGNvbXBUeXBlID0gYy50eXBlLnN1YnN0cmluZygwLCBpZHgpXG4gICAgICB9XG4gICAgICBsZXQgY29tcCA9IGNoaXAuY29tcG9uZW50cy5maW5kKHggPT4geC5pZCA9PT0gYy5pZClcbiAgICAgIGxldCB0eXBlQ29udmVydCA9IGNvbXAuY29uZmlnLnR5cGVDb252ZXJ0XG4gICAgICAvLyBpZiAobmV3UGxhdGZvcm0gPT09ICdCJykge1xuICAgICAgaWYgKHR5cGVDb252ZXJ0KSB7XG4gICAgICAgIGlmICh0eXBlQ29udmVydFsxXSA9PT0gJ2FueScpIHtcbiAgICAgICAgICBjLnZlcnNpb24gPSAnQicgKyBjb21wVmVyXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgYy52ZXJzaW9uID0gdHlwZUNvbnZlcnRbMV1cbiAgICAgICAgfVxuICAgICAgICBjLnR5cGUgPSB0eXBlQ29udmVydFswXVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYy52ZXJzaW9uID0gQ29tcG9uZW50TWFuYWdlci5nZXREZWZhdWx0VmVyc2lvbihjLCBjLnR5cGUsIG5ld1BsYXRmb3JtLCBjaGlwLCB0cnVlKVsxXVxuICAgICAgICBjLnR5cGUgPSBjb21wVHlwZVxuICAgICAgfVxuICAgICAgLy8gfSBlbHNlIHtcbiAgICAgIC8vICBjLnZlcnNpb24gPSBDb21wb25lbnRNYW5hZ2VyLmdldERlZmF1bHRWZXJzaW9uKGMsIGMudHlwZSwgbmV3UGxhdGZvcm0sIGNoaXAsIHRydWUpWzFdXG4gICAgICAvLyAgYy50eXBlID0gY29tcFR5cGVcbiAgICAgIC8vIH1cbiAgICB9KVxuICAgIHByb2plY3QuY29uZmlnLmNoaXBzWzBdLmRpZ2l0YWxzLmZvckVhY2goYyA9PiB7XG4gICAgICBjLnZlcnNpb24gPSBDb21wb25lbnRNYW5hZ2VyLmdldERlZmF1bHRWZXJzaW9uKGMsIGMudHlwZSwgbmV3UGxhdGZvcm0sIGNoaXAsIHRydWUpWzFdXG4gICAgfSlcbiAgICAvLyByZWJ1aWxkIHByb2plY3RcbiAgICBwcm9qZWN0LmNoaXBzLmNvbXBvbmVudHMgPSBwcm9qZWN0LmNvbmZpZy5jaGlwc1swXS5jb21wb25lbnRzXG4gICAgcHJvamVjdC5jaGlwcy5kaWdpdGFscyA9IHByb2plY3QuY29uZmlnLmNoaXBzWzBdLmRpZ2l0YWxzXG4gICAgdGhpcy5jbGVhclByb2plY3QodHJ1ZSlcbiAgICBfLnJlbW92ZShwcm9qZWN0cywgcCA9PiBwLnByb2plY3RJRCA9PT0gcHJvamVjdC5wcm9qZWN0SUQpXG4gICAgcHJvamVjdHMudW5zaGlmdChwcm9qZWN0KVxuICAgIHByb2plY3QgPSBuZXcgUHJvamVjdChwcm9qZWN0KVxuICAgIGF3YWl0IHRoaXMuc2F2ZVByb2plY3QoKVxuICAgIGNoaXAgPSBwcm9qZWN0LmNoaXBcbiAgICBpZiAodmFsaWRhdGVQYXJhbXMpIHtcbiAgICAgIGNoaXAuY29tcG9uZW50cy5mb3JFYWNoKGMgPT4ge1xuICAgICAgICBjLnZhbGlkYXRlUGFyYW1zKClcbiAgICAgIH0pXG4gICAgICBjaGlwLmRpZ2l0YWxzLmZvckVhY2goYyA9PiB7XG4gICAgICAgIGMudmFsaWRhdGVQYXJhbXMoKVxuICAgICAgfSlcbiAgICB9XG4gICAgLyogaWYgKHByb2Nlc3MuZW52LkpVTVBfRU5BQkxFID09PSAneWVzJykge1xuICAgICAgaWYgKG5ld1BsYXRmb3JtID09PSAnQScpIHtcbiAgICAgICAgbGV0IGlkID0gcHJvamVjdC5wcm9qZWN0SURcbiAgICAgICAgLy8gcmVkaXJlY3QgdG8gQSBwbGF0Zm9ybVxuICAgICAgICB3aW5kb3cubG9jYXRpb24ucmVwbGFjZShwcm9jZXNzLmVudi5SRVZJU0lPTl9BX1VSTCArIGAvcHJvamVjdHMvJHtpZH1gKVxuICAgICAgICByZXR1cm5cbiAgICAgIH1cbiAgICB9ICovXG4gICAgaWYgKGNoaXAuY3VycmVudFN0YWdlID09PSAndHVuaW5nJykge1xuICAgICAgY2hpcC5jdXJyZW50U3RhZ2UgPSAnZGVzaWduJ1xuICAgIH1cbiAgICAvLyBjaGlwLnVwZGF0ZU9sZExET0NvbXBvbmVudCgpXG4gICAgaWYgKGJ1aWxkQ2F0ZWdvcmllcykge1xuICAgICAgbGV0IHNjcmVlbiA9IFNjcmVlbk1hbmFnZXIuZ2V0U2NyZWVuKCdkZXNpZ24nKVxuICAgICAgaWYgKHNjcmVlbiAmJiBzY3JlZW4uaW5pdGlhbGl6ZWQpIHtcbiAgICAgICAgLy8gY29uc2lkZXJpbmcgcG9zc2libGUgcGxhdGZvcm0gY2hhbmdlZCwgbmVlZCB0byByZSBidWlsZCBjYXRlZ29yaWVzXG4gICAgICAgIHNjcmVlbi5idWlsZENhdGVnb3JpZXMoKVxuICAgICAgICBzY3JlZW4ucmVmcmVzaCgpXG4gICAgICB9XG4gICAgfVxuICAgIC8vIGNoaXAudXBkYXRlT2xkTERPQ29tcG9uZW50KClcbiAgICB0aGlzLnJlZnJlc2hQcm9qZWN0c01lbnUoKVxuICAgIC8vIEV2ZW50QnVzLiRlbWl0KCdwcm9qZWN0TG9hZGVkJylcbiAgfSxcblxuICBjbGVhclByb2plY3QgKGNoZWNrRGlydHkpIHtcbiAgICBkZWJ1ZygnY2xlYXJQcm9qZWN0JylcbiAgICBsZXQgY2hlY2sgPSBjaGVja0RpcnR5XG4gICAgaWYgKF8uaXNVbmRlZmluZWQoY2hlY2tEaXJ0eSkpIGNoZWNrID0gZmFsc2VcbiAgICBpZiAocHJvamVjdCkge1xuICAgICAgaWYgKCFjaGVjaykgcHJvamVjdC5kaXJ0eSA9IGZhbHNlXG4gICAgICAvLyBUT0RPOiB1c2UgZXZlbnQgaW5zdGVhZFxuICAgICAgJCgnI3RvcFVwbG9hZGVkJykuaGlkZSgpXG4gICAgICAkKCcjcGFyYW1VcGxvYWRlZCcpLmhpZGUoKVxuICAgICAgJCgnI2ltcGxVcGxvYWRlZCcpLmhpZGUoKVxuICAgICAgJCgnI3BjZlVwbG9hZGVkJykuaGlkZSgpXG4gICAgICBTY3JlZW5NYW5hZ2VyLnJlc2V0KClcbiAgICB9XG4gIH0sXG5cbiAgY29uZmlybVNhdmUgKGNhbGxiYWNrKSB7XG4gICAgaWYgKCFwcm9qZWN0IHx8ICFwcm9qZWN0LmRpcnR5KSB7XG4gICAgICBpZiAoY2FsbGJhY2spIGNhbGxiYWNrKClcbiAgICAgIHJldHVyblxuICAgIH1cbiAgICBzaG93Q29uZmlybSgnRG8geW91IHdhbnQgdG8gc2F2ZSB0aGUgY3VycmVudCBwcm9qZWN0PycsXG4gICAgICB7IG5hbWU6ICdObycsIGNsYXNzTmFtZTogJ2J0bi1kYW5nZXInIH0sIHsgbmFtZTogJ1llcycsIGNsYXNzTmFtZTogJ2J0bi1zdWNjZXNzJyB9LFxuICAgICAgYXN5bmMgKGNvbmZpcm0pID0+IHtcbiAgICAgICAgaWYgKGNvbmZpcm0pIHtcbiAgICAgICAgICBhd2FpdCB0aGlzLnNhdmVQcm9qZWN0KClcbiAgICAgICAgfVxuICAgICAgICBpZiAoY2FsbGJhY2spIGNhbGxiYWNrKClcbiAgICAgIH0pXG4gIH0sXG5cbiAga2VlcFRkYyAoKSB7XG4gICAgY29uc3QgY2hpcCA9IHByb2plY3QuY2hpcFxuICAgIGNoaXAuY29tcG9uZW50cy5mb3JFYWNoKGMgPT4ge1xuICAgICAgaWYgKGMudGRjKSB7XG4gICAgICAgIGxldCBjb21wID0gcHJvamVjdC5jb25maWcuY2hpcHNbMF0uY29tcG9uZW50cy5maW5kKHAgPT4gcC5pZCA9PT0gYy5pZClcbiAgICAgICAgaWYgKGNvbXApIHtcbiAgICAgICAgICBjb21wLnRkYyA9IGMudGRjXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KVxuICAgIHByb2plY3QuY29uZmlnLmNoaXBzWzBdLlRBID0gY2hpcC5UQVxuICB9LFxuXG4gIGFzeW5jIHNhdmVQcm9qZWN0ICgpIHtcbiAgICBpZiAoIXByb2plY3QpIHJldHVyblxuICAgIHRyeSB7XG4gICAgICBzaG93QnVzeSh0cnVlLCAnU2F2aW5nLi4uJylcbiAgICAgIHRoaXMua2VlcFRkYygpXG4gICAgICBhd2FpdCB0aGlzLnNhdmVQcm9qZWN0cygpXG4gICAgICBoaWRlQnVzeSgpXG4gICAgICBwcm9qZWN0LmRpcnR5ID0gZmFsc2VcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICByZXR1cm4gc2hvd01vZGFsRGlhbG9nKCdFcnJvcicsIGUubWVzc2FnZSlcbiAgICB9XG4gICAgLy8gc2hvd01lc3NhZ2UoJ1Byb2plY3QgU2F2ZWQnKVxuICB9LFxuXG4gIC8vIGJhdGNoIG9wZXJhdGlvbnNcbiAgYXN5bmMgc2F2ZVByb2plY3RzIChwcm9qZWN0cykge1xuICAgIGlmICghcHJvamVjdHMpIHtcbiAgICAgIHByb2plY3RzID0gW3sgcHJvamVjdElEOiBwcm9qZWN0LnByb2plY3RJRCwgY29uZmlnOiBwcm9qZWN0LmNvbmZpZywgbmFtZTogcHJvamVjdC5uYW1lIH1dXG4gICAgfVxuICAgIGlmICghQXJyYXkuaXNBcnJheShwcm9qZWN0cykpIHByb2plY3RzID0gW3Byb2plY3RzXVxuXG4gICAgLy8gSWYgdGhlcmUgYXJlIHRvbyBtYW55IHByb2plY3RzLCB3ZSBuZWVkIHRvIGJyZWFrIGl0IHVwIHNvIGFzIHRvIGF2b2lkIHBheWxvYWQgdG9vIGxhcmdlIGVycm9yLlxuICAgIGNvbnN0IG1heCA9IDEwXG4gICAgaWYgKHByb2plY3RzLmxlbmd0aCA+IG1heCkge1xuICAgICAgY29uc3QgYmF0Y2ggPSBwcm9qZWN0cy5zcGxpY2UoMCwgbWF4KVxuICAgICAgYXdhaXQgdGhpcy5zYXZlUHJvamVjdHMoYmF0Y2gpXG4gICAgICByZXR1cm4gdGhpcy5zYXZlUHJvamVjdHMocHJvamVjdHMpXG4gICAgfVxuXG4gICAgaWYgKHByb2plY3RzLmxlbmd0aCA+IDApIHtcbiAgICAgIGF3YWl0IHNlbmRDb21tYW5kKCcvcHJvamVjdCcsIHsgbWV0aG9kOiAnc2F2ZVByb2plY3RzJywgcHJvamVjdHM6IHByb2plY3RzIH0pXG4gICAgfVxuICB9LFxuXG4gIGNvbmZpcm1EZWxldGUgKHNlbGVjdGlvbnMpIHtcbiAgICBpZiAoIXNlbGVjdGlvbnMpIHtcbiAgICAgIHNlbGVjdGlvbnMgPSBwcm9qZWN0ID8gW3Byb2plY3QucHJvamVjdElEXSA6IG51bGxcbiAgICB9XG4gICAgaWYgKCFzZWxlY3Rpb25zKSByZXR1cm5cblxuICAgIGxldCBtc2cgPSAnQXJlIHlvdSBzdXJlIHlvdSB3YW50IHRvIGRlbGV0ZSB0aGVzZSBwcm9qZWN0cz8nXG4gICAgaWYgKHNlbGVjdGlvbnMubGVuZ3RoID09PSAxICYmIHR5cGVvZiBwcm9qZWN0ICE9PSAndW5kZWZpbmVkJyAmJiBwcm9qZWN0ICYmXG4gICAgICAoXy5pc09iamVjdChzZWxlY3Rpb25zWzBdKSA/IHNlbGVjdGlvbnNbMF0uaWQgPT09IHByb2plY3QucHJvamVjdElEIDogc2VsZWN0aW9uc1swXSA9PT0gcHJvamVjdC5wcm9qZWN0SUQpKSB7XG4gICAgICBtc2cgPSAnQXJlIHlvdSBzdXJlIHlvdSB3YW50IHRvIGRlbGV0ZSB0aGlzIHByb2plY3Q/J1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgICAgc2hvd0NvbmZpcm0obXNnLCBudWxsLFxuICAgICAgICB7IG5hbWU6ICdEZWxldGUnLCBjbGFzc05hbWU6ICdidG4tZGFuZ2VyJyB9LFxuICAgICAgICBhc3luYyBjb25maXJtID0+IHtcbiAgICAgICAgICBpZiAoY29uZmlybSkge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5kZWxldGVQcm9qZWN0cyhzZWxlY3Rpb25zKVxuICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUodHJ1ZSlcbiAgICAgICAgICB9XG4gICAgICAgICAgcmVzb2x2ZShmYWxzZSlcbiAgICAgICAgfSlcbiAgICB9KVxuICB9LFxuXG4gIGFzeW5jIGRlbGV0ZVByb2plY3QgKHNob3dDb25maXJtKSB7XG4gICAgaWYgKHByb2plY3QpIHtcbiAgICAgIGlmIChfLmlzVW5kZWZpbmVkKHNob3dDb25maXJtKSkge1xuICAgICAgICBzaG93Q29uZmlybSA9IHRydWVcbiAgICAgIH1cbiAgICAgIGlmIChzaG93Q29uZmlybSkge1xuICAgICAgICBjb25zdCBkZWxldGVkID0gYXdhaXQgdGhpcy5jb25maXJtRGVsZXRlKFtwcm9qZWN0LnByb2plY3RJRF0pXG4gICAgICAgIGlmICghZGVsZXRlZCkgcmV0dXJuXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBhd2FpdCB0aGlzLmRlbGV0ZVByb2plY3RzKFtwcm9qZWN0LnByb2plY3RJRF0pXG4gICAgICB9XG4gICAgICB0aGlzLmNsZWFyUHJvamVjdCgpXG4gICAgICBwcm9qZWN0ID0gbnVsbFxuICAgICAgdGhpcy5yZWZyZXNoUHJvamVjdHNNZW51KClcbiAgICAgIFNjcmVlbk1hbmFnZXIuc2hvd1NjcmVlbigpXG4gICAgfVxuICB9LFxuXG4gIGFzeW5jIGRlbGV0ZVByb2plY3RzIChzZWxlY3Rpb25zKSB7XG4gICAgaWYgKCFzZWxlY3Rpb25zKSByZXR1cm5cbiAgICBjb25zdCB7IHN1Y2Nlc3MgfSA9IGF3YWl0IHNlbmRDb21tYW5kKCcvcHJvamVjdCcsIHsgbWV0aG9kOiAnZGVsZXRlUHJvamVjdHMnLCBwcm9qZWN0czogc2VsZWN0aW9ucyB9KVxuICAgIGlmICghc3VjY2VzcykgcmV0dXJuXG4gICAgaWYgKHByb2plY3RzKSB7XG4gICAgICBfLnJlbW92ZShwcm9qZWN0cywgcCA9PiB7XG4gICAgICAgIHJldHVybiBzZWxlY3Rpb25zLmluZGV4T2YocC5wcm9qZWN0SUQpID49IDBcbiAgICAgIH0pXG4gICAgfVxuICB9LFxuXG4gIGFzeW5jIGNoYW5nZURldmljZSAoZGV2aWNlTmFtZSkge1xuICAgIGNvbnN0IGNoaXAgPSBwcm9qZWN0LmNoaXBcbiAgICBpZiAoIWNoaXAuZGV2aWNlKSB7XG4gICAgICBjaGlwLmRldmljZSA9IGRldmljZU5hbWVcbiAgICAgIGlmIChkZXZpY2VOYW1lKSB7XG4gICAgICAgIC8vIGluIGNhc2UsIGl0IGlzIGEgb2xkIHdlYmFtcCBwcm9qZWN0XG4gICAgICAgIC8vIGRldmljZU5hbWUgPSBkZXZpY2VOYW1lLnJlcGxhY2UoJ1MnLCAnJylcbiAgICAgICAgbGV0IGlkID0gcHJvamVjdC5wcm9qZWN0SURcbiAgICAgICAgbGV0IHJldmlzaW9uID0gJ0EnXG4gICAgICAgIGxldCBwYXJ0cyA9IGRldmljZU5hbWUubWF0Y2goL15BbVAoXFxkKylEKFtBfEJ8Q10/KShcXGQpKC4qKSQvKVxuICAgICAgICBpZiAocGFydHNbMl0ubGVuZ3RoID4gMCkge1xuICAgICAgICAgIHJldmlzaW9uID0gcGFydHNbMl1cbiAgICAgICAgfVxuICAgICAgICBpZiAocHJvY2Vzcy5lbnYuSlVNUF9FTkFCTEUgPT09ICd5ZXMnKSB7XG4gICAgICAgICAgaWYgKHJldmlzaW9uID09PSAnQScpIHtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuc2F2ZVByb2plY3QoKVxuICAgICAgICAgICAgLy8gcmVkaXJlY3QgdG8gQSBwbGF0Zm9ybVxuICAgICAgICAgICAgd2luZG93LmxvY2F0aW9uLnJlcGxhY2UocHJvY2Vzcy5lbnYuUkVWSVNJT05fQV9VUkwgKyBgL3Byb2plY3RzLyR7aWR9YClcbiAgICAgICAgICAgIHJldHVyblxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy8gY2hvc2VuIHBsYXRmb3JtLCBuZWVkIHRvIHJlLWJ1aWxkIENhdGVnb3JpZXNcbiAgICAgIGxldCBzY3JlZW4gPSBTY3JlZW5NYW5hZ2VyLmdldFNjcmVlbignZGVzaWduJylcbiAgICAgIGlmIChzY3JlZW4gJiYgc2NyZWVuLmluaXRpYWxpemVkKSB7XG4gICAgICAgIC8vIGNvbnNpZGVyaW5nIHBvc3NpYmxlIHBsYXRmb3JtIGNoYW5nZWQsIG5lZWQgdG8gcmUgYnVpbGQgY2F0ZWdvcmllc1xuICAgICAgICBzY3JlZW4uYnVpbGRDYXRlZ29yaWVzKClcbiAgICAgICAgc2NyZWVuLnJlZnJlc2goKVxuICAgICAgfVxuICAgICAgdGhpcy5yZWZyZXNoUHJvamVjdHNNZW51KClcbiAgICB9IGVsc2UgaWYgKGNoaXAuZGV2aWNlLm5hbWUgIT09IGRldmljZU5hbWUpIHtcbiAgICAgIGNvbnN0IG5ld0RldmljZUNvbmZpZyA9IFBhY2thZ2VNYW5hZ2VyLmRldmljZXMuZmluZChkZXZpY2UgPT4gZGV2aWNlLm5hbWUgPT09IGRldmljZU5hbWUpXG4gICAgICBpZiAoY2hpcC5kZXZpY2UubW9zZmV0cyAhPT0gbmV3RGV2aWNlQ29uZmlnLm1vc2ZldHMpIHtcbiAgICAgICAgc2hvd01vZGFsRGlhbG9nKCdXYXJuaW5nJywgJ0NhbiBub3QgbWlncmF0ZSB0byBkZXZpY2Ugd2l0aCBkaWZmZXJlbnQgbW9zZmV0cycpXG4gICAgICAgIHJldHVyblxuICAgICAgfVxuICAgICAgc2hvd0NvbmZpcm0oYERvIHlvdSB3YW50IHRvIG1pZ3JhdGUgZnJvbSAke2NoaXAuZGV2aWNlLm5hbWV9IHRvICR7ZGV2aWNlTmFtZX0gP2AsXG4gICAgICAgIHsgbmFtZTogJ05vJywgY2xhc3NOYW1lOiAnYnRuLWRhbmdlcicgfSwgeyBuYW1lOiAnWWVzJywgY2xhc3NOYW1lOiAnYnRuLXN1Y2Nlc3MnIH0sXG4gICAgICAgIGNvbmZpcm0gPT4ge1xuICAgICAgICAgIGlmIChjb25maXJtKSB7XG4gICAgICAgICAgICBzaG93QnVzeSh0cnVlLCAnQ2hhbmdpbmcgRGV2aWNlLi4uJylcbiAgICAgICAgICAgIGNoaXAuZGV2aWNlID0gZGV2aWNlTmFtZVxuICAgICAgICAgICAgaGlkZUJ1c3koKVxuICAgICAgICAgICAgdGhpcy5yZWZyZXNoUHJvamVjdHNNZW51KClcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIClcbiAgICB9XG4gIH0sXG5cbiAgaW1wb3J0ICgpIHtcbiAgICBjb25zdCBkaWFsb2cgPSAkKHRlbXBsYXRlSW1wb3J0UHJvamVjdCgpKVxuICAgICQoJ2JvZHknKS5hcHBlbmQoZGlhbG9nKVxuXG4gICAgbGV0IGltcG9ydGVkUHJvamVjdFxuICAgICQoZGlhbG9nLmZpbmQoJ2lucHV0JylbMV0pLm9uKCdjaGFuZ2UnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBpbkZpbGVOYW1lID0gdGhpcy5maWxlc1swXS5uYW1lXG4gICAgICBjb25zdCByZWFkZXIgPSBuZXcgRmlsZVJlYWRlcigpXG4gICAgICByZWFkZXIub25sb2FkID0gYXN5bmMgZnVuY3Rpb24gKGZsZSkge1xuICAgICAgICBsZXQganNvbkNvbnRlbnRcbiAgICAgICAgaWYgKGluRmlsZU5hbWUuZW5kc1dpdGgoJy56aXAnKSkge1xuICAgICAgICAgIGxldCB6aXAgPSBhd2FpdCBKU1ppcC5sb2FkQXN5bmMoZmxlLnRhcmdldC5yZXN1bHQpXG4gICAgICAgICAgbGV0IGpzb25OYW1lID0gT2JqZWN0LmtleXMoemlwLmZpbGVzKS5maW5kKGZOYW1lID0+IGZOYW1lLmVuZHNXaXRoKCcuanNvbicpKVxuICAgICAgICAgIGlmIChqc29uTmFtZSkge1xuICAgICAgICAgICAganNvbkNvbnRlbnQgPSBhd2FpdCB6aXAuZmlsZShqc29uTmFtZSkuYXN5bmMoJ3N0cmluZycpXG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGpzb25Db250ZW50ID0gcmVhZGVyLnJlc3VsdFxuICAgICAgICB9XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBpbXBvcnRlZFByb2plY3QgPSBKU09OLnBhcnNlKGpzb25Db250ZW50KVxuICAgICAgICAgIGxldCBkZXZpY2UgPSBpbXBvcnRlZFByb2plY3QuY29uZmlnLmNoaXBzWzBdLmRldmljZVxuICAgICAgICAgIGlmICghZGV2aWNlIHx8IGRldmljZS5pbmNsdWRlcygnUUY3NCcpKSB7XG4gICAgICAgICAgICBsZXQgZXJyID0gJ1BhY2thZ2UgaW4gcHJvamVjdCBmaWxlIGlzIHVuc3VwcG9ydGVkOiAnICsgZGV2aWNlXG4gICAgICAgICAgICB0aHJvdyBlcnJcbiAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICBzaG93TW9kYWxEaWFsb2coJ0ltcG9ydCBGYWlsZWQnLCAnUHJvamVjdCBmaWxlIG1pZ2h0IGJlIGNvcnJ1cHRlZCBvciB1bnN1cHBvcnRlZC48YnI+PGJyPicgKyAnUGxlYXNlIGNob29zZSBhIG5ldyBmaWxlIG9yIHppcC48YnI+PGJyPiAnICsgZSlcbiAgICAgICAgfVxuICAgICAgICAkKGRpYWxvZy5maW5kKCdpbnB1dCcpWzBdKS52YWwoaW1wb3J0ZWRQcm9qZWN0Lm5hbWUpXG4gICAgICB9XG5cbiAgICAgIGlmIChpbkZpbGVOYW1lLmVuZHNXaXRoKCcuemlwJykpIHtcbiAgICAgICAgcmVhZGVyLnJlYWRBc0FycmF5QnVmZmVyKHRoaXMuZmlsZXNbMF0pXG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZWFkZXIucmVhZEFzVGV4dCh0aGlzLmZpbGVzWzBdKVxuICAgICAgfVxuICAgIH0pXG5cbiAgICBzZXREaWFsb2dCdXR0b25BY3Rpb24oZGlhbG9nLCAnSW1wb3J0JywgYXN5bmMgKGV2ZW50KSA9PiB7XG4gICAgICBjb25zdCBpbnB1dHMgPSBkaWFsb2cuZmluZCgnaW5wdXQnKVxuICAgICAgbGV0IG5hbWUgPSAkKGlucHV0cykudmFsKClcbiAgICAgIHRyeSB7XG4gICAgICAgIGlmICghaW1wb3J0ZWRQcm9qZWN0KSB7XG4gICAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcbiAgICAgICAgICByZXR1cm4gJChkaWFsb2cuZmluZCgnc21hbGwnKSkuYXBwZW5kKCc8c3BhbiBjbGFzcz1cImxhYmVsIGxhYmVsLWRhbmdlclwiPlBsZWFzZSBzcGVjaWZ5IGEgZmlsZS48L3NwYW4+JylcbiAgICAgICAgfVxuICAgICAgICBpZiAoJChpbnB1dHNbMF0pLnZhbCgpLnRyaW0oKSA9PT0gJycpIHtcbiAgICAgICAgICAkKGlucHV0c1swXSkudmFsKGltcG9ydGVkUHJvamVjdC5uYW1lKVxuICAgICAgICAgIG5hbWUgPSBpbXBvcnRlZFByb2plY3QubmFtZVxuICAgICAgICB9XG4gICAgICAgIGxldCBuVmFsaWQgPSBmYWxzZVxuICAgICAgICBsZXQgdmFsaWROYW1lRXhwID0gL15bQS1aX11bMC05QS1aX10qJC9pXG4gICAgICAgIG5WYWxpZCA9IHZhbGlkTmFtZUV4cC50ZXN0KG5hbWUpXG4gICAgICAgIGlmICghblZhbGlkKSB7XG4gICAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcbiAgICAgICAgICByZXR1cm4gZGlhbG9nLmZpbmQoJy5tb2RhbC1oZWFkZXIgc21hbGwgc3BhbicpLnRleHQoJ1Byb2plY3QgbmFtZSBPTkxZIGluY2x1ZGVzIEEuLlosIGEuLnosIDAuLjksIF8nKVxuICAgICAgICB9IGVsc2UgaWYgKCF0aGlzLmNoZWNrUHJvamVjdE5hbWUoaW5wdXRzWzBdKSkge1xuICAgICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXG4gICAgICAgICAgcmV0dXJuIGRpYWxvZy5maW5kKCcubW9kYWwtaGVhZGVyIHNtYWxsIHNwYW4nKS50ZXh0KCdQcm9qZWN0IG5hbWUgaGFzIGJlZW4gdGFrZW4nKVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHsgc3VjY2VzcywgZGF0YSB9ID0gYXdhaXQgc2VuZENvbW1hbmQoJy9wcm9qZWN0Jywge1xuICAgICAgICAgIG1ldGhvZDogJ25ldycsXG4gICAgICAgICAgbmFtZTogJChpbnB1dHNbMF0pLnZhbCgpLnRyaW0oKSxcbiAgICAgICAgICBjb25maWc6IEpTT04uc3RyaW5naWZ5KGltcG9ydGVkUHJvamVjdC5jb25maWcpLFxuICAgICAgICB9KVxuICAgICAgICBpZiAoIXN1Y2Nlc3MpIHJldHVyblxuICAgICAgICBpZiAoIWRhdGEpIHJldHVyblxuICAgICAgICBwcm9qZWN0cy5wdXNoKGRhdGEpXG4gICAgICAgIHRoaXMubG9hZFByb2plY3QoZGF0YS5wcm9qZWN0SUQsIGZhbHNlKVxuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBzaG93TW9kYWxEaWFsb2coJ0ltcG9ydCBGYWlsZWQnLCAnUHJvamVjdCBmaWxlIG1pZ2h0IGJlIGNvcnJ1cHRlZC4nKVxuICAgICAgfVxuICAgIH0sIHRydWUpXG4gIH0sXG5cbiAgZ2V0VXNlcklEICgpIHtcbiAgICBsZXQgc2hvd2luZm8gPSAnVXNlcklEOiAnICsgdXNlci51c2VySUQudG9TdHJpbmcoKVxuICAgIGlmIChwcm9qZWN0KSB7XG4gICAgICBzaG93aW5mbyA9IHNob3dpbmZvICsgJyAgIFByb2plY3RJRDogJyArIHByb2plY3QucHJvamVjdElEXG4gICAgfVxuICAgIHNob3dNb2RhbERpYWxvZygnVXNlciBJRCcsIHNob3dpbmZvKVxuICB9LFxuXG4gIC8vIFRPRE86IHRoaXMgY291bGQgYmUgcmVmYWN0b3JlZC4gRG9uJ3QgbmVlZCB0byBnZXQgZmlsZSBhbmQgdGhlbiBzZW5kIGJhY2suXG4gIGFzeW5jIGltcG9ydEV4YW1wbGUgKG5hbWUpIHtcbiAgICBsZXQgeyBzdWNjZXNzLCBkYXRhIH0gPSBhd2FpdCBzZW5kQ29tbWFuZCgnL3Byb2plY3QnLCB7XG4gICAgICBtZXRob2Q6ICdnZXRGaWxlJyxcbiAgICAgIGZpbGU6ICdleGFtcGxlcy8nICsgbmFtZSArICcuanNvbicsXG4gICAgfSlcbiAgICBpZiAoIXN1Y2Nlc3MpIHJldHVyblxuICAgIGxldCBjb25maWcgPSBKU09OLnBhcnNlKGRhdGEpLmNvbmZpZ1xuICAgIGxldCBuYW1lQXJyID0gbmFtZS5zcGxpdCgnLycpXG4gICAgbmFtZSA9IG5hbWVBcnJbbmFtZUFyci5sZW5ndGggLSAxXSAvLyBnZXQgcmlkIG9mIHRoZSBkaXJlY3RvcnkgbmFtZS5cbiAgICBjb25zdCBwcm9qZWN0TmFtZSA9IHRoaXMuZ2V0TW9kaWZpZWRQcm9qZWN0TmFtZShuYW1lKTtcbiAgICAoeyBzdWNjZXNzLCBkYXRhIH0gPSBhd2FpdCBzZW5kQ29tbWFuZCgnL3Byb2plY3QnLCB7IG1ldGhvZDogJ25ldycsIG5hbWU6IHByb2plY3ROYW1lLCBjb25maWc6IEpTT04uc3RyaW5naWZ5KGNvbmZpZykgfSkpXG4gICAgaWYgKCFzdWNjZXNzKSByZXR1cm5cbiAgICBpZiAoIWRhdGEpIHJldHVyblxuICAgIHByb2plY3RzLnB1c2goZGF0YSlcbiAgICB0aGlzLmxvYWRQcm9qZWN0KGRhdGEucHJvamVjdElELCBmYWxzZSlcbiAgfSxcblxuICBhc3luYyBpbXBvcnRXZWJBZGFwdGVyUHJvZHVjdCAodHlwZSwgbW9kZSA9ICdUaW1lJykge1xuICAgIC8vIGdldCBkYXRhXG4gICAgbGV0IHsgc3VjY2VzcywgZGF0YSB9ID0gYXdhaXQgc2VuZENvbW1hbmQoJy93ZWJhZGFwdGVyJywgeyBtZXRob2Q6ICdnZXRQcm9kdWN0JywgdHlwZSB9KVxuICAgIGlmICghc3VjY2VzcykgcmV0dXJuXG5cbiAgICBkYXRhLmNvbmZpZy5jaGlwc1swXS50eXBlID0gdHlwZVxuXG4gICAgY29uc3QgcHJvamVjdE5hbWUgPSB0aGlzLmdldE1vZGlmaWVkUHJvamVjdE5hbWUodHlwZSk7XG4gICAgLy8gY3JlYXRlIG5ldyBwcm9qZWN0IHdpdGggZGF0YVxuICAgICh7IHN1Y2Nlc3MsIGRhdGEgfSA9IGF3YWl0IHNlbmRDb21tYW5kKCcvcHJvamVjdCcsIHsgbWV0aG9kOiAnbmV3JywgbmFtZTogcHJvamVjdE5hbWUsIGNvbmZpZzogSlNPTi5zdHJpbmdpZnkoZGF0YS5jb25maWcpIH0pKVxuICAgIGlmICghc3VjY2VzcykgcmV0dXJuXG4gICAgaWYgKCFkYXRhKSByZXR1cm5cbiAgICBwcm9qZWN0cy5wdXNoKGRhdGEpXG4gICAgdGhpcy5sb2FkUHJvamVjdChkYXRhLnByb2plY3RJRCwgZmFsc2UpXG4gIH0sXG5cbiAgYXN5bmMgZXhwb3J0ICgpIHtcbiAgICBpZiAoIXByb2plY3QpIHJldHVyblxuICAgIGNvbnN0IGZpbGVGb3JtdHMgPSBbJyRoYXgnLCAnJGhleCcsICckYml0J11cbiAgICBsZXQgemlwID0gbmV3IEpTWmlwKClcbiAgICBjb25zdCBmb3JtYXREdCA9IHQgPT4ge1xuICAgICAgdCA9IHQgPCAxMCA/ICcwJyArIHQgOiB0XG4gICAgICByZXR1cm4gdFxuICAgIH1cbiAgICBjb25zdCB0c1RvU3RyaW5nID0gdHMgPT4ge1xuICAgICAgbGV0IHRzU3RyaW5nID0gdHMuZ2V0RnVsbFllYXIoKSArICdfJyArIGZvcm1hdER0KHRzLmdldE1vbnRoKCkgKyAxKSArICdfJyArIGZvcm1hdER0KHRzLmdldERhdGUoKSlcbiAgICAgIHRzU3RyaW5nICs9ICdfJyArIGZvcm1hdER0KHRzLmdldEhvdXJzKCkpICsgZm9ybWF0RHQodHMuZ2V0TWludXRlcygpKVxuICAgICAgcmV0dXJuIHRzU3RyaW5nXG4gICAgfVxuXG4gICAgLy8gQWRkIGZpbGVzIGJpbiwgaGF4LCBoZXggdG8gemlwXG4gICAgbGV0IHRzU3VmZml4XG4gICAgbGV0IHppcFN1ZmZpeCA9ICcnXG4gICAgaWYgKHByb2plY3QudHNwKSB7XG4gICAgICB0c1N1ZmZpeCA9IHRzVG9TdHJpbmcocHJvamVjdC50c3ApXG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGZpbGVGb3JtdHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgbGV0IGRhdGEgPSBhd2FpdCBzZW5kQ29tbWFuZCgnL3Byb2plY3QnLCB7XG4gICAgICAgICAgbWV0aG9kOiAnZ2V0RmlsZScsXG4gICAgICAgICAgcHJvamVjdElkOiBwcm9qZWN0LnByb2plY3RJRCxcbiAgICAgICAgICBjaGlwTmFtZTogcHJvamVjdC5jaGlwLm5hbWUsXG4gICAgICAgICAgcHJvamVjdE5hbWU6IHByb2plY3QubmFtZSxcbiAgICAgICAgICBmaWxlOiBmaWxlRm9ybXRzW2ldLFxuICAgICAgICB9LCBmYWxzZSlcbiAgICAgICAgaWYgKGRhdGEgJiYgZGF0YS5zdWNjZXNzKSB7XG4gICAgICAgICAgbGV0IG5hbWVTdHJzID0gZGF0YS5uYW1lLnNwbGl0KCcuJylcbiAgICAgICAgICB6aXBTdWZmaXggPSAnXycgKyB0c1N1ZmZpeFxuICAgICAgICAgIGxldCBkYXRhVG9aaXAgPSBkYXRhLmRhdGFcbiAgICAgICAgICBpZiAoZmlsZUZvcm10c1tpXS5pbmNsdWRlcygnYml0JykpIHtcbiAgICAgICAgICAgIGRhdGFUb1ppcCA9IGF3YWl0IEJ1ZmZlci5mcm9tKGRhdGEuZGF0YSwgJ2Jhc2U2NCcpXG4gICAgICAgICAgfVxuICAgICAgICAgIHppcC5maWxlKG5hbWVTdHJzWzBdICsgemlwU3VmZml4ICsgJy4nICsgbmFtZVN0cnNbMV0sIGRhdGFUb1ppcClcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIEFkZCBwcm9qZWN0J3MganNvbiB0byB6aXBcbiAgICB0c1N1ZmZpeCA9IHRzVG9TdHJpbmcobmV3IERhdGUoKSlcbiAgICB6aXAuZmlsZShwcm9qZWN0Lm5hbWUgKyAnXycgKyB0c1N1ZmZpeCArICcuanNvbicsIEpTT04uc3RyaW5naWZ5KHByb2plY3QudG9Kc29uKCksIG51bGwsICdcXHQnKSlcblxuICAgIC8vIEdlbmVyYXRlIHppcCBhbmQgcHJvbXB0ICdzYXZlIGFzJ1xuICAgIHppcC5nZW5lcmF0ZUFzeW5jKHtcbiAgICAgIHR5cGU6ICdibG9iJyxcbiAgICAgIGNvbXByZXNzaW9uOiAnREVGTEFURScsXG4gICAgICBjb21wcmVzc2lvbk9wdGlvbnM6IHtcbiAgICAgICAgbGV2ZWw6IDksXG4gICAgICB9LFxuICAgIH0pLnRoZW4oZnVuY3Rpb24gKGJsb2IpIHtcbiAgICAgIHNhdmVBcyhibG9iLCBwcm9qZWN0Lm5hbWUgKyB6aXBTdWZmaXggKyAnLnppcCcpXG4gICAgfSlcblxuICAgIC8vIGNvbnN0IGRvd25sb2FkTGluayA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2EnKVxuICAgIC8vIGRvd25sb2FkTGluay5ocmVmID0gJ2RhdGE6YXR0YWNobWVudC90ZXh0LCcgKyBlbmNvZGVVUklDb21wb25lbnQoSlNPTi5zdHJpbmdpZnkocHJvamVjdC50b0pzb24oKSwgbnVsbCwgJ1xcdCcpKVxuICAgIC8vIGRvd25sb2FkTGluay50YXJnZXQgPSAnX2JsYW5rJ1xuICAgIC8vIGRvd25sb2FkTGluay5kb3dubG9hZCA9IHByb2plY3QubmFtZSArICcuanNvbidcbiAgICAvLyBkb3dubG9hZExpbmsuc3R5bGUgPSAnZGlzcGxheTpub25lJ1xuICAgIC8vICQoJ2JvZHknKS5hcHBlbmQoZG93bmxvYWRMaW5rKVxuICAgIC8vIGRvd25sb2FkTGluay5jbGljaygpXG4gICAgLy8gZG93bmxvYWRMaW5rLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoZG93bmxvYWRMaW5rKVxuICB9LFxuXG4gIGV4cG9ydFByb2plY3RzIChwcm9qZWN0cykge1xuICAgIGlmICghcHJvamVjdHMpIHByb2plY3RzID0gcHJvamVjdCA/IFtwcm9qZWN0XSA6IG51bGxcbiAgICBpZiAoIXByb2plY3RzKSByZXR1cm5cbiAgICBsZXQgZG93bmxvYWRMaW5rID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYScpXG4gICAgZG93bmxvYWRMaW5rLnRhcmdldCA9ICdfYmxhbmsnXG4gICAgZG93bmxvYWRMaW5rLnN0eWxlID0gJ2Rpc3BsYXk6bm9uZSdcbiAgICAkKCdib2R5JykuYXBwZW5kKGRvd25sb2FkTGluaylcbiAgICBsZXQgcHJvcGVydGllcyA9IFsncHJvamVjdElEJywgJ3VzZXJJRCcsICduYW1lJywgJ2NvbmZpZycsICdjcmVhdGlvbl90aW1lJywgJ21vZGlmaWNhdGlvbl90aW1lJ11cbiAgICBsZXQgY2xvbmVcbiAgICBwcm9qZWN0cy5mb3JFYWNoKHByb2plY3QgPT4ge1xuICAgICAgY2xvbmUgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHByb2plY3QpKVxuICAgICAgXy5mb3JFYWNoKGNsb25lLCAodmFsdWUsIG5hbWUpID0+IHtcbiAgICAgICAgaWYgKHByb3BlcnRpZXMuaW5kZXhPZihuYW1lKSA8IDApIHtcbiAgICAgICAgICBkZWxldGUgY2xvbmVbbmFtZV1cbiAgICAgICAgfVxuICAgICAgfSlcbiAgICAgIGRvd25sb2FkTGluay5ocmVmID0gJ2RhdGE6YXR0YWNobWVudC90ZXh0LCcgKyBlbmNvZGVVUklDb21wb25lbnQoSlNPTi5zdHJpbmdpZnkoY2xvbmUpKVxuICAgICAgZG93bmxvYWRMaW5rLmRvd25sb2FkID0gY2xvbmUubmFtZSArICcuanNvbidcbiAgICAgIGRvd25sb2FkTGluay5jbGljaygpXG4gICAgfSlcbiAgICBkb3dubG9hZExpbmsucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChkb3dubG9hZExpbmspXG4gIH0sXG5cbiAgY2xlYW5VUENvbm5lY3Rpb25zIChjaGlwLCBXaXJlQ29ubnMpIHtcbiAgICAvLyBoYW5kbGUgbG9jYWwgY29ubmVjdGlvbnNcbiAgICBsZXQgZGVsZXRlZFdpcmVzID0gW11cbiAgICBPYmplY3Qua2V5cyhXaXJlQ29ubnMpLmZvckVhY2god2lyZU5hbWUgPT4ge1xuICAgICAgaWYgKHdpcmVOYW1lICE9PSAnR1BJTycgJiYgd2lyZU5hbWUgIT09ICdWQ0MnICYmIHdpcmVOYW1lICE9PSAnR05EJyAmJiAhKGNoaXAuYXV0b0Nvbm5lY3Rpb25zICYmIF8uZmluZChjaGlwLmF1dG9Db25uZWN0aW9ucywgeyBwb3J0TmFtZTogd2lyZU5hbWUgfSkgJiYgIU9iamVjdC52YWx1ZXMoY2hpcC5jb25uZWN0aW9ucykuaW5jbHVkZXMod2lyZU5hbWUpKSkge1xuICAgICAgICBsZXQgY29ubnMgPSBXaXJlQ29ubnNbd2lyZU5hbWVdXG4gICAgICAgIGlmIChjb25ucy5sZW5ndGggPD0gMSkge1xuICAgICAgICAgIC8vIGNoZWNrIGlmIHRoaXMgd2lyZSBjb25uZWN0aW5nIHRvIHNwZWNpZmljIEdQSU9cbiAgICAgICAgICBsZXQgZ3BpbyA9IGZhbHNlXG4gICAgICAgICAgaWYgKGNoaXAuY29ubmVjdGlvbnMpIHtcbiAgICAgICAgICAgIGdwaW8gPSBfLmZpbmRLZXkoY2hpcC5jb25uZWN0aW9ucywgZSA9PiBlID09PSB3aXJlTmFtZSlcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKCFncGlvKSB7XG4gICAgICAgICAgICAvLyB0aGlzIGxvY2FsIHdpcmUgb25seSBjb25uZWN0IG9uZSBwb2ludCwgcmVtb3ZlZCBpdFxuICAgICAgICAgICAgZGVsZXRlZFdpcmVzLnB1c2god2lyZU5hbWUpXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNvbm5zLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgIGxldCBjb25uID0gY29ubnNbaV1cbiAgICAgICAgICAgICAgbGV0IGNvbXBpZCA9IGNvbm4uY29tcFxuICAgICAgICAgICAgICBsZXQgcG9ydG5hbWUgPSBjb25uLnBvcnRcbiAgICAgICAgICAgICAgY29uc3QgY29tcG9uZW50ID0gcHJvamVjdC5jaGlwLmZpbmRDb21wb25lbnRCeUlkKGNvbXBpZClcbiAgICAgICAgICAgICAgZGVsZXRlIGNvbXBvbmVudC5jb25uZWN0aW9uc1twb3J0bmFtZV1cbiAgICAgICAgICAgICAgY29uc29sZS5sb2coJ3JlbW92ZWQgbG9jYWwgY29ubmVjdGlvbihzKSBhdCBwb3J0KCcgKyBwb3J0bmFtZSArICcpIHdpcmUoJyArIHdpcmVOYW1lICsgJykgY29tcCBpZCggJyArIGNvbXBpZCArICcpXFxuJylcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KVxuICAgIC8vIGhhbmRsZSBnbG9iYWwgY29ubmVjdGlvbnNcbiAgICBsZXQga2VlcEdsb2JhbENvbm5zID0ge31cbiAgICBPYmplY3Qua2V5cyhjaGlwLmNvbm5lY3Rpb25zKS5mb3JFYWNoKGdwaW8gPT4ge1xuICAgICAgbGV0IHdpcmUgPSBjaGlwLmNvbm5lY3Rpb25zW2dwaW9dXG4gICAgICBpZiAoIWRlbGV0ZWRXaXJlcy5pbmNsdWRlcyh3aXJlKSkge1xuICAgICAgICBrZWVwR2xvYmFsQ29ubnNbZ3Bpb10gPSB3aXJlXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zb2xlLmxvZygncmVtb3ZlZCBnbG9iYWwgY29ubmVjdGlvbiBhdCBHUElPKCcgKyBncGlvICsgJykgd2lyZSggJyArIHdpcmUgKyAnKVxcbicpXG4gICAgICB9XG4gICAgfSlcbiAgICAvLyBnbG9iYWwgY29ubmVjdGlvbnMgaGFzIGJlZW4gY2xlYW4gdXBcbiAgICBjaGlwLmNvbm5lY3Rpb25zID0ga2VlcEdsb2JhbENvbm5zXG4gIH0sXG5cbiAgZ2V0V2lyZXNDb25uZWN0aW9uczogZnVuY3Rpb24gKGNoaXAsIGNvbXAsIFdpcmVDb25ucykge1xuICAgIC8vIGZpbmQgYWxsIHZhbGlkIHdpcmVzIHRoYXQgb2NjdXIgaW4gY29tcG9uZW50IGNvbm5lY3Rpb25zXG4gICAgT2JqZWN0LmtleXMoY29tcC5jb25uZWN0aW9ucykuZm9yRWFjaChwb3J0ID0+IHtcbiAgICAgIGxldCB3aXJlTmFtZSA9IGNvbXAuY29ubmVjdGlvbnNbcG9ydF1cbiAgICAgIGxldCBrZWVwID0gdHJ1ZVxuICAgICAgaWYgKHdpcmVOYW1lICE9PSAnR1BJTycgJiYgd2lyZU5hbWUgIT09ICdWQ0MnICYmIHdpcmVOYW1lICE9PSAnR05EJyAmJiAoY2hpcC5hdXRvQ29ubmVjdGlvbnMgJiYgXy5maW5kKGNoaXAuYXV0b0Nvbm5lY3Rpb25zLCB7IHBvcnROYW1lOiB3aXJlTmFtZSB9KSAmJiAhT2JqZWN0LnZhbHVlcyhjaGlwLmNvbm5lY3Rpb25zKS5pbmNsdWRlcyh3aXJlTmFtZSkpKSB7XG4gICAgICAgIC8vIGNoZWNrIHBvcnQgZXhpc3RlZCBmb3IgbG9jYWwgY29ubmVjdGlvblxuICAgICAgICBsZXQgZm91bmRwb3J0ID0gZmFsc2VcbiAgICAgICAgY29tcC5wb3J0cy5mb3JFYWNoKHB0ID0+IHtcbiAgICAgICAgICBpZiAocHQubmFtZSA9PT0gcG9ydCkge1xuICAgICAgICAgICAgZm91bmRwb3J0ID0gdHJ1ZVxuICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICAgICAgaWYgKCFmb3VuZHBvcnQpIHtcbiAgICAgICAgICAvLyBuZWVkIHRvIHJlbW92ZSB0aGlzIGxvY2FsIGNvbm5lY3Rpb25cbiAgICAgICAgICBkZWxldGUgY29tcC5jb25uZWN0aW9uc1twb3J0XVxuICAgICAgICAgIGNvbnNvbGUubG9nKCdyZW1vdmVkIGxvY2FsIGNvbm5lY3Rpb24gYXQgcG9ydCgnICsgcG9ydCArICcpIHdpcmUoJyArIHdpcmVOYW1lICsgJykgY29tcCBpZCggJyArIGNvbXAuaWQgKyAnKVxcbicpXG4gICAgICAgICAga2VlcCA9IGZhbHNlXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChrZWVwKSB7XG4gICAgICAgIGxldCB3aXJlID0ge31cbiAgICAgICAgd2lyZVsncG9ydCddID0gcG9ydFxuICAgICAgICB3aXJlWydjb21wJ10gPSBjb21wLmlkXG4gICAgICAgIGlmICghV2lyZUNvbm5zW3dpcmVOYW1lXSkge1xuICAgICAgICAgIGxldCBjb25ucyA9IFtdXG4gICAgICAgICAgY29ubnMucHVzaCh3aXJlKVxuICAgICAgICAgIFdpcmVDb25uc1t3aXJlTmFtZV0gPSBjb25uc1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIFdpcmVDb25uc1t3aXJlTmFtZV0ucHVzaCh3aXJlKVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSlcbiAgICByZXR1cm4gV2lyZUNvbm5zXG4gIH0sXG5cbiAgdmFsaWRhdGVDb25uZWN0aW9ucyAocHJvamVjdEZpbGUgPSBudWxsKSB7XG4gICAgbGV0IHRoYXQgPSB0aGlzXG4gICAgbGV0IGNoaXAgPSAocHJvamVjdEZpbGUpID8gcHJvamVjdEZpbGUuY2hpcCA6IHByb2plY3QuY2hpcFxuICAgIGxldCBXaXJlQ29ubnMgPSB7fVxuICAgIGNoaXAuY29tcG9uZW50cy5mb3JFYWNoKGMgPT4ge1xuICAgICAgV2lyZUNvbm5zID0gdGhhdC5nZXRXaXJlc0Nvbm5lY3Rpb25zKGNoaXAsIGMsIFdpcmVDb25ucylcbiAgICB9KVxuICAgIGNoaXAuZGlnaXRhbHMuZm9yRWFjaChjID0+IHtcbiAgICAgIFdpcmVDb25ucyA9IHRoYXQuZ2V0V2lyZXNDb25uZWN0aW9ucyhjaGlwLCBjLCBXaXJlQ29ubnMpXG4gICAgfSlcbiAgICBjaGlwLkxET1MuZm9yRWFjaChjID0+IHtcbiAgICAgIFdpcmVDb25ucyA9IHRoYXQuZ2V0V2lyZXNDb25uZWN0aW9ucyhjaGlwLCBjLCBXaXJlQ29ubnMpXG4gICAgfSlcbiAgICB0aGF0LmNsZWFuVVBDb25uZWN0aW9ucyhjaGlwLCBXaXJlQ29ubnMpXG4gIH0sXG5cbiAgc2V0Q29tcG9uZW50VmVyc2lvblV0aWwgKGNvbXBJZCwgY29tcFR5cGUsIGNvbXBTdWJUeXBlKSB7XG4gICAgY29uc3QgY2hlY2tQb3J0cyA9IChwb3J0TmFtZSwgY29tcG9uZW50KSA9PiB7XG4gICAgICBsZXQgcG9ydHMgPSBjb21wb25lbnQucG9ydHNcbiAgICAgIGxldCBmb3VuZCA9IGZhbHNlXG4gICAgICBwb3J0cy5mb3JFYWNoKHBvcnQgPT4ge1xuICAgICAgICBpZiAocG9ydC5uYW1lID09PSBwb3J0TmFtZSkge1xuICAgICAgICAgIGZvdW5kID0gdHJ1ZVxuICAgICAgICAgIHJldHVybiB0cnVlXG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgICByZXR1cm4gZm91bmRcbiAgICB9XG4gICAgY29uc3QgY2hlY2tXaXJlTmFtZSA9ICh3aXJlTikgPT4ge1xuICAgICAgbGV0IGZvdW5kID0gZmFsc2VcbiAgICAgIGNoaXAuY29tcG9uZW50cy5mb3JFYWNoKGNwID0+IHtcbiAgICAgICAgT2JqZWN0LmtleXMoY3AuY29ubmVjdGlvbnMpLmZvckVhY2gocG9ydCA9PiB7XG4gICAgICAgICAgbGV0IHdpcmVOYW1lID0gY3AuY29ubmVjdGlvbnNbcG9ydF1cbiAgICAgICAgICBpZiAod2lyZU4gPT09IHdpcmVOYW1lKSB7XG4gICAgICAgICAgICBmb3VuZCA9IHRydWVcbiAgICAgICAgICAgIHJldHVybiB0cnVlXG4gICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgfSlcbiAgICAgIHJldHVybiBmb3VuZFxuICAgIH1cbiAgICBsZXQgY29tcCA9IENvbXBvbmVudE1hbmFnZXIubmV3Q29tcG9uZW50KGNvbXBUeXBlLCBwcm9qZWN0LmNoaXAsIGNvbXBTdWJUeXBlKVxuICAgIGNvbXAudmVyc2lvbiA9IGNvbXBTdWJUeXBlXG4gICAgdGhpcy5jbGVhclByb2plY3QodHJ1ZSlcbiAgICBwcm9qZWN0ID0gbmV3IFByb2plY3QocHJvamVjdClcbiAgICBwcm9qZWN0LnNlbGVjdGVkID0gY29tcFxuICAgIHRoaXMudmFsaWRhdGVDb25uZWN0aW9ucygpXG4gICAgY29uc3QgY2hpcCA9IHByb2plY3QuY2hpcFxuICAgIC8vIHJlcGxhY2UgY29tcCBieSBjb21wSWRcbiAgICBjaGlwLmNvbXBvbmVudHMuZm9yRWFjaChjcCA9PiB7XG4gICAgICBpZiAoY3AuaWQgPT09IGNvbXBJZCkge1xuICAgICAgICAvLyB1cGRhdGUgdHlwZSwgY29uZmlnIGFuZCB1cGRhdGUgcGFyYW1ldGVycyBpbml0XG4gICAgICAgIGNwLnZlcnNpb24gPSBjb21wU3ViVHlwZVxuICAgICAgICBjcC5jb25maWcgPSBjb21wLmNvbmZpZ1xuICAgICAgICBjcC5pbml0Q29tcCgpXG5cbiAgICAgICAgLy8gY2hlY2sgcG9ydCBhbmQgY29ubmVjdGlvbnNcbiAgICAgICAgbGV0IGdwaW9zID0gW11cbiAgICAgICAgT2JqZWN0LmtleXMoY3AuY29ubmVjdGlvbnMpLmZvckVhY2gocG9ydCA9PiB7XG4gICAgICAgICAgbGV0IHdpcmVOYW1lID0gY3AuY29ubmVjdGlvbnNbcG9ydF1cbiAgICAgICAgICBsZXQgZm91bmQgPSBjaGVja1BvcnRzKHBvcnQsIGNvbXApXG4gICAgICAgICAgaWYgKCFmb3VuZCkge1xuICAgICAgICAgICAgLy8gbm8gcG9ydCBmb3VuZFxuICAgICAgICAgICAgaWYgKHdpcmVOYW1lICE9PSAnR1BJTycpIHtcbiAgICAgICAgICAgICAgbGV0IGFGb3VuZCA9IGNoZWNrV2lyZU5hbWUod2lyZU5hbWUpXG4gICAgICAgICAgICAgIGlmICghYUZvdW5kKSB7XG4gICAgICAgICAgICAgICAgLy8gdGhpcyB3aXJlTmFtZSBvbmx5IGhhdmUgb25lIHBvcnQgY29ubmVjdCB0byBncGlvLCBuZWVkIHRvIGJlIGRlbGV0ZWRcbiAgICAgICAgICAgICAgICBPYmplY3Qua2V5cyhjaGlwLmNvbm5lY3Rpb25zKS5mb3JFYWNoKGdwaW8gPT4ge1xuICAgICAgICAgICAgICAgICAgbGV0IHdpcmVOID0gY2hpcC5jb25uZWN0aW9uc1tncGlvXVxuICAgICAgICAgICAgICAgICAgaWYgKHdpcmVOID09PSB3aXJlTmFtZSkge1xuICAgICAgICAgICAgICAgICAgICAvLyByZWNvcmQgdGhpcyBncGlvXG4gICAgICAgICAgICAgICAgICAgIGdwaW9zLnB1c2goZ3BpbylcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWVcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgICBpZiAoZ3Bpb3MubGVuZ3RoID4gMCkge1xuICAgICAgICAgIC8vIHJlbW92ZWQgdGhlc2UgY29ubmVjdGlvbnMgZnJvbSBjaGlwLmNvbm5lY3Rpb25zXG4gICAgICAgICAgZ3Bpb3MuZm9yRWFjaChncGlvID0+IHtcbiAgICAgICAgICAgIGRlbGV0ZSBjaGlwLmNvbm5lY3Rpb25zW2dwaW9dXG4gICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pXG4gICAgY2hpcC5kaWdpdGFscy5mb3JFYWNoKGNwID0+IHtcbiAgICAgIGlmIChjcC5pZCA9PT0gY29tcElkKSB7XG4gICAgICAgIC8vIHVwZGF0ZSB0eXBlLCBjb25maWcgYW5kIHVwZGF0ZSBwYXJhbWV0ZXJzIGluaXRcbiAgICAgICAgY3AudmVyc2lvbiA9IGNvbXBTdWJUeXBlXG4gICAgICAgIGNwLmNvbmZpZyA9IGNvbXAuY29uZmlnXG4gICAgICAgIGNwLmluaXRDb21wKClcblxuICAgICAgICAvLyBjaGVjayBwb3J0IGFuZCBjb25uZWN0aW9uc1xuICAgICAgICBsZXQgZ3Bpb3MgPSBbXVxuICAgICAgICBPYmplY3Qua2V5cyhjcC5jb25uZWN0aW9ucykuZm9yRWFjaChwb3J0ID0+IHtcbiAgICAgICAgICBsZXQgd2lyZU5hbWUgPSBjcC5jb25uZWN0aW9uc1twb3J0XVxuICAgICAgICAgIGxldCBmb3VuZCA9IGNoZWNrUG9ydHMocG9ydCwgY29tcClcbiAgICAgICAgICBpZiAoIWZvdW5kKSB7XG4gICAgICAgICAgICAvLyBubyBwb3J0IGZvdW5kXG4gICAgICAgICAgICBpZiAod2lyZU5hbWUgIT09ICdHUElPJykge1xuICAgICAgICAgICAgICBsZXQgYUZvdW5kID0gY2hlY2tXaXJlTmFtZSh3aXJlTmFtZSlcbiAgICAgICAgICAgICAgaWYgKCFhRm91bmQpIHtcbiAgICAgICAgICAgICAgICAvLyB0aGlzIHdpcmVOYW1lIG9ubHkgaGF2ZSBvbmUgcG9ydCBjb25uZWN0IHRvIGdwaW8sIG5lZWQgdG8gYmUgZGVsZXRlZFxuICAgICAgICAgICAgICAgIE9iamVjdC5rZXlzKGNoaXAuY29ubmVjdGlvbnMpLmZvckVhY2goZ3BpbyA9PiB7XG4gICAgICAgICAgICAgICAgICBsZXQgd2lyZU4gPSBjaGlwLmNvbm5lY3Rpb25zW2dwaW9dXG4gICAgICAgICAgICAgICAgICBpZiAod2lyZU4gPT09IHdpcmVOYW1lKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIHJlY29yZCB0aGlzIGdwaW9cbiAgICAgICAgICAgICAgICAgICAgZ3Bpb3MucHVzaChncGlvKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICAgIGlmIChncGlvcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgLy8gcmVtb3ZlZCB0aGVzZSBjb25uZWN0aW9ucyBmcm9tIGNoaXAuY29ubmVjdGlvbnNcbiAgICAgICAgICBncGlvcy5mb3JFYWNoKGdwaW8gPT4ge1xuICAgICAgICAgICAgZGVsZXRlIGNoaXAuY29ubmVjdGlvbnNbZ3Bpb11cbiAgICAgICAgICB9KVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSlcbiAgICBpZiAoY2hpcC5jdXJyZW50U3RhZ2UgPT09ICd0dW5pbmcnKSB7XG4gICAgICBjaGlwLmN1cnJlbnRTdGFnZSA9ICdkZXNpZ24nXG4gICAgfVxuICAgIGxldCBzY3JlZW4gPSBTY3JlZW5NYW5hZ2VyLmdldFNjcmVlbignZGVzaWduJylcbiAgICBpZiAoc2NyZWVuICYmIHNjcmVlbi5pbml0aWFsaXplZCkge1xuICAgICAgLy8gY29uc2lkZXJpbmcgcG9zc2libGUgcGxhdGZvcm0gY2hhbmdlZCwgbmVlZCB0byByZSBidWlsZCBjYXRlZ29yaWVzXG4gICAgICBzY3JlZW4uYnVpbGRDYXRlZ29yaWVzKClcbiAgICAgIHNjcmVlbi5yZWZyZXNoKClcbiAgICB9XG4gICAgLy8gRXZlbnRCdXMuJGVtaXQoJ3Byb2plY3RMb2FkZWQnKVxuICB9LFxuXG4gIHNldFZlcmlsb2dMaWJWZXJzaW9uIChlbCkge1xuICAgIGNvbnN0IGNoaXAgPSBwcm9qZWN0LmNoaXBcbiAgICBjaGlwLnZlcmlsb2dMaWJWZXJzaW9ucyA9ICQoZWwpLnZhbCgpXG4gIH0sXG5cbiAgc2V0dGluZ3MgKCkge1xuICAgIGNvbnN0IGNoaXAgPSBwcm9qZWN0LmNoaXBcblxuICAgIC8vIFRPRE86IGtpbmQgb2YgbGlrZSBhIGhhY2sgbm93XG4gICAgY29uc3QgZGlhbG9nID0gJCh0ZW1wbGF0ZVByb2plY3RTZXR0aW5ncygpKVxuICAgICQoJ2JvZHknKS5hcHBlbmQoZGlhbG9nKVxuICAgIGxldCBtb2RhbCA9ICQoJyNtb2RhbC1zZXR0aW5ncy1mb3JtJylcbiAgICAkKG1vZGFsKS5vbignaGlkZGVuLmJzLm1vZGFsJywgKCkgPT4ge1xuICAgICAgLy8gdGhpcy5zZXREaXJ0eSh0cnVlKVxuICAgICAgaWYgKFNjcmVlbk1hbmFnZXIuY3VycmVudFNjcmVlbi5uYW1lID09PSAndHVuaW5nJykge1xuICAgICAgICBTY3JlZW5NYW5hZ2VyLmN1cnJlbnRTY3JlZW4ucmVmcmVzaFBhcmFtZXRlckZvcm0oZmFsc2UpXG4gICAgICB9XG4gICAgICBTY3JlZW5NYW5hZ2VyLnJlZnJlc2goKVxuICAgIH0pXG4gICAgJCgnI21vZGFsLXNldHRpbmdzLWZvcm0nKS5tb2RhbCh7XG4gICAgICBzaG93OiBmYWxzZSxcbiAgICAgIGtleWJvYXJkOiBmYWxzZSxcbiAgICAgIGJhY2tkcm9wOiAnc3RhdGljJyxcbiAgICB9KVxuICAgICQoJyNtb2RhbC1zZXR0aW5ncy1mb3JtICNjbG9ja3NUYWInKS5odG1sKGJ1aWxkQ2xvY2tGb3JtKGNoaXApKVxuICAgICQoJyNtb2RhbC1zZXR0aW5ncy1mb3JtICNwbGF0Zm9ybUJvTVRhYicpLmh0bWwoQm9NQVBJLmdldFBsYXRmb3JtQm9NSFRNTChjaGlwKSlcbiAgICAkKCcjbW9kYWwtc2V0dGluZ3MtZm9ybScpLm1vZGFsKCdzaG93JylcbiAgICBsZXQgdmVyID0gJ1Byb2R1Y3Rpb24nXG4gICAgaWYgKGNoaXAudmVyaWxvZ0xpYlZlcnNpb25zKSB7XG4gICAgICB2ZXIgPSBjaGlwLnZlcmlsb2dMaWJWZXJzaW9uc1xuICAgIH1cbiAgICAkKCcjdmVyaWxvZ0xpYnJhcnktdmVyc2lvbnMnKS52YWwodmVyKVxuICAgICQoJyNzZXR0aW5nc2J0bicpLmNsaWNrKGZ1bmN0aW9uICgpIHsgVmVyaWZ5Q29tcENsb2NrKGNoaXApIH0pXG4gICAgJChtb2RhbCkuZHJhZ2dhYmxlKHtcbiAgICAgIGhhbmRsZTogJy5tb2RhbC1oZWFkZXIsIC5tb2RhbC1mb290ZXInLFxuICAgIH0pXG4gIH0sXG5cbiAgc2lnbm91dCAoKSB7XG4gICAgdGhpcy5jb25maXJtU2F2ZShmdW5jdGlvbiAoKSB7XG4gICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHsgcmVkaXJlY3QoJ2xvZ2luJykgfSwgNTApXG4gICAgfSlcbiAgfSxcblxuICBnZXRNYW5hZ2VtZW50VG9vbGJhciAoY2FsbGJhY2spIHtcbiAgICBjb25zdCBpdGVtcyA9IFtdXG4gICAgY29uc3QgdGhhdCA9IHRoaXNcbiAgICBpZiAodXNlci5pc0FkbWluKCkpIHtcbiAgICAgIGl0ZW1zLnB1c2goeyB0eXBlOiAnYnV0dG9uJywgaWQ6ICdleGVjdXRlJywgY2FwdGlvbjogJ1NjcmlwdCcsIGljb246ICdmYSBmYS1jb2RlJyB9KVxuICAgIH1cbiAgICBpdGVtcy5wdXNoKHsgdHlwZTogJ2J1dHRvbicsIGlkOiAnZHVwbGljYXRlJywgY2FwdGlvbjogJ0R1cGxpY2F0ZScsIGljb246ICdmYSBmYS1jb3B5JyB9KVxuICAgIGl0ZW1zLnB1c2goeyB0eXBlOiAnYnV0dG9uJywgaWQ6ICdleHBvcnQnLCBjYXB0aW9uOiAnRXhwb3J0JywgaWNvbjogJ2ZhIGZhLWNsb3VkLWRvd25sb2FkJyB9KVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGl0ZW1zLFxuICAgICAgb25DbGljazogYXN5bmMgZnVuY3Rpb24gKHRhcmdldCwgZXZlbnQpIHtcbiAgICAgICAgY29uc3QgZ3JpZCA9IHRoaXMub3duZXJcbiAgICAgICAgY29uc3Qgc2VsZWN0aW9uID0gZ3JpZC5nZXRTZWxlY3Rpb24oKVxuXG4gICAgICAgIHN3aXRjaCAodGFyZ2V0KSB7XG4gICAgICAgICAgY2FzZSAnZXhlY3V0ZSc6XG4gICAgICAgICAgICBpZiAoc2VsZWN0aW9uLmxlbmd0aCA9PT0gMCkgcmV0dXJuXG4gICAgICAgICAgICBjb25zdCBkaWFsb2cgPSAkKGNyZWF0ZU1vZGFsRGlhbG9nKCdleGVjdXRlLXNjcmlwdCcsICdtb2RhbC1zbScpKVxuICAgICAgICAgICAgZGlhbG9nLmZpbmQoJy5tb2RhbC1oZWFkZXIgaDQnKS50ZXh0KCdFbnRlciBTY3JpcHQnKVxuICAgICAgICAgICAgY29uc3QgaHRtbCA9ICc8dGV4dGFyZWEgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIiByb3dzPVwiNVwiIHN0eWxlPVwiZm9udDoxMnB4IFxcJ0NvdXJpZXJcXCdcIj48L3RleHRhcmVhPidcbiAgICAgICAgICAgIGRpYWxvZy5maW5kKCcubW9kYWwtYm9keScpLmh0bWwoaHRtbClcbiAgICAgICAgICAgICQoJ2JvZHknKS5hcHBlbmQoZGlhbG9nKVxuICAgICAgICAgICAgc2V0RGlhbG9nQnV0dG9uQWN0aW9uKGRpYWxvZywgJ0V4ZWN1dGUnLCAoKSA9PiB7XG4gICAgICAgICAgICAgIGNvbnN0IHNjcmlwdCA9IGRpYWxvZy5maW5kKCd0ZXh0YXJlYScpLnZhbCgpXG4gICAgICAgICAgICAgIGxldCByZWNvcmRcbiAgICAgICAgICAgICAgY29uc3QgZiA9IChzY3JpcHQpID0+IHtcbiAgICAgICAgICAgICAgICAvLyB2YXIgY29uZmlnID0gdGhpcy5jb25maWdcbiAgICAgICAgICAgICAgICBldmFsKHNjcmlwdClcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHNlbGVjdGlvbi5mb3JFYWNoKHJlY2lkID0+IHtcbiAgICAgICAgICAgICAgICAgIHJlY29yZCA9IGdyaWQucmVjb3Jkcy5maW5kKHIgPT4gci5yZWNpZCA9PT0gcmVjaWQpXG4gICAgICAgICAgICAgICAgICBpZiAocmVjb3JkKSB7XG4gICAgICAgICAgICAgICAgICAgIGYuY2FsbChyZWNvcmQsIHNjcmlwdClcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFyZWNvcmQuY2hhbmdlcykge1xuICAgICAgICAgICAgICAgICAgICAgIHJlY29yZC5jaGFuZ2VzID0ge31cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZWNvcmQuY2hhbmdlcy5uYW1lID0gcmVjb3JkLm5hbWVcbiAgICAgICAgICAgICAgICAgICAgcmVjb3JkLmNoYW5nZXMuY29uZmlnID0gcmVjb3JkLmNvbmZpZ1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgZ3JpZC5yZWZyZXNoKClcbiAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgIGRlYnVnKGUpXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICByZXR1cm5cbiAgICAgICAgICBjYXNlICdkdXBsaWNhdGUnOlxuICAgICAgICAgICAgaWYgKHNlbGVjdGlvbi5sZW5ndGggPT09IDApIHJldHVyblxuICAgICAgICAgICAgc2hvd0NvbmZpcm0oJ0FyZSB5b3Ugc3VyZSB5b3Ugd2FudCB0byBjcmVhdGUgJyArIHNlbGVjdGlvbi5sZW5ndGggKyAnIG5ldyBwcm9qZWN0cz8nLCBudWxsLFxuICAgICAgICAgICAgICB7IG5hbWU6ICdEdXBsaWNhdGUnLCBjbGFzc05hbWU6ICdidG4tZGFuZ2VyJyB9LFxuICAgICAgICAgICAgICBhc3luYyBjb25maXJtID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoY29uZmlybSkge1xuICAgICAgICAgICAgICAgICAgY29uc3QgY29waWVkUHJvamVjdHMgPSBbXVxuICAgICAgICAgICAgICAgICAgY29uc3QgbmFtZXMgPSBncmlkLnJlY29yZHMubWFwKHIgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4geyBuYW1lOiByLmNoYW5nZXMgJiYgci5jaGFuZ2VzLm5hbWUgPyByLmNoYW5nZXMubmFtZSA6IHIubmFtZSwgdXNlcklEOiByLnVzZXJJRCB9XG4gICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgc2VsZWN0aW9uLmZvckVhY2gocmVjaWQgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCByZWNvcmQgPSBncmlkLnJlY29yZHMuZmluZChyID0+IHIucmVjaWQgPT09IHJlY2lkKVxuICAgICAgICAgICAgICAgICAgICBjb25zdCBuZXdOYW1lID0gdGhhdC5nZXRNb2RpZmllZFByb2plY3ROYW1lKHJlY29yZC5uYW1lLCBudWxsLCBuYW1lcylcbiAgICAgICAgICAgICAgICAgICAgY29waWVkUHJvamVjdHMucHVzaCh7IHByb2plY3RJRDogJ04nICsgcmVjb3JkLnJlY2lkLCBuYW1lOiBuZXdOYW1lLCBjb25maWc6IHJlY29yZC5jb25maWcgPyBfLmNsb25lRGVlcChyZWNvcmQuY29uZmlnKSA6IG51bGwsIHVzZXJJRDogcmVjb3JkLnVzZXJJRCB9KVxuICAgICAgICAgICAgICAgICAgICBuYW1lcy5wdXNoKHsgbmFtZTogbmV3TmFtZSwgdXNlcklEOiByZWNvcmQudXNlcklEIH0pXG4gICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgYXdhaXQgdGhhdC5jcmVhdGVQcm9qZWN0cyhjb3BpZWRQcm9qZWN0cylcbiAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKGdyaWQsIHRhcmdldCwgY29waWVkUHJvamVjdHMpXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApXG4gICAgICAgICAgICByZXR1cm5cbiAgICAgICAgICBjYXNlICdleHBvcnQnOlxuICAgICAgICAgICAgaWYgKHNlbGVjdGlvbi5sZW5ndGggPT09IDApIHJldHVyblxuICAgICAgICAgICAgY29uc3QgcHJvamVjdHMgPSBbXVxuICAgICAgICAgICAgbGV0IHJlY29yZFxuICAgICAgICAgICAgc2VsZWN0aW9uLmZvckVhY2gocmVjaWQgPT4ge1xuICAgICAgICAgICAgICByZWNvcmQgPSBncmlkLnJlY29yZHMuZmluZChyID0+IHIucmVjaWQgPT09IHJlY2lkKVxuICAgICAgICAgICAgICBwcm9qZWN0cy5wdXNoKHJlY29yZClcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB0aGF0LmV4cG9ydFByb2plY3RzKHByb2plY3RzKVxuICAgICAgICB9XG4gICAgICB9LFxuICAgIH1cbiAgfSxcblxuICBtYW5hZ2VQcm9qZWN0cyAoKSB7XG4gICAgY29uc3QgdGhhdCA9IHRoaXNcbiAgICBjb25zdCBnZXRSZWNvcmRzID0gKCkgPT4ge1xuICAgICAgcmV0dXJuIHByb2plY3RzLm1hcChwID0+IHtcbiAgICAgICAgY29uc3Qgb3JkZXIgPSB1c2VyLnByb2plY3RvcmRlci5pbmRleE9mKHAucHJvamVjdElEKSArIDFcbiAgICAgICAgbGV0IGFkZXZpY2UgPSBwLmNvbmZpZyA/IHAuY29uZmlnLmRldmljZSA6IG51bGxcbiAgICAgICAgaWYgKHAuY29uZmlnICYmIHAuY29uZmlnLmNoaXBzKSB7XG4gICAgICAgICAgYWRldmljZSA9IF8ubWFwKHAuY29uZmlnLmNoaXBzLCAnZGV2aWNlJykuam9pbigpXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHJlY2lkOiBwLnByb2plY3RJRCxcbiAgICAgICAgICBuYW1lOiBwLm5hbWUsXG4gICAgICAgICAgbW9kaWZpY2F0aW9uX3RpbWU6IHAubW9kaWZpY2F0aW9uX3RpbWUsXG4gICAgICAgICAgY3JlYXRpb25fdGltZTogcC5jcmVhdGlvbl90aW1lLFxuICAgICAgICAgIGRldmljZTogYWRldmljZSxcbiAgICAgICAgICBjb25maWc6IHAuY29uZmlnLFxuICAgICAgICAgIG9yZGVyLFxuICAgICAgICB9XG4gICAgICB9KVxuICAgIH1cbiAgICBjb25zdCBkaWFsb2cgPSAkKHRlbXBsYXRlTWFuYWdlUHJvamVjdHMoKSlcbiAgICAkKCdib2R5JykuYXBwZW5kKGRpYWxvZylcbiAgICBpZiAoIXcydWlbJ3Byb2plY3RzLWdyaWQnXSkge1xuICAgICAgJCgnI3Byb2plY3RzLWdyaWQnKS53MmdyaWQoe1xuICAgICAgICBuYW1lOiAncHJvamVjdHMtZ3JpZCcsXG4gICAgICAgIHdpZHRoOiAnMTAwJScsXG4gICAgICAgIGhlaWdodDogJzEwMCUnLFxuICAgICAgICBzaG93OiB7XG4gICAgICAgICAgdG9vbGJhcjogdHJ1ZSxcbiAgICAgICAgICBmb290ZXI6IHRydWUsXG4gICAgICAgICAgdG9vbGJhckRlbGV0ZTogdHJ1ZSxcbiAgICAgICAgICBjb2x1bW5IZWFkZXJzOiB0cnVlLFxuICAgICAgICAgIHNlbGVjdENvbHVtbjogdHJ1ZSxcbiAgICAgICAgfSxcbiAgICAgICAgbXVsdGlTZWxlY3Q6IHRydWUsXG4gICAgICAgIHJlb3JkZXJSb3dzOiBmYWxzZSxcbiAgICAgICAgdG9vbGJhcjogdGhpcy5nZXRNYW5hZ2VtZW50VG9vbGJhcigoZ3JpZCwgYWN0aW9uLCBkYXRhKSA9PiB7XG4gICAgICAgICAgaWYgKGFjdGlvbiA9PT0gJ2R1cGxpY2F0ZScpIHtcbiAgICAgICAgICAgIGRhdGEuZm9yRWFjaCgocCkgPT4ge1xuICAgICAgICAgICAgICBsZXQgYWRldmljZSA9IHAuY29uZmlnID8gcC5jb25maWcuZGV2aWNlIDogbnVsbFxuICAgICAgICAgICAgICBpZiAocC5jb25maWcgJiYgcC5jb25maWcuY2hpcHMpIHtcbiAgICAgICAgICAgICAgICBhZGV2aWNlID0gXy5tYXAocC5jb25maWcuY2hpcHMsICdkZXZpY2UnKS5qb2luKClcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBncmlkLnJlY29yZHMucHVzaCh7XG4gICAgICAgICAgICAgICAgcmVjaWQ6IHAucHJvamVjdElELFxuICAgICAgICAgICAgICAgIG5hbWU6IHAubmFtZSxcbiAgICAgICAgICAgICAgICBtb2RpZmljYXRpb25fdGltZTogcC5tb2RpZmljYXRpb25fdGltZSxcbiAgICAgICAgICAgICAgICBkZXZpY2U6IGFkZXZpY2UsXG4gICAgICAgICAgICAgICAgY29uZmlnOiBwLmNvbmZpZyxcbiAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICBncmlkLnRvdGFsID0gZ3JpZC5yZWNvcmRzLmxlbmd0aFxuICAgICAgICAgICAgZ3JpZC5zZWxlY3ROb25lKClcbiAgICAgICAgICAgIGdyaWQucmVmcmVzaCgpXG4gICAgICAgICAgICB0aGlzLnJlZnJlc2hQcm9qZWN0c01lbnUoKVxuICAgICAgICAgIH1cbiAgICAgICAgfSksXG4gICAgICAgIGNvbHVtbnM6IHRvb2xCYXJDb2xvdW1zLFxuICAgICAgICBvbkNoYW5nZTogZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICAgICAgaWYgKGV2ZW50LmNvbHVtbiA9PT0gMCkge1xuICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKVxuICAgICAgICAgICAgaWYgKHRoaXMucmVjb3Jkc1tldmVudC5pbmRleF0ub3JkZXIgPj0gZXZlbnQudmFsdWVfbmV3KSB7XG4gICAgICAgICAgICAgIHRoaXMucmVjb3Jkc1tldmVudC5pbmRleF0ub3JkZXIgPSBldmVudC52YWx1ZV9uZXcgLSAwLjVcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHRoaXMucmVjb3Jkc1tldmVudC5pbmRleF0ub3JkZXIgPSBldmVudC52YWx1ZV9uZXcgKyAwLjVcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuc29ydCgnb3JkZXInLCAnYXNjJylcbiAgICAgICAgICAgIF8uZm9yRWFjaCh0aGlzLnJlY29yZHMsIGZ1bmN0aW9uIChwLCBpbmRleCkge1xuICAgICAgICAgICAgICBwLm9yZGVyID0gaW5kZXggKyAxXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgdGhpcy5yZWZyZXNoKClcbiAgICAgICAgICB9IGVsc2UgaWYgKGV2ZW50LmNvbHVtbiA9PT0gMSkge1xuICAgICAgICAgICAgbGV0IG5hbWVzID0gXy5tYXAodGhpcy5yZWNvcmRzLCBmdW5jdGlvbiAocikge1xuICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIG5hbWU6IHIuY2hhbmdlcyAmJiByLmNoYW5nZXMubmFtZSA/IHIuY2hhbmdlcy5uYW1lIDogci5uYW1lLFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgbGV0IG1vZGlmeU5hbWUgPSBldmVudC52YWx1ZV9uZXdcbiAgICAgICAgICAgIC8vIGNoZWNrIG1vZGlmeU5hbWUgbGVhZ2FsXG4gICAgICAgICAgICBsZXQgdmFsaWROYW1lRXhwID0gL15bQS1aX11bMC05QS1aX10qJC9pXG4gICAgICAgICAgICBsZXQgblZhbGlkID0gdmFsaWROYW1lRXhwLnRlc3QobW9kaWZ5TmFtZSlcbiAgICAgICAgICAgIGlmICghblZhbGlkKSB7XG4gICAgICAgICAgICAgIC8vIHJlcG9ydCBhIGVycm9yXG4gICAgICAgICAgICAgIGlmIChtb2RpZnlOYW1lLm1hdGNoKC9eXFxkLykpIHtcbiAgICAgICAgICAgICAgICBzaG93TW9kYWxEaWFsb2coJ1JlbmFtZSBGYWlsZWQnLCAnUHJvamVjdCBuYW1lIGNhbiBub3Qgc3RhcnQgd2l0aCBudW1iZXIuJylcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzaG93TW9kYWxEaWFsb2coJ1JlbmFtZSBGYWlsZWQnLCAnUHJvamVjdCBuYW1lIE9OTFkgaW5jbHVkZXMgQS4uWiwgYS4ueiwgMC4uOSwgXycpXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgLy8gZ3JpZCByZWZyZXNoXG4gICAgICAgICAgICAgIGNvbnN0IGdyaWQgPSB3MnVpWydwcm9qZWN0cy1ncmlkJ11cbiAgICAgICAgICAgICAgdGhpcy5yZWNvcmRzID0gZ2V0UmVjb3JkcygpXG4gICAgICAgICAgICAgIGdyaWQucmVmcmVzaCgpXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBldmVudC52YWx1ZV9uZXcgPSB0aGF0LmdldE1vZGlmaWVkUHJvamVjdE5hbWUobW9kaWZ5TmFtZSwgZXZlbnQuaW5kZXgsIG5hbWVzKVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgb25EZWxldGU6IGFzeW5jIGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgICAgIGV2ZW50LmZvcmNlID0gdHJ1ZVxuICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KClcbiAgICAgICAgICBjb25zdCBncmlkID0gdzJ1aVsncHJvamVjdHMtZ3JpZCddXG4gICAgICAgICAgbGV0IHNlbGVjdGVkID0gZ3JpZC5nZXRTZWxlY3Rpb24oKVxuICAgICAgICAgIGlmIChzZWxlY3RlZC5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBjb25zdCBkYXRhID0gYXdhaXQgdGhhdC5jb25maXJtRGVsZXRlKHNlbGVjdGVkKVxuICAgICAgICAgICAgaWYgKGRhdGEpIHtcbiAgICAgICAgICAgICAgaWYgKHByb2plY3QgJiYgc2VsZWN0ZWQuaW5kZXhPZihwcm9qZWN0LnByb2plY3RJRCkgPj0gMCkge1xuICAgICAgICAgICAgICAgIHRoYXQuY2xlYXJQcm9qZWN0KClcbiAgICAgICAgICAgICAgICBwcm9qZWN0ID0gbnVsbFxuICAgICAgICAgICAgICAgIFNjcmVlbk1hbmFnZXIuc2hvd1NjcmVlbigpXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgdGhpcy5yZWNvcmRzID0gZ2V0UmVjb3JkcygpXG4gICAgICAgICAgICAgIHRoaXMudG90YWwgPSB0aGlzLnJlY29yZHMubGVuZ3RoXG4gICAgICAgICAgICAgIGdyaWQuc2VsZWN0Tm9uZSgpXG4gICAgICAgICAgICAgIGdyaWQucmVmcmVzaCgpXG4gICAgICAgICAgICAgIHRoYXQucmVmcmVzaFByb2plY3RzTWVudSgpXG4gICAgICAgICAgICAgIHNob3dNb2RhbERpYWxvZygnU3VjY2VzcycsICdQcm9qZWN0cyBkZWxldGVkLicpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgfSlcbiAgICAgIGNvbnN0IGNvbnRlbnQgPSBkaWFsb2cuZmluZCgnLm1vZGFsLWNvbnRlbnQnKVxuICAgICAgY29udGVudC5yZXNpemFibGUoe30pXG4gICAgICBjb250ZW50Lm9uKCdyZXNpemUnLCBmdW5jdGlvbiAoZXZlbnQsIHVpKSB7XG4gICAgICAgIGRpYWxvZy5maW5kKCcjcHJvamVjdHMtZ3JpZCcpLmNzcygnaGVpZ2h0JywgKHVpLnNpemUuaGVpZ2h0IC0gMTUxKSArICdweCcpXG4gICAgICAgIHcydWlbJ3Byb2plY3RzLWdyaWQnXS5yZXNpemUoKVxuICAgICAgICB3MnVpWydwcm9qZWN0cy1ncmlkJ10ucmVmcmVzaCgpXG4gICAgICB9KVxuICAgICAgZGlhbG9nLmZpbmQoJy5tb2RhbC1kaWFsb2cnKS5kcmFnZ2FibGUoe1xuICAgICAgICBoYW5kbGU6ICcubW9kYWwtaGVhZGVyJyxcbiAgICAgIH0pXG4gICAgfVxuICAgIHNldERpYWxvZ0J1dHRvbkFjdGlvbihkaWFsb2csIG51bGwsIGFzeW5jIChldmVudCkgPT4ge1xuICAgICAgY29uc3QgZ3JpZCA9IHcydWlbJ3Byb2plY3RzLWdyaWQnXVxuICAgICAgY29uc3QgY2hhbmdlcyA9IGdyaWQuZ2V0Q2hhbmdlcygpXG4gICAgICBjb25zdCBjaGFuZ2VkUHJvamVjdHMgPSBbXVxuICAgICAgbGV0IHJlbG9hZCA9IGZhbHNlXG4gICAgICBsZXQgcmVjb3JkcyA9IGdldFJlY29yZHMoKVxuICAgICAgY2hhbmdlcy5mb3JFYWNoKChjaGFuZ2UpID0+IHtcbiAgICAgICAgaWYgKGNoYW5nZS5jb25maWcgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHJlY29yZHMuZm9yRWFjaChyZWMgPT4ge1xuICAgICAgICAgICAgaWYgKHJlYy5yZWNpZCA9PT0gY2hhbmdlLnJlY2lkKSB7XG4gICAgICAgICAgICAgIGNoYW5nZS5jb25maWcgPSByZWMuY29uZmlnXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgICAgICBjaGFuZ2VkUHJvamVjdHMucHVzaCh7XG4gICAgICAgICAgcHJvamVjdElEOiBjaGFuZ2UucmVjaWQsXG4gICAgICAgICAgbmFtZTogY2hhbmdlLm5hbWUsXG4gICAgICAgICAgY29uZmlnOiBjaGFuZ2UuY29uZmlnLFxuICAgICAgICB9KVxuICAgICAgICBpZiAoY2hhbmdlLmNvbmZpZyAmJiBwcm9qZWN0ICYmIGNoYW5nZS5yZWNpZCA9PT0gcHJvamVjdC5wcm9qZWN0SUQpIHtcbiAgICAgICAgICByZWxvYWQgPSB0cnVlXG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgICBzaG93QnVzeSh0cnVlLCAnVXBkYXRpbmcgUHJvamVjdHMuLi4nKVxuICAgICAgYXdhaXQgdGhhdC5zYXZlUHJvamVjdHMoY2hhbmdlZFByb2plY3RzKVxuICAgICAgaGlkZUJ1c3koKVxuICAgICAgLy8gdXBkYXRlIHByb2plY3RzIGZvciB0aGVzZSBwcm9qZWN0IGluIGNoYW5nZWRQcm9qZWN0c1xuICAgICAgY2hhbmdlZFByb2plY3RzLmZvckVhY2gocHJqID0+IHtcbiAgICAgICAgbGV0IHByb2plY3RUZW1wID0gcHJvamVjdHMuZmluZChwID0+IHAucHJvamVjdElEID09PSBwcmoucHJvamVjdElEKVxuICAgICAgICBwcm9qZWN0VGVtcC5uYW1lID0gcHJqLm5hbWVcbiAgICAgIH0pXG4gICAgICBsZXQgb3JkZXIgPSB1c2VyLnByb2plY3RvcmRlclxuICAgICAgcHJvamVjdHMuc29ydChmdW5jdGlvbiAoYSwgYikge1xuICAgICAgICByZXR1cm4gb3JkZXIuaW5kZXhPZihhLnByb2plY3RJRCkgLSBvcmRlci5pbmRleE9mKGIucHJvamVjdElEKVxuICAgICAgfSlcbiAgICAgIHRoYXQucmVmcmVzaFByb2plY3RzTWVudSgpXG4gICAgICBpZiAocmVsb2FkKSB7XG4gICAgICAgIHRoaXMubG9hZFByb2plY3QocHJvamVjdC5wcm9qZWN0SUQsIGZhbHNlKVxuICAgICAgfVxuICAgICAgc2hvd01vZGFsRGlhbG9nKCdTdWNjZXNzJywgJ1Byb2plY3RzIHNhdmVkLicpXG4gICAgfSwgdHJ1ZSlcbiAgICBkaWFsb2cub24oJ2hpZGRlbi5icy5tb2RhbCcsIGFzeW5jICgpID0+IHtcbiAgICAgIC8vIHNob3dCdXN5KHRydWUsIFwiVXBkYXRpbmcgUHJvamVjdHMgb3JkZXJzLi4uXCIpO1xuICAgICAgaWYgKHVzZXIucHJvamVjdE9yZGVyKSB7XG4gICAgICAgIGRlbGV0ZSB1c2VyLnByb2plY3RPcmRlclxuICAgICAgfVxuICAgICAgbGV0IHJlY29yZHMgPSB3MnVpWydwcm9qZWN0cy1ncmlkJ10ucmVjb3Jkc1xuICAgICAgbGV0IG9yZGVyID0gXy5tYXAocmVjb3JkcywgJ3JlY2lkJylcbiAgICAgIHVzZXIucHJvamVjdG9yZGVyID0gb3JkZXJcbiAgICAgIGlmICh1c2VyLmNvbmZpZykge1xuICAgICAgICAvLyBzYXZlIHByb2plY3RvcmRlciB0byB1c2VyIERCXG4gICAgICAgIHVzZXIuY29uZmlnLnByb2plY3RvcmRlciA9IG9yZGVyXG4gICAgICB9XG4gICAgICBhd2FpdCB0aGlzLnNhdmVVc2VyQ29uZmlnKHVzZXIpXG4gICAgICAvLyBoaWRlQnVzeSgpXG4gICAgICAvLyBzb3J0IHVzZXIucHJvamVjdCBiYXNlZCBvbiBvcmRlciBpbiBjb25maWdcbiAgICAgIHByb2plY3RzLnNvcnQoKGEsIGIpID0+IHtcbiAgICAgICAgcmV0dXJuIG9yZGVyLmluZGV4T2YoYS5wcm9qZWN0SUQpIC0gb3JkZXIuaW5kZXhPZihiLnByb2plY3RJRClcbiAgICAgIH0pXG4gICAgICB0aGlzLnJlZnJlc2hQcm9qZWN0c01lbnUoKVxuICAgICAgLy8gRXZlbnRCdXMuJGVtaXQoJ3Byb2plY3RMb2FkZWQnKVxuICAgICAgdzJ1aVsncHJvamVjdHMtZ3JpZCddLmRlc3Ryb3koKVxuICAgICAgLy8gJCgnI3Byb2plY3RfbmFtZScpLnRleHQoJ1Byb2plY3RzJylcbiAgICB9KVxuICAgIGRpYWxvZy5vbignc2hvd24uYnMubW9kYWwnLCAoKSA9PiB7XG4gICAgICBjb25zdCBncmlkID0gdzJ1aVsncHJvamVjdHMtZ3JpZCddXG4gICAgICBncmlkLnJlc2l6ZSgpXG4gICAgICBncmlkLnJlY29yZHMgPSBnZXRSZWNvcmRzKClcbiAgICAgIGdyaWQuc29ydCgnb3JkZXInLCAnYXNjJylcbiAgICAgIGdyaWQucmVjb3Jkcy5mb3JFYWNoKChwLCBpbmRleCkgPT4ge1xuICAgICAgICBwLm9yZGVyID0gaW5kZXggKyAxXG4gICAgICB9KVxuICAgICAgdzJ1aVsncHJvamVjdHMtZ3JpZCddLnJlZnJlc2goKVxuICAgIH0pXG4gIH0sXG5cbiAgY2xvc2UgKCkge1xuICAgIGlmICghcHJvamVjdCkgcmV0dXJuXG4gICAgdGhpcy5jb25maXJtU2F2ZShhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB7IHN1Y2Nlc3MsIGRhdGEgfSA9IGF3YWl0IHNlbmRDb21tYW5kKCcvcHJvamVjdCcsIHtcbiAgICAgICAgbWV0aG9kOiAnY2xvc2VQcm9qZWN0JyxcbiAgICAgICAgaWQ6IHByb2plY3QucHJvamVjdElELFxuICAgICAgfSlcbiAgICAgIGlmICghc3VjY2VzcykgcmV0dXJuXG4gICAgICBpZiAoIWRhdGEpIHJldHVyblxuICAgICAgdGhpcy5jbGVhclByb2plY3QoKVxuICAgICAgcHJvamVjdCA9IG51bGxcbiAgICAgIHRoaXMucmVmcmVzaFByb2plY3RzTWVudSgpXG4gICAgICBTY3JlZW5NYW5hZ2VyLnNob3dTY3JlZW4oKVxuICAgIH0pXG4gIH0sXG5cbiAgc2F2ZUFzICAoKSB7XG4gICAgaWYgKCFwcm9qZWN0KSByZXR1cm5cbiAgICBsZXQgZGlhbG9nID0gJCh0ZW1wbGF0ZVNhdmVBc1Byb2plY3QoKSlcbiAgICAkKCdib2R5JykuYXBwZW5kKGRpYWxvZylcblxuICAgIHNldERpYWxvZ0J1dHRvbkFjdGlvbihkaWFsb2csICdTYXZlJywgYXN5bmMgKGV2ZW50KSA9PiB7XG4gICAgICBsZXQgaW5wdXQgPSBkaWFsb2cuZmluZCgnaW5wdXQnKVxuICAgICAgbGV0IG5WYWxpZCA9IGZhbHNlXG4gICAgICBsZXQgbmFtZSA9ICQoaW5wdXQpLnZhbCgpXG4gICAgICBsZXQgdmFsaWROYW1lRXhwID0gL15bQS1aX11bMC05QS1aX10qJC9pXG4gICAgICBuVmFsaWQgPSB2YWxpZE5hbWVFeHAudGVzdChuYW1lKVxuICAgICAgaWYgKCFuVmFsaWQpIHtcbiAgICAgICAgaWYgKCQoaW5wdXQpLnZhbCgpLm1hdGNoKC9eXFxkLykpIHtcbiAgICAgICAgICBkaWFsb2cuZmluZCgnLm1vZGFsLWhlYWRlciBzbWFsbCBzcGFuJykudGV4dCgnUHJvamVjdCBuYW1lIGNhbiBub3Qgc3RhcnQgd2l0aCBudW1iZXInKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGRpYWxvZy5maW5kKCcubW9kYWwtaGVhZGVyIHNtYWxsIHNwYW4nKS50ZXh0KCdQcm9qZWN0IG5hbWUgT05MWSBpbmNsdWRlcyBBLi5aLCBhLi56LCAwLi45LCBfJylcbiAgICAgICAgfVxuICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKVxuICAgICAgfSBlbHNlIGlmICghdGhpcy5jaGVja1Byb2plY3ROYW1lKGlucHV0WzBdKSkge1xuICAgICAgICBkaWFsb2cuZmluZCgnLm1vZGFsLWhlYWRlciBzbWFsbCBzcGFuJykudGV4dCgnUHJvamVjdCBuYW1lIGhhcyBiZWVuIHRha2VuJylcbiAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IHsgc3VjY2VzcywgZGF0YSB9ID0gYXdhaXQgc2VuZENvbW1hbmQoJy9wcm9qZWN0Jywge1xuICAgICAgICAgIG1ldGhvZDogJ25ldycsXG4gICAgICAgICAgbmFtZTogaW5wdXQudmFsKCksXG4gICAgICAgICAgY29uZmlnOiBKU09OLnN0cmluZ2lmeShwcm9qZWN0LmNvbmZpZyksXG4gICAgICAgIH0pXG4gICAgICAgIGlmICghc3VjY2VzcykgcmV0dXJuXG4gICAgICAgIGlmICghZGF0YSkgcmV0dXJuXG4gICAgICAgIHByb2plY3RzLnB1c2goZGF0YSlcbiAgICAgICAgdGhpcy5yZWZyZXNoUHJvamVjdHNNZW51KClcbiAgICAgICAgdGhpcy5sb2FkUHJvamVjdChkYXRhLnByb2plY3RJRCwgZmFsc2UpXG4gICAgICB9XG4gICAgfSwgdHJ1ZSlcbiAgfSxcbiAgY3JlYXRlTW9kdWxhciAoKSB7XG4gICAgaWYgKCFwcm9qZWN0KSByZXR1cm5cbiAgICBsZXQgZGlhbG9nID0gJCh0ZW1wbGF0ZU1vZHVsYXJQcm9qZWN0KCkpXG4gICAgJCgnYm9keScpLmFwcGVuZChkaWFsb2cpXG4gICAgY29uc3QgY2hlY2tOYW1lID0gKG1OYW1lKSA9PiB7XG4gICAgICBpZiAocHJvamVjdC5jb25maWcuY3VzdG9tQ29tcG9uZW50cykge1xuICAgICAgICBpZiAoXy5maW5kKHByb2plY3QuY29uZmlnLmN1c3RvbUNvbXBvbmVudHMsIHsgaWQ6ICdjdXN0b21fJyArIG1OYW1lIH0pKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiB0cnVlXG4gICAgfVxuICAgIHNldERpYWxvZ0J1dHRvbkFjdGlvbihkaWFsb2csICdDcmVhdGUgTW9kdWxlJywgYXN5bmMgKGV2ZW50KSA9PiB7XG4gICAgICBsZXQgaW5wdXQgPSBkaWFsb2cuZmluZCgnaW5wdXQnKVxuICAgICAgbGV0IG5WYWxpZCA9IGZhbHNlXG4gICAgICBsZXQgbmFtZSA9ICQoaW5wdXQpLnZhbCgpXG4gICAgICBsZXQgdmFsaWROYW1lRXhwID0gL15bQS1aX11bMC05QS1aX10qJC9pXG4gICAgICBuVmFsaWQgPSB2YWxpZE5hbWVFeHAudGVzdChuYW1lKVxuICAgICAgaWYgKCFuVmFsaWQpIHtcbiAgICAgICAgaWYgKG5hbWUubWF0Y2goL15cXGQvKSkge1xuICAgICAgICAgIGRpYWxvZy5maW5kKCcubW9kYWwtaGVhZGVyIHNtYWxsIHNwYW4nKS50ZXh0KCdNb2R1bGFyIG5hbWUgY2FuIG5vdCBzdGFydCB3aXRoIG51bWJlcicpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZGlhbG9nLmZpbmQoJy5tb2RhbC1oZWFkZXIgc21hbGwgc3BhbicpLnRleHQoJ01vZHVsYXIgbmFtZSBPTkxZIGluY2x1ZGVzIEEuLlosIGEuLnosIDAuLjksIF8nKVxuICAgICAgICB9XG4gICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXG4gICAgICB9IGVsc2UgaWYgKCFjaGVja05hbWUobmFtZSkpIHtcbiAgICAgICAgZGlhbG9nLmZpbmQoJy5tb2RhbC1oZWFkZXIgc21hbGwgc3BhbicpLnRleHQoJ01vZHVsYXIgbmFtZSBoYXMgYmVlbiB0YWtlbicpXG4gICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmltcG9ydERlZmF1bHRNb2R1bGFyKG5hbWUpXG4gICAgICB9XG4gICAgfSwgdHJ1ZSlcbiAgfSxcblxuICBnZXRNb2R1bGFyUG9ydHMgKCkge1xuICAgIGxldCBjaGlwID0gcHJvamVjdC5jaGlwXG4gICAgbGV0IGV4cFBvcnRzID0gW11cbiAgICBsZXQgV2lyZUNvbm5zID0ge31cbiAgICBjaGlwLmRpZ2l0YWxzLmZvckVhY2goYyA9PiB7XG4gICAgICBXaXJlQ29ubnMgPSB0aGlzLmdldFdpcmVzQ29ubmVjdGlvbnMoY2hpcCwgYywgV2lyZUNvbm5zKVxuICAgIH0pXG4gICAgT2JqZWN0LmtleXMoV2lyZUNvbm5zKS5mb3JFYWNoKHdpcmVOYW1lID0+IHtcbiAgICAgIGlmICh3aXJlTmFtZSAhPT0gJ0dQSU8nICYmIHdpcmVOYW1lICE9PSAnVkNDJyAmJiB3aXJlTmFtZSAhPT0gJ0dORCcpIHtcbiAgICAgICAgbGV0IGNvbm5zID0gV2lyZUNvbm5zW3dpcmVOYW1lXVxuICAgICAgICAvLyBjaGVjayBpZiB0aGlzIHdpcmUgY29ubmVjdGluZyB0byBzcGVjaWZpYyBHUElPXG4gICAgICAgIGxldCBncGlvID0gZmFsc2VcbiAgICAgICAgaWYgKGNoaXAuY29ubmVjdGlvbnMpIHtcbiAgICAgICAgICBncGlvID0gXy5maW5kS2V5KGNoaXAuY29ubmVjdGlvbnMsIGUgPT4gZSA9PT0gd2lyZU5hbWUpXG4gICAgICAgIH1cbiAgICAgICAgaWYgKGdwaW8pIHtcbiAgICAgICAgICBsZXQgZGlzcGxheVdpcmVOYW1lID0gJydcbiAgICAgICAgICBjb25zdCBwa2cgPSBjaGlwLmRldmljZS5wYWNrYWdlXG4gICAgICAgICAgaWYgKHBrZy5tb2R1bGFyUGluTWFwLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIGNvbnN0IHBrZyA9IGNoaXAuZGV2aWNlLnBhY2thZ2VcbiAgICAgICAgICAgIGxldCBpbmRleCA9IF8uZmluZEluZGV4KHBrZy5tb2R1bGFyUGluTWFwLCB7XG4gICAgICAgICAgICAgIHBpbk5hbWU6IGdwaW8sXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgaWYgKGluZGV4ID49IDApIHtcbiAgICAgICAgICAgICAgZGlzcGxheVdpcmVOYW1lID0gcGtnLm1vZHVsYXJQaW5NYXBbaW5kZXhdLnBpbkRpc3BsYXlOYW1lXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIHRoaXMgaXMgYSB3aXJlIGNvbm5lY3RpbmcgdG8gR1BJTywgZ2V0IGl0cyBkaXJlY3Rpb25cbiAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNvbm5zLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBsZXQgY29ubiA9IGNvbm5zW2ldXG4gICAgICAgICAgICBsZXQgY29tcGlkID0gY29ubi5jb21wXG4gICAgICAgICAgICBsZXQgcG9ydG5hbWUgPSBjb25uLnBvcnRcbiAgICAgICAgICAgIGlmIChkaXNwbGF5V2lyZU5hbWUubGVuZ3RoID09PSAwKSBkaXNwbGF5V2lyZU5hbWUgPSAnQycgKyBjb21waWQgKyBwb3J0bmFtZVxuICAgICAgICAgICAgY29uc3QgY29tcG9uZW50ID0gcHJvamVjdC5jaGlwLmZpbmRDb21wb25lbnRCeUlkKGNvbXBpZClcbiAgICAgICAgICAgIGxldCBwb3J0cyA9IGNvbXBvbmVudC5wb3J0c1xuICAgICAgICAgICAgcG9ydHMuZm9yRWFjaChwb3J0ID0+IHtcbiAgICAgICAgICAgICAgaWYgKHBvcnQubmFtZSA9PT0gcG9ydG5hbWUpIHtcbiAgICAgICAgICAgICAgICBsZXQgd2lyZUluZGV4ID0gXy5maW5kSW5kZXgoZXhwUG9ydHMsIHtcbiAgICAgICAgICAgICAgICAgIHdpcmU6IHdpcmVOYW1lLFxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgaWYgKHdpcmVJbmRleCA9PT0gLTEpIHtcbiAgICAgICAgICAgICAgICAgIGV4cFBvcnRzLnB1c2goeyB3aXJlOiB3aXJlTmFtZSwgbmFtZTogZGlzcGxheVdpcmVOYW1lLCB0eXBlOiBwb3J0LnR5cGUgfSlcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWVcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSlcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KVxuICAgIHJldHVybiBleHBQb3J0c1xuICB9LFxuXG4gIGFzeW5jIGRlbGV0ZU1vZHVsYXIgKCkge1xuICAgIC8vIGRlbGV0ZSBtb2R1bGFyIHByb2plY3RcbiAgICBsZXQgcHJqSWQgPSBwcm9qZWN0Lm9yaWdQcm9qZWN0SWRcbiAgICBhd2FpdCB0aGlzLmRlbGV0ZVByb2plY3RzKFtwcm9qZWN0LnByb2plY3RJRF0pXG4gICAgLy8gYmFjayB0byBvcmlnaW5hbCBwcm9qZWN0XG4gICAgY29uc3QgY29tcG9uZW50ID0gbnVsbFxuICAgIGNvbnN0IGN1c3RvbUNvbXBzID0gbnVsbFxuICAgIGNvbnN0IG1vZHVsYXJQaW5NYXAgPSBudWxsXG4gICAgdGhpcy5sb2FkTW9kUHJvamVjdChwcmpJZCwgY29tcG9uZW50LCBjdXN0b21Db21wcywgbW9kdWxhclBpbk1hcCwgdHJ1ZSlcbiAgfSxcblxuICBhc3luYyBsb2FkTW9kdWxhciAoaW5OZXRsaXN0LCBvcmlnUHJvamVjdElkLCB0b3BOYW1lKSB7XG4gICAgbGV0IG5ldGxpc3QgPSBpbk5ldGxpc3RcbiAgICBpZiAoXy5pc1N0cmluZyhpbk5ldGxpc3QpKSB7XG4gICAgICBuZXRsaXN0ID0gSlNPTi5wYXJzZShpbk5ldGxpc3QpXG4gICAgfVxuICAgIGxldCBuYW1lID0gJ2RlZmF1bHRNb2R1bGFyJ1xuICAgIGxldCB7IHN1Y2Nlc3MsIGRhdGEgfSA9IGF3YWl0IHNlbmRDb21tYW5kKCcvcHJvamVjdCcsIHtcbiAgICAgIG1ldGhvZDogJ2dldEZpbGUnLFxuICAgICAgZmlsZTogJ2ZpbGVzLycgKyBuYW1lICsgJy5qc29uJyxcbiAgICB9KVxuICAgIGlmICghc3VjY2VzcykgcmV0dXJuXG4gICAgbGV0IGNvbmZpZyA9IEpTT04ucGFyc2UoZGF0YSkuY29uZmlnXG4gICAgY29uZmlnLmNoaXBzWzBdLmNvbm5lY3Rpb25zID0gbmV0bGlzdC5jb25uc1xuICAgIGNvbmZpZy5jaGlwc1swXS5kaWdpdGFscyA9IG5ldGxpc3QuY29tcHNcbiAgICBjb25zdCBwb3J0c21hcCA9IG5ldGxpc3QucG9ydHNtYXBcbiAgICBjb25zdCBwcm9qZWN0TmFtZSA9IHRvcE5hbWVcbiAgICBjb25zdCBjdXN0b21Db21wcyA9IG51bGxcbiAgICBjb25zdCBkYXRhbiA9IGF3YWl0IHNlbmRDb21tYW5kKCcvcHJvamVjdCcsIHsgbWV0aG9kOiAnbmV3JywgbmFtZTogcHJvamVjdE5hbWUsIGNvbmZpZzogSlNPTi5zdHJpbmdpZnkoY29uZmlnKSB9KVxuICAgIGlmICghZGF0YW4pIHJldHVyblxuICAgIGlmICghZGF0YW4uc3VjY2VzcykgcmV0dXJuXG4gICAgcHJvamVjdHMucHVzaChkYXRhbilcbiAgICB0aGlzLmxvYWRNb2RQcm9qZWN0KGRhdGFuLmRhdGEucHJvamVjdElELCBvcmlnUHJvamVjdElkLCBjdXN0b21Db21wcywgcG9ydHNtYXAsIGZhbHNlKVxuICB9LFxuICBhc3luYyBhZGRNb2R1bGFyICgpIHtcbiAgICAvLyBnZXQgcG9ydHMgZGVzY3JpcHRpb25cbiAgICBjb25zdCBhY2hpcCA9IHByb2plY3QuY2hpcFxuICAgIGNvbnN0IHBrZyA9IGFjaGlwLmRldmljZS5wYWNrYWdlXG4gICAgbGV0IG1vZE5hbWUgPSBwcm9qZWN0Lm5hbWVcbiAgICBsZXQgcG9ydHMgPSB0aGlzLmdldE1vZHVsYXJQb3J0cygpXG4gICAgbGV0IGNvbXBvbmVudCA9IHtcbiAgICAgICdpZCc6ICdjdXN0b21fJyArIG1vZE5hbWUsXG4gICAgICAndG9wTmFtZSc6IG1vZE5hbWUsXG4gICAgICAndHlwZSc6ICdtb2R1bGFyJyxcbiAgICAgICd2ZXJzaW9uJzogJycsXG4gICAgICAnZnVuY3Rpb24nOiAnQ3VzdG9tIENvbXBvbmVudCcsXG4gICAgICAndmVyaWxvZyc6ICcnLFxuICAgICAgJ2ZldHMnOiAxLFxuICAgICAgJ2RpZ2l0YWwnOiB0cnVlLFxuICAgICAgJ3N0eWxlJzoge1xuICAgICAgICAnZmlsbCc6ICcjYmZlNWZmJyxcbiAgICAgICAgJ3N0cm9rZSc6ICcjMDA1MTg5JyxcbiAgICAgIH0sXG4gICAgICBwb3J0czogW10sXG4gICAgfVxuICAgIGxldCBwb3J0c21hcCA9IFtdXG4gICAgcG9ydHMuZm9yRWFjaCgocG9ydCkgPT4ge1xuICAgICAgY29tcG9uZW50LnBvcnRzLnB1c2goe1xuICAgICAgICBuYW1lOiBwb3J0Lm5hbWUsXG4gICAgICAgIHR5cGU6IHBvcnQudHlwZSxcbiAgICAgICAgYWxpZ246IHBvcnQudHlwZSA9PT0gJ291dHB1dCcgPyAncmlnaHQnIDogJ2xlZnQnLFxuICAgICAgICBkZXNjcmlwdGlvbjogJ0N1c3RvbSBQb3J0JyxcbiAgICAgIH0pXG4gICAgICBpZiAocGtnLm1vZHVsYXJQaW5NYXAubGVuZ3RoID4gMCkge1xuICAgICAgICBsZXQgaW5kZXggPSBfLmZpbmRJbmRleChwa2cubW9kdWxhclBpbk1hcCwge1xuICAgICAgICAgIHBpbkRpc3BsYXlOYW1lOiBwb3J0Lm5hbWUsXG4gICAgICAgIH0pXG4gICAgICAgIGlmIChpbmRleCA+PSAwKSB7XG4gICAgICAgICAgcG9ydHNtYXAucHVzaChwa2cubW9kdWxhclBpbk1hcFtpbmRleF0pXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KVxuICAgIGxldCBjb21wb25lbnRzID0ge31cbiAgICBsZXQgYUNvbXBDb25maWdzID0gW11cbiAgICBhY2hpcC5kaWdpdGFscy5mb3JFYWNoKGNvbXAgPT4ge1xuICAgICAgaWYgKGNvbXAuY2F0ZWdvcnkgPT09ICdTdXBlcnZpc29yJykge1xuICAgICAgICBjb21wb25lbnRzW2NvbXAudHlwZV0gPSBjb21wLmNvbmZpZy52ZXJpbG9nLnRvcF9uYW1lXG4gICAgICAgIGxldCBjb21wQ29uZmlnID0gY29tcC5jb25maWdcbiAgICAgICAgbGV0IGMgPSB7IG5hbWU6IGNvbXAubmFtZSwgY29uZmlnOiBjb21wQ29uZmlnIH1cbiAgICAgICAgYUNvbXBDb25maWdzLnB1c2goYylcbiAgICAgIH1cbiAgICB9KVxuICAgIGNvbnN0IGNoaXAgPSBwcm9qZWN0LmNvbmZpZy5jaGlwc1swXVxuICAgIGxldCBhQ29tcG9uZW50cyA9IFtdXG4gICAgY2hpcC5kaWdpdGFscy5mb3JFYWNoKGNvbXAgPT4ge1xuICAgICAgbGV0IGluZm8gPSBDb21wb25lbnRNYW5hZ2VyLmNvbXBvbmVudHNbY29tcC50eXBlXVxuICAgICAgaWYgKGluZm8uY2F0ZWdvcnkgPT09ICdTdXBlcnZpc29yJykge1xuICAgICAgICBjb21wLnZlcmlsb2dUb3BOYW1lID0gY29tcG9uZW50c1tjb21wLnR5cGVdXG4gICAgICAgIGxldCBjb25maWdDb21wID0gXy5maW5kKGFDb21wQ29uZmlncywgeyBuYW1lOiBjb21wLm5hbWUgfSlcbiAgICAgICAgaWYgKGNvbmZpZ0NvbXApIHtcbiAgICAgICAgICBsZXQgYUNvbXAgPSBjb21wXG4gICAgICAgICAgYUNvbXAuY29uZmlnID0gY29uZmlnQ29tcC5jb25maWdcbiAgICAgICAgICBhQ29tcG9uZW50cy5wdXNoKGFDb21wKVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSlcbiAgICBjb25zdCBjaGlwTmFtZSA9IGNoaXAubmFtZVxuICAgIGNvbnN0IG1vZHVsZU5ldExpc3QgPSB7IGNvbm5zOiBjaGlwLmNvbm5lY3Rpb25zLCBwb3J0c21hcDogcG9ydHNtYXAsIGNvbXBzOiBhQ29tcG9uZW50cyB9XG4gICAgY29tcG9uZW50WyduZXRsaXN0J10gPSBtb2R1bGVOZXRMaXN0IC8vIEpTT04uc3RyaW5naWZ5KG1vZHVsZU5ldExpc3QsIG51bGwsICdcXHQnKVxuICAgIGlmIChwcm9qZWN0LmRpcnR5KSBjb21wb25lbnRbJ2RpcnR5J10gPSB0cnVlXG4gICAgbGV0IGRhdGEgPSBhd2FpdCBzZW5kQ29tbWFuZCgnL3Byb2plY3QnLCB7IG1ldGhvZDogJ2dlbkN1c3RvbVZlcmlsb2cnLCBkYXRhOiB7IGlkOiBwcm9qZWN0Lm9yaWdQcm9qZWN0SWQsIHRvcE5hbWU6IG1vZE5hbWUsIHBvcnRzOiBwb3J0cywgY2hpcG5hbWU6IGNoaXBOYW1lLCBuZXRsaXN0OiBtb2R1bGVOZXRMaXN0IH0gfSlcbiAgICBpZiAoZGF0YS5zdWNjZXNzKSB7XG4gICAgICBjb21wb25lbnQudmVyaWxvZyA9IGRhdGEuZGF0YVxuICAgICAgLy8gZGVsZXRlIGNvbXBvbmVudC5uZXRsaXN0XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbXBvbmVudCA9IG51bGxcbiAgICB9XG5cbiAgICAvLyBkZWxldGUgbW9kdWxhciBwcm9qZWN0XG4gICAgbGV0IHByaklkID0gcHJvamVjdC5vcmlnUHJvamVjdElkXG4gICAgYXdhaXQgdGhpcy5kZWxldGVQcm9qZWN0cyhbcHJvamVjdC5wcm9qZWN0SURdKVxuICAgIC8vIGJhY2sgdG8gb3JpZ2luYWwgcHJvamVjdFxuICAgIGNvbnN0IGN1c3RvbUNvbXBzID0gbnVsbFxuICAgIGNvbnN0IG1vZHVsYXJQaW5NYXAgPSBudWxsXG4gICAgdGhpcy5sb2FkTW9kUHJvamVjdChwcmpJZCwgY29tcG9uZW50LCBjdXN0b21Db21wcywgbW9kdWxhclBpbk1hcCwgdHJ1ZSlcbiAgfSxcblxuICBhc3luYyBpbXBvcnREZWZhdWx0TW9kdWxhciAocE5hbWUpIHtcbiAgICBsZXQgb3JpZ1Byb2plY3RJZCA9IHByb2plY3QucHJvamVjdElEXG4gICAgbGV0IGN1c3RvbUNvbXBzID0gbnVsbFxuICAgIGlmIChwcm9qZWN0LmNvbmZpZy5jdXN0b21Db21wb25lbnRzKSB7XG4gICAgICBjdXN0b21Db21wcyA9IHByb2plY3QuY29uZmlnLmN1c3RvbUNvbXBvbmVudHNcbiAgICB9XG4gICAgbGV0IG5hbWUgPSAnZGVmYXVsdE1vZHVsYXInXG4gICAgbGV0IHsgc3VjY2VzcywgZGF0YSB9ID0gYXdhaXQgc2VuZENvbW1hbmQoJy9wcm9qZWN0Jywge1xuICAgICAgbWV0aG9kOiAnZ2V0RmlsZScsXG4gICAgICBmaWxlOiAnZmlsZXMvJyArIG5hbWUgKyAnLmpzb24nLFxuICAgIH0pXG4gICAgaWYgKCFzdWNjZXNzKSByZXR1cm5cbiAgICBsZXQgbW9kdWxhclBpbk1hcCA9IG51bGxcbiAgICBsZXQgY29uZmlnID0gSlNPTi5wYXJzZShkYXRhKS5jb25maWdcbiAgICBjb25zdCBwcm9qZWN0TmFtZSA9IHBOYW1lO1xuICAgICh7IHN1Y2Nlc3MsIGRhdGEgfSA9IGF3YWl0IHNlbmRDb21tYW5kKCcvcHJvamVjdCcsIHsgbWV0aG9kOiAnbmV3JywgbmFtZTogcHJvamVjdE5hbWUsIGNvbmZpZzogSlNPTi5zdHJpbmdpZnkoY29uZmlnKSB9KSlcbiAgICBpZiAoIXN1Y2Nlc3MpIHJldHVyblxuICAgIGlmICghZGF0YSkgcmV0dXJuXG4gICAgcHJvamVjdHMucHVzaChkYXRhKVxuICAgIHRoaXMubG9hZE1vZFByb2plY3QoZGF0YS5wcm9qZWN0SUQsIG9yaWdQcm9qZWN0SWQsIGN1c3RvbUNvbXBzLCBtb2R1bGFyUGluTWFwLCBmYWxzZSlcbiAgfSxcblxuICBhc3luYyBsb2FkTW9kUHJvamVjdCAoaWQsIGluRGF0YSwgY3VzdG9tQ29tcHMsIG1vZHVsYXJQaW5NYXAsIG5vcm1hbFByb2plY3QpIHtcbiAgICBkZWJ1ZygnbG9hZE1vZFByb2plY3QgLSBpZDogJXMnLCBpZClcbiAgICBsZXQgaWROdW0gPSBpZFxuICAgIGlmIChfLmlzU3RyaW5nKGlkKSkge1xuICAgICAgaWROdW0gPSBwYXJzZUludChpZClcbiAgICB9XG4gICAgYXdhaXQgdGhpcy5zYXZlUHJvamVjdCgpXG4gICAgLy8gY2hlY2sgaWYgY29tcG9uZW50IGlzIHJldmlzaW9uIEEgb3IgQlxuICAgIGNvbnN0IHsgc3VjY2VzcywgZGF0YSB9ID0gYXdhaXQgc2VuZENvbW1hbmQoJy9wcm9qZWN0JywgeyBtZXRob2Q6ICdsb2FkJywgaWQgfSlcbiAgICBpZiAoIXN1Y2Nlc3MpIHJldHVyblxuICAgIGlmICghZGF0YSkgcmV0dXJuXG4gICAgdGhpcy5jbGVhclByb2plY3QodHJ1ZSlcbiAgICBfLnJlbW92ZShwcm9qZWN0cywgcCA9PiBwLnByb2plY3RJRCA9PT0gaWROdW0pXG4gICAgdXNlci5zdXBlck1vZGUgPSBmYWxzZVxuICAgIHByb2plY3RzLnVuc2hpZnQoZGF0YSlcbiAgICBwcm9qZWN0ID0gbmV3IFByb2plY3QoZGF0YSlcbiAgICBjb25zdCBjaGlwID0gcHJvamVjdC5jaGlwXG4gICAgcHJvamVjdC5jb25maWcubW9kdWxhciA9IHRydWVcbiAgICBpZiAobm9ybWFsUHJvamVjdCkge1xuICAgICAgLy8gdGhpcyBpcyBhIG5vcm1hbCBwcm9qZWN0IChvcmlnaW5hbCBwcm9qZWN0IG9mIG1vZHVsYXIpXG4gICAgICBpZiAoaW5EYXRhKSB7XG4gICAgICAgIGxldCBjb21wb25lbnQgPSBpbkRhdGFcbiAgICAgICAgaWYgKCFwcm9qZWN0LmNvbmZpZy5jdXN0b21Db21wb25lbnRzKSB7XG4gICAgICAgICAgcHJvamVjdC5jb25maWcuY3VzdG9tQ29tcG9uZW50cyA9IFtdXG4gICAgICAgIH1cbiAgICAgICAgbGV0IGluZGV4ID0gXy5maW5kSW5kZXgocHJvamVjdC5jb25maWcuY3VzdG9tQ29tcG9uZW50cywge1xuICAgICAgICAgIGlkOiBjb21wb25lbnQuaWQsXG4gICAgICAgIH0pXG4gICAgICAgIGlmIChpbmRleCA8IDApIHtcbiAgICAgICAgICBpZiAoY29tcG9uZW50LmRpcnR5KSB7XG4gICAgICAgICAgICBkZWxldGUgY29tcG9uZW50LmRpcnR5XG4gICAgICAgICAgfVxuICAgICAgICAgIHByb2plY3QuY29uZmlnLmN1c3RvbUNvbXBvbmVudHMucHVzaChjb21wb25lbnQpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcHJvamVjdC5jb25maWcuY3VzdG9tQ29tcG9uZW50cy5zcGxpY2UoaW5kZXgsIDEsIGNvbXBvbmVudClcbiAgICAgICAgICBpZiAoY29tcG9uZW50LmRpcnR5KSB7XG4gICAgICAgICAgICBkZWxldGUgY29tcG9uZW50LmRpcnR5XG4gICAgICAgICAgICBjaGlwLmRpZ2l0YWxzLmZvckVhY2goY3AgPT4ge1xuICAgICAgICAgICAgICBpZiAoY3AudHlwZSA9PT0gY29tcG9uZW50LmlkKSB7XG4gICAgICAgICAgICAgICAgc2hvd01vZGFsRGlhbG9nKCdXYXJuaW5nJywgJ21vZHVsYXIoJyArIGNvbXBvbmVudC50b3BOYW1lICsgJykgY2hhbmdlZCwgcGxlYXNlIHJlbW92ZWQgJyArIGNwLm5hbWUgKyAnYW5kIGRvIGFnYWluJylcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSlcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChwcm9qZWN0LmNvbmZpZy5tb2R1bGFyKSBkZWxldGUgcHJvamVjdC5jb25maWcubW9kdWxhclxuICAgICAgaWYgKHByb2plY3QuY3VzdG9tQ29tcHMpIGRlbGV0ZSBwcm9qZWN0LmN1c3RvbUNvbXBzXG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIHRoaXMgaXMgYSBwcm9qZWN0IGZvciBtb2R1bGFyXG4gICAgICBwcm9qZWN0Lm9yaWdQcm9qZWN0SWQgPSBpbkRhdGFcbiAgICAgIGlmIChjdXN0b21Db21wcykgcHJvamVjdC5jdXN0b21Db21wcyA9IGN1c3RvbUNvbXBzXG4gICAgfVxuICAgIGxldCBzY3JlZW4gPSBTY3JlZW5NYW5hZ2VyLmdldFNjcmVlbignZGVzaWduJylcbiAgICBpZiAobm9ybWFsUHJvamVjdCkge1xuICAgICAgLy8gdGhpcyBpcyBhIG5vcm1hbCBwcm9qZWN0IChvcmlnaW5hbCBwcm9qZWN0IG9mIG1vZHVsYXIpXG4gICAgICBzY3JlZW4uYnVpbGRDYXRlZ29yaWVzKClcbiAgICAgIHNjcmVlbi5lbmFibGVCdG5zKClcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gdGhpcyBpcyBhIHByb2plY3QgZm9yIG1vZHVsYXJcbiAgICAgIHNjcmVlbi5idWlsZE1vZENhdGVnb3JpZXMoKVxuICAgICAgc2NyZWVuLmRpc2FibGVCdG5zKClcbiAgICB9XG4gICAgaWYgKG1vZHVsYXJQaW5NYXAgJiYgQXJyYXkuaXNBcnJheShtb2R1bGFyUGluTWFwKSAmJiBtb2R1bGFyUGluTWFwLmxlbmd0aCkge1xuICAgICAgY29uc3QgcGtnID0gY2hpcC5kZXZpY2UucGFja2FnZVxuICAgICAgcGtnLm1vZHVsYXJQaW5NYXAgPSBtb2R1bGFyUGluTWFwXG4gICAgfVxuICAgIHNjcmVlbi5zaG93VGhlcm1hbCA9IGZhbHNlIC8vIG1ha2Ugc3VyZSBpdCBpcyBub3QgaW4gdGhlcm1hbCBwYWdlIHdoZW4gbG9hZGVkXG4gICAgc2NyZWVuLnNob3dDb21wb25lbnRzID0gdHJ1ZVxuICAgIHNjcmVlbi5zaG93Q29ubmVjdGlvbnMgPSB0cnVlXG4gICAgc2NyZWVuLnJlZnJlc2goKVxuXG4gICAgdGhpcy5yZWZyZXNoUHJvamVjdHNNZW51KClcbiAgICBFdmVudEJ1cy4kZW1pdCgncHJvamVjdExvYWRlZCcpXG4gICAgaWYgKCFjaGlwLnZlcmlsb2dMaWJWZXJzaW9ucykge1xuICAgICAgY2hpcFsndmVyaWxvZ0xpYlZlcnNpb25zJ10gPSAnUHJvZHVjdGlvbidcbiAgICB9XG4gICAgbGV0IGlzTnVtYmVyID0gZmFsc2VcbiAgICBpZiAoY2hpcC5WSU4pIHtcbiAgICAgIGlzTnVtYmVyID0gXy5pc051bWJlcihjaGlwLlZJTilcbiAgICB9XG4gICAgaWYgKCFpc051bWJlcikge1xuICAgICAgaWYgKHNjcmVlbikge1xuICAgICAgICBzY3JlZW4uaGFuZGxlVklOKClcbiAgICAgIH1cbiAgICB9XG4gIH0sXG59XG4iLCJ2YXIgcHVnID0gcmVxdWlyZShcIiEuLi8uLi9ub2RlX21vZHVsZXMvcHVnLXJ1bnRpbWUvaW5kZXguanNcIik7XG5cbmZ1bmN0aW9uIHRlbXBsYXRlKGxvY2Fscykge3ZhciBwdWdfaHRtbCA9IFwiXCIsIHB1Z19taXhpbnMgPSB7fSwgcHVnX2ludGVycDtwdWdfaHRtbCA9IHB1Z19odG1sICsgXCJcXHUwMDNDZGl2IGNsYXNzPVxcXCJtb2RhbCBmYWRlXFxcIiBpZD1cXFwibW9kYWwtc2F2ZUFzLXByb2plY3RcXFwiIHJvbGU9XFxcImRpYWxvZ1xcXCIgdGFiaW5kZXg9XFxcIi0xXFxcIlxcdTAwM0VcXHUwMDNDZGl2IGNsYXNzPVxcXCJtb2RhbC1kaWFsb2dcXFwiXFx1MDAzRVxcdTAwM0NkaXYgY2xhc3M9XFxcIm1vZGFsLWNvbnRlbnRcXFwiXFx1MDAzRVxcdTAwM0NkaXYgY2xhc3M9XFxcIm1vZGFsLWhlYWRlclxcXCJcXHUwMDNFXFx1MDAzQ2J1dHRvbiBjbGFzcz1cXFwiY2xvc2VcXFwiIGRhdGEtZGlzbWlzcz1cXFwibW9kYWxcXFwiIGFyaWEtbGFiZWw9XFxcImNsb3NlXFxcIlxcdTAwM0VcXHUwMDNDc3BhbiBhcmlhLWhpZGRlbj1cXFwidHJ1ZVxcXCJcXHUwMDNFJnRpbWVzO1xcdTAwM0NcXHUwMDJGc3BhblxcdTAwM0VcXHUwMDNDXFx1MDAyRmJ1dHRvblxcdTAwM0VcXHUwMDNDaDQgY2xhc3M9XFxcIm1vZGFsLXRpdGxlXFxcIlxcdTAwM0VTYXZlIEFzXFx1MDAzQ1xcdTAwMkZoNFxcdTAwM0VcXHUwMDNDc21hbGxcXHUwMDNFXFx1MDAzQ3NwYW4gY2xhc3M9XFxcImxhYmVsIGxhYmVsLWRhbmdlclxcXCJcXHUwMDNFXFx1MDAzQ1xcdTAwMkZzcGFuXFx1MDAzRVxcdTAwM0NcXHUwMDJGc21hbGxcXHUwMDNFXFx1MDAzQ1xcdTAwMkZkaXZcXHUwMDNFXFx1MDAzQ2RpdiBjbGFzcz1cXFwibW9kYWwtYm9keVxcXCJcXHUwMDNFXFx1MDAzQ2Zvcm0gY2xhc3M9XFxcInBhcmFtLWZvcm0gZm9ybS1ob3Jpem9udGFsXFxcIiBpZD1cXFwic2F2ZUFzXFxcIlxcdTAwM0VcXHUwMDNDZGl2IGNsYXNzPVxcXCJmb3JtLWdyb3VwIGZvcm0tZ3JvdXAtc21cXFwiXFx1MDAzRVxcdTAwM0NsYWJlbCBjbGFzcz1cXFwiY29sLXNtLTQgY29udHJvbC1sYWJlbFxcXCIgZm9yPVxcXCJQcm9qZWN0IE5hbWVcXFwiIHRpdGxlPVxcXCJcXFwiXFx1MDAzRVByb2plY3QgTmFtZVxcdTAwM0NcXHUwMDJGbGFiZWxcXHUwMDNFXFx1MDAzQ2RpdiBjbGFzcz1cXFwiY29sLXNtLTRcXFwiXFx1MDAzRVxcdTAwM0NpbnB1dCBjbGFzcz1cXFwiZm9ybS1jb250cm9sXFxcIiBpZD1cXFwicHJvamVjdC1uYW1lXFxcIiBvbmNoYW5nZT1cXFwiYW1wLlByb2plY3RNYW5hZ2VyLmNoZWNrUHJvamVjdE5hbWUodGhpcylcXFwiIHZhbHVlPVxcXCJcXFwiXFx1MDAzRVxcdTAwM0NcXHUwMDJGZGl2XFx1MDAzRVxcdTAwM0NcXHUwMDJGZGl2XFx1MDAzRVxcdTAwM0NcXHUwMDJGZm9ybVxcdTAwM0VcXHUwMDNDXFx1MDAyRmRpdlxcdTAwM0VcXHUwMDNDZGl2IGNsYXNzPVxcXCJtb2RhbC1mb290ZXJcXFwiXFx1MDAzRVxcdTAwM0NidXR0b24gY2xhc3M9XFxcImJ0biBidG4tZGVmYXVsdFxcXCIgZGF0YS1kaXNtaXNzPVxcXCJtb2RhbFxcXCJcXHUwMDNFQ3JlYXRlXFx1MDAzQ1xcdTAwMkZidXR0b25cXHUwMDNFXFx1MDAzQ1xcdTAwMkZkaXZcXHUwMDNFXFx1MDAzQ1xcdTAwMkZkaXZcXHUwMDNFXFx1MDAzQ1xcdTAwMkZkaXZcXHUwMDNFXFx1MDAzQ1xcdTAwMkZkaXZcXHUwMDNFXCI7O3JldHVybiBwdWdfaHRtbDt9O1xubW9kdWxlLmV4cG9ydHMgPSB0ZW1wbGF0ZTsiLCJ2YXIgcHVnID0gcmVxdWlyZShcIiEuLi8uLi9ub2RlX21vZHVsZXMvcHVnLXJ1bnRpbWUvaW5kZXguanNcIik7XG5cbmZ1bmN0aW9uIHRlbXBsYXRlKGxvY2Fscykge3ZhciBwdWdfaHRtbCA9IFwiXCIsIHB1Z19taXhpbnMgPSB7fSwgcHVnX2ludGVycDtwdWdfaHRtbCA9IHB1Z19odG1sICsgXCJcXHUwMDNDZGl2IGNsYXNzPVxcXCJtb2RhbCBmYWRlXFxcIiBpZD1cXFwibW9kYWwtc2V0dGluZ3MtZm9ybVxcXCIgcm9sZT1cXFwiZGlhbG9nXFxcIiB0YWJpbmRleD1cXFwiLTFcXFwiXFx1MDAzRVxcdTAwM0NkaXYgY2xhc3M9XFxcIm1vZGFsLWRpYWxvZyBtb2RhbC1sZ1xcXCJcXHUwMDNFXFx1MDAzQ2RpdiBjbGFzcz1cXFwibW9kYWwtY29udGVudFxcXCIgc3R5bGU9XFxcIm92ZXJmbG93OmF1dG87cmVzaXplOmJvdGhcXFwiXFx1MDAzRVxcdTAwM0NkaXYgY2xhc3M9XFxcIm1vZGFsLWhlYWRlclxcXCJcXHUwMDNFXFx1MDAzQ2J1dHRvbiBjbGFzcz1cXFwiY2xvc2VcXFwiIGRhdGEtZGlzbWlzcz1cXFwibW9kYWxcXFwiIGFyaWEtbGFiZWw9XFxcImNsb3NlXFxcIlxcdTAwM0VcXHUwMDNDc3BhbiBhcmlhLWhpZGRlbj1cXFwidHJ1ZVxcXCJcXHUwMDNFJnRpbWVzO1xcdTAwM0NcXHUwMDJGc3BhblxcdTAwM0VcXHUwMDNDXFx1MDAyRmJ1dHRvblxcdTAwM0VcXHUwMDNDaDQgY2xhc3M9XFxcIm1vZGFsLXRpdGxlXFxcIlxcdTAwM0VQcm9qZWN0IFNldHRpbmdzXFx1MDAzQ1xcdTAwMkZoNFxcdTAwM0VcXHUwMDNDc21hbGxcXHUwMDNFXFx1MDAzQ1xcdTAwMkZzbWFsbFxcdTAwM0VcXHUwMDNDXFx1MDAyRmRpdlxcdTAwM0VcXHUwMDNDZGl2IGNsYXNzPVxcXCJtb2RhbC1ib2R5XFxcIlxcdTAwM0VcXHUwMDNDZGl2XFx1MDAzRVxcdTAwM0N1bCBjbGFzcz1cXFwibmF2IG5hdi10YWJzXFxcIiByb2xlPVxcXCJ0YWJsaXN0XFxcIlxcdTAwM0VcXHUwMDNDbGkgY2xhc3M9XFxcImFjdGl2ZVxcXCIgcm9sZT1cXFwicHJlc2VudGF0aW9uXFxcIlxcdTAwM0VcXHUwMDNDYSBocmVmPVxcXCIjY2xvY2tzVGFiXFxcIiBhcmlhLWNvbnRyb2xzPVxcXCJjbG9ja3NUYWJcXFwiIHJvbGU9XFxcInRhYlxcXCIgZGF0YS10b2dnbGU9XFxcInRhYlxcXCJcXHUwMDNFQ2xvY2tcXHUwMDNDXFx1MDAyRmFcXHUwMDNFXFx1MDAzQ1xcdTAwMkZsaVxcdTAwM0VcXHUwMDNDbGkgcm9sZT1cXFwicHJlc2VudGF0aW9uXFxcIlxcdTAwM0VcXHUwMDNDYSBocmVmPVxcXCIjcGxhdGZvcm1Cb01UYWJcXFwiIGFyaWEtY29udHJvbHM9XFxcInBsYXRmb3JtQm9NVGFiXFxcIiByb2xlPVxcXCJ0YWJcXFwiIGRhdGEtdG9nZ2xlPVxcXCJ0YWJcXFwiXFx1MDAzRVBsYXRmb3JtIEJvTVxcdTAwM0NcXHUwMDJGYVxcdTAwM0VcXHUwMDNDXFx1MDAyRmxpXFx1MDAzRVxcdTAwM0NsaSByb2xlPVxcXCJwcmVzZW50YXRpb25cXFwiXFx1MDAzRVxcdTAwM0NhIGhyZWY9XFxcIiN2ZXJpbG9nVmVyc2lvbnNUYWJcXFwiIGFyaWEtY29udHJvbHM9XFxcIiN2ZXJpbG9nVmVyc2lvbnNUYWJcXFwiIHJvbGU9XFxcInRhYlxcXCIgZGF0YS10b2dnbGU9XFxcInRhYlxcXCJcXHUwMDNFIFZlcmlsb2cgTGlicmFyeSBWZXJzaW9uc1xcdTAwM0NcXHUwMDJGYVxcdTAwM0VcXHUwMDNDXFx1MDAyRmxpXFx1MDAzRVxcdTAwM0NcXHUwMDJGdWxcXHUwMDNFXFx1MDAzQ2RpdiBjbGFzcz1cXFwidGFiLWNvbnRlbnRcXFwiXFx1MDAzRVxcdTAwM0NkaXYgY2xhc3M9XFxcInRhYi1wYW5lIGZhZGUgaW4gYWN0aXZlXFxcIiBpZD1cXFwiY2xvY2tzVGFiXFxcIiByb2xlPVxcXCJ0YWJwYW5lbFxcXCJcXHUwMDNFXFx1MDAzQ1xcdTAwMkZkaXZcXHUwMDNFXFx1MDAzQ2RpdiBjbGFzcz1cXFwidGFiLXBhbmUgZmFkZVxcXCIgaWQ9XFxcInBsYXRmb3JtQm9NVGFiXFxcIiByb2xlPVxcXCJ0YWJwYW5lbFxcXCIgc3R5bGU9XFxcIm92ZXJmbG93LXg6YXV0bztvdmVyZmxvdy15OmF1dG9cXFwiXFx1MDAzRVxcdTAwM0NcXHUwMDJGZGl2XFx1MDAzRVxcdTAwM0NkaXYgY2xhc3M9XFxcInRhYi1wYW5lIGZhZGVcXFwiIGlkPVxcXCJ2ZXJpbG9nVmVyc2lvbnNUYWJcXFwiIHJvbGU9XFxcInRhYnBhbmVsXFxcIiBzdHlsZT1cXFwib3ZlcmZsb3cteDphdXRvO292ZXJmbG93LXk6YXV0b1xcXCJcXHUwMDNFXFx1MDAzQ2RpdiBjbGFzcz1cXFwiY29udGFpbmVyLWZsdWlkXFxcIiBzdHlsZT1cXFwib3ZlcmZsb3cteTphdXRvO2hlaWdodDoxMDAlO1xcXCJcXHUwMDNFXFx1MDAzQ2RpdiBjbGFzcz1cXFwicm93XFxcIlxcdTAwM0UmbmJzcDtcXHUwMDNDXFx1MDAyRmRpdlxcdTAwM0VcXHUwMDNDZGl2IGNsYXNzPVxcXCJyb3dcXFwiXFx1MDAzRVxcdTAwM0NkaXYgY2xhc3M9XFxcImNvbC1tZC0xMlxcXCJcXHUwMDNFXFx1MDAzQ3RhYmxlIGNsYXNzPVxcXCJ0YWJsZSB0YWJsZS1ib3JkZXJlZCB0YWJsZS1zdHJpcGVkXFxcIlxcdTAwM0VcXHUwMDNDXFx1MDAyRnRhYmxlXFx1MDAzRVxcdTAwM0N0Ym9keVxcdTAwM0VcXHUwMDNDdHJcXHUwMDNFXFx1MDAzQ3RkXFx1MDAzRVZlcnNpb25cXHUwMDNDXFx1MDAyRnRkXFx1MDAzRVxcdTAwM0N0ZFxcdTAwM0VcXHUwMDNDZGl2IGNsYXNzPVxcXCJmb3JtLWlubGluZVxcXCJcXHUwMDNFXFx1MDAzQ3NlbGVjdCBjbGFzcz1cXFwiZm9ybS1jb250cm9sXFxcIiBpZD1cXFwidmVyaWxvZ0xpYnJhcnktdmVyc2lvbnNcXFwiIHN0eWxlPVxcXCJ3aWR0aDoyMCVcXFwiIG9uY2hhbmdlPVxcXCJhbXAuUHJvamVjdE1hbmFnZXIuc2V0VmVyaWxvZ0xpYlZlcnNpb24odGhpcylcXFwiXFx1MDAzRVxcdTAwM0NvcHRpb24gdmFsdWU9XFxcIlByb2R1Y3Rpb25cXFwiIHNlbGVjdGVkXFx1MDAzRVByb2R1Y3Rpb25cXHUwMDNDXFx1MDAyRm9wdGlvblxcdTAwM0VcXHUwMDNDb3B0aW9uIHZhbHVlPVxcXCJBbHBoYVxcXCJcXHUwMDNFQWxwaGFcXHUwMDNDXFx1MDAyRm9wdGlvblxcdTAwM0VcXHUwMDNDb3B0aW9uIHZhbHVlPVxcXCJCZXRhXFxcIlxcdTAwM0VCZXRhXFx1MDAzQ1xcdTAwMkZvcHRpb25cXHUwMDNFXFx1MDAzQ1xcdTAwMkZzZWxlY3RcXHUwMDNFXFx1MDAzQ1xcdTAwMkZkaXZcXHUwMDNFXFx1MDAzQ1xcdTAwMkZ0ZFxcdTAwM0VcXHUwMDNDXFx1MDAyRnRyXFx1MDAzRVxcdTAwM0NcXHUwMDJGdGJvZHlcXHUwMDNFXFx1MDAzQ1xcdTAwMkZkaXZcXHUwMDNFXFx1MDAzQ1xcdTAwMkZkaXZcXHUwMDNFXFx1MDAzQ1xcdTAwMkZkaXZcXHUwMDNFXFx1MDAzQ1xcdTAwMkZkaXZcXHUwMDNFXFx1MDAzQ1xcdTAwMkZkaXZcXHUwMDNFXFx1MDAzQ1xcdTAwMkZkaXZcXHUwMDNFXFx1MDAzQ1xcdTAwMkZkaXZcXHUwMDNFXFx1MDAzQ2RpdiBjbGFzcz1cXFwibW9kYWwtZm9vdGVyXFxcIlxcdTAwM0VcXHUwMDNDYnV0dG9uIGNsYXNzPVxcXCJidG4gYnRuLWRlZmF1bHRcXFwiIGlkPVxcXCJzZXR0aW5nc2J0blxcXCIgZGF0YS1kaXNtaXNzPVxcXCJtb2RhbFxcXCJcXHUwMDNFT2tcXHUwMDNDXFx1MDAyRmJ1dHRvblxcdTAwM0VcXHUwMDNDXFx1MDAyRmRpdlxcdTAwM0VcXHUwMDNDXFx1MDAyRmRpdlxcdTAwM0VcXHUwMDNDXFx1MDAyRmRpdlxcdTAwM0VcXHUwMDNDXFx1MDAyRmRpdlxcdTAwM0VcIjs7cmV0dXJuIHB1Z19odG1sO307XG5tb2R1bGUuZXhwb3J0cyA9IHRlbXBsYXRlOyJdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7OztBQ0hBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7O0FDSEE7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7QUNIQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQ0hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFFQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQU5BO0FBQUE7QUFPQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBUEE7QUFRQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFBQTtBQUVBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBRUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUVBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUVBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFFQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBR0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFBQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUVBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFFQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUVBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQU1BO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFFQTtBQUVBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUVBO0FBRUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUVBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUVBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBRUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBR0E7QUFFQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQUE7QUFHQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBRUE7QUFFQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUVBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBRUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUVBO0FBRUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUVBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUEseUJBQ0E7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFHQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBRUE7QUFBQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFFQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUdBO0FBQUE7QUFBQTtBQUlBO0FBQ0E7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFHQTtBQUFBO0FBRUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBRUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUpBO0FBQUE7QUFBQTtBQUtBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUVBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBRUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFFQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBSEE7QUFBQTtBQUFBO0FBSUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFFQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBRUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFFQTtBQUVBO0FBQ0E7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUVBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBSUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBTkE7QUFBQTtBQU9BO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUVBO0FBQUE7QUFmQTtBQUFBO0FBQUE7QUFBQTtBQW9CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUVBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQUE7QUFFQTtBQXVEQTtBQUFBO0FBQUE7QUFyREE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBR0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBRUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFHQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFFQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUVBO0FBckVBO0FBQUE7QUFBQTtBQUFBO0FBc0VBO0FBQ0E7QUFFQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFFQTtBQXJCQTtBQUFBO0FBQUE7QUFBQTtBQXNCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFBQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFFQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBSEE7QUFBQTtBQUFBO0FBSUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBRUE7QUFFQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUpBO0FBQUE7QUFBQTtBQUtBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFFQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUVBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQWxCQTtBQUFBO0FBQUE7QUFtQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUVBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFFQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBSEE7QUFBQTtBQUFBO0FBSUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFFQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFFQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBSEE7QUFBQTtBQUFBO0FBSUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBRUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUVBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBOzs7Ozs7OztBQ2prRUE7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7QUNIQTtBQUNBO0FBQ0E7QUFDQTs7OztBIiwic291cmNlUm9vdCI6IiJ9