\").trim();\n\nvar PageMedia = /*#__PURE__*/function (_FilesField) {\n _inherits(PageMedia, _FilesField);\n\n var _super = _createSuper(PageMedia);\n\n function PageMedia() {\n var _this;\n\n var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},\n _ref$container = _ref.container,\n container = _ref$container === void 0 ? '#grav-dropzone' : _ref$container,\n _ref$options = _ref.options,\n options = _ref$options === void 0 ? {} : _ref$options;\n\n _classCallCheck(this, PageMedia);\n\n var previewTemplate = jquery__WEBPACK_IMPORTED_MODULE_0___default()('#dropzone-media-template').html() || template;\n options = Object.assign(options, {\n previewTemplate: previewTemplate\n });\n _this = _super.call(this, {\n container: container,\n options: options\n });\n\n if (!_this.container.length) {\n return _possibleConstructorReturn(_this);\n }\n\n _this.urls = {\n fetch: \"\".concat(_this.container.data('media-url'), \"/task\").concat(grav_form__WEBPACK_IMPORTED_MODULE_2__[\"config\"].param_sep, \"listmedia\"),\n add: \"\".concat(_this.container.data('media-url'), \"/task\").concat(grav_form__WEBPACK_IMPORTED_MODULE_2__[\"config\"].param_sep, \"addmedia\"),\n \"delete\": \"\".concat(_this.container.data('media-url'), \"/task\").concat(grav_form__WEBPACK_IMPORTED_MODULE_2__[\"config\"].param_sep, \"delmedia\")\n };\n _this.dropzone.options.url = _this.urls.add;\n\n if (typeof _this.options.fetchMedia === 'undefined' || _this.options.fetchMedia) {\n _this.fetchMedia();\n }\n\n var field = jquery__WEBPACK_IMPORTED_MODULE_0___default()(\"[name=\\\"\".concat(_this.container.data('dropzone-field'), \"\\\"]\"));\n\n if (field.length) {\n _this.sortable = new sortablejs__WEBPACK_IMPORTED_MODULE_3__[\"default\"](_this.container.get(0), {\n animation: 150,\n // forceFallback: true,\n setData: function setData(dataTransfer, target) {\n target = jquery__WEBPACK_IMPORTED_MODULE_0___default()(target);\n\n _this.dropzone.disable();\n\n target.addClass('hide-backface');\n dataTransfer.effectAllowed = 'copy';\n },\n onSort: function onSort() {\n var names = [];\n\n _this.container.find('[data-dz-name]').each(function (index, file) {\n file = jquery__WEBPACK_IMPORTED_MODULE_0___default()(file);\n var name = file.text().trim();\n names.push(name);\n });\n\n field.val(names.join(','));\n }\n });\n }\n\n return _this;\n }\n\n _createClass(PageMedia, [{\n key: \"onDropzoneRemovedFile\",\n value: function onDropzoneRemovedFile(file) {\n var _this2 = this;\n\n if (!file.accepted || file.rejected) {\n return;\n }\n\n var form = this.container.closest('form');\n var unique_id = form.find('[name=\"__unique_form_id__\"]');\n var url = file.removeUrl || this.urls[\"delete\"] || \"\".concat(location.href, \".json\");\n var path = (url || '').match(/path:(.*)\\//);\n var data = new FormData();\n data.append('filename', file.name);\n data.append('__form-name__', form.find('[name=\"__form-name__\"]').val());\n\n if (unique_id.length) {\n data.append('__unique_form_id__', unique_id.val());\n }\n\n data.append('name', this.options.dotNotation);\n data.append('form-nonce', grav_form__WEBPACK_IMPORTED_MODULE_2__[\"config\"].form_nonce);\n\n if (file.sessionParams) {\n data.append('__form-file-remover__', '1');\n data.append('session', file.sessionParams);\n }\n\n jquery__WEBPACK_IMPORTED_MODULE_0___default.a.ajax({\n url: url,\n data: data,\n method: 'POST',\n contentType: false,\n processData: false,\n success: function success() {\n if (!path) {\n return;\n }\n\n path = global.atob(path[1]);\n\n var input = _this2.container.find('[name][type=\"hidden\"]');\n\n var data = JSON.parse(input.val() || '{}');\n delete data[path];\n input.val(JSON.stringify(data));\n }\n });\n }\n }, {\n key: \"fetchMedia\",\n value: function fetchMedia() {\n var _this3 = this;\n\n var order = this.container.closest('.form-field').find('[name=\"data[header][media_order]\"]').val();\n var data = {\n order: order\n };\n var url = this.urls.fetch;\n jquery__WEBPACK_IMPORTED_MODULE_0___default.a.ajax({\n url: url,\n method: 'POST',\n data: data,\n success: function success(response) {\n if (typeof response === 'string' || response instanceof String) {\n return false;\n }\n\n response = response.results;\n Object.keys(response).forEach(function (name) {\n var data = response[name];\n var mock = {\n name: name,\n size: data.size,\n accepted: true,\n extras: data\n };\n\n _this3.dropzone.files.push(mock);\n\n _this3.dropzone.options.addedfile.call(_this3.dropzone, mock);\n\n _this3.dropzone.options.thumbnail.call(_this3.dropzone, mock, data.url);\n });\n\n _this3.container.find('.dz-preview').prop('draggable', 'true');\n }\n });\n /*\n request(url, { method: 'post', body }, (response) => {\n let results = response.results;\n Object.keys(results).forEach((name) => {\n let data = results[name];\n let mock = { name, size: data.size, accepted: true, extras: data };\n this.dropzone.files.push(mock);\n this.dropzone.options.addedfile.call(this.dropzone, mock);\n this.dropzone.options.thumbnail.call(this.dropzone, mock, data.url);\n });\n this.container.find('.dz-preview').prop('draggable', 'true');\n });*/\n }\n }, {\n key: \"onDropzoneSending\",\n value: function onDropzoneSending(file, xhr, formData) {\n /*\n // Cannot call super because Safari and IE API don't implement `delete`\n super.onDropzoneSending(file, xhr, formData);\n formData.delete('task');\n */\n formData.append('name', this.options.dotNotation);\n formData.append('admin-nonce', grav_form__WEBPACK_IMPORTED_MODULE_2__[\"config\"].admin_nonce);\n }\n }, {\n key: \"onDropzoneComplete\",\n value: function onDropzoneComplete(file) {\n _get(_getPrototypeOf(PageMedia.prototype), \"onDropzoneComplete\", this).call(this, file);\n\n this.sortable.options.onSort(); // accepted\n\n jquery__WEBPACK_IMPORTED_MODULE_0___default()('.dz-preview').prop('draggable', 'true');\n }\n }, {\n key: \"onDropzoneRemovedFile\",\n value: function onDropzoneRemovedFile(file) {\n var _get2;\n\n for (var _len = arguments.length, extra = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n extra[_key - 1] = arguments[_key];\n }\n\n (_get2 = _get(_getPrototypeOf(PageMedia.prototype), \"onDropzoneRemovedFile\", this)).call.apply(_get2, [this, file].concat(extra));\n\n this.sortable.options.onSort();\n }\n }]);\n\n return PageMedia;\n}(_file__WEBPACK_IMPORTED_MODULE_1__[\"default\"]);\n\n\nvar Instance = new PageMedia();\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../node_modules/webpack/buildin/global.js */ \"./node_modules/webpack/buildin/global.js\")))//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9hcHAvZmllbGRzL21lZGlhLmpzPzk5MTciXSwibmFtZXMiOlsidGVtcGxhdGUiLCJ0cmFuc2xhdGlvbnMiLCJQTFVHSU5fRk9STSIsIkRFTEVURSIsInRyaW0iLCJQYWdlTWVkaWEiLCJjb250YWluZXIiLCJvcHRpb25zIiwicHJldmlld1RlbXBsYXRlIiwiJCIsImh0bWwiLCJPYmplY3QiLCJhc3NpZ24iLCJsZW5ndGgiLCJ1cmxzIiwiZmV0Y2giLCJkYXRhIiwiY29uZmlnIiwicGFyYW1fc2VwIiwiYWRkIiwiZHJvcHpvbmUiLCJ1cmwiLCJmZXRjaE1lZGlhIiwiZmllbGQiLCJzb3J0YWJsZSIsIlNvcnRhYmxlIiwiZ2V0IiwiYW5pbWF0aW9uIiwic2V0RGF0YSIsImRhdGFUcmFuc2ZlciIsInRhcmdldCIsImRpc2FibGUiLCJhZGRDbGFzcyIsImVmZmVjdEFsbG93ZWQiLCJvblNvcnQiLCJuYW1lcyIsImZpbmQiLCJlYWNoIiwiaW5kZXgiLCJmaWxlIiwibmFtZSIsInRleHQiLCJwdXNoIiwidmFsIiwiam9pbiIsImFjY2VwdGVkIiwicmVqZWN0ZWQiLCJmb3JtIiwiY2xvc2VzdCIsInVuaXF1ZV9pZCIsInJlbW92ZVVybCIsImxvY2F0aW9uIiwiaHJlZiIsInBhdGgiLCJtYXRjaCIsIkZvcm1EYXRhIiwiYXBwZW5kIiwiZG90Tm90YXRpb24iLCJmb3JtX25vbmNlIiwic2Vzc2lvblBhcmFtcyIsImFqYXgiLCJtZXRob2QiLCJjb250ZW50VHlwZSIsInByb2Nlc3NEYXRhIiwic3VjY2VzcyIsImdsb2JhbCIsImF0b2IiLCJpbnB1dCIsIkpTT04iLCJwYXJzZSIsInN0cmluZ2lmeSIsIm9yZGVyIiwicmVzcG9uc2UiLCJTdHJpbmciLCJyZXN1bHRzIiwia2V5cyIsImZvckVhY2giLCJtb2NrIiwic2l6ZSIsImV4dHJhcyIsImZpbGVzIiwiYWRkZWRmaWxlIiwiY2FsbCIsInRodW1ibmFpbCIsInByb3AiLCJ4aHIiLCJmb3JtRGF0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QW5DLENBQXdDLFdBQXhDLEVBQXFELE1BQXJEO0FBQ0g7QUFwQkUsT0FBUDtBQXVCQTs7Ozs7Ozs7Ozs7O0FBZUg7OztzQ0FFaUI3QyxJLEVBQU04QyxHLEVBQUtDLFEsRUFBVTtBQUNuQzs7Ozs7QUFNQUEsY0FBUSxDQUFDOUIsTUFBVCxDQUFnQixNQUFoQixFQUF3QixLQUFLakQsT0FBTCxDQUFha0QsV0FBckM7QUFDQTZCLGNBQVEsQ0FBQzlCLE1BQVQsQ0FBZ0IsYUFBaEIsRUFBK0J2QyxnREFBTSxDQUFDc0UsV0FBdEM7QUFDSDs7O3VDQUVrQmhELEksRUFBTTtBQUNyQix3RkFBeUJBLElBQXpCOztBQUNBLFdBQUtmLFFBQUwsQ0FBY2pCLE9BQWQsQ0FBc0IyQixNQUF0QixHQUZxQixDQUlyQjs7QUFDQXpCLG1EQUFDLENBQUMsYUFBRCxDQUFELENBQWlCMkUsSUFBakIsQ0FBc0IsV0FBdEIsRUFBbUMsTUFBbkM7QUFDSDs7OzBDQUVxQjdDLEksRUFBZ0I7QUFBQTs7QUFBQSx3Q0FBUGlELEtBQU87QUFBUEEsYUFBTztBQUFBOztBQUNsQyxtSEFBNEJqRCxJQUE1QixTQUFxQ2lELEtBQXJDOztBQUNBLFdBQUtoRSxRQUFMLENBQWNqQixPQUFkLENBQXNCMkIsTUFBdEI7QUFDSDs7OztFQXZKa0N1RCw2Qzs7O0FBMEpoQyxJQUFJQyxRQUFRLEdBQUcsSUFBSXJGLFNBQUosRUFBZixDIiwiZmlsZSI6Ii4vYXBwL2ZpZWxkcy9tZWRpYS5qcy5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAkIGZyb20gJ2pxdWVyeSc7XG5pbXBvcnQgRmlsZXNGaWVsZCBmcm9tICcuL2ZpbGUnO1xuaW1wb3J0IHsgY29uZmlnLCB0cmFuc2xhdGlvbnMgfSBmcm9tICdncmF2LWZvcm0nO1xuaW1wb3J0IFNvcnRhYmxlIGZyb20gJ3NvcnRhYmxlanMnO1xuXG5jb25zdCB0ZW1wbGF0ZSA9IGBcbiAgICA8ZGl2IGNsYXNzPVwiZHotcHJldmlldyBkei1maWxlLXByZXZpZXdcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJkei1kZXRhaWxzXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJkei1maWxlbmFtZVwiPjxzcGFuIGRhdGEtZHotbmFtZT48L3NwYW4+PC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJkei1zaXplXCIgZGF0YS1kei1zaXplPjwvZGl2PlxuICAgICAgICA8aW1nIGRhdGEtZHotdGh1bWJuYWlsIC8+XG4gICAgICA8L2Rpdj5cbiAgICAgIDxkaXYgY2xhc3M9XCJkei1wcm9ncmVzc1wiPjxzcGFuIGNsYXNzPVwiZHotdXBsb2FkXCIgZGF0YS1kei11cGxvYWRwcm9ncmVzcz48L3NwYW4+PC9kaXY+XG4gICAgICA8ZGl2IGNsYXNzPVwiZHotc3VjY2Vzcy1tYXJrXCI+PHNwYW4+4pyUPC9zcGFuPjwvZGl2PlxuICAgICAgPGRpdiBjbGFzcz1cImR6LWVycm9yLW1hcmtcIj48c3Bhbj7inJg8L3NwYW4+PC9kaXY+XG4gICAgICA8ZGl2IGNsYXNzPVwiZHotZXJyb3ItbWVzc2FnZVwiPjxzcGFuIGRhdGEtZHotZXJyb3JtZXNzYWdlPjwvc3Bhbj48L2Rpdj5cbiAgICAgIDxhIGNsYXNzPVwiZHotcmVtb3ZlXCIgdGl0bGU9XCIke3RyYW5zbGF0aW9ucy5QTFVHSU5fRk9STS5ERUxFVEV9XCIgaHJlZj1cImphdmFzY3JpcHQ6dW5kZWZpbmVkO1wiIGRhdGEtZHotcmVtb3ZlPiR7dHJhbnNsYXRpb25zLlBMVUdJTl9GT1JNLkRFTEVURX08L2E+XG4gICAgPC9kaXY+YC50cmltKCk7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFBhZ2VNZWRpYSBleHRlbmRzIEZpbGVzRmllbGQge1xuICAgIGNvbnN0cnVjdG9yKHsgY29udGFpbmVyID0gJyNncmF2LWRyb3B6b25lJywgb3B0aW9ucyA9IHt9IH0gPSB7fSkge1xuICAgICAgICBjb25zdCBwcmV2aWV3VGVtcGxhdGUgPSAkKCcjZHJvcHpvbmUtbWVkaWEtdGVtcGxhdGUnKS5odG1sKCkgfHwgdGVtcGxhdGU7XG4gICAgICAgIG9wdGlvbnMgPSBPYmplY3QuYXNzaWduKG9wdGlvbnMsIHsgcHJldmlld1RlbXBsYXRlIH0pO1xuICAgICAgICBzdXBlcih7IGNvbnRhaW5lciwgb3B0aW9ucyB9KTtcbiAgICAgICAgaWYgKCF0aGlzLmNvbnRhaW5lci5sZW5ndGgpIHsgcmV0dXJuOyB9XG5cbiAgICAgICAgdGhpcy51cmxzID0ge1xuICAgICAgICAgICAgZmV0Y2g6IGAke3RoaXMuY29udGFpbmVyLmRhdGEoJ21lZGlhLXVybCcpfS90YXNrJHtjb25maWcucGFyYW1fc2VwfWxpc3RtZWRpYWAsXG4gICAgICAgICAgICBhZGQ6IGAke3RoaXMuY29udGFpbmVyLmRhdGEoJ21lZGlhLXVybCcpfS90YXNrJHtjb25maWcucGFyYW1fc2VwfWFkZG1lZGlhYCxcbiAgICAgICAgICAgIGRlbGV0ZTogYCR7dGhpcy5jb250YWluZXIuZGF0YSgnbWVkaWEtdXJsJyl9L3Rhc2ske2NvbmZpZy5wYXJhbV9zZXB9ZGVsbWVkaWFgXG4gICAgICAgIH07XG5cbiAgICAgICAgdGhpcy5kcm9wem9uZS5vcHRpb25zLnVybCA9IHRoaXMudXJscy5hZGQ7XG5cbiAgICAgICAgaWYgKHR5cGVvZiB0aGlzLm9wdGlvbnMuZmV0Y2hNZWRpYSA9PT0gJ3VuZGVmaW5lZCcgfHwgdGhpcy5vcHRpb25zLmZldGNoTWVkaWEpIHtcbiAgICAgICAgICAgIHRoaXMuZmV0Y2hNZWRpYSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZmllbGQgPSAkKGBbbmFtZT1cIiR7dGhpcy5jb250YWluZXIuZGF0YSgnZHJvcHpvbmUtZmllbGQnKX1cIl1gKTtcblxuICAgICAgICBpZiAoZmllbGQubGVuZ3RoKSB7XG4gICAgICAgICAgICB0aGlzLnNvcnRhYmxlID0gbmV3IFNvcnRhYmxlKHRoaXMuY29udGFpbmVyLmdldCgwKSwge1xuICAgICAgICAgICAgICAgIGFuaW1hdGlvbjogMTUwLFxuICAgICAgICAgICAgICAgIC8vIGZvcmNlRmFsbGJhY2s6IHRydWUsXG4gICAgICAgICAgICAgICAgc2V0RGF0YTogKGRhdGFUcmFuc2ZlciwgdGFyZ2V0KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRhcmdldCA9ICQodGFyZ2V0KTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kcm9wem9uZS5kaXNhYmxlKCk7XG4gICAgICAgICAgICAgICAgICAgIHRhcmdldC5hZGRDbGFzcygnaGlkZS1iYWNrZmFjZScpO1xuICAgICAgICAgICAgICAgICAgICBkYXRhVHJhbnNmZXIuZWZmZWN0QWxsb3dlZCA9ICdjb3B5JztcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIG9uU29ydDogKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBsZXQgbmFtZXMgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb250YWluZXIuZmluZCgnW2RhdGEtZHotbmFtZV0nKS5lYWNoKChpbmRleCwgZmlsZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgZmlsZSA9ICQoZmlsZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBuYW1lID0gZmlsZS50ZXh0KCkudHJpbSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgbmFtZXMucHVzaChuYW1lKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgZmllbGQudmFsKG5hbWVzLmpvaW4oJywnKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBvbkRyb3B6b25lUmVtb3ZlZEZpbGUoZmlsZSwgLi4uZXh0cmEpIHtcbiAgICAgICAgaWYgKCFmaWxlLmFjY2VwdGVkIHx8IGZpbGUucmVqZWN0ZWQpIHsgcmV0dXJuOyB9XG4gICAgICAgIGNvbnN0IGZvcm0gPSB0aGlzLmNvbnRhaW5lci5jbG9zZXN0KCdmb3JtJyk7XG4gICAgICAgIGNvbnN0IHVuaXF1ZV9pZCA9IGZvcm0uZmluZCgnW25hbWU9XCJfX3VuaXF1ZV9mb3JtX2lkX19cIl0nKTtcbiAgICAgICAgbGV0IHVybCA9IGZpbGUucmVtb3ZlVXJsIHx8IHRoaXMudXJscy5kZWxldGUgfHwgYCR7bG9jYXRpb24uaHJlZn0uanNvbmA7XG4gICAgICAgIGxldCBwYXRoID0gKHVybCB8fCAnJykubWF0Y2goL3BhdGg6KC4qKVxcLy8pO1xuICAgICAgICBsZXQgZGF0YSA9IG5ldyBGb3JtRGF0YSgpO1xuXG4gICAgICAgIGRhdGEuYXBwZW5kKCdmaWxlbmFtZScsIGZpbGUubmFtZSk7XG4gICAgICAgIGRhdGEuYXBwZW5kKCdfX2Zvcm0tbmFtZV9fJywgZm9ybS5maW5kKCdbbmFtZT1cIl9fZm9ybS1uYW1lX19cIl0nKS52YWwoKSk7XG4gICAgICAgIGlmICh1bmlxdWVfaWQubGVuZ3RoKSB7XG4gICAgICAgICAgICBkYXRhLmFwcGVuZCgnX191bmlxdWVfZm9ybV9pZF9fJywgdW5pcXVlX2lkLnZhbCgpKTtcbiAgICAgICAgfVxuICAgICAgICBkYXRhLmFwcGVuZCgnbmFtZScsIHRoaXMub3B0aW9ucy5kb3ROb3RhdGlvbik7XG4gICAgICAgIGRhdGEuYXBwZW5kKCdmb3JtLW5vbmNlJywgY29uZmlnLmZvcm1fbm9uY2UpO1xuXG4gICAgICAgIGlmIChmaWxlLnNlc3Npb25QYXJhbXMpIHtcbiAgICAgICAgICAgIGRhdGEuYXBwZW5kKCdfX2Zvcm0tZmlsZS1yZW1vdmVyX18nLCAnMScpO1xuICAgICAgICAgICAgZGF0YS5hcHBlbmQoJ3Nlc3Npb24nLCBmaWxlLnNlc3Npb25QYXJhbXMpO1xuICAgICAgICB9XG5cbiAgICAgICAgJC5hamF4KHtcbiAgICAgICAgICAgIHVybCxcbiAgICAgICAgICAgIGRhdGEsXG4gICAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICAgIGNvbnRlbnRUeXBlOiBmYWxzZSxcbiAgICAgICAgICAgIHByb2Nlc3NEYXRhOiBmYWxzZSxcbiAgICAgICAgICAgIHN1Y2Nlc3M6ICgpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoIXBhdGgpIHsgcmV0dXJuOyB9XG5cbiAgICAgICAgICAgICAgICBwYXRoID0gZ2xvYmFsLmF0b2IocGF0aFsxXSk7XG4gICAgICAgICAgICAgICAgbGV0IGlucHV0ID0gdGhpcy5jb250YWluZXIuZmluZCgnW25hbWVdW3R5cGU9XCJoaWRkZW5cIl0nKTtcbiAgICAgICAgICAgICAgICBsZXQgZGF0YSA9IEpTT04ucGFyc2UoaW5wdXQudmFsKCkgfHwgJ3t9Jyk7XG4gICAgICAgICAgICAgICAgZGVsZXRlIGRhdGFbcGF0aF07XG4gICAgICAgICAgICAgICAgaW5wdXQudmFsKEpTT04uc3RyaW5naWZ5KGRhdGEpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgZmV0Y2hNZWRpYSgpIHtcbiAgICAgICAgY29uc3Qgb3JkZXIgPSB0aGlzLmNvbnRhaW5lci5jbG9zZXN0KCcuZm9ybS1maWVsZCcpLmZpbmQoJ1tuYW1lPVwiZGF0YVtoZWFkZXJdW21lZGlhX29yZGVyXVwiXScpLnZhbCgpO1xuICAgICAgICBjb25zdCBkYXRhID0geyBvcmRlciB9O1xuICAgICAgICBsZXQgdXJsID0gdGhpcy51cmxzLmZldGNoO1xuXG4gICAgICAgICQuYWpheCh7XG4gICAgICAgICAgICB1cmwsXG4gICAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICAgIGRhdGEsXG4gICAgICAgICAgICBzdWNjZXNzOiAocmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHJlc3BvbnNlID09PSAnc3RyaW5nJyB8fCByZXNwb25zZSBpbnN0YW5jZW9mIFN0cmluZykge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmVzcG9uc2UgPSByZXNwb25zZS5yZXN1bHRzO1xuICAgICAgICAgICAgICAgIE9iamVjdC5rZXlzKHJlc3BvbnNlKS5mb3JFYWNoKChuYW1lKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGxldCBkYXRhID0gcmVzcG9uc2VbbmFtZV07XG4gICAgICAgICAgICAgICAgICAgIGxldCBtb2NrID0geyBuYW1lLCBzaXplOiBkYXRhLnNpemUsIGFjY2VwdGVkOiB0cnVlLCBleHRyYXM6IGRhdGEgfTtcblxuICAgICAgICAgICAgICAgICAgICB0aGlzLmRyb3B6b25lLmZpbGVzLnB1c2gobW9jayk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZHJvcHpvbmUub3B0aW9ucy5hZGRlZGZpbGUuY2FsbCh0aGlzLmRyb3B6b25lLCBtb2NrKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kcm9wem9uZS5vcHRpb25zLnRodW1ibmFpbC5jYWxsKHRoaXMuZHJvcHpvbmUsIG1vY2ssIGRhdGEudXJsKTtcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgIHRoaXMuY29udGFpbmVyLmZpbmQoJy5kei1wcmV2aWV3JykucHJvcCgnZHJhZ2dhYmxlJywgJ3RydWUnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgLypcbiAgICAgICAgcmVxdWVzdCh1cmwsIHsgbWV0aG9kOiAncG9zdCcsIGJvZHkgfSwgKHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICBsZXQgcmVzdWx0cyA9IHJlc3BvbnNlLnJlc3VsdHM7XG5cbiAgICAgICAgICAgIE9iamVjdC5rZXlzKHJlc3VsdHMpLmZvckVhY2goKG5hbWUpID0+IHtcbiAgICAgICAgICAgICAgICBsZXQgZGF0YSA9IHJlc3VsdHNbbmFtZV07XG4gICAgICAgICAgICAgICAgbGV0IG1vY2sgPSB7IG5hbWUsIHNpemU6IGRhdGEuc2l6ZSwgYWNjZXB0ZWQ6IHRydWUsIGV4dHJhczogZGF0YSB9O1xuXG4gICAgICAgICAgICAgICAgdGhpcy5kcm9wem9uZS5maWxlcy5wdXNoKG1vY2spO1xuICAgICAgICAgICAgICAgIHRoaXMuZHJvcHpvbmUub3B0aW9ucy5hZGRlZGZpbGUuY2FsbCh0aGlzLmRyb3B6b25lLCBtb2NrKTtcbiAgICAgICAgICAgICAgICB0aGlzLmRyb3B6b25lLm9wdGlvbnMudGh1bWJuYWlsLmNhbGwodGhpcy5kcm9wem9uZSwgbW9jaywgZGF0YS51cmwpO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIHRoaXMuY29udGFpbmVyLmZpbmQoJy5kei1wcmV2aWV3JykucHJvcCgnZHJhZ2dhYmxlJywgJ3RydWUnKTtcbiAgICAgICAgfSk7Ki9cbiAgICB9XG5cbiAgICBvbkRyb3B6b25lU2VuZGluZyhmaWxlLCB4aHIsIGZvcm1EYXRhKSB7XG4gICAgICAgIC8qXG4gICAgICAgIC8vIENhbm5vdCBjYWxsIHN1cGVyIGJlY2F1c2UgU2FmYXJpIGFuZCBJRSBBUEkgZG9uJ3QgaW1wbGVtZW50IGBkZWxldGVgXG4gICAgICAgIHN1cGVyLm9uRHJvcHpvbmVTZW5kaW5nKGZpbGUsIHhociwgZm9ybURhdGEpO1xuICAgICAgICBmb3JtRGF0YS5kZWxldGUoJ3Rhc2snKTtcbiAgICAgICAgKi9cblxuICAgICAgICBmb3JtRGF0YS5hcHBlbmQoJ25hbWUnLCB0aGlzLm9wdGlvbnMuZG90Tm90YXRpb24pO1xuICAgICAgICBmb3JtRGF0YS5hcHBlbmQoJ2FkbWluLW5vbmNlJywgY29uZmlnLmFkbWluX25vbmNlKTtcbiAgICB9XG5cbiAgICBvbkRyb3B6b25lQ29tcGxldGUoZmlsZSkge1xuICAgICAgICBzdXBlci5vbkRyb3B6b25lQ29tcGxldGUoZmlsZSk7XG4gICAgICAgIHRoaXMuc29ydGFibGUub3B0aW9ucy5vblNvcnQoKTtcblxuICAgICAgICAvLyBhY2NlcHRlZFxuICAgICAgICAkKCcuZHotcHJldmlldycpLnByb3AoJ2RyYWdnYWJsZScsICd0cnVlJyk7XG4gICAgfVxuXG4gICAgb25Ecm9wem9uZVJlbW92ZWRGaWxlKGZpbGUsIC4uLmV4dHJhKSB7XG4gICAgICAgIHN1cGVyLm9uRHJvcHpvbmVSZW1vdmVkRmlsZShmaWxlLCAuLi5leHRyYSk7XG4gICAgICAgIHRoaXMuc29ydGFibGUub3B0aW9ucy5vblNvcnQoKTtcbiAgICB9XG59XG5cbmV4cG9ydCBsZXQgSW5zdGFuY2UgPSBuZXcgUGFnZU1lZGlhKCk7XG4iXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./app/fields/media.js\n");
-
-/***/ }),
-
-/***/ "./app/fields/tabs.js":
+/*! exports provided: default, Instance */function(e,l,y){"use strict";y.r(l),function(s){y.d(l,"default",function(){return a}),y.d(l,"Instance",function(){return c});var e=y(/*! jquery */"jquery"),d=y.n(e),n=y(/*! ./file */"./app/fields/file.js"),u=y(/*! grav-form */"grav-form"),p=y(/*! sortablejs */"./node_modules/sortablejs/modular/sortable.esm.js");function t(e){return(t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function r(e,a){for(var t=0;t').concat(u.translations.PLUGIN_FORM.DELETE,"\n
").trim(),a=function(){!function(e,a){if("function"!=typeof a&&null!==a)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(a&&a.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),a&&v(e,a)}(l,n["default"]);var e,a,t,c=i(l);function l(){var t,e=0 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n args[_key - 1] = arguments[_key];\n }\n\n var _iteratorNormalCompletion = true;\n var _didIteratorError = false;\n var _iteratorError = undefined;\n\n try {\n for (var _iterator = callbacks[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n var callback = _step.value;\n callback.apply(this, args);\n }\n } catch (err) {\n _didIteratorError = true;\n _iteratorError = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion && _iterator[\"return\"] != null) {\n _iterator[\"return\"]();\n }\n } finally {\n if (_didIteratorError) {\n throw _iteratorError;\n }\n }\n }\n }\n\n return this;\n } // Remove event listener for given event. If fn is not provided, all event\n // listeners for that event will be removed. If neither is provided, all\n // event listeners will be removed.\n\n }, {\n key: \"off\",\n value: function off(event, fn) {\n if (!this._callbacks || arguments.length === 0) {\n this._callbacks = {};\n return this;\n } // specific event\n\n\n var callbacks = this._callbacks[event];\n\n if (!callbacks) {\n return this;\n } // remove all handlers\n\n\n if (arguments.length === 1) {\n delete this._callbacks[event];\n return this;\n } // remove specific handler\n\n\n for (var i = 0; i < callbacks.length; i++) {\n var callback = callbacks[i];\n\n if (callback === fn) {\n callbacks.splice(i, 1);\n break;\n }\n }\n\n return this;\n }\n }]);\n\n return Emitter;\n}();\n\nvar Dropzone =\n/*#__PURE__*/\nfunction (_Emitter) {\n _inherits(Dropzone, _Emitter);\n\n _createClass(Dropzone, null, [{\n key: \"initClass\",\n value: function initClass() {\n // Exposing the emitter class, mainly for tests\n this.prototype.Emitter = Emitter;\n /*\n This is a list of all available events you can register on a dropzone object.\n You can register an event handler like this:\n dropzone.on(\"dragEnter\", function() { });\n */\n\n this.prototype.events = [\"drop\", \"dragstart\", \"dragend\", \"dragenter\", \"dragover\", \"dragleave\", \"addedfile\", \"addedfiles\", \"removedfile\", \"thumbnail\", \"error\", \"errormultiple\", \"processing\", \"processingmultiple\", \"uploadprogress\", \"totaluploadprogress\", \"sending\", \"sendingmultiple\", \"success\", \"successmultiple\", \"canceled\", \"canceledmultiple\", \"complete\", \"completemultiple\", \"reset\", \"maxfilesexceeded\", \"maxfilesreached\", \"queuecomplete\"];\n this.prototype.defaultOptions = {\n /**\n * Has to be specified on elements other than form (or when the form\n * doesn't have an `action` attribute). You can also\n * provide a function that will be called with `files` and\n * must return the url (since `v3.12.0`)\n */\n url: null,\n\n /**\n * Can be changed to `\"put\"` if necessary. You can also provide a function\n * that will be called with `files` and must return the method (since `v3.12.0`).\n */\n method: \"post\",\n\n /**\n * Will be set on the XHRequest.\n */\n withCredentials: false,\n\n /**\n * The timeout for the XHR requests in milliseconds (since `v4.4.0`).\n */\n timeout: 30000,\n\n /**\n * How many file uploads to process in parallel (See the\n * Enqueuing file uploads documentation section for more info)\n */\n parallelUploads: 2,\n\n /**\n * Whether to send multiple files in one request. If\n * this it set to true, then the fallback file input element will\n * have the `multiple` attribute as well. This option will\n * also trigger additional events (like `processingmultiple`). See the events\n * documentation section for more information.\n */\n uploadMultiple: false,\n\n /**\n * Whether you want files to be uploaded in chunks to your server. This can't be\n * used in combination with `uploadMultiple`.\n *\n * See [chunksUploaded](#config-chunksUploaded) for the callback to finalise an upload.\n */\n chunking: false,\n\n /**\n * If `chunking` is enabled, this defines whether **every** file should be chunked,\n * even if the file size is below chunkSize. This means, that the additional chunk\n * form data will be submitted and the `chunksUploaded` callback will be invoked.\n */\n forceChunking: false,\n\n /**\n * If `chunking` is `true`, then this defines the chunk size in bytes.\n */\n chunkSize: 2000000,\n\n /**\n * If `true`, the individual chunks of a file are being uploaded simultaneously.\n */\n parallelChunkUploads: false,\n\n /**\n * Whether a chunk should be retried if it fails.\n */\n retryChunks: false,\n\n /**\n * If `retryChunks` is true, how many times should it be retried.\n */\n retryChunksLimit: 3,\n\n /**\n * If not `null` defines how many files this Dropzone handles. If it exceeds,\n * the event `maxfilesexceeded` will be called. The dropzone element gets the\n * class `dz-max-files-reached` accordingly so you can provide visual feedback.\n */\n maxFilesize: 256,\n\n /**\n * The name of the file param that gets transferred.\n * **NOTE**: If you have the option `uploadMultiple` set to `true`, then\n * Dropzone will append `[]` to the name.\n */\n paramName: \"file\",\n\n /**\n * Whether thumbnails for images should be generated\n */\n createImageThumbnails: true,\n\n /**\n * In MB. When the filename exceeds this limit, the thumbnail will not be generated.\n */\n maxThumbnailFilesize: 10,\n\n /**\n * If `null`, the ratio of the image will be used to calculate it.\n */\n thumbnailWidth: 120,\n\n /**\n * The same as `thumbnailWidth`. If both are null, images will not be resized.\n */\n thumbnailHeight: 120,\n\n /**\n * How the images should be scaled down in case both, `thumbnailWidth` and `thumbnailHeight` are provided.\n * Can be either `contain` or `crop`.\n */\n thumbnailMethod: 'crop',\n\n /**\n * If set, images will be resized to these dimensions before being **uploaded**.\n * If only one, `resizeWidth` **or** `resizeHeight` is provided, the original aspect\n * ratio of the file will be preserved.\n *\n * The `options.transformFile` function uses these options, so if the `transformFile` function\n * is overridden, these options don't do anything.\n */\n resizeWidth: null,\n\n /**\n * See `resizeWidth`.\n */\n resizeHeight: null,\n\n /**\n * The mime type of the resized image (before it gets uploaded to the server).\n * If `null` the original mime type will be used. To force jpeg, for example, use `image/jpeg`.\n * See `resizeWidth` for more information.\n */\n resizeMimeType: null,\n\n /**\n * The quality of the resized images. See `resizeWidth`.\n */\n resizeQuality: 0.8,\n\n /**\n * How the images should be scaled down in case both, `resizeWidth` and `resizeHeight` are provided.\n * Can be either `contain` or `crop`.\n */\n resizeMethod: 'contain',\n\n /**\n * The base that is used to calculate the filesize. You can change this to\n * 1024 if you would rather display kibibytes, mebibytes, etc...\n * 1024 is technically incorrect, because `1024 bytes` are `1 kibibyte` not `1 kilobyte`.\n * You can change this to `1024` if you don't care about validity.\n */\n filesizeBase: 1000,\n\n /**\n * Can be used to limit the maximum number of files that will be handled by this Dropzone\n */\n maxFiles: null,\n\n /**\n * An optional object to send additional headers to the server. Eg:\n * `{ \"My-Awesome-Header\": \"header value\" }`\n */\n headers: null,\n\n /**\n * If `true`, the dropzone element itself will be clickable, if `false`\n * nothing will be clickable.\n *\n * You can also pass an HTML element, a CSS selector (for multiple elements)\n * or an array of those. In that case, all of those elements will trigger an\n * upload when clicked.\n */\n clickable: true,\n\n /**\n * Whether hidden files in directories should be ignored.\n */\n ignoreHiddenFiles: true,\n\n /**\n * The default implementation of `accept` checks the file's mime type or\n * extension against this list. This is a comma separated list of mime\n * types or file extensions.\n *\n * Eg.: `image/*,application/pdf,.psd`\n *\n * If the Dropzone is `clickable` this option will also be used as\n * [`accept`](https://developer.mozilla.org/en-US/docs/HTML/Element/input#attr-accept)\n * parameter on the hidden file input as well.\n */\n acceptedFiles: null,\n\n /**\n * **Deprecated!**\n * Use acceptedFiles instead.\n */\n acceptedMimeTypes: null,\n\n /**\n * If false, files will be added to the queue but the queue will not be\n * processed automatically.\n * This can be useful if you need some additional user input before sending\n * files (or if you want want all files sent at once).\n * If you're ready to send the file simply call `myDropzone.processQueue()`.\n *\n * See the [enqueuing file uploads](#enqueuing-file-uploads) documentation\n * section for more information.\n */\n autoProcessQueue: true,\n\n /**\n * If false, files added to the dropzone will not be queued by default.\n * You'll have to call `enqueueFile(file)` manually.\n */\n autoQueue: true,\n\n /**\n * If `true`, this will add a link to every file preview to remove or cancel (if\n * already uploading) the file. The `dictCancelUpload`, `dictCancelUploadConfirmation`\n * and `dictRemoveFile` options are used for the wording.\n */\n addRemoveLinks: false,\n\n /**\n * Defines where to display the file previews – if `null` the\n * Dropzone element itself is used. Can be a plain `HTMLElement` or a CSS\n * selector. The element should have the `dropzone-previews` class so\n * the previews are displayed properly.\n */\n previewsContainer: null,\n\n /**\n * This is the element the hidden input field (which is used when clicking on the\n * dropzone to trigger file selection) will be appended to. This might\n * be important in case you use frameworks to switch the content of your page.\n *\n * Can be a selector string, or an element directly.\n */\n hiddenInputContainer: \"body\",\n\n /**\n * If null, no capture type will be specified\n * If camera, mobile devices will skip the file selection and choose camera\n * If microphone, mobile devices will skip the file selection and choose the microphone\n * If camcorder, mobile devices will skip the file selection and choose the camera in video mode\n * On apple devices multiple must be set to false. AcceptedFiles may need to\n * be set to an appropriate mime type (e.g. \"image/*\", \"audio/*\", or \"video/*\").\n */\n capture: null,\n\n /**\n * **Deprecated**. Use `renameFile` instead.\n */\n renameFilename: null,\n\n /**\n * A function that is invoked before the file is uploaded to the server and renames the file.\n * This function gets the `File` as argument and can use the `file.name`. The actual name of the\n * file that gets used during the upload can be accessed through `file.upload.filename`.\n */\n renameFile: null,\n\n /**\n * If `true` the fallback will be forced. This is very useful to test your server\n * implementations first and make sure that everything works as\n * expected without dropzone if you experience problems, and to test\n * how your fallbacks will look.\n */\n forceFallback: false,\n\n /**\n * The text used before any files are dropped.\n */\n dictDefaultMessage: \"Drop files here to upload\",\n\n /**\n * The text that replaces the default message text it the browser is not supported.\n */\n dictFallbackMessage: \"Your browser does not support drag'n'drop file uploads.\",\n\n /**\n * The text that will be added before the fallback form.\n * If you provide a fallback element yourself, or if this option is `null` this will\n * be ignored.\n */\n dictFallbackText: \"Please use the fallback form below to upload your files like in the olden days.\",\n\n /**\n * If the filesize is too big.\n * `{{filesize}}` and `{{maxFilesize}}` will be replaced with the respective configuration values.\n */\n dictFileTooBig: \"File is too big ({{filesize}}MiB). Max filesize: {{maxFilesize}}MiB.\",\n\n /**\n * If the file doesn't match the file type.\n */\n dictInvalidFileType: \"You can't upload files of this type.\",\n\n /**\n * If the server response was invalid.\n * `{{statusCode}}` will be replaced with the servers status code.\n */\n dictResponseError: \"Server responded with {{statusCode}} code.\",\n\n /**\n * If `addRemoveLinks` is true, the text to be used for the cancel upload link.\n */\n dictCancelUpload: \"Cancel upload\",\n\n /**\n * The text that is displayed if an upload was manually canceled\n */\n dictUploadCanceled: \"Upload canceled.\",\n\n /**\n * If `addRemoveLinks` is true, the text to be used for confirmation when cancelling upload.\n */\n dictCancelUploadConfirmation: \"Are you sure you want to cancel this upload?\",\n\n /**\n * If `addRemoveLinks` is true, the text to be used to remove a file.\n */\n dictRemoveFile: \"Remove file\",\n\n /**\n * If this is not null, then the user will be prompted before removing a file.\n */\n dictRemoveFileConfirmation: null,\n\n /**\n * Displayed if `maxFiles` is st and exceeded.\n * The string `{{maxFiles}}` will be replaced by the configuration value.\n */\n dictMaxFilesExceeded: \"You can not upload any more files.\",\n\n /**\n * Allows you to translate the different units. Starting with `tb` for terabytes and going down to\n * `b` for bytes.\n */\n dictFileSizeUnits: {\n tb: \"TB\",\n gb: \"GB\",\n mb: \"MB\",\n kb: \"KB\",\n b: \"b\"\n },\n\n /**\n * Called when dropzone initialized\n * You can add event listeners here\n */\n init: function init() {},\n\n /**\n * Can be an **object** of additional parameters to transfer to the server, **or** a `Function`\n * that gets invoked with the `files`, `xhr` and, if it's a chunked upload, `chunk` arguments. In case\n * of a function, this needs to return a map.\n *\n * The default implementation does nothing for normal uploads, but adds relevant information for\n * chunked uploads.\n *\n * This is the same as adding hidden input fields in the form element.\n */\n params: function params(files, xhr, chunk) {\n if (chunk) {\n return {\n dzuuid: chunk.file.upload.uuid,\n dzchunkindex: chunk.index,\n dztotalfilesize: chunk.file.size,\n dzchunksize: this.options.chunkSize,\n dztotalchunkcount: chunk.file.upload.totalChunkCount,\n dzchunkbyteoffset: chunk.index * this.options.chunkSize\n };\n }\n },\n\n /**\n * A function that gets a [file](https://developer.mozilla.org/en-US/docs/DOM/File)\n * and a `done` function as parameters.\n *\n * If the done function is invoked without arguments, the file is \"accepted\" and will\n * be processed. If you pass an error message, the file is rejected, and the error\n * message will be displayed.\n * This function will not be called if the file is too big or doesn't match the mime types.\n */\n accept: function accept(file, done) {\n return done();\n },\n\n /**\n * The callback that will be invoked when all chunks have been uploaded for a file.\n * It gets the file for which the chunks have been uploaded as the first parameter,\n * and the `done` function as second. `done()` needs to be invoked when everything\n * needed to finish the upload process is done.\n */\n chunksUploaded: function chunksUploaded(file, done) {\n done();\n },\n\n /**\n * Gets called when the browser is not supported.\n * The default implementation shows the fallback input field and adds\n * a text.\n */\n fallback: function fallback() {\n // This code should pass in IE7... :(\n var messageElement;\n this.element.className = \"\".concat(this.element.className, \" dz-browser-not-supported\");\n var _iteratorNormalCompletion2 = true;\n var _didIteratorError2 = false;\n var _iteratorError2 = undefined;\n\n try {\n for (var _iterator2 = this.element.getElementsByTagName(\"div\")[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {\n var child = _step2.value;\n\n if (/(^| )dz-message($| )/.test(child.className)) {\n messageElement = child;\n child.className = \"dz-message\"; // Removes the 'dz-default' class\n\n break;\n }\n }\n } catch (err) {\n _didIteratorError2 = true;\n _iteratorError2 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion2 && _iterator2[\"return\"] != null) {\n _iterator2[\"return\"]();\n }\n } finally {\n if (_didIteratorError2) {\n throw _iteratorError2;\n }\n }\n }\n\n if (!messageElement) {\n messageElement = Dropzone.createElement(\"
\");\n this.element.appendChild(messageElement);\n }\n\n var span = messageElement.getElementsByTagName(\"span\")[0];\n\n if (span) {\n if (span.textContent != null) {\n span.textContent = this.options.dictFallbackMessage;\n } else if (span.innerText != null) {\n span.innerText = this.options.dictFallbackMessage;\n }\n }\n\n return this.element.appendChild(this.getFallbackForm());\n },\n\n /**\n * Gets called to calculate the thumbnail dimensions.\n *\n * It gets `file`, `width` and `height` (both may be `null`) as parameters and must return an object containing:\n *\n * - `srcWidth` & `srcHeight` (required)\n * - `trgWidth` & `trgHeight` (required)\n * - `srcX` & `srcY` (optional, default `0`)\n * - `trgX` & `trgY` (optional, default `0`)\n *\n * Those values are going to be used by `ctx.drawImage()`.\n */\n resize: function resize(file, width, height, resizeMethod) {\n var info = {\n srcX: 0,\n srcY: 0,\n srcWidth: file.width,\n srcHeight: file.height\n };\n var srcRatio = file.width / file.height; // Automatically calculate dimensions if not specified\n\n if (width == null && height == null) {\n width = info.srcWidth;\n height = info.srcHeight;\n } else if (width == null) {\n width = height * srcRatio;\n } else if (height == null) {\n height = width / srcRatio;\n } // Make sure images aren't upscaled\n\n\n width = Math.min(width, info.srcWidth);\n height = Math.min(height, info.srcHeight);\n var trgRatio = width / height;\n\n if (info.srcWidth > width || info.srcHeight > height) {\n // Image is bigger and needs rescaling\n if (resizeMethod === 'crop') {\n if (srcRatio > trgRatio) {\n info.srcHeight = file.height;\n info.srcWidth = info.srcHeight * trgRatio;\n } else {\n info.srcWidth = file.width;\n info.srcHeight = info.srcWidth / trgRatio;\n }\n } else if (resizeMethod === 'contain') {\n // Method 'contain'\n if (srcRatio > trgRatio) {\n height = width / srcRatio;\n } else {\n width = height * srcRatio;\n }\n } else {\n throw new Error(\"Unknown resizeMethod '\".concat(resizeMethod, \"'\"));\n }\n }\n\n info.srcX = (file.width - info.srcWidth) / 2;\n info.srcY = (file.height - info.srcHeight) / 2;\n info.trgWidth = width;\n info.trgHeight = height;\n return info;\n },\n\n /**\n * Can be used to transform the file (for example, resize an image if necessary).\n *\n * The default implementation uses `resizeWidth` and `resizeHeight` (if provided) and resizes\n * images according to those dimensions.\n *\n * Gets the `file` as the first parameter, and a `done()` function as the second, that needs\n * to be invoked with the file when the transformation is done.\n */\n transformFile: function transformFile(file, done) {\n if ((this.options.resizeWidth || this.options.resizeHeight) && file.type.match(/image.*/)) {\n return this.resizeImage(file, this.options.resizeWidth, this.options.resizeHeight, this.options.resizeMethod, done);\n } else {\n return done(file);\n }\n },\n\n /**\n * A string that contains the template used for each dropped\n * file. Change it to fulfill your needs but make sure to properly\n * provide all elements.\n *\n * If you want to use an actual HTML element instead of providing a String\n * as a config option, you could create a div with the id `tpl`,\n * put the template inside it and provide the element like this:\n *\n * document\n * .querySelector('#tpl')\n * .innerHTML\n *\n */\n previewTemplate: \"
\\n \\n
\\n
\\n
\\n
\\n
\\n
\\n
\\n \\n
\\n
\\n \\n
\\n
\",\n // END OPTIONS\n // (Required by the dropzone documentation parser)\n\n /*\n Those functions register themselves to the events on init and handle all\n the user interface specific stuff. Overwriting them won't break the upload\n but can break the way it's displayed.\n You can overwrite them if you don't like the default behavior. If you just\n want to add an additional event handler, register it on the dropzone object\n and don't overwrite those options.\n */\n // Those are self explanatory and simply concern the DragnDrop.\n drop: function drop(e) {\n return this.element.classList.remove(\"dz-drag-hover\");\n },\n dragstart: function dragstart(e) {},\n dragend: function dragend(e) {\n return this.element.classList.remove(\"dz-drag-hover\");\n },\n dragenter: function dragenter(e) {\n return this.element.classList.add(\"dz-drag-hover\");\n },\n dragover: function dragover(e) {\n return this.element.classList.add(\"dz-drag-hover\");\n },\n dragleave: function dragleave(e) {\n return this.element.classList.remove(\"dz-drag-hover\");\n },\n paste: function paste(e) {},\n // Called whenever there are no files left in the dropzone anymore, and the\n // dropzone should be displayed as if in the initial state.\n reset: function reset() {\n return this.element.classList.remove(\"dz-started\");\n },\n // Called when a file is added to the queue\n // Receives `file`\n addedfile: function addedfile(file) {\n var _this2 = this;\n\n if (this.element === this.previewsContainer) {\n this.element.classList.add(\"dz-started\");\n }\n\n if (this.previewsContainer) {\n file.previewElement = Dropzone.createElement(this.options.previewTemplate.trim());\n file.previewTemplate = file.previewElement; // Backwards compatibility\n\n this.previewsContainer.appendChild(file.previewElement);\n var _iteratorNormalCompletion3 = true;\n var _didIteratorError3 = false;\n var _iteratorError3 = undefined;\n\n try {\n for (var _iterator3 = file.previewElement.querySelectorAll(\"[data-dz-name]\")[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {\n var node = _step3.value;\n node.textContent = file.name;\n }\n } catch (err) {\n _didIteratorError3 = true;\n _iteratorError3 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion3 && _iterator3[\"return\"] != null) {\n _iterator3[\"return\"]();\n }\n } finally {\n if (_didIteratorError3) {\n throw _iteratorError3;\n }\n }\n }\n\n var _iteratorNormalCompletion4 = true;\n var _didIteratorError4 = false;\n var _iteratorError4 = undefined;\n\n try {\n for (var _iterator4 = file.previewElement.querySelectorAll(\"[data-dz-size]\")[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {\n node = _step4.value;\n node.innerHTML = this.filesize(file.size);\n }\n } catch (err) {\n _didIteratorError4 = true;\n _iteratorError4 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion4 && _iterator4[\"return\"] != null) {\n _iterator4[\"return\"]();\n }\n } finally {\n if (_didIteratorError4) {\n throw _iteratorError4;\n }\n }\n }\n\n if (this.options.addRemoveLinks) {\n file._removeLink = Dropzone.createElement(\"\".concat(this.options.dictRemoveFile, \"\"));\n file.previewElement.appendChild(file._removeLink);\n }\n\n var removeFileEvent = function removeFileEvent(e) {\n e.preventDefault();\n e.stopPropagation();\n\n if (file.status === Dropzone.UPLOADING) {\n return Dropzone.confirm(_this2.options.dictCancelUploadConfirmation, function () {\n return _this2.removeFile(file);\n });\n } else {\n if (_this2.options.dictRemoveFileConfirmation) {\n return Dropzone.confirm(_this2.options.dictRemoveFileConfirmation, function () {\n return _this2.removeFile(file);\n });\n } else {\n return _this2.removeFile(file);\n }\n }\n };\n\n var _iteratorNormalCompletion5 = true;\n var _didIteratorError5 = false;\n var _iteratorError5 = undefined;\n\n try {\n for (var _iterator5 = file.previewElement.querySelectorAll(\"[data-dz-remove]\")[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) {\n var removeLink = _step5.value;\n removeLink.addEventListener(\"click\", removeFileEvent);\n }\n } catch (err) {\n _didIteratorError5 = true;\n _iteratorError5 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion5 && _iterator5[\"return\"] != null) {\n _iterator5[\"return\"]();\n }\n } finally {\n if (_didIteratorError5) {\n throw _iteratorError5;\n }\n }\n }\n }\n },\n // Called whenever a file is removed.\n removedfile: function removedfile(file) {\n if (file.previewElement != null && file.previewElement.parentNode != null) {\n file.previewElement.parentNode.removeChild(file.previewElement);\n }\n\n return this._updateMaxFilesReachedClass();\n },\n // Called when a thumbnail has been generated\n // Receives `file` and `dataUrl`\n thumbnail: function thumbnail(file, dataUrl) {\n if (file.previewElement) {\n file.previewElement.classList.remove(\"dz-file-preview\");\n var _iteratorNormalCompletion6 = true;\n var _didIteratorError6 = false;\n var _iteratorError6 = undefined;\n\n try {\n for (var _iterator6 = file.previewElement.querySelectorAll(\"[data-dz-thumbnail]\")[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) {\n var thumbnailElement = _step6.value;\n thumbnailElement.alt = file.name;\n thumbnailElement.src = dataUrl;\n }\n } catch (err) {\n _didIteratorError6 = true;\n _iteratorError6 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion6 && _iterator6[\"return\"] != null) {\n _iterator6[\"return\"]();\n }\n } finally {\n if (_didIteratorError6) {\n throw _iteratorError6;\n }\n }\n }\n\n return setTimeout(function () {\n return file.previewElement.classList.add(\"dz-image-preview\");\n }, 1);\n }\n },\n // Called whenever an error occurs\n // Receives `file` and `message`\n error: function error(file, message) {\n if (file.previewElement) {\n file.previewElement.classList.add(\"dz-error\");\n\n if (typeof message !== \"String\" && message.error) {\n message = message.error;\n }\n\n var _iteratorNormalCompletion7 = true;\n var _didIteratorError7 = false;\n var _iteratorError7 = undefined;\n\n try {\n for (var _iterator7 = file.previewElement.querySelectorAll(\"[data-dz-errormessage]\")[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) {\n var node = _step7.value;\n node.textContent = message;\n }\n } catch (err) {\n _didIteratorError7 = true;\n _iteratorError7 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion7 && _iterator7[\"return\"] != null) {\n _iterator7[\"return\"]();\n }\n } finally {\n if (_didIteratorError7) {\n throw _iteratorError7;\n }\n }\n }\n }\n },\n errormultiple: function errormultiple() {},\n // Called when a file gets processed. Since there is a cue, not all added\n // files are processed immediately.\n // Receives `file`\n processing: function processing(file) {\n if (file.previewElement) {\n file.previewElement.classList.add(\"dz-processing\");\n\n if (file._removeLink) {\n return file._removeLink.innerHTML = this.options.dictCancelUpload;\n }\n }\n },\n processingmultiple: function processingmultiple() {},\n // Called whenever the upload progress gets updated.\n // Receives `file`, `progress` (percentage 0-100) and `bytesSent`.\n // To get the total number of bytes of the file, use `file.size`\n uploadprogress: function uploadprogress(file, progress, bytesSent) {\n if (file.previewElement) {\n var _iteratorNormalCompletion8 = true;\n var _didIteratorError8 = false;\n var _iteratorError8 = undefined;\n\n try {\n for (var _iterator8 = file.previewElement.querySelectorAll(\"[data-dz-uploadprogress]\")[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) {\n var node = _step8.value;\n node.nodeName === 'PROGRESS' ? node.value = progress : node.style.width = \"\".concat(progress, \"%\");\n }\n } catch (err) {\n _didIteratorError8 = true;\n _iteratorError8 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion8 && _iterator8[\"return\"] != null) {\n _iterator8[\"return\"]();\n }\n } finally {\n if (_didIteratorError8) {\n throw _iteratorError8;\n }\n }\n }\n }\n },\n // Called whenever the total upload progress gets updated.\n // Called with totalUploadProgress (0-100), totalBytes and totalBytesSent\n totaluploadprogress: function totaluploadprogress() {},\n // Called just before the file is sent. Gets the `xhr` object as second\n // parameter, so you can modify it (for example to add a CSRF token) and a\n // `formData` object to add additional information.\n sending: function sending() {},\n sendingmultiple: function sendingmultiple() {},\n // When the complete upload is finished and successful\n // Receives `file`\n success: function success(file) {\n if (file.previewElement) {\n return file.previewElement.classList.add(\"dz-success\");\n }\n },\n successmultiple: function successmultiple() {},\n // When the upload is canceled.\n canceled: function canceled(file) {\n return this.emit(\"error\", file, this.options.dictUploadCanceled);\n },\n canceledmultiple: function canceledmultiple() {},\n // When the upload is finished, either with success or an error.\n // Receives `file`\n complete: function complete(file) {\n if (file._removeLink) {\n file._removeLink.innerHTML = this.options.dictRemoveFile;\n }\n\n if (file.previewElement) {\n return file.previewElement.classList.add(\"dz-complete\");\n }\n },\n completemultiple: function completemultiple() {},\n maxfilesexceeded: function maxfilesexceeded() {},\n maxfilesreached: function maxfilesreached() {},\n queuecomplete: function queuecomplete() {},\n addedfiles: function addedfiles() {}\n };\n this.prototype._thumbnailQueue = [];\n this.prototype._processingThumbnail = false;\n } // global utility\n\n }, {\n key: \"extend\",\n value: function extend(target) {\n for (var _len2 = arguments.length, objects = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {\n objects[_key2 - 1] = arguments[_key2];\n }\n\n for (var _i = 0, _objects = objects; _i < _objects.length; _i++) {\n var object = _objects[_i];\n\n for (var key in object) {\n var val = object[key];\n target[key] = val;\n }\n }\n\n return target;\n }\n }]);\n\n function Dropzone(el, options) {\n var _this;\n\n _classCallCheck(this, Dropzone);\n\n _this = _possibleConstructorReturn(this, _getPrototypeOf(Dropzone).call(this));\n var fallback, left;\n _this.element = el; // For backwards compatibility since the version was in the prototype previously\n\n _this.version = Dropzone.version;\n _this.defaultOptions.previewTemplate = _this.defaultOptions.previewTemplate.replace(/\\n*/g, \"\");\n _this.clickableElements = [];\n _this.listeners = [];\n _this.files = []; // All files\n\n if (typeof _this.element === \"string\") {\n _this.element = document.querySelector(_this.element);\n } // Not checking if instance of HTMLElement or Element since IE9 is extremely weird.\n\n\n if (!_this.element || _this.element.nodeType == null) {\n throw new Error(\"Invalid dropzone element.\");\n }\n\n if (_this.element.dropzone) {\n throw new Error(\"Dropzone already attached.\");\n } // Now add this dropzone to the instances.\n\n\n Dropzone.instances.push(_assertThisInitialized(_this)); // Put the dropzone inside the element itself.\n\n _this.element.dropzone = _assertThisInitialized(_this);\n var elementOptions = (left = Dropzone.optionsForElement(_this.element)) != null ? left : {};\n _this.options = Dropzone.extend({}, _this.defaultOptions, elementOptions, options != null ? options : {}); // If the browser failed, just call the fallback and leave\n\n if (_this.options.forceFallback || !Dropzone.isBrowserSupported()) {\n return _possibleConstructorReturn(_this, _this.options.fallback.call(_assertThisInitialized(_this)));\n } // @options.url = @element.getAttribute \"action\" unless @options.url?\n\n\n if (_this.options.url == null) {\n _this.options.url = _this.element.getAttribute(\"action\");\n }\n\n if (!_this.options.url) {\n throw new Error(\"No URL provided.\");\n }\n\n if (_this.options.acceptedFiles && _this.options.acceptedMimeTypes) {\n throw new Error(\"You can't provide both 'acceptedFiles' and 'acceptedMimeTypes'. 'acceptedMimeTypes' is deprecated.\");\n }\n\n if (_this.options.uploadMultiple && _this.options.chunking) {\n throw new Error('You cannot set both: uploadMultiple and chunking.');\n } // Backwards compatibility\n\n\n if (_this.options.acceptedMimeTypes) {\n _this.options.acceptedFiles = _this.options.acceptedMimeTypes;\n delete _this.options.acceptedMimeTypes;\n } // Backwards compatibility\n\n\n if (_this.options.renameFilename != null) {\n _this.options.renameFile = function (file) {\n return _this.options.renameFilename.call(_assertThisInitialized(_this), file.name, file);\n };\n }\n\n _this.options.method = _this.options.method.toUpperCase();\n\n if ((fallback = _this.getExistingFallback()) && fallback.parentNode) {\n // Remove the fallback\n fallback.parentNode.removeChild(fallback);\n } // Display previews in the previewsContainer element or the Dropzone element unless explicitly set to false\n\n\n if (_this.options.previewsContainer !== false) {\n if (_this.options.previewsContainer) {\n _this.previewsContainer = Dropzone.getElement(_this.options.previewsContainer, \"previewsContainer\");\n } else {\n _this.previewsContainer = _this.element;\n }\n }\n\n if (_this.options.clickable) {\n if (_this.options.clickable === true) {\n _this.clickableElements = [_this.element];\n } else {\n _this.clickableElements = Dropzone.getElements(_this.options.clickable, \"clickable\");\n }\n }\n\n _this.init();\n\n return _this;\n } // Returns all files that have been accepted\n\n\n _createClass(Dropzone, [{\n key: \"getAcceptedFiles\",\n value: function getAcceptedFiles() {\n return this.files.filter(function (file) {\n return file.accepted;\n }).map(function (file) {\n return file;\n });\n } // Returns all files that have been rejected\n // Not sure when that's going to be useful, but added for completeness.\n\n }, {\n key: \"getRejectedFiles\",\n value: function getRejectedFiles() {\n return this.files.filter(function (file) {\n return !file.accepted;\n }).map(function (file) {\n return file;\n });\n }\n }, {\n key: \"getFilesWithStatus\",\n value: function getFilesWithStatus(status) {\n return this.files.filter(function (file) {\n return file.status === status;\n }).map(function (file) {\n return file;\n });\n } // Returns all files that are in the queue\n\n }, {\n key: \"getQueuedFiles\",\n value: function getQueuedFiles() {\n return this.getFilesWithStatus(Dropzone.QUEUED);\n }\n }, {\n key: \"getUploadingFiles\",\n value: function getUploadingFiles() {\n return this.getFilesWithStatus(Dropzone.UPLOADING);\n }\n }, {\n key: \"getAddedFiles\",\n value: function getAddedFiles() {\n return this.getFilesWithStatus(Dropzone.ADDED);\n } // Files that are either queued or uploading\n\n }, {\n key: \"getActiveFiles\",\n value: function getActiveFiles() {\n return this.files.filter(function (file) {\n return file.status === Dropzone.UPLOADING || file.status === Dropzone.QUEUED;\n }).map(function (file) {\n return file;\n });\n } // The function that gets called when Dropzone is initialized. You\n // can (and should) setup event listeners inside this function.\n\n }, {\n key: \"init\",\n value: function init() {\n var _this3 = this;\n\n // In case it isn't set already\n if (this.element.tagName === \"form\") {\n this.element.setAttribute(\"enctype\", \"multipart/form-data\");\n }\n\n if (this.element.classList.contains(\"dropzone\") && !this.element.querySelector(\".dz-message\")) {\n this.element.appendChild(Dropzone.createElement(\"\")));\n }\n\n if (this.clickableElements.length) {\n var setupHiddenFileInput = function setupHiddenFileInput() {\n if (_this3.hiddenFileInput) {\n _this3.hiddenFileInput.parentNode.removeChild(_this3.hiddenFileInput);\n }\n\n _this3.hiddenFileInput = document.createElement(\"input\");\n\n _this3.hiddenFileInput.setAttribute(\"type\", \"file\");\n\n if (_this3.options.maxFiles === null || _this3.options.maxFiles > 1) {\n _this3.hiddenFileInput.setAttribute(\"multiple\", \"multiple\");\n }\n\n _this3.hiddenFileInput.className = \"dz-hidden-input\";\n\n if (_this3.options.acceptedFiles !== null) {\n _this3.hiddenFileInput.setAttribute(\"accept\", _this3.options.acceptedFiles);\n }\n\n if (_this3.options.capture !== null) {\n _this3.hiddenFileInput.setAttribute(\"capture\", _this3.options.capture);\n } // Not setting `display=\"none\"` because some browsers don't accept clicks\n // on elements that aren't displayed.\n\n\n _this3.hiddenFileInput.style.visibility = \"hidden\";\n _this3.hiddenFileInput.style.position = \"absolute\";\n _this3.hiddenFileInput.style.top = \"0\";\n _this3.hiddenFileInput.style.left = \"0\";\n _this3.hiddenFileInput.style.height = \"0\";\n _this3.hiddenFileInput.style.width = \"0\";\n Dropzone.getElement(_this3.options.hiddenInputContainer, 'hiddenInputContainer').appendChild(_this3.hiddenFileInput);\n return _this3.hiddenFileInput.addEventListener(\"change\", function () {\n var files = _this3.hiddenFileInput.files;\n\n if (files.length) {\n var _iteratorNormalCompletion9 = true;\n var _didIteratorError9 = false;\n var _iteratorError9 = undefined;\n\n try {\n for (var _iterator9 = files[Symbol.iterator](), _step9; !(_iteratorNormalCompletion9 = (_step9 = _iterator9.next()).done); _iteratorNormalCompletion9 = true) {\n var file = _step9.value;\n\n _this3.addFile(file);\n }\n } catch (err) {\n _didIteratorError9 = true;\n _iteratorError9 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion9 && _iterator9[\"return\"] != null) {\n _iterator9[\"return\"]();\n }\n } finally {\n if (_didIteratorError9) {\n throw _iteratorError9;\n }\n }\n }\n }\n\n _this3.emit(\"addedfiles\", files);\n\n return setupHiddenFileInput();\n });\n };\n\n setupHiddenFileInput();\n }\n\n this.URL = window.URL !== null ? window.URL : window.webkitURL; // Setup all event listeners on the Dropzone object itself.\n // They're not in @setupEventListeners() because they shouldn't be removed\n // again when the dropzone gets disabled.\n\n var _iteratorNormalCompletion10 = true;\n var _didIteratorError10 = false;\n var _iteratorError10 = undefined;\n\n try {\n for (var _iterator10 = this.events[Symbol.iterator](), _step10; !(_iteratorNormalCompletion10 = (_step10 = _iterator10.next()).done); _iteratorNormalCompletion10 = true) {\n var eventName = _step10.value;\n this.on(eventName, this.options[eventName]);\n }\n } catch (err) {\n _didIteratorError10 = true;\n _iteratorError10 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion10 && _iterator10[\"return\"] != null) {\n _iterator10[\"return\"]();\n }\n } finally {\n if (_didIteratorError10) {\n throw _iteratorError10;\n }\n }\n }\n\n this.on(\"uploadprogress\", function () {\n return _this3.updateTotalUploadProgress();\n });\n this.on(\"removedfile\", function () {\n return _this3.updateTotalUploadProgress();\n });\n this.on(\"canceled\", function (file) {\n return _this3.emit(\"complete\", file);\n }); // Emit a `queuecomplete` event if all files finished uploading.\n\n this.on(\"complete\", function (file) {\n if (_this3.getAddedFiles().length === 0 && _this3.getUploadingFiles().length === 0 && _this3.getQueuedFiles().length === 0) {\n // This needs to be deferred so that `queuecomplete` really triggers after `complete`\n return setTimeout(function () {\n return _this3.emit(\"queuecomplete\");\n }, 0);\n }\n });\n\n var containsFiles = function containsFiles(e) {\n return e.dataTransfer.types && e.dataTransfer.types.some(function (type) {\n return type == \"Files\";\n });\n };\n\n var noPropagation = function noPropagation(e) {\n // If there are no files, we don't want to stop\n // propagation so we don't interfere with other\n // drag and drop behaviour.\n if (!containsFiles(e)) return;\n e.stopPropagation();\n\n if (e.preventDefault) {\n return e.preventDefault();\n } else {\n return e.returnValue = false;\n }\n }; // Create the listeners\n\n\n this.listeners = [{\n element: this.element,\n events: {\n \"dragstart\": function dragstart(e) {\n return _this3.emit(\"dragstart\", e);\n },\n \"dragenter\": function dragenter(e) {\n noPropagation(e);\n return _this3.emit(\"dragenter\", e);\n },\n \"dragover\": function dragover(e) {\n // Makes it possible to drag files from chrome's download bar\n // http://stackoverflow.com/questions/19526430/drag-and-drop-file-uploads-from-chrome-downloads-bar\n // Try is required to prevent bug in Internet Explorer 11 (SCRIPT65535 exception)\n var efct;\n\n try {\n efct = e.dataTransfer.effectAllowed;\n } catch (error) {}\n\n e.dataTransfer.dropEffect = 'move' === efct || 'linkMove' === efct ? 'move' : 'copy';\n noPropagation(e);\n return _this3.emit(\"dragover\", e);\n },\n \"dragleave\": function dragleave(e) {\n return _this3.emit(\"dragleave\", e);\n },\n \"drop\": function drop(e) {\n noPropagation(e);\n return _this3.drop(e);\n },\n \"dragend\": function dragend(e) {\n return _this3.emit(\"dragend\", e);\n }\n } // This is disabled right now, because the browsers don't implement it properly.\n // \"paste\": (e) =>\n // noPropagation e\n // @paste e\n\n }];\n this.clickableElements.forEach(function (clickableElement) {\n return _this3.listeners.push({\n element: clickableElement,\n events: {\n \"click\": function click(evt) {\n // Only the actual dropzone or the message element should trigger file selection\n if (clickableElement !== _this3.element || evt.target === _this3.element || Dropzone.elementInside(evt.target, _this3.element.querySelector(\".dz-message\"))) {\n _this3.hiddenFileInput.click(); // Forward the click\n\n }\n\n return true;\n }\n }\n });\n });\n this.enable();\n return this.options.init.call(this);\n } // Not fully tested yet\n\n }, {\n key: \"destroy\",\n value: function destroy() {\n this.disable();\n this.removeAllFiles(true);\n\n if (this.hiddenFileInput != null ? this.hiddenFileInput.parentNode : undefined) {\n this.hiddenFileInput.parentNode.removeChild(this.hiddenFileInput);\n this.hiddenFileInput = null;\n }\n\n delete this.element.dropzone;\n return Dropzone.instances.splice(Dropzone.instances.indexOf(this), 1);\n }\n }, {\n key: \"updateTotalUploadProgress\",\n value: function updateTotalUploadProgress() {\n var totalUploadProgress;\n var totalBytesSent = 0;\n var totalBytes = 0;\n var activeFiles = this.getActiveFiles();\n\n if (activeFiles.length) {\n var _iteratorNormalCompletion11 = true;\n var _didIteratorError11 = false;\n var _iteratorError11 = undefined;\n\n try {\n for (var _iterator11 = this.getActiveFiles()[Symbol.iterator](), _step11; !(_iteratorNormalCompletion11 = (_step11 = _iterator11.next()).done); _iteratorNormalCompletion11 = true) {\n var file = _step11.value;\n totalBytesSent += file.upload.bytesSent;\n totalBytes += file.upload.total;\n }\n } catch (err) {\n _didIteratorError11 = true;\n _iteratorError11 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion11 && _iterator11[\"return\"] != null) {\n _iterator11[\"return\"]();\n }\n } finally {\n if (_didIteratorError11) {\n throw _iteratorError11;\n }\n }\n }\n\n totalUploadProgress = 100 * totalBytesSent / totalBytes;\n } else {\n totalUploadProgress = 100;\n }\n\n return this.emit(\"totaluploadprogress\", totalUploadProgress, totalBytes, totalBytesSent);\n } // @options.paramName can be a function taking one parameter rather than a string.\n // A parameter name for a file is obtained simply by calling this with an index number.\n\n }, {\n key: \"_getParamName\",\n value: function _getParamName(n) {\n if (typeof this.options.paramName === \"function\") {\n return this.options.paramName(n);\n } else {\n return \"\".concat(this.options.paramName).concat(this.options.uploadMultiple ? \"[\".concat(n, \"]\") : \"\");\n }\n } // If @options.renameFile is a function,\n // the function will be used to rename the file.name before appending it to the formData\n\n }, {\n key: \"_renameFile\",\n value: function _renameFile(file) {\n if (typeof this.options.renameFile !== \"function\") {\n return file.name;\n }\n\n return this.options.renameFile(file);\n } // Returns a form that can be used as fallback if the browser does not support DragnDrop\n //\n // If the dropzone is already a form, only the input field and button are returned. Otherwise a complete form element is provided.\n // This code has to pass in IE7 :(\n\n }, {\n key: \"getFallbackForm\",\n value: function getFallbackForm() {\n var existingFallback, form;\n\n if (existingFallback = this.getExistingFallback()) {\n return existingFallback;\n }\n\n var fieldsString = \"
\";\n\n if (this.options.dictFallbackText) {\n fieldsString += \"
\".concat(this.options.dictFallbackText, \"
\");\n }\n\n fieldsString += \"
\");\n var fields = Dropzone.createElement(fieldsString);\n\n if (this.element.tagName !== \"FORM\") {\n form = Dropzone.createElement(\"\"));\n form.appendChild(fields);\n } else {\n // Make sure that the enctype and method attributes are set properly\n this.element.setAttribute(\"enctype\", \"multipart/form-data\");\n this.element.setAttribute(\"method\", this.options.method);\n }\n\n return form != null ? form : fields;\n } // Returns the fallback elements if they exist already\n //\n // This code has to pass in IE7 :(\n\n }, {\n key: \"getExistingFallback\",\n value: function getExistingFallback() {\n var getFallback = function getFallback(elements) {\n var _iteratorNormalCompletion12 = true;\n var _didIteratorError12 = false;\n var _iteratorError12 = undefined;\n\n try {\n for (var _iterator12 = elements[Symbol.iterator](), _step12; !(_iteratorNormalCompletion12 = (_step12 = _iterator12.next()).done); _iteratorNormalCompletion12 = true) {\n var el = _step12.value;\n\n if (/(^| )fallback($| )/.test(el.className)) {\n return el;\n }\n }\n } catch (err) {\n _didIteratorError12 = true;\n _iteratorError12 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion12 && _iterator12[\"return\"] != null) {\n _iterator12[\"return\"]();\n }\n } finally {\n if (_didIteratorError12) {\n throw _iteratorError12;\n }\n }\n }\n };\n\n for (var _i2 = 0, _arr = [\"div\", \"form\"]; _i2 < _arr.length; _i2++) {\n var tagName = _arr[_i2];\n var fallback;\n\n if (fallback = getFallback(this.element.getElementsByTagName(tagName))) {\n return fallback;\n }\n }\n } // Activates all listeners stored in @listeners\n\n }, {\n key: \"setupEventListeners\",\n value: function setupEventListeners() {\n return this.listeners.map(function (elementListeners) {\n return function () {\n var result = [];\n\n for (var event in elementListeners.events) {\n var listener = elementListeners.events[event];\n result.push(elementListeners.element.addEventListener(event, listener, false));\n }\n\n return result;\n }();\n });\n } // Deactivates all listeners stored in @listeners\n\n }, {\n key: \"removeEventListeners\",\n value: function removeEventListeners() {\n return this.listeners.map(function (elementListeners) {\n return function () {\n var result = [];\n\n for (var event in elementListeners.events) {\n var listener = elementListeners.events[event];\n result.push(elementListeners.element.removeEventListener(event, listener, false));\n }\n\n return result;\n }();\n });\n } // Removes all event listeners and cancels all files in the queue or being processed.\n\n }, {\n key: \"disable\",\n value: function disable() {\n var _this4 = this;\n\n this.clickableElements.forEach(function (element) {\n return element.classList.remove(\"dz-clickable\");\n });\n this.removeEventListeners();\n this.disabled = true;\n return this.files.map(function (file) {\n return _this4.cancelUpload(file);\n });\n }\n }, {\n key: \"enable\",\n value: function enable() {\n delete this.disabled;\n this.clickableElements.forEach(function (element) {\n return element.classList.add(\"dz-clickable\");\n });\n return this.setupEventListeners();\n } // Returns a nicely formatted filesize\n\n }, {\n key: \"filesize\",\n value: function filesize(size) {\n var selectedSize = 0;\n var selectedUnit = \"b\";\n\n if (size > 0) {\n var units = ['tb', 'gb', 'mb', 'kb', 'b'];\n\n for (var i = 0; i < units.length; i++) {\n var unit = units[i];\n var cutoff = Math.pow(this.options.filesizeBase, 4 - i) / 10;\n\n if (size >= cutoff) {\n selectedSize = size / Math.pow(this.options.filesizeBase, 4 - i);\n selectedUnit = unit;\n break;\n }\n }\n\n selectedSize = Math.round(10 * selectedSize) / 10; // Cutting of digits\n }\n\n return \"\".concat(selectedSize, \" \").concat(this.options.dictFileSizeUnits[selectedUnit]);\n } // Adds or removes the `dz-max-files-reached` class from the form.\n\n }, {\n key: \"_updateMaxFilesReachedClass\",\n value: function _updateMaxFilesReachedClass() {\n if (this.options.maxFiles != null && this.getAcceptedFiles().length >= this.options.maxFiles) {\n if (this.getAcceptedFiles().length === this.options.maxFiles) {\n this.emit('maxfilesreached', this.files);\n }\n\n return this.element.classList.add(\"dz-max-files-reached\");\n } else {\n return this.element.classList.remove(\"dz-max-files-reached\");\n }\n }\n }, {\n key: \"drop\",\n value: function drop(e) {\n if (!e.dataTransfer) {\n return;\n }\n\n this.emit(\"drop\", e); // Convert the FileList to an Array\n // This is necessary for IE11\n\n var files = [];\n\n for (var i = 0; i < e.dataTransfer.files.length; i++) {\n files[i] = e.dataTransfer.files[i];\n } // Even if it's a folder, files.length will contain the folders.\n\n\n if (files.length) {\n var items = e.dataTransfer.items;\n\n if (items && items.length && items[0].webkitGetAsEntry != null) {\n // The browser supports dropping of folders, so handle items instead of files\n this._addFilesFromItems(items);\n } else {\n this.handleFiles(files);\n }\n }\n\n this.emit(\"addedfiles\", files);\n }\n }, {\n key: \"paste\",\n value: function paste(e) {\n if (__guard__(e != null ? e.clipboardData : undefined, function (x) {\n return x.items;\n }) == null) {\n return;\n }\n\n this.emit(\"paste\", e);\n var items = e.clipboardData.items;\n\n if (items.length) {\n return this._addFilesFromItems(items);\n }\n }\n }, {\n key: \"handleFiles\",\n value: function handleFiles(files) {\n var _iteratorNormalCompletion13 = true;\n var _didIteratorError13 = false;\n var _iteratorError13 = undefined;\n\n try {\n for (var _iterator13 = files[Symbol.iterator](), _step13; !(_iteratorNormalCompletion13 = (_step13 = _iterator13.next()).done); _iteratorNormalCompletion13 = true) {\n var file = _step13.value;\n this.addFile(file);\n }\n } catch (err) {\n _didIteratorError13 = true;\n _iteratorError13 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion13 && _iterator13[\"return\"] != null) {\n _iterator13[\"return\"]();\n }\n } finally {\n if (_didIteratorError13) {\n throw _iteratorError13;\n }\n }\n }\n } // When a folder is dropped (or files are pasted), items must be handled\n // instead of files.\n\n }, {\n key: \"_addFilesFromItems\",\n value: function _addFilesFromItems(items) {\n var _this5 = this;\n\n return function () {\n var result = [];\n var _iteratorNormalCompletion14 = true;\n var _didIteratorError14 = false;\n var _iteratorError14 = undefined;\n\n try {\n for (var _iterator14 = items[Symbol.iterator](), _step14; !(_iteratorNormalCompletion14 = (_step14 = _iterator14.next()).done); _iteratorNormalCompletion14 = true) {\n var item = _step14.value;\n var entry;\n\n if (item.webkitGetAsEntry != null && (entry = item.webkitGetAsEntry())) {\n if (entry.isFile) {\n result.push(_this5.addFile(item.getAsFile()));\n } else if (entry.isDirectory) {\n // Append all files from that directory to files\n result.push(_this5._addFilesFromDirectory(entry, entry.name));\n } else {\n result.push(undefined);\n }\n } else if (item.getAsFile != null) {\n if (item.kind == null || item.kind === \"file\") {\n result.push(_this5.addFile(item.getAsFile()));\n } else {\n result.push(undefined);\n }\n } else {\n result.push(undefined);\n }\n }\n } catch (err) {\n _didIteratorError14 = true;\n _iteratorError14 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion14 && _iterator14[\"return\"] != null) {\n _iterator14[\"return\"]();\n }\n } finally {\n if (_didIteratorError14) {\n throw _iteratorError14;\n }\n }\n }\n\n return result;\n }();\n } // Goes through the directory, and adds each file it finds recursively\n\n }, {\n key: \"_addFilesFromDirectory\",\n value: function _addFilesFromDirectory(directory, path) {\n var _this6 = this;\n\n var dirReader = directory.createReader();\n\n var errorHandler = function errorHandler(error) {\n return __guardMethod__(console, 'log', function (o) {\n return o.log(error);\n });\n };\n\n var readEntries = function readEntries() {\n return dirReader.readEntries(function (entries) {\n if (entries.length > 0) {\n var _iteratorNormalCompletion15 = true;\n var _didIteratorError15 = false;\n var _iteratorError15 = undefined;\n\n try {\n for (var _iterator15 = entries[Symbol.iterator](), _step15; !(_iteratorNormalCompletion15 = (_step15 = _iterator15.next()).done); _iteratorNormalCompletion15 = true) {\n var entry = _step15.value;\n\n if (entry.isFile) {\n entry.file(function (file) {\n if (_this6.options.ignoreHiddenFiles && file.name.substring(0, 1) === '.') {\n return;\n }\n\n file.fullPath = \"\".concat(path, \"/\").concat(file.name);\n return _this6.addFile(file);\n });\n } else if (entry.isDirectory) {\n _this6._addFilesFromDirectory(entry, \"\".concat(path, \"/\").concat(entry.name));\n }\n } // Recursively call readEntries() again, since browser only handle\n // the first 100 entries.\n // See: https://developer.mozilla.org/en-US/docs/Web/API/DirectoryReader#readEntries\n\n } catch (err) {\n _didIteratorError15 = true;\n _iteratorError15 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion15 && _iterator15[\"return\"] != null) {\n _iterator15[\"return\"]();\n }\n } finally {\n if (_didIteratorError15) {\n throw _iteratorError15;\n }\n }\n }\n\n readEntries();\n }\n\n return null;\n }, errorHandler);\n };\n\n return readEntries();\n } // If `done()` is called without argument the file is accepted\n // If you call it with an error message, the file is rejected\n // (This allows for asynchronous validation)\n //\n // This function checks the filesize, and if the file.type passes the\n // `acceptedFiles` check.\n\n }, {\n key: \"accept\",\n value: function accept(file, done) {\n if (this.options.maxFilesize && file.size > this.options.maxFilesize * 1024 * 1024) {\n done(this.options.dictFileTooBig.replace(\"{{filesize}}\", Math.round(file.size / 1024 / 10.24) / 100).replace(\"{{maxFilesize}}\", this.options.maxFilesize));\n } else if (!Dropzone.isValidFile(file, this.options.acceptedFiles)) {\n done(this.options.dictInvalidFileType);\n } else if (this.options.maxFiles != null && this.getAcceptedFiles().length >= this.options.maxFiles) {\n done(this.options.dictMaxFilesExceeded.replace(\"{{maxFiles}}\", this.options.maxFiles));\n this.emit(\"maxfilesexceeded\", file);\n } else {\n this.options.accept.call(this, file, done);\n }\n }\n }, {\n key: \"addFile\",\n value: function addFile(file) {\n var _this7 = this;\n\n file.upload = {\n uuid: Dropzone.uuidv4(),\n progress: 0,\n // Setting the total upload size to file.size for the beginning\n // It's actual different than the size to be transmitted.\n total: file.size,\n bytesSent: 0,\n filename: this._renameFile(file) // Not setting chunking information here, because the acutal data — and\n // thus the chunks — might change if `options.transformFile` is set\n // and does something to the data.\n\n };\n this.files.push(file);\n file.status = Dropzone.ADDED;\n this.emit(\"addedfile\", file);\n\n this._enqueueThumbnail(file);\n\n this.accept(file, function (error) {\n if (error) {\n file.accepted = false;\n\n _this7._errorProcessing([file], error); // Will set the file.status\n\n } else {\n file.accepted = true;\n\n if (_this7.options.autoQueue) {\n _this7.enqueueFile(file);\n } // Will set .accepted = true\n\n }\n\n _this7._updateMaxFilesReachedClass();\n });\n } // Wrapper for enqueueFile\n\n }, {\n key: \"enqueueFiles\",\n value: function enqueueFiles(files) {\n var _iteratorNormalCompletion16 = true;\n var _didIteratorError16 = false;\n var _iteratorError16 = undefined;\n\n try {\n for (var _iterator16 = files[Symbol.iterator](), _step16; !(_iteratorNormalCompletion16 = (_step16 = _iterator16.next()).done); _iteratorNormalCompletion16 = true) {\n var file = _step16.value;\n this.enqueueFile(file);\n }\n } catch (err) {\n _didIteratorError16 = true;\n _iteratorError16 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion16 && _iterator16[\"return\"] != null) {\n _iterator16[\"return\"]();\n }\n } finally {\n if (_didIteratorError16) {\n throw _iteratorError16;\n }\n }\n }\n\n return null;\n }\n }, {\n key: \"enqueueFile\",\n value: function enqueueFile(file) {\n var _this8 = this;\n\n if (file.status === Dropzone.ADDED && file.accepted === true) {\n file.status = Dropzone.QUEUED;\n\n if (this.options.autoProcessQueue) {\n return setTimeout(function () {\n return _this8.processQueue();\n }, 0); // Deferring the call\n }\n } else {\n throw new Error(\"This file can't be queued because it has already been processed or was rejected.\");\n }\n }\n }, {\n key: \"_enqueueThumbnail\",\n value: function _enqueueThumbnail(file) {\n var _this9 = this;\n\n if (this.options.createImageThumbnails && file.type.match(/image.*/) && file.size <= this.options.maxThumbnailFilesize * 1024 * 1024) {\n this._thumbnailQueue.push(file);\n\n return setTimeout(function () {\n return _this9._processThumbnailQueue();\n }, 0); // Deferring the call\n }\n }\n }, {\n key: \"_processThumbnailQueue\",\n value: function _processThumbnailQueue() {\n var _this10 = this;\n\n if (this._processingThumbnail || this._thumbnailQueue.length === 0) {\n return;\n }\n\n this._processingThumbnail = true;\n\n var file = this._thumbnailQueue.shift();\n\n return this.createThumbnail(file, this.options.thumbnailWidth, this.options.thumbnailHeight, this.options.thumbnailMethod, true, function (dataUrl) {\n _this10.emit(\"thumbnail\", file, dataUrl);\n\n _this10._processingThumbnail = false;\n return _this10._processThumbnailQueue();\n });\n } // Can be called by the user to remove a file\n\n }, {\n key: \"removeFile\",\n value: function removeFile(file) {\n if (file.status === Dropzone.UPLOADING) {\n this.cancelUpload(file);\n }\n\n this.files = without(this.files, file);\n this.emit(\"removedfile\", file);\n\n if (this.files.length === 0) {\n return this.emit(\"reset\");\n }\n } // Removes all files that aren't currently processed from the list\n\n }, {\n key: \"removeAllFiles\",\n value: function removeAllFiles(cancelIfNecessary) {\n // Create a copy of files since removeFile() changes the @files array.\n if (cancelIfNecessary == null) {\n cancelIfNecessary = false;\n }\n\n var _iteratorNormalCompletion17 = true;\n var _didIteratorError17 = false;\n var _iteratorError17 = undefined;\n\n try {\n for (var _iterator17 = this.files.slice()[Symbol.iterator](), _step17; !(_iteratorNormalCompletion17 = (_step17 = _iterator17.next()).done); _iteratorNormalCompletion17 = true) {\n var file = _step17.value;\n\n if (file.status !== Dropzone.UPLOADING || cancelIfNecessary) {\n this.removeFile(file);\n }\n }\n } catch (err) {\n _didIteratorError17 = true;\n _iteratorError17 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion17 && _iterator17[\"return\"] != null) {\n _iterator17[\"return\"]();\n }\n } finally {\n if (_didIteratorError17) {\n throw _iteratorError17;\n }\n }\n }\n\n return null;\n } // Resizes an image before it gets sent to the server. This function is the default behavior of\n // `options.transformFile` if `resizeWidth` or `resizeHeight` are set. The callback is invoked with\n // the resized blob.\n\n }, {\n key: \"resizeImage\",\n value: function resizeImage(file, width, height, resizeMethod, callback) {\n var _this11 = this;\n\n return this.createThumbnail(file, width, height, resizeMethod, true, function (dataUrl, canvas) {\n if (canvas == null) {\n // The image has not been resized\n return callback(file);\n } else {\n var resizeMimeType = _this11.options.resizeMimeType;\n\n if (resizeMimeType == null) {\n resizeMimeType = file.type;\n }\n\n var resizedDataURL = canvas.toDataURL(resizeMimeType, _this11.options.resizeQuality);\n\n if (resizeMimeType === 'image/jpeg' || resizeMimeType === 'image/jpg') {\n // Now add the original EXIF information\n resizedDataURL = ExifRestore.restore(file.dataURL, resizedDataURL);\n }\n\n return callback(Dropzone.dataURItoBlob(resizedDataURL));\n }\n });\n }\n }, {\n key: \"createThumbnail\",\n value: function createThumbnail(file, width, height, resizeMethod, fixOrientation, callback) {\n var _this12 = this;\n\n var fileReader = new FileReader();\n\n fileReader.onload = function () {\n file.dataURL = fileReader.result; // Don't bother creating a thumbnail for SVG images since they're vector\n\n if (file.type === \"image/svg+xml\") {\n if (callback != null) {\n callback(fileReader.result);\n }\n\n return;\n }\n\n _this12.createThumbnailFromUrl(file, width, height, resizeMethod, fixOrientation, callback);\n };\n\n fileReader.readAsDataURL(file);\n } // `mockFile` needs to have these attributes:\n // \n // { name: 'name', size: 12345, imageUrl: '' }\n //\n // `callback` will be invoked when the image has been downloaded and displayed.\n // `crossOrigin` will be added to the `img` tag when accessing the file.\n\n }, {\n key: \"displayExistingFile\",\n value: function displayExistingFile(mockFile, imageUrl, callback, crossOrigin) {\n var _this13 = this;\n\n var resizeThumbnail = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true;\n this.emit(\"addedfile\", mockFile);\n this.emit(\"complete\", mockFile);\n\n if (!resizeThumbnail) {\n this.emit(\"thumbnail\", mockFile, imageUrl);\n if (callback) callback();\n } else {\n var onDone = function onDone(thumbnail) {\n _this13.emit('thumbnail', mockFile, thumbnail);\n\n if (callback) callback();\n };\n\n mockFile.dataURL = imageUrl;\n this.createThumbnailFromUrl(mockFile, this.options.thumbnailWidth, this.options.thumbnailHeight, this.options.resizeMethod, this.options.fixOrientation, onDone, crossOrigin);\n }\n }\n }, {\n key: \"createThumbnailFromUrl\",\n value: function createThumbnailFromUrl(file, width, height, resizeMethod, fixOrientation, callback, crossOrigin) {\n var _this14 = this;\n\n // Not using `new Image` here because of a bug in latest Chrome versions.\n // See https://github.com/enyo/dropzone/pull/226\n var img = document.createElement(\"img\");\n\n if (crossOrigin) {\n img.crossOrigin = crossOrigin;\n }\n\n img.onload = function () {\n var loadExif = function loadExif(callback) {\n return callback(1);\n };\n\n if (typeof EXIF !== 'undefined' && EXIF !== null && fixOrientation) {\n loadExif = function loadExif(callback) {\n return EXIF.getData(img, function () {\n return callback(EXIF.getTag(this, 'Orientation'));\n });\n };\n }\n\n return loadExif(function (orientation) {\n file.width = img.width;\n file.height = img.height;\n\n var resizeInfo = _this14.options.resize.call(_this14, file, width, height, resizeMethod);\n\n var canvas = document.createElement(\"canvas\");\n var ctx = canvas.getContext(\"2d\");\n canvas.width = resizeInfo.trgWidth;\n canvas.height = resizeInfo.trgHeight;\n\n if (orientation > 4) {\n canvas.width = resizeInfo.trgHeight;\n canvas.height = resizeInfo.trgWidth;\n }\n\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(canvas.width, 0);\n ctx.scale(-1, 1);\n break;\n\n case 3:\n // 180° rotate left\n ctx.translate(canvas.width, canvas.height);\n ctx.rotate(Math.PI);\n break;\n\n case 4:\n // vertical flip\n ctx.translate(0, canvas.height);\n ctx.scale(1, -1);\n break;\n\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n\n case 6:\n // 90° rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -canvas.width);\n break;\n\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(canvas.height, -canvas.width);\n ctx.scale(-1, 1);\n break;\n\n case 8:\n // 90° rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-canvas.height, 0);\n break;\n } // This is a bugfix for iOS' scaling bug.\n\n\n drawImageIOSFix(ctx, img, resizeInfo.srcX != null ? resizeInfo.srcX : 0, resizeInfo.srcY != null ? resizeInfo.srcY : 0, resizeInfo.srcWidth, resizeInfo.srcHeight, resizeInfo.trgX != null ? resizeInfo.trgX : 0, resizeInfo.trgY != null ? resizeInfo.trgY : 0, resizeInfo.trgWidth, resizeInfo.trgHeight);\n var thumbnail = canvas.toDataURL(\"image/png\");\n\n if (callback != null) {\n return callback(thumbnail, canvas);\n }\n });\n };\n\n if (callback != null) {\n img.onerror = callback;\n }\n\n return img.src = file.dataURL;\n } // Goes through the queue and processes files if there aren't too many already.\n\n }, {\n key: \"processQueue\",\n value: function processQueue() {\n var parallelUploads = this.options.parallelUploads;\n var processingLength = this.getUploadingFiles().length;\n var i = processingLength; // There are already at least as many files uploading than should be\n\n if (processingLength >= parallelUploads) {\n return;\n }\n\n var queuedFiles = this.getQueuedFiles();\n\n if (!(queuedFiles.length > 0)) {\n return;\n }\n\n if (this.options.uploadMultiple) {\n // The files should be uploaded in one request\n return this.processFiles(queuedFiles.slice(0, parallelUploads - processingLength));\n } else {\n while (i < parallelUploads) {\n if (!queuedFiles.length) {\n return;\n } // Nothing left to process\n\n\n this.processFile(queuedFiles.shift());\n i++;\n }\n }\n } // Wrapper for `processFiles`\n\n }, {\n key: \"processFile\",\n value: function processFile(file) {\n return this.processFiles([file]);\n } // Loads the file, then calls finishedLoading()\n\n }, {\n key: \"processFiles\",\n value: function processFiles(files) {\n var _iteratorNormalCompletion18 = true;\n var _didIteratorError18 = false;\n var _iteratorError18 = undefined;\n\n try {\n for (var _iterator18 = files[Symbol.iterator](), _step18; !(_iteratorNormalCompletion18 = (_step18 = _iterator18.next()).done); _iteratorNormalCompletion18 = true) {\n var file = _step18.value;\n file.processing = true; // Backwards compatibility\n\n file.status = Dropzone.UPLOADING;\n this.emit(\"processing\", file);\n }\n } catch (err) {\n _didIteratorError18 = true;\n _iteratorError18 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion18 && _iterator18[\"return\"] != null) {\n _iterator18[\"return\"]();\n }\n } finally {\n if (_didIteratorError18) {\n throw _iteratorError18;\n }\n }\n }\n\n if (this.options.uploadMultiple) {\n this.emit(\"processingmultiple\", files);\n }\n\n return this.uploadFiles(files);\n }\n }, {\n key: \"_getFilesWithXhr\",\n value: function _getFilesWithXhr(xhr) {\n var files;\n return files = this.files.filter(function (file) {\n return file.xhr === xhr;\n }).map(function (file) {\n return file;\n });\n } // Cancels the file upload and sets the status to CANCELED\n // **if** the file is actually being uploaded.\n // If it's still in the queue, the file is being removed from it and the status\n // set to CANCELED.\n\n }, {\n key: \"cancelUpload\",\n value: function cancelUpload(file) {\n if (file.status === Dropzone.UPLOADING) {\n var groupedFiles = this._getFilesWithXhr(file.xhr);\n\n var _iteratorNormalCompletion19 = true;\n var _didIteratorError19 = false;\n var _iteratorError19 = undefined;\n\n try {\n for (var _iterator19 = groupedFiles[Symbol.iterator](), _step19; !(_iteratorNormalCompletion19 = (_step19 = _iterator19.next()).done); _iteratorNormalCompletion19 = true) {\n var groupedFile = _step19.value;\n groupedFile.status = Dropzone.CANCELED;\n }\n } catch (err) {\n _didIteratorError19 = true;\n _iteratorError19 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion19 && _iterator19[\"return\"] != null) {\n _iterator19[\"return\"]();\n }\n } finally {\n if (_didIteratorError19) {\n throw _iteratorError19;\n }\n }\n }\n\n if (typeof file.xhr !== 'undefined') {\n file.xhr.abort();\n }\n\n var _iteratorNormalCompletion20 = true;\n var _didIteratorError20 = false;\n var _iteratorError20 = undefined;\n\n try {\n for (var _iterator20 = groupedFiles[Symbol.iterator](), _step20; !(_iteratorNormalCompletion20 = (_step20 = _iterator20.next()).done); _iteratorNormalCompletion20 = true) {\n var _groupedFile = _step20.value;\n this.emit(\"canceled\", _groupedFile);\n }\n } catch (err) {\n _didIteratorError20 = true;\n _iteratorError20 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion20 && _iterator20[\"return\"] != null) {\n _iterator20[\"return\"]();\n }\n } finally {\n if (_didIteratorError20) {\n throw _iteratorError20;\n }\n }\n }\n\n if (this.options.uploadMultiple) {\n this.emit(\"canceledmultiple\", groupedFiles);\n }\n } else if (file.status === Dropzone.ADDED || file.status === Dropzone.QUEUED) {\n file.status = Dropzone.CANCELED;\n this.emit(\"canceled\", file);\n\n if (this.options.uploadMultiple) {\n this.emit(\"canceledmultiple\", [file]);\n }\n }\n\n if (this.options.autoProcessQueue) {\n return this.processQueue();\n }\n }\n }, {\n key: \"resolveOption\",\n value: function resolveOption(option) {\n if (typeof option === 'function') {\n for (var _len3 = arguments.length, args = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {\n args[_key3 - 1] = arguments[_key3];\n }\n\n return option.apply(this, args);\n }\n\n return option;\n }\n }, {\n key: \"uploadFile\",\n value: function uploadFile(file) {\n return this.uploadFiles([file]);\n }\n }, {\n key: \"uploadFiles\",\n value: function uploadFiles(files) {\n var _this15 = this;\n\n this._transformFiles(files, function (transformedFiles) {\n if (_this15.options.chunking) {\n // Chunking is not allowed to be used with `uploadMultiple` so we know\n // that there is only __one__file.\n var transformedFile = transformedFiles[0];\n files[0].upload.chunked = _this15.options.chunking && (_this15.options.forceChunking || transformedFile.size > _this15.options.chunkSize);\n files[0].upload.totalChunkCount = Math.ceil(transformedFile.size / _this15.options.chunkSize);\n }\n\n if (files[0].upload.chunked) {\n // This file should be sent in chunks!\n // If the chunking option is set, we **know** that there can only be **one** file, since\n // uploadMultiple is not allowed with this option.\n var file = files[0];\n var _transformedFile = transformedFiles[0];\n var startedChunkCount = 0;\n file.upload.chunks = [];\n\n var handleNextChunk = function handleNextChunk() {\n var chunkIndex = 0; // Find the next item in file.upload.chunks that is not defined yet.\n\n while (file.upload.chunks[chunkIndex] !== undefined) {\n chunkIndex++;\n } // This means, that all chunks have already been started.\n\n\n if (chunkIndex >= file.upload.totalChunkCount) return;\n startedChunkCount++;\n var start = chunkIndex * _this15.options.chunkSize;\n var end = Math.min(start + _this15.options.chunkSize, file.size);\n var dataBlock = {\n name: _this15._getParamName(0),\n data: _transformedFile.webkitSlice ? _transformedFile.webkitSlice(start, end) : _transformedFile.slice(start, end),\n filename: file.upload.filename,\n chunkIndex: chunkIndex\n };\n file.upload.chunks[chunkIndex] = {\n file: file,\n index: chunkIndex,\n dataBlock: dataBlock,\n // In case we want to retry.\n status: Dropzone.UPLOADING,\n progress: 0,\n retries: 0 // The number of times this block has been retried.\n\n };\n\n _this15._uploadData(files, [dataBlock]);\n };\n\n file.upload.finishedChunkUpload = function (chunk) {\n var allFinished = true;\n chunk.status = Dropzone.SUCCESS; // Clear the data from the chunk\n\n chunk.dataBlock = null; // Leaving this reference to xhr intact here will cause memory leaks in some browsers\n\n chunk.xhr = null;\n\n for (var i = 0; i < file.upload.totalChunkCount; i++) {\n if (file.upload.chunks[i] === undefined) {\n return handleNextChunk();\n }\n\n if (file.upload.chunks[i].status !== Dropzone.SUCCESS) {\n allFinished = false;\n }\n }\n\n if (allFinished) {\n _this15.options.chunksUploaded(file, function () {\n _this15._finished(files, '', null);\n });\n }\n };\n\n if (_this15.options.parallelChunkUploads) {\n for (var i = 0; i < file.upload.totalChunkCount; i++) {\n handleNextChunk();\n }\n } else {\n handleNextChunk();\n }\n } else {\n var dataBlocks = [];\n\n for (var _i3 = 0; _i3 < files.length; _i3++) {\n dataBlocks[_i3] = {\n name: _this15._getParamName(_i3),\n data: transformedFiles[_i3],\n filename: files[_i3].upload.filename\n };\n }\n\n _this15._uploadData(files, dataBlocks);\n }\n });\n } /// Returns the right chunk for given file and xhr\n\n }, {\n key: \"_getChunk\",\n value: function _getChunk(file, xhr) {\n for (var i = 0; i < file.upload.totalChunkCount; i++) {\n if (file.upload.chunks[i] !== undefined && file.upload.chunks[i].xhr === xhr) {\n return file.upload.chunks[i];\n }\n }\n } // This function actually uploads the file(s) to the server.\n // If dataBlocks contains the actual data to upload (meaning, that this could either be transformed\n // files, or individual chunks for chunked upload).\n\n }, {\n key: \"_uploadData\",\n value: function _uploadData(files, dataBlocks) {\n var _this16 = this;\n\n var xhr = new XMLHttpRequest(); // Put the xhr object in the file objects to be able to reference it later.\n\n var _iteratorNormalCompletion21 = true;\n var _didIteratorError21 = false;\n var _iteratorError21 = undefined;\n\n try {\n for (var _iterator21 = files[Symbol.iterator](), _step21; !(_iteratorNormalCompletion21 = (_step21 = _iterator21.next()).done); _iteratorNormalCompletion21 = true) {\n var file = _step21.value;\n file.xhr = xhr;\n }\n } catch (err) {\n _didIteratorError21 = true;\n _iteratorError21 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion21 && _iterator21[\"return\"] != null) {\n _iterator21[\"return\"]();\n }\n } finally {\n if (_didIteratorError21) {\n throw _iteratorError21;\n }\n }\n }\n\n if (files[0].upload.chunked) {\n // Put the xhr object in the right chunk object, so it can be associated later, and found with _getChunk\n files[0].upload.chunks[dataBlocks[0].chunkIndex].xhr = xhr;\n }\n\n var method = this.resolveOption(this.options.method, files);\n var url = this.resolveOption(this.options.url, files);\n xhr.open(method, url, true); // Setting the timeout after open because of IE11 issue: https://gitlab.com/meno/dropzone/issues/8\n\n xhr.timeout = this.resolveOption(this.options.timeout, files); // Has to be after `.open()`. See https://github.com/enyo/dropzone/issues/179\n\n xhr.withCredentials = !!this.options.withCredentials;\n\n xhr.onload = function (e) {\n _this16._finishedUploading(files, xhr, e);\n };\n\n xhr.ontimeout = function () {\n _this16._handleUploadError(files, xhr, \"Request timedout after \".concat(_this16.options.timeout, \" seconds\"));\n };\n\n xhr.onerror = function () {\n _this16._handleUploadError(files, xhr);\n }; // Some browsers do not have the .upload property\n\n\n var progressObj = xhr.upload != null ? xhr.upload : xhr;\n\n progressObj.onprogress = function (e) {\n return _this16._updateFilesUploadProgress(files, xhr, e);\n };\n\n var headers = {\n \"Accept\": \"application/json\",\n \"Cache-Control\": \"no-cache\",\n \"X-Requested-With\": \"XMLHttpRequest\"\n };\n\n if (this.options.headers) {\n Dropzone.extend(headers, this.options.headers);\n }\n\n for (var headerName in headers) {\n var headerValue = headers[headerName];\n\n if (headerValue) {\n xhr.setRequestHeader(headerName, headerValue);\n }\n }\n\n var formData = new FormData(); // Adding all @options parameters\n\n if (this.options.params) {\n var additionalParams = this.options.params;\n\n if (typeof additionalParams === 'function') {\n additionalParams = additionalParams.call(this, files, xhr, files[0].upload.chunked ? this._getChunk(files[0], xhr) : null);\n }\n\n for (var key in additionalParams) {\n var value = additionalParams[key];\n formData.append(key, value);\n }\n } // Let the user add additional data if necessary\n\n\n var _iteratorNormalCompletion22 = true;\n var _didIteratorError22 = false;\n var _iteratorError22 = undefined;\n\n try {\n for (var _iterator22 = files[Symbol.iterator](), _step22; !(_iteratorNormalCompletion22 = (_step22 = _iterator22.next()).done); _iteratorNormalCompletion22 = true) {\n var _file = _step22.value;\n this.emit(\"sending\", _file, xhr, formData);\n }\n } catch (err) {\n _didIteratorError22 = true;\n _iteratorError22 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion22 && _iterator22[\"return\"] != null) {\n _iterator22[\"return\"]();\n }\n } finally {\n if (_didIteratorError22) {\n throw _iteratorError22;\n }\n }\n }\n\n if (this.options.uploadMultiple) {\n this.emit(\"sendingmultiple\", files, xhr, formData);\n }\n\n this._addFormElementData(formData); // Finally add the files\n // Has to be last because some servers (eg: S3) expect the file to be the last parameter\n\n\n for (var i = 0; i < dataBlocks.length; i++) {\n var dataBlock = dataBlocks[i];\n formData.append(dataBlock.name, dataBlock.data, dataBlock.filename);\n }\n\n this.submitRequest(xhr, formData, files);\n } // Transforms all files with this.options.transformFile and invokes done with the transformed files when done.\n\n }, {\n key: \"_transformFiles\",\n value: function _transformFiles(files, done) {\n var _this17 = this;\n\n var transformedFiles = []; // Clumsy way of handling asynchronous calls, until I get to add a proper Future library.\n\n var doneCounter = 0;\n\n var _loop = function _loop(i) {\n _this17.options.transformFile.call(_this17, files[i], function (transformedFile) {\n transformedFiles[i] = transformedFile;\n\n if (++doneCounter === files.length) {\n done(transformedFiles);\n }\n });\n };\n\n for (var i = 0; i < files.length; i++) {\n _loop(i);\n }\n } // Takes care of adding other input elements of the form to the AJAX request\n\n }, {\n key: \"_addFormElementData\",\n value: function _addFormElementData(formData) {\n // Take care of other input elements\n if (this.element.tagName === \"FORM\") {\n var _iteratorNormalCompletion23 = true;\n var _didIteratorError23 = false;\n var _iteratorError23 = undefined;\n\n try {\n for (var _iterator23 = this.element.querySelectorAll(\"input, textarea, select, button\")[Symbol.iterator](), _step23; !(_iteratorNormalCompletion23 = (_step23 = _iterator23.next()).done); _iteratorNormalCompletion23 = true) {\n var input = _step23.value;\n var inputName = input.getAttribute(\"name\");\n var inputType = input.getAttribute(\"type\");\n if (inputType) inputType = inputType.toLowerCase(); // If the input doesn't have a name, we can't use it.\n\n if (typeof inputName === 'undefined' || inputName === null) continue;\n\n if (input.tagName === \"SELECT\" && input.hasAttribute(\"multiple\")) {\n // Possibly multiple values\n var _iteratorNormalCompletion24 = true;\n var _didIteratorError24 = false;\n var _iteratorError24 = undefined;\n\n try {\n for (var _iterator24 = input.options[Symbol.iterator](), _step24; !(_iteratorNormalCompletion24 = (_step24 = _iterator24.next()).done); _iteratorNormalCompletion24 = true) {\n var option = _step24.value;\n\n if (option.selected) {\n formData.append(inputName, option.value);\n }\n }\n } catch (err) {\n _didIteratorError24 = true;\n _iteratorError24 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion24 && _iterator24[\"return\"] != null) {\n _iterator24[\"return\"]();\n }\n } finally {\n if (_didIteratorError24) {\n throw _iteratorError24;\n }\n }\n }\n } else if (!inputType || inputType !== \"checkbox\" && inputType !== \"radio\" || input.checked) {\n formData.append(inputName, input.value);\n }\n }\n } catch (err) {\n _didIteratorError23 = true;\n _iteratorError23 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion23 && _iterator23[\"return\"] != null) {\n _iterator23[\"return\"]();\n }\n } finally {\n if (_didIteratorError23) {\n throw _iteratorError23;\n }\n }\n }\n }\n } // Invoked when there is new progress information about given files.\n // If e is not provided, it is assumed that the upload is finished.\n\n }, {\n key: \"_updateFilesUploadProgress\",\n value: function _updateFilesUploadProgress(files, xhr, e) {\n var progress;\n\n if (typeof e !== 'undefined') {\n progress = 100 * e.loaded / e.total;\n\n if (files[0].upload.chunked) {\n var file = files[0]; // Since this is a chunked upload, we need to update the appropriate chunk progress.\n\n var chunk = this._getChunk(file, xhr);\n\n chunk.progress = progress;\n chunk.total = e.total;\n chunk.bytesSent = e.loaded;\n var fileProgress = 0,\n fileTotal,\n fileBytesSent;\n file.upload.progress = 0;\n file.upload.total = 0;\n file.upload.bytesSent = 0;\n\n for (var i = 0; i < file.upload.totalChunkCount; i++) {\n if (file.upload.chunks[i] !== undefined && file.upload.chunks[i].progress !== undefined) {\n file.upload.progress += file.upload.chunks[i].progress;\n file.upload.total += file.upload.chunks[i].total;\n file.upload.bytesSent += file.upload.chunks[i].bytesSent;\n }\n }\n\n file.upload.progress = file.upload.progress / file.upload.totalChunkCount;\n } else {\n var _iteratorNormalCompletion25 = true;\n var _didIteratorError25 = false;\n var _iteratorError25 = undefined;\n\n try {\n for (var _iterator25 = files[Symbol.iterator](), _step25; !(_iteratorNormalCompletion25 = (_step25 = _iterator25.next()).done); _iteratorNormalCompletion25 = true) {\n var _file2 = _step25.value;\n _file2.upload.progress = progress;\n _file2.upload.total = e.total;\n _file2.upload.bytesSent = e.loaded;\n }\n } catch (err) {\n _didIteratorError25 = true;\n _iteratorError25 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion25 && _iterator25[\"return\"] != null) {\n _iterator25[\"return\"]();\n }\n } finally {\n if (_didIteratorError25) {\n throw _iteratorError25;\n }\n }\n }\n }\n\n var _iteratorNormalCompletion26 = true;\n var _didIteratorError26 = false;\n var _iteratorError26 = undefined;\n\n try {\n for (var _iterator26 = files[Symbol.iterator](), _step26; !(_iteratorNormalCompletion26 = (_step26 = _iterator26.next()).done); _iteratorNormalCompletion26 = true) {\n var _file3 = _step26.value;\n this.emit(\"uploadprogress\", _file3, _file3.upload.progress, _file3.upload.bytesSent);\n }\n } catch (err) {\n _didIteratorError26 = true;\n _iteratorError26 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion26 && _iterator26[\"return\"] != null) {\n _iterator26[\"return\"]();\n }\n } finally {\n if (_didIteratorError26) {\n throw _iteratorError26;\n }\n }\n }\n } else {\n // Called when the file finished uploading\n var allFilesFinished = true;\n progress = 100;\n var _iteratorNormalCompletion27 = true;\n var _didIteratorError27 = false;\n var _iteratorError27 = undefined;\n\n try {\n for (var _iterator27 = files[Symbol.iterator](), _step27; !(_iteratorNormalCompletion27 = (_step27 = _iterator27.next()).done); _iteratorNormalCompletion27 = true) {\n var _file4 = _step27.value;\n\n if (_file4.upload.progress !== 100 || _file4.upload.bytesSent !== _file4.upload.total) {\n allFilesFinished = false;\n }\n\n _file4.upload.progress = progress;\n _file4.upload.bytesSent = _file4.upload.total;\n } // Nothing to do, all files already at 100%\n\n } catch (err) {\n _didIteratorError27 = true;\n _iteratorError27 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion27 && _iterator27[\"return\"] != null) {\n _iterator27[\"return\"]();\n }\n } finally {\n if (_didIteratorError27) {\n throw _iteratorError27;\n }\n }\n }\n\n if (allFilesFinished) {\n return;\n }\n\n var _iteratorNormalCompletion28 = true;\n var _didIteratorError28 = false;\n var _iteratorError28 = undefined;\n\n try {\n for (var _iterator28 = files[Symbol.iterator](), _step28; !(_iteratorNormalCompletion28 = (_step28 = _iterator28.next()).done); _iteratorNormalCompletion28 = true) {\n var _file5 = _step28.value;\n this.emit(\"uploadprogress\", _file5, progress, _file5.upload.bytesSent);\n }\n } catch (err) {\n _didIteratorError28 = true;\n _iteratorError28 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion28 && _iterator28[\"return\"] != null) {\n _iterator28[\"return\"]();\n }\n } finally {\n if (_didIteratorError28) {\n throw _iteratorError28;\n }\n }\n }\n }\n }\n }, {\n key: \"_finishedUploading\",\n value: function _finishedUploading(files, xhr, e) {\n var response;\n\n if (files[0].status === Dropzone.CANCELED) {\n return;\n }\n\n if (xhr.readyState !== 4) {\n return;\n }\n\n if (xhr.responseType !== 'arraybuffer' && xhr.responseType !== 'blob') {\n response = xhr.responseText;\n\n if (xhr.getResponseHeader(\"content-type\") && ~xhr.getResponseHeader(\"content-type\").indexOf(\"application/json\")) {\n try {\n response = JSON.parse(response);\n } catch (error) {\n e = error;\n response = \"Invalid JSON response from server.\";\n }\n }\n }\n\n this._updateFilesUploadProgress(files);\n\n if (!(200 <= xhr.status && xhr.status < 300)) {\n this._handleUploadError(files, xhr, response);\n } else {\n if (files[0].upload.chunked) {\n files[0].upload.finishedChunkUpload(this._getChunk(files[0], xhr));\n } else {\n this._finished(files, response, e);\n }\n }\n }\n }, {\n key: \"_handleUploadError\",\n value: function _handleUploadError(files, xhr, response) {\n if (files[0].status === Dropzone.CANCELED) {\n return;\n }\n\n if (files[0].upload.chunked && this.options.retryChunks) {\n var chunk = this._getChunk(files[0], xhr);\n\n if (chunk.retries++ < this.options.retryChunksLimit) {\n this._uploadData(files, [chunk.dataBlock]);\n\n return;\n } else {\n console.warn('Retried this chunk too often. Giving up.');\n }\n }\n\n this._errorProcessing(files, response || this.options.dictResponseError.replace(\"{{statusCode}}\", xhr.status), xhr);\n }\n }, {\n key: \"submitRequest\",\n value: function submitRequest(xhr, formData, files) {\n xhr.send(formData);\n } // Called internally when processing is finished.\n // Individual callbacks have to be called in the appropriate sections.\n\n }, {\n key: \"_finished\",\n value: function _finished(files, responseText, e) {\n var _iteratorNormalCompletion29 = true;\n var _didIteratorError29 = false;\n var _iteratorError29 = undefined;\n\n try {\n for (var _iterator29 = files[Symbol.iterator](), _step29; !(_iteratorNormalCompletion29 = (_step29 = _iterator29.next()).done); _iteratorNormalCompletion29 = true) {\n var file = _step29.value;\n file.status = Dropzone.SUCCESS;\n this.emit(\"success\", file, responseText, e);\n this.emit(\"complete\", file);\n }\n } catch (err) {\n _didIteratorError29 = true;\n _iteratorError29 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion29 && _iterator29[\"return\"] != null) {\n _iterator29[\"return\"]();\n }\n } finally {\n if (_didIteratorError29) {\n throw _iteratorError29;\n }\n }\n }\n\n if (this.options.uploadMultiple) {\n this.emit(\"successmultiple\", files, responseText, e);\n this.emit(\"completemultiple\", files);\n }\n\n if (this.options.autoProcessQueue) {\n return this.processQueue();\n }\n } // Called internally when processing is finished.\n // Individual callbacks have to be called in the appropriate sections.\n\n }, {\n key: \"_errorProcessing\",\n value: function _errorProcessing(files, message, xhr) {\n var _iteratorNormalCompletion30 = true;\n var _didIteratorError30 = false;\n var _iteratorError30 = undefined;\n\n try {\n for (var _iterator30 = files[Symbol.iterator](), _step30; !(_iteratorNormalCompletion30 = (_step30 = _iterator30.next()).done); _iteratorNormalCompletion30 = true) {\n var file = _step30.value;\n file.status = Dropzone.ERROR;\n this.emit(\"error\", file, message, xhr);\n this.emit(\"complete\", file);\n }\n } catch (err) {\n _didIteratorError30 = true;\n _iteratorError30 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion30 && _iterator30[\"return\"] != null) {\n _iterator30[\"return\"]();\n }\n } finally {\n if (_didIteratorError30) {\n throw _iteratorError30;\n }\n }\n }\n\n if (this.options.uploadMultiple) {\n this.emit(\"errormultiple\", files, message, xhr);\n this.emit(\"completemultiple\", files);\n }\n\n if (this.options.autoProcessQueue) {\n return this.processQueue();\n }\n }\n }], [{\n key: \"uuidv4\",\n value: function uuidv4() {\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {\n var r = Math.random() * 16 | 0,\n v = c === 'x' ? r : r & 0x3 | 0x8;\n return v.toString(16);\n });\n }\n }]);\n\n return Dropzone;\n}(Emitter);\n\nDropzone.initClass();\nDropzone.version = \"5.7.0\"; // This is a map of options for your different dropzones. Add configurations\n// to this object for your different dropzone elemens.\n//\n// Example:\n//\n// Dropzone.options.myDropzoneElementId = { maxFilesize: 1 };\n//\n// To disable autoDiscover for a specific element, you can set `false` as an option:\n//\n// Dropzone.options.myDisabledElementId = false;\n//\n// And in html:\n//\n// \n\nDropzone.options = {}; // Returns the options for an element or undefined if none available.\n\nDropzone.optionsForElement = function (element) {\n // Get the `Dropzone.options.elementId` for this element if it exists\n if (element.getAttribute(\"id\")) {\n return Dropzone.options[camelize(element.getAttribute(\"id\"))];\n } else {\n return undefined;\n }\n}; // Holds a list of all dropzone instances\n\n\nDropzone.instances = []; // Returns the dropzone for given element if any\n\nDropzone.forElement = function (element) {\n if (typeof element === \"string\") {\n element = document.querySelector(element);\n }\n\n if ((element != null ? element.dropzone : undefined) == null) {\n throw new Error(\"No Dropzone found for given element. This is probably because you're trying to access it before Dropzone had the time to initialize. Use the `init` option to setup any additional observers on your Dropzone.\");\n }\n\n return element.dropzone;\n}; // Set to false if you don't want Dropzone to automatically find and attach to .dropzone elements.\n\n\nDropzone.autoDiscover = true; // Looks for all .dropzone elements and creates a dropzone for them\n\nDropzone.discover = function () {\n var dropzones;\n\n if (document.querySelectorAll) {\n dropzones = document.querySelectorAll(\".dropzone\");\n } else {\n dropzones = []; // IE :(\n\n var checkElements = function checkElements(elements) {\n return function () {\n var result = [];\n var _iteratorNormalCompletion31 = true;\n var _didIteratorError31 = false;\n var _iteratorError31 = undefined;\n\n try {\n for (var _iterator31 = elements[Symbol.iterator](), _step31; !(_iteratorNormalCompletion31 = (_step31 = _iterator31.next()).done); _iteratorNormalCompletion31 = true) {\n var el = _step31.value;\n\n if (/(^| )dropzone($| )/.test(el.className)) {\n result.push(dropzones.push(el));\n } else {\n result.push(undefined);\n }\n }\n } catch (err) {\n _didIteratorError31 = true;\n _iteratorError31 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion31 && _iterator31[\"return\"] != null) {\n _iterator31[\"return\"]();\n }\n } finally {\n if (_didIteratorError31) {\n throw _iteratorError31;\n }\n }\n }\n\n return result;\n }();\n };\n\n checkElements(document.getElementsByTagName(\"div\"));\n checkElements(document.getElementsByTagName(\"form\"));\n }\n\n return function () {\n var result = [];\n var _iteratorNormalCompletion32 = true;\n var _didIteratorError32 = false;\n var _iteratorError32 = undefined;\n\n try {\n for (var _iterator32 = dropzones[Symbol.iterator](), _step32; !(_iteratorNormalCompletion32 = (_step32 = _iterator32.next()).done); _iteratorNormalCompletion32 = true) {\n var dropzone = _step32.value;\n\n // Create a dropzone unless auto discover has been disabled for specific element\n if (Dropzone.optionsForElement(dropzone) !== false) {\n result.push(new Dropzone(dropzone));\n } else {\n result.push(undefined);\n }\n }\n } catch (err) {\n _didIteratorError32 = true;\n _iteratorError32 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion32 && _iterator32[\"return\"] != null) {\n _iterator32[\"return\"]();\n }\n } finally {\n if (_didIteratorError32) {\n throw _iteratorError32;\n }\n }\n }\n\n return result;\n }();\n}; // Since the whole Drag'n'Drop API is pretty new, some browsers implement it,\n// but not correctly.\n// So I created a blacklist of userAgents. Yes, yes. Browser sniffing, I know.\n// But what to do when browsers *theoretically* support an API, but crash\n// when using it.\n//\n// This is a list of regular expressions tested against navigator.userAgent\n//\n// ** It should only be used on browser that *do* support the API, but\n// incorrectly **\n//\n\n\nDropzone.blacklistedBrowsers = [// The mac os and windows phone version of opera 12 seems to have a problem with the File drag'n'drop API.\n/opera.*(Macintosh|Windows Phone).*version\\/12/i]; // Checks if the browser is supported\n\nDropzone.isBrowserSupported = function () {\n var capableBrowser = true;\n\n if (window.File && window.FileReader && window.FileList && window.Blob && window.FormData && document.querySelector) {\n if (!(\"classList\" in document.createElement(\"a\"))) {\n capableBrowser = false;\n } else {\n // The browser supports the API, but may be blacklisted.\n var _iteratorNormalCompletion33 = true;\n var _didIteratorError33 = false;\n var _iteratorError33 = undefined;\n\n try {\n for (var _iterator33 = Dropzone.blacklistedBrowsers[Symbol.iterator](), _step33; !(_iteratorNormalCompletion33 = (_step33 = _iterator33.next()).done); _iteratorNormalCompletion33 = true) {\n var regex = _step33.value;\n\n if (regex.test(navigator.userAgent)) {\n capableBrowser = false;\n continue;\n }\n }\n } catch (err) {\n _didIteratorError33 = true;\n _iteratorError33 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion33 && _iterator33[\"return\"] != null) {\n _iterator33[\"return\"]();\n }\n } finally {\n if (_didIteratorError33) {\n throw _iteratorError33;\n }\n }\n }\n }\n } else {\n capableBrowser = false;\n }\n\n return capableBrowser;\n};\n\nDropzone.dataURItoBlob = function (dataURI) {\n // convert base64 to raw binary data held in a string\n // doesn't handle URLEncoded DataURIs - see SO answer #6850276 for code that does this\n var byteString = atob(dataURI.split(',')[1]); // separate out the mime component\n\n var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]; // write the bytes of the string to an ArrayBuffer\n\n var ab = new ArrayBuffer(byteString.length);\n var ia = new Uint8Array(ab);\n\n for (var i = 0, end = byteString.length, asc = 0 <= end; asc ? i <= end : i >= end; asc ? i++ : i--) {\n ia[i] = byteString.charCodeAt(i);\n } // write the ArrayBuffer to a blob\n\n\n return new Blob([ab], {\n type: mimeString\n });\n}; // Returns an array without the rejected item\n\n\nvar without = function without(list, rejectedItem) {\n return list.filter(function (item) {\n return item !== rejectedItem;\n }).map(function (item) {\n return item;\n });\n}; // abc-def_ghi -> abcDefGhi\n\n\nvar camelize = function camelize(str) {\n return str.replace(/[\\-_](\\w)/g, function (match) {\n return match.charAt(1).toUpperCase();\n });\n}; // Creates an element from string\n\n\nDropzone.createElement = function (string) {\n var div = document.createElement(\"div\");\n div.innerHTML = string;\n return div.childNodes[0];\n}; // Tests if given element is inside (or simply is) the container\n\n\nDropzone.elementInside = function (element, container) {\n if (element === container) {\n return true;\n } // Coffeescript doesn't support do/while loops\n\n\n while (element = element.parentNode) {\n if (element === container) {\n return true;\n }\n }\n\n return false;\n};\n\nDropzone.getElement = function (el, name) {\n var element;\n\n if (typeof el === \"string\") {\n element = document.querySelector(el);\n } else if (el.nodeType != null) {\n element = el;\n }\n\n if (element == null) {\n throw new Error(\"Invalid `\".concat(name, \"` option provided. Please provide a CSS selector or a plain HTML element.\"));\n }\n\n return element;\n};\n\nDropzone.getElements = function (els, name) {\n var el, elements;\n\n if (els instanceof Array) {\n elements = [];\n\n try {\n var _iteratorNormalCompletion34 = true;\n var _didIteratorError34 = false;\n var _iteratorError34 = undefined;\n\n try {\n for (var _iterator34 = els[Symbol.iterator](), _step34; !(_iteratorNormalCompletion34 = (_step34 = _iterator34.next()).done); _iteratorNormalCompletion34 = true) {\n el = _step34.value;\n elements.push(this.getElement(el, name));\n }\n } catch (err) {\n _didIteratorError34 = true;\n _iteratorError34 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion34 && _iterator34[\"return\"] != null) {\n _iterator34[\"return\"]();\n }\n } finally {\n if (_didIteratorError34) {\n throw _iteratorError34;\n }\n }\n }\n } catch (e) {\n elements = null;\n }\n } else if (typeof els === \"string\") {\n elements = [];\n var _iteratorNormalCompletion35 = true;\n var _didIteratorError35 = false;\n var _iteratorError35 = undefined;\n\n try {\n for (var _iterator35 = document.querySelectorAll(els)[Symbol.iterator](), _step35; !(_iteratorNormalCompletion35 = (_step35 = _iterator35.next()).done); _iteratorNormalCompletion35 = true) {\n el = _step35.value;\n elements.push(el);\n }\n } catch (err) {\n _didIteratorError35 = true;\n _iteratorError35 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion35 && _iterator35[\"return\"] != null) {\n _iterator35[\"return\"]();\n }\n } finally {\n if (_didIteratorError35) {\n throw _iteratorError35;\n }\n }\n }\n } else if (els.nodeType != null) {\n elements = [els];\n }\n\n if (elements == null || !elements.length) {\n throw new Error(\"Invalid `\".concat(name, \"` option provided. Please provide a CSS selector, a plain HTML element or a list of those.\"));\n }\n\n return elements;\n}; // Asks the user the question and calls accepted or rejected accordingly\n//\n// The default implementation just uses `window.confirm` and then calls the\n// appropriate callback.\n\n\nDropzone.confirm = function (question, accepted, rejected) {\n if (window.confirm(question)) {\n return accepted();\n } else if (rejected != null) {\n return rejected();\n }\n}; // Validates the mime type like this:\n//\n// https://developer.mozilla.org/en-US/docs/HTML/Element/input#attr-accept\n\n\nDropzone.isValidFile = function (file, acceptedFiles) {\n if (!acceptedFiles) {\n return true;\n } // If there are no accepted mime types, it's OK\n\n\n acceptedFiles = acceptedFiles.split(\",\");\n var mimeType = file.type;\n var baseMimeType = mimeType.replace(/\\/.*$/, \"\");\n var _iteratorNormalCompletion36 = true;\n var _didIteratorError36 = false;\n var _iteratorError36 = undefined;\n\n try {\n for (var _iterator36 = acceptedFiles[Symbol.iterator](), _step36; !(_iteratorNormalCompletion36 = (_step36 = _iterator36.next()).done); _iteratorNormalCompletion36 = true) {\n var validType = _step36.value;\n validType = validType.trim();\n\n if (validType.charAt(0) === \".\") {\n if (file.name.toLowerCase().indexOf(validType.toLowerCase(), file.name.length - validType.length) !== -1) {\n return true;\n }\n } else if (/\\/\\*$/.test(validType)) {\n // This is something like a image/* mime type\n if (baseMimeType === validType.replace(/\\/.*$/, \"\")) {\n return true;\n }\n } else {\n if (mimeType === validType) {\n return true;\n }\n }\n }\n } catch (err) {\n _didIteratorError36 = true;\n _iteratorError36 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion36 && _iterator36[\"return\"] != null) {\n _iterator36[\"return\"]();\n }\n } finally {\n if (_didIteratorError36) {\n throw _iteratorError36;\n }\n }\n }\n\n return false;\n}; // Augment jQuery\n\n\nif (typeof jQuery !== 'undefined' && jQuery !== null) {\n jQuery.fn.dropzone = function (options) {\n return this.each(function () {\n return new Dropzone(this, options);\n });\n };\n}\n\nif ( true && module !== null) {\n module.exports = Dropzone;\n} else {\n window.Dropzone = Dropzone;\n} // Dropzone file status codes\n\n\nDropzone.ADDED = \"added\";\nDropzone.QUEUED = \"queued\"; // For backwards compatibility. Now, if a file is accepted, it's either queued\n// or uploading.\n\nDropzone.ACCEPTED = Dropzone.QUEUED;\nDropzone.UPLOADING = \"uploading\";\nDropzone.PROCESSING = Dropzone.UPLOADING; // alias\n\nDropzone.CANCELED = \"canceled\";\nDropzone.ERROR = \"error\";\nDropzone.SUCCESS = \"success\";\n/*\n\n Bugfix for iOS 6 and 7\n Source: http://stackoverflow.com/questions/11929099/html5-canvas-drawimage-ratio-bug-ios\n based on the work of https://github.com/stomita/ios-imagefile-megapixel\n\n */\n// Detecting vertical squash in loaded image.\n// Fixes a bug which squash image vertically while drawing into canvas for some images.\n// This is a bug in iOS6 devices. This function from https://github.com/stomita/ios-imagefile-megapixel\n\nvar detectVerticalSquash = function detectVerticalSquash(img) {\n var iw = img.naturalWidth;\n var ih = img.naturalHeight;\n var canvas = document.createElement(\"canvas\");\n canvas.width = 1;\n canvas.height = ih;\n var ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n\n var _ctx$getImageData = ctx.getImageData(1, 0, 1, ih),\n data = _ctx$getImageData.data; // search image edge pixel position in case it is squashed vertically.\n\n\n var sy = 0;\n var ey = ih;\n var py = ih;\n\n while (py > sy) {\n var alpha = data[(py - 1) * 4 + 3];\n\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n\n py = ey + sy >> 1;\n }\n\n var ratio = py / ih;\n\n if (ratio === 0) {\n return 1;\n } else {\n return ratio;\n }\n}; // A replacement for context.drawImage\n// (args are for source and destination).\n\n\nvar drawImageIOSFix = function drawImageIOSFix(ctx, img, sx, sy, sw, sh, dx, dy, dw, dh) {\n var vertSquashRatio = detectVerticalSquash(img);\n return ctx.drawImage(img, sx, sy, sw, sh, dx, dy, dw, dh / vertSquashRatio);\n}; // Based on MinifyJpeg\n// Source: http://www.perry.cz/files/ExifRestorer.js\n// http://elicon.blog57.fc2.com/blog-entry-206.html\n\n\nvar ExifRestore =\n/*#__PURE__*/\nfunction () {\n function ExifRestore() {\n _classCallCheck(this, ExifRestore);\n }\n\n _createClass(ExifRestore, null, [{\n key: \"initClass\",\n value: function initClass() {\n this.KEY_STR = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';\n }\n }, {\n key: \"encode64\",\n value: function encode64(input) {\n var output = '';\n var chr1 = undefined;\n var chr2 = undefined;\n var chr3 = '';\n var enc1 = undefined;\n var enc2 = undefined;\n var enc3 = undefined;\n var enc4 = '';\n var i = 0;\n\n while (true) {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n enc1 = chr1 >> 2;\n enc2 = (chr1 & 3) << 4 | chr2 >> 4;\n enc3 = (chr2 & 15) << 2 | chr3 >> 6;\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output + this.KEY_STR.charAt(enc1) + this.KEY_STR.charAt(enc2) + this.KEY_STR.charAt(enc3) + this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = '';\n enc1 = enc2 = enc3 = enc4 = '';\n\n if (!(i < input.length)) {\n break;\n }\n }\n\n return output;\n }\n }, {\n key: \"restore\",\n value: function restore(origFileBase64, resizedFileBase64) {\n if (!origFileBase64.match('data:image/jpeg;base64,')) {\n return resizedFileBase64;\n }\n\n var rawImage = this.decode64(origFileBase64.replace('data:image/jpeg;base64,', ''));\n var segments = this.slice2Segments(rawImage);\n var image = this.exifManipulation(resizedFileBase64, segments);\n return \"data:image/jpeg;base64,\".concat(this.encode64(image));\n }\n }, {\n key: \"exifManipulation\",\n value: function exifManipulation(resizedFileBase64, segments) {\n var exifArray = this.getExifArray(segments);\n var newImageArray = this.insertExif(resizedFileBase64, exifArray);\n var aBuffer = new Uint8Array(newImageArray);\n return aBuffer;\n }\n }, {\n key: \"getExifArray\",\n value: function getExifArray(segments) {\n var seg = undefined;\n var x = 0;\n\n while (x < segments.length) {\n seg = segments[x];\n\n if (seg[0] === 255 & seg[1] === 225) {\n return seg;\n }\n\n x++;\n }\n\n return [];\n }\n }, {\n key: \"insertExif\",\n value: function insertExif(resizedFileBase64, exifArray) {\n var imageData = resizedFileBase64.replace('data:image/jpeg;base64,', '');\n var buf = this.decode64(imageData);\n var separatePoint = buf.indexOf(255, 3);\n var mae = buf.slice(0, separatePoint);\n var ato = buf.slice(separatePoint);\n var array = mae;\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n }\n }, {\n key: \"slice2Segments\",\n value: function slice2Segments(rawImageArray) {\n var head = 0;\n var segments = [];\n\n while (true) {\n var length;\n\n if (rawImageArray[head] === 255 & rawImageArray[head + 1] === 218) {\n break;\n }\n\n if (rawImageArray[head] === 255 & rawImageArray[head + 1] === 216) {\n head += 2;\n } else {\n length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3];\n var endPoint = head + length + 2;\n var seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n\n if (head > rawImageArray.length) {\n break;\n }\n }\n\n return segments;\n }\n }, {\n key: \"decode64\",\n value: function decode64(input) {\n var output = '';\n var chr1 = undefined;\n var chr2 = undefined;\n var chr3 = '';\n var enc1 = undefined;\n var enc2 = undefined;\n var enc3 = undefined;\n var enc4 = '';\n var i = 0;\n var buf = []; // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n\n if (base64test.exec(input)) {\n console.warn('There were invalid base64 characters in the input text.\\nValid base64 characters are A-Z, a-z, 0-9, \\'+\\', \\'/\\',and \\'=\\'\\nExpect errors in decoding.');\n }\n\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, '');\n\n while (true) {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n chr1 = enc1 << 2 | enc2 >> 4;\n chr2 = (enc2 & 15) << 4 | enc3 >> 2;\n chr3 = (enc3 & 3) << 6 | enc4;\n buf.push(chr1);\n\n if (enc3 !== 64) {\n buf.push(chr2);\n }\n\n if (enc4 !== 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = '';\n enc1 = enc2 = enc3 = enc4 = '';\n\n if (!(i < input.length)) {\n break;\n }\n }\n\n return buf;\n }\n }]);\n\n return ExifRestore;\n}();\n\nExifRestore.initClass();\n/*\n * contentloaded.js\n *\n * Author: Diego Perini (diego.perini at gmail.com)\n * Summary: cross-browser wrapper for DOMContentLoaded\n * Updated: 20101020\n * License: MIT\n * Version: 1.2\n *\n * URL:\n * http://javascript.nwbox.com/ContentLoaded/\n * http://javascript.nwbox.com/ContentLoaded/MIT-LICENSE\n */\n// @win window reference\n// @fn function reference\n\nvar contentLoaded = function contentLoaded(win, fn) {\n var done = false;\n var top = true;\n var doc = win.document;\n var root = doc.documentElement;\n var add = doc.addEventListener ? \"addEventListener\" : \"attachEvent\";\n var rem = doc.addEventListener ? \"removeEventListener\" : \"detachEvent\";\n var pre = doc.addEventListener ? \"\" : \"on\";\n\n var init = function init(e) {\n if (e.type === \"readystatechange\" && doc.readyState !== \"complete\") {\n return;\n }\n\n (e.type === \"load\" ? win : doc)[rem](pre + e.type, init, false);\n\n if (!done && (done = true)) {\n return fn.call(win, e.type || e);\n }\n };\n\n var poll = function poll() {\n try {\n root.doScroll(\"left\");\n } catch (e) {\n setTimeout(poll, 50);\n return;\n }\n\n return init(\"poll\");\n };\n\n if (doc.readyState !== \"complete\") {\n if (doc.createEventObject && root.doScroll) {\n try {\n top = !win.frameElement;\n } catch (error) {}\n\n if (top) {\n poll();\n }\n }\n\n doc[add](pre + \"DOMContentLoaded\", init, false);\n doc[add](pre + \"readystatechange\", init, false);\n return win[add](pre + \"load\", init, false);\n }\n}; // As a single function to be able to write tests.\n\n\nDropzone._autoDiscoverFunction = function () {\n if (Dropzone.autoDiscover) {\n return Dropzone.discover();\n }\n};\n\ncontentLoaded(window, Dropzone._autoDiscoverFunction);\n\nfunction __guard__(value, transform) {\n return typeof value !== 'undefined' && value !== null ? transform(value) : undefined;\n}\n\nfunction __guardMethod__(obj, methodName, transform) {\n if (typeof obj !== 'undefined' && obj !== null && typeof obj[methodName] === 'function') {\n return transform(obj, methodName);\n } else {\n return undefined;\n }\n}\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../webpack/buildin/module.js */ \"./node_modules/webpack/buildin/module.js\")(module)))//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvZHJvcHpvbmUvZGlzdC9kcm9wem9uZS5qcz83OWUzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDhDQUFhOztBQUViLHVCQUF1QiwyQkFBMkIsMkVBQTJFLGtDQUFrQyxtQkFBbUIsR0FBRyxFQUFFLE9BQU8sa0NBQWtDLDhIQUE4SCxHQUFHLEVBQUUscUJBQXFCOztBQUV4WCxpREFBaUQsMEVBQTBFLGFBQWEsRUFBRSxxQ0FBcUM7O0FBRS9LLDZCQUE2QixnR0FBZ0csZ0RBQWdELEdBQUcsMkJBQTJCOztBQUUzTSx1Q0FBdUMsdUJBQXVCLHVGQUF1RixFQUFFLGFBQWE7O0FBRXBLLDBDQUEwQywrREFBK0QsMkVBQTJFLEVBQUUseUVBQXlFLGVBQWUsc0RBQXNELEVBQUUsRUFBRSx1REFBdUQ7O0FBRS9YLGdDQUFnQyw0RUFBNEUsaUJBQWlCLFVBQVUsR0FBRyw4QkFBOEI7O0FBRXhLLGlEQUFpRCwwQ0FBMEMsMERBQTBELEVBQUU7O0FBRXZKLDJDQUEyQyxnQkFBZ0Isa0JBQWtCLE9BQU8sMkJBQTJCLHdEQUF3RCxnQ0FBZ0MsdURBQXVELDJEQUEyRCxFQUFFOztBQUUzVCw2REFBNkQsc0VBQXNFLDhEQUE4RCxvQkFBb0I7O0FBRXJOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSw4Q0FBOEM7O0FBRTlDO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsOEZBQThGLGFBQWE7QUFDM0c7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxtRUFBbUUsZ0VBQWdFO0FBQ25JO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVztBQUNYO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTzs7O0FBR1A7O0FBRUE7QUFDQTtBQUNBLE9BQU87OztBQUdQO0FBQ0E7QUFDQTtBQUNBLE9BQU87OztBQUdQLHFCQUFxQixzQkFBc0I7QUFDM0M7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZDQUE2QyxFQUFFO0FBQy9DOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsYUFBYSxzQ0FBc0M7QUFDbkQ7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxjQUFjLFVBQVUsU0FBUyxhQUFhO0FBQzlDO0FBQ0EsNENBQTRDLFVBQVUsc0JBQXNCLGFBQWE7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QUVBO0FBQ0EsT0FBTztBQUNQLEtBQUs7O0FBRUwsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxpRUFBaUUsc0VBQXNFO0FBQ3ZJO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLEtBQUs7QUFDaEI7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxTQUFTLEtBQUs7QUFDZDtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsT0FBTztBQUNQLEtBQUs7O0FBRUwsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsOEVBQThFLHNFQUFzRTtBQUNwSjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0EsR0FBRztBQUNI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O0FBQ2pEO0FBQ0E7O0FBRUEsMkVBQTJFO0FBQzNFO0FBQ0E7QUFDQSw4QkFBOEI7QUFDOUI7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSxpRUFBaUU7QUFDakU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQjs7QUFFbkI7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7OztBQUdGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EiLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvZHJvcHpvbmUvZGlzdC9kcm9wem9uZS5qcy5qcyIsInNvdXJjZXNDb250ZW50IjpbIlwidXNlIHN0cmljdFwiO1xuXG5mdW5jdGlvbiBfdHlwZW9mKG9iaikgeyBcIkBiYWJlbC9oZWxwZXJzIC0gdHlwZW9mXCI7IGlmICh0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgdHlwZW9mIFN5bWJvbC5pdGVyYXRvciA9PT0gXCJzeW1ib2xcIikgeyBfdHlwZW9mID0gZnVuY3Rpb24gX3R5cGVvZihvYmopIHsgcmV0dXJuIHR5cGVvZiBvYmo7IH07IH0gZWxzZSB7IF90eXBlb2YgPSBmdW5jdGlvbiBfdHlwZW9mKG9iaikgeyByZXR1cm4gb2JqICYmIHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBvYmouY29uc3RydWN0b3IgPT09IFN5bWJvbCAmJiBvYmogIT09IFN5bWJvbC5wcm90b3R5cGUgPyBcInN5bWJvbFwiIDogdHlwZW9mIG9iajsgfTsgfSByZXR1cm4gX3R5cGVvZihvYmopOyB9XG5cbmZ1bmN0aW9uIF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuKHNlbGYsIGNhbGwpIHsgaWYgKGNhbGwgJiYgKF90eXBlb2YoY2FsbCkgPT09IFwib2JqZWN0XCIgfHwgdHlwZW9mIGNhbGwgPT09IFwiZnVuY3Rpb25cIikpIHsgcmV0dXJuIGNhbGw7IH0gcmV0dXJuIF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQoc2VsZik7IH1cblxuZnVuY3Rpb24gX2dldFByb3RvdHlwZU9mKG8pIHsgX2dldFByb3RvdHlwZU9mID0gT2JqZWN0LnNldFByb3RvdHlwZU9mID8gT2JqZWN0LmdldFByb3RvdHlwZU9mIDogZnVuY3Rpb24gX2dldFByb3RvdHlwZU9mKG8pIHsgcmV0dXJuIG8uX19wcm90b19fIHx8IE9iamVjdC5nZXRQcm90b3R5cGVPZihvKTsgfTsgcmV0dXJuIF9nZXRQcm90b3R5cGVPZihvKTsgfVxuXG5mdW5jdGlvbiBfYXNzZXJ0VGhpc0luaXRpYWxpemVkKHNlbGYpIHsgaWYgKHNlbGYgPT09IHZvaWQgMCkgeyB0aHJvdyBuZXcgUmVmZXJlbmNlRXJyb3IoXCJ0aGlzIGhhc24ndCBiZWVuIGluaXRpYWxpc2VkIC0gc3VwZXIoKSBoYXNuJ3QgYmVlbiBjYWxsZWRcIik7IH0gcmV0dXJuIHNlbGY7IH1cblxuZnVuY3Rpb24gX2luaGVyaXRzKHN1YkNsYXNzLCBzdXBlckNsYXNzKSB7IGlmICh0eXBlb2Ygc3VwZXJDbGFzcyAhPT0gXCJmdW5jdGlvblwiICYmIHN1cGVyQ2xhc3MgIT09IG51bGwpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN1cGVyIGV4cHJlc3Npb24gbXVzdCBlaXRoZXIgYmUgbnVsbCBvciBhIGZ1bmN0aW9uXCIpOyB9IHN1YkNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcyAmJiBzdXBlckNsYXNzLnByb3RvdHlwZSwgeyBjb25zdHJ1Y3RvcjogeyB2YWx1ZTogc3ViQ2xhc3MsIHdyaXRhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUgfSB9KTsgaWYgKHN1cGVyQ2xhc3MpIF9zZXRQcm90b3R5cGVPZihzdWJDbGFzcywgc3VwZXJDbGFzcyk7IH1cblxuZnVuY3Rpb24gX3NldFByb3RvdHlwZU9mKG8sIHApIHsgX3NldFByb3RvdHlwZU9mID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IGZ1bmN0aW9uIF9zZXRQcm90b3R5cGVPZihvLCBwKSB7IG8uX19wcm90b19fID0gcDsgcmV0dXJuIG87IH07IHJldHVybiBfc2V0UHJvdG90eXBlT2YobywgcCk7IH1cblxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpOyB9IH1cblxuZnVuY3Rpb24gX2RlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcykgeyBmb3IgKHZhciBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSsrKSB7IHZhciBkZXNjcmlwdG9yID0gcHJvcHNbaV07IGRlc2NyaXB0b3IuZW51bWVyYWJsZSA9IGRlc2NyaXB0b3IuZW51bWVyYWJsZSB8fCBmYWxzZTsgZGVzY3JpcHRvci5jb25maWd1cmFibGUgPSB0cnVlOyBpZiAoXCJ2YWx1ZVwiIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlOyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBkZXNjcmlwdG9yLmtleSwgZGVzY3JpcHRvcik7IH0gfVxuXG5mdW5jdGlvbiBfY3JlYXRlQ2xhc3MoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7IGlmIChwcm90b1Byb3BzKSBfZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIF9kZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLCBzdGF0aWNQcm9wcyk7IHJldHVybiBDb25zdHJ1Y3RvcjsgfVxuXG4vKlxuICpcbiAqIE1vcmUgaW5mbyBhdCBbd3d3LmRyb3B6b25lanMuY29tXShodHRwOi8vd3d3LmRyb3B6b25lanMuY29tKVxuICpcbiAqIENvcHlyaWdodCAoYykgMjAxMiwgTWF0aWFzIE1lbm9cbiAqXG4gKiBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5XG4gKiBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLCB0byBkZWFsXG4gKiBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzXG4gKiB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsXG4gKiBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcbiAqIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4gKlxuICogVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW5cbiAqIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuICpcbiAqIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1JcbiAqIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFXG4gKiBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSXG4gKiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLFxuICogT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTlxuICogVEhFIFNPRlRXQVJFLlxuICpcbiAqL1xuLy8gVGhlIEVtaXR0ZXIgY2xhc3MgcHJvdmlkZXMgdGhlIGFiaWxpdHkgdG8gY2FsbCBgLm9uKClgIG9uIERyb3B6b25lIHRvIGxpc3RlblxuLy8gdG8gZXZlbnRzLlxuLy8gSXQgaXMgc3Ryb25nbHkgYmFzZWQgb24gY29tcG9uZW50J3MgZW1pdHRlciBjbGFzcywgYW5kIEkgcmVtb3ZlZCB0aGVcbi8vIGZ1bmN0aW9uYWxpdHkgYmVjYXVzZSBvZiB0aGUgZGVwZW5kZW5jeSBoZWxsIHdpdGggZGlmZmVyZW50IGZyYW1ld29ya3MuXG52YXIgRW1pdHRlciA9XG4vKiNfX1BVUkVfXyovXG5mdW5jdGlvbiAoKSB7XG4gIGZ1bmN0aW9uIEVtaXR0ZXIoKSB7XG4gICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIEVtaXR0ZXIpO1xuICB9XG5cbiAgX2NyZWF0ZUNsYXNzKEVtaXR0ZXIsIFt7XG4gICAga2V5OiBcIm9uXCIsXG4gICAgLy8gQWRkIGFuIGV2ZW50IGxpc3RlbmVyIGZvciBnaXZlbiBldmVudFxuICAgIHZhbHVlOiBmdW5jdGlvbiBvbihldmVudCwgZm4pIHtcbiAgICAgIHRoaXMuX2NhbGxiYWNrcyA9IHRoaXMuX2NhbGxiYWNrcyB8fCB7fTsgLy8gQ3JlYXRlIG5hbWVzcGFjZSBmb3IgdGhpcyBldmVudFxuXG4gICAgICBpZiAoIXRoaXMuX2NhbGxiYWNrc1tldmVudF0pIHtcbiAgICAgICAgdGhpcy5fY2FsbGJhY2tzW2V2ZW50XSA9IFtdO1xuICAgICAgfVxuXG4gICAgICB0aGlzLl9jYWxsYmFja3NbZXZlbnRdLnB1c2goZm4pO1xuXG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiZW1pdFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBlbWl0KGV2ZW50KSB7XG4gICAgICB0aGlzLl9jYWxsYmFja3MgPSB0aGlzLl9jYWxsYmFja3MgfHwge307XG4gICAgICB2YXIgY2FsbGJhY2tzID0gdGhpcy5fY2FsbGJhY2tzW2V2ZW50XTtcblxuICAgICAgaWYgKGNhbGxiYWNrcykge1xuICAgICAgICBmb3IgKHZhciBfbGVuID0gYXJndW1lbnRzLmxlbmd0aCwgYXJncyA9IG5ldyBBcnJheShfbGVuID4gMSA/IF9sZW4gLSAxIDogMCksIF9rZXkgPSAxOyBfa2V5IDwgX2xlbjsgX2tleSsrKSB7XG4gICAgICAgICAgYXJnc1tfa2V5IC0gMV0gPSBhcmd1bWVudHNbX2tleV07XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbiA9IHRydWU7XG4gICAgICAgIHZhciBfZGlkSXRlcmF0b3JFcnJvciA9IGZhbHNlO1xuICAgICAgICB2YXIgX2l0ZXJhdG9yRXJyb3IgPSB1bmRlZmluZWQ7XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBmb3IgKHZhciBfaXRlcmF0b3IgPSBjYWxsYmFja3NbU3ltYm9sLml0ZXJhdG9yXSgpLCBfc3RlcDsgIShfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uID0gKF9zdGVwID0gX2l0ZXJhdG9yLm5leHQoKSkuZG9uZSk7IF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24gPSB0cnVlKSB7XG4gICAgICAgICAgICB2YXIgY2FsbGJhY2sgPSBfc3RlcC52YWx1ZTtcbiAgICAgICAgICAgIGNhbGxiYWNrLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgX2RpZEl0ZXJhdG9yRXJyb3IgPSB0cnVlO1xuICAgICAgICAgIF9pdGVyYXRvckVycm9yID0gZXJyO1xuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBpZiAoIV9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24gJiYgX2l0ZXJhdG9yW1wicmV0dXJuXCJdICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgX2l0ZXJhdG9yW1wicmV0dXJuXCJdKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgIGlmIChfZGlkSXRlcmF0b3JFcnJvcikge1xuICAgICAgICAgICAgICB0aHJvdyBfaXRlcmF0b3JFcnJvcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSAvLyBSZW1vdmUgZXZlbnQgbGlzdGVuZXIgZm9yIGdpdmVuIGV2ZW50LiBJZiBmbiBpcyBub3QgcHJvdmlkZWQsIGFsbCBldmVudFxuICAgIC8vIGxpc3RlbmVycyBmb3IgdGhhdCBldmVudCB3aWxsIGJlIHJlbW92ZWQuIElmIG5laXRoZXIgaXMgcHJvdmlkZWQsIGFsbFxuICAgIC8vIGV2ZW50IGxpc3RlbmVycyB3aWxsIGJlIHJlbW92ZWQuXG5cbiAgfSwge1xuICAgIGtleTogXCJvZmZcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gb2ZmKGV2ZW50LCBmbikge1xuICAgICAgaWYgKCF0aGlzLl9jYWxsYmFja3MgfHwgYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB0aGlzLl9jYWxsYmFja3MgPSB7fTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9IC8vIHNwZWNpZmljIGV2ZW50XG5cblxuICAgICAgdmFyIGNhbGxiYWNrcyA9IHRoaXMuX2NhbGxiYWNrc1tldmVudF07XG5cbiAgICAgIGlmICghY2FsbGJhY2tzKSB7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfSAvLyByZW1vdmUgYWxsIGhhbmRsZXJzXG5cblxuICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgZGVsZXRlIHRoaXMuX2NhbGxiYWNrc1tldmVudF07XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfSAvLyByZW1vdmUgc3BlY2lmaWMgaGFuZGxlclxuXG5cbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY2FsbGJhY2tzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBjYWxsYmFjayA9IGNhbGxiYWNrc1tpXTtcblxuICAgICAgICBpZiAoY2FsbGJhY2sgPT09IGZuKSB7XG4gICAgICAgICAgY2FsbGJhY2tzLnNwbGljZShpLCAxKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gIH1dKTtcblxuICByZXR1cm4gRW1pdHRlcjtcbn0oKTtcblxudmFyIERyb3B6b25lID1cbi8qI19fUFVSRV9fKi9cbmZ1bmN0aW9uIChfRW1pdHRlcikge1xuICBfaW5oZXJpdHMoRHJvcHpvbmUsIF9FbWl0dGVyKTtcblxuICBfY3JlYXRlQ2xhc3MoRHJvcHpvbmUsIG51bGwsIFt7XG4gICAga2V5OiBcImluaXRDbGFzc1wiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBpbml0Q2xhc3MoKSB7XG4gICAgICAvLyBFeHBvc2luZyB0aGUgZW1pdHRlciBjbGFzcywgbWFpbmx5IGZvciB0ZXN0c1xuICAgICAgdGhpcy5wcm90b3R5cGUuRW1pdHRlciA9IEVtaXR0ZXI7XG4gICAgICAvKlxuICAgICAgIFRoaXMgaXMgYSBsaXN0IG9mIGFsbCBhdmFpbGFibGUgZXZlbnRzIHlvdSBjYW4gcmVnaXN0ZXIgb24gYSBkcm9wem9uZSBvYmplY3QuXG4gICAgICAgIFlvdSBjYW4gcmVnaXN0ZXIgYW4gZXZlbnQgaGFuZGxlciBsaWtlIHRoaXM6XG4gICAgICAgIGRyb3B6b25lLm9uKFwiZHJhZ0VudGVyXCIsIGZ1bmN0aW9uKCkgeyB9KTtcbiAgICAgICAgKi9cblxuICAgICAgdGhpcy5wcm90b3R5cGUuZXZlbnRzID0gW1wiZHJvcFwiLCBcImRyYWdzdGFydFwiLCBcImRyYWdlbmRcIiwgXCJkcmFnZW50ZXJcIiwgXCJkcmFnb3ZlclwiLCBcImRyYWdsZWF2ZVwiLCBcImFkZGVkZmlsZVwiLCBcImFkZGVkZmlsZXNcIiwgXCJyZW1vdmVkZmlsZVwiLCBcInRodW1ibmFpbFwiLCBcImVycm9yXCIsIFwiZXJyb3JtdWx0aXBsZVwiLCBcInByb2Nlc3NpbmdcIiwgXCJwcm9jZXNzaW5nbXVsdGlwbGVcIiwgXCJ1cGxvYWRwcm9ncmVzc1wiLCBcInRvdGFsdXBsb2FkcHJvZ3Jlc3NcIiwgXCJzZW5kaW5nXCIsIFwic2VuZGluZ211bHRpcGxlXCIsIFwic3VjY2Vzc1wiLCBcInN1Y2Nlc3NtdWx0aXBsZVwiLCBcImNhbmNlbGVkXCIsIFwiY2FuY2VsZWRtdWx0aXBsZVwiLCBcImNvbXBsZXRlXCIsIFwiY29tcGxldGVtdWx0aXBsZVwiLCBcInJlc2V0XCIsIFwibWF4ZmlsZXNleGNlZWRlZFwiLCBcIm1heGZpbGVzcmVhY2hlZFwiLCBcInF1ZXVlY29tcGxldGVcIl07XG4gICAgICB0aGlzLnByb3RvdHlwZS5kZWZhdWx0T3B0aW9ucyA9IHtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEhhcyB0byBiZSBzcGVjaWZpZWQgb24gZWxlbWVudHMgb3RoZXIgdGhhbiBmb3JtIChvciB3aGVuIHRoZSBmb3JtXG4gICAgICAgICAqIGRvZXNuJ3QgaGF2ZSBhbiBgYWN0aW9uYCBhdHRyaWJ1dGUpLiBZb3UgY2FuIGFsc29cbiAgICAgICAgICogcHJvdmlkZSBhIGZ1bmN0aW9uIHRoYXQgd2lsbCBiZSBjYWxsZWQgd2l0aCBgZmlsZXNgIGFuZFxuICAgICAgICAgKiBtdXN0IHJldHVybiB0aGUgdXJsIChzaW5jZSBgdjMuMTIuMGApXG4gICAgICAgICAqL1xuICAgICAgICB1cmw6IG51bGwsXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIENhbiBiZSBjaGFuZ2VkIHRvIGBcInB1dFwiYCBpZiBuZWNlc3NhcnkuIFlvdSBjYW4gYWxzbyBwcm92aWRlIGEgZnVuY3Rpb25cbiAgICAgICAgICogdGhhdCB3aWxsIGJlIGNhbGxlZCB3aXRoIGBmaWxlc2AgYW5kIG11c3QgcmV0dXJuIHRoZSBtZXRob2QgKHNpbmNlIGB2My4xMi4wYCkuXG4gICAgICAgICAqL1xuICAgICAgICBtZXRob2Q6IFwicG9zdFwiLFxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBXaWxsIGJlIHNldCBvbiB0aGUgWEhSZXF1ZXN0LlxuICAgICAgICAgKi9cbiAgICAgICAgd2l0aENyZWRlbnRpYWxzOiBmYWxzZSxcblxuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHRpbWVvdXQgZm9yIHRoZSBYSFIgcmVxdWVzdHMgaW4gbWlsbGlzZWNvbmRzIChzaW5jZSBgdjQuNC4wYCkuXG4gICAgICAgICAqL1xuICAgICAgICB0aW1lb3V0OiAzMDAwMCxcblxuICAgICAgICAvKipcbiAgICAgICAgICogSG93IG1hbnkgZmlsZSB1cGxvYWRzIHRvIHByb2Nlc3MgaW4gcGFyYWxsZWwgKFNlZSB0aGVcbiAgICAgICAgICogRW5xdWV1aW5nIGZpbGUgdXBsb2FkcyBkb2N1bWVudGF0aW9uIHNlY3Rpb24gZm9yIG1vcmUgaW5mbylcbiAgICAgICAgICovXG4gICAgICAgIHBhcmFsbGVsVXBsb2FkczogMixcblxuICAgICAgICAvKipcbiAgICAgICAgICogV2hldGhlciB0byBzZW5kIG11bHRpcGxlIGZpbGVzIGluIG9uZSByZXF1ZXN0LiBJZlxuICAgICAgICAgKiB0aGlzIGl0IHNldCB0byB0cnVlLCB0aGVuIHRoZSBmYWxsYmFjayBmaWxlIGlucHV0IGVsZW1lbnQgd2lsbFxuICAgICAgICAgKiBoYXZlIHRoZSBgbXVsdGlwbGVgIGF0dHJpYnV0ZSBhcyB3ZWxsLiBUaGlzIG9wdGlvbiB3aWxsXG4gICAgICAgICAqIGFsc28gdHJpZ2dlciBhZGRpdGlvbmFsIGV2ZW50cyAobGlrZSBgcHJvY2Vzc2luZ211bHRpcGxlYCkuIFNlZSB0aGUgZXZlbnRzXG4gICAgICAgICAqIGRvY3VtZW50YXRpb24gc2VjdGlvbiBmb3IgbW9yZSBpbmZvcm1hdGlvbi5cbiAgICAgICAgICovXG4gICAgICAgIHVwbG9hZE11bHRpcGxlOiBmYWxzZSxcblxuICAgICAgICAvKipcbiAgICAgICAgICogV2hldGhlciB5b3Ugd2FudCBmaWxlcyB0byBiZSB1cGxvYWRlZCBpbiBjaHVua3MgdG8geW91ciBzZXJ2ZXIuIFRoaXMgY2FuJ3QgYmVcbiAgICAgICAgICogdXNlZCBpbiBjb21iaW5hdGlvbiB3aXRoIGB1cGxvYWRNdWx0aXBsZWAuXG4gICAgICAgICAqXG4gICAgICAgICAqIFNlZSBbY2h1bmtzVXBsb2FkZWRdKCNjb25maWctY2h1bmtzVXBsb2FkZWQpIGZvciB0aGUgY2FsbGJhY2sgdG8gZmluYWxpc2UgYW4gdXBsb2FkLlxuICAgICAgICAgKi9cbiAgICAgICAgY2h1bmtpbmc6IGZhbHNlLFxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBJZiBgY2h1bmtpbmdgIGlzIGVuYWJsZWQsIHRoaXMgZGVmaW5lcyB3aGV0aGVyICoqZXZlcnkqKiBmaWxlIHNob3VsZCBiZSBjaHVua2VkLFxuICAgICAgICAgKiBldmVuIGlmIHRoZSBmaWxlIHNpemUgaXMgYmVsb3cgY2h1bmtTaXplLiBUaGlzIG1lYW5zLCB0aGF0IHRoZSBhZGRpdGlvbmFsIGNodW5rXG4gICAgICAgICAqIGZvcm0gZGF0YSB3aWxsIGJlIHN1Ym1pdHRlZCBhbmQgdGhlIGBjaHVua3NVcGxvYWRlZGAgY2FsbGJhY2sgd2lsbCBiZSBpbnZva2VkLlxuICAgICAgICAgKi9cbiAgICAgICAgZm9yY2VDaHVua2luZzogZmFsc2UsXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIElmIGBjaHVua2luZ2AgaXMgYHRydWVgLCB0aGVuIHRoaXMgZGVmaW5lcyB0aGUgY2h1bmsgc2l6ZSBpbiBieXRlcy5cbiAgICAgICAgICovXG4gICAgICAgIGNodW5rU2l6ZTogMjAwMDAwMCxcblxuICAgICAgICAvKipcbiAgICAgICAgICogSWYgYHRydWVgLCB0aGUgaW5kaXZpZHVhbCBjaHVua3Mgb2YgYSBmaWxlIGFyZSBiZWluZyB1cGxvYWRlZCBzaW11bHRhbmVvdXNseS5cbiAgICAgICAgICovXG4gICAgICAgIHBhcmFsbGVsQ2h1bmtVcGxvYWRzOiBmYWxzZSxcblxuICAgICAgICAvKipcbiAgICAgICAgICogV2hldGhlciBhIGNodW5rIHNob3VsZCBiZSByZXRyaWVkIGlmIGl0IGZhaWxzLlxuICAgICAgICAgKi9cbiAgICAgICAgcmV0cnlDaHVua3M6IGZhbHNlLFxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBJZiBgcmV0cnlDaHVua3NgIGlzIHRydWUsIGhvdyBtYW55IHRpbWVzIHNob3VsZCBpdCBiZSByZXRyaWVkLlxuICAgICAgICAgKi9cbiAgICAgICAgcmV0cnlDaHVua3NMaW1pdDogMyxcblxuICAgICAgICAvKipcbiAgICAgICAgICogSWYgbm90IGBudWxsYCBkZWZpbmVzIGhvdyBtYW55IGZpbGVzIHRoaXMgRHJvcHpvbmUgaGFuZGxlcy4gSWYgaXQgZXhjZWVkcyxcbiAgICAgICAgICogdGhlIGV2ZW50IGBtYXhmaWxlc2V4Y2VlZGVkYCB3aWxsIGJlIGNhbGxlZC4gVGhlIGRyb3B6b25lIGVsZW1lbnQgZ2V0cyB0aGVcbiAgICAgICAgICogY2xhc3MgYGR6LW1heC1maWxlcy1yZWFjaGVkYCBhY2NvcmRpbmdseSBzbyB5b3UgY2FuIHByb3ZpZGUgdmlzdWFsIGZlZWRiYWNrLlxuICAgICAgICAgKi9cbiAgICAgICAgbWF4RmlsZXNpemU6IDI1NixcblxuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIG5hbWUgb2YgdGhlIGZpbGUgcGFyYW0gdGhhdCBnZXRzIHRyYW5zZmVycmVkLlxuICAgICAgICAgKiAqKk5PVEUqKjogSWYgeW91IGhhdmUgdGhlIG9wdGlvbiAgYHVwbG9hZE11bHRpcGxlYCBzZXQgdG8gYHRydWVgLCB0aGVuXG4gICAgICAgICAqIERyb3B6b25lIHdpbGwgYXBwZW5kIGBbXWAgdG8gdGhlIG5hbWUuXG4gICAgICAgICAqL1xuICAgICAgICBwYXJhbU5hbWU6IFwiZmlsZVwiLFxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBXaGV0aGVyIHRodW1ibmFpbHMgZm9yIGltYWdlcyBzaG91bGQgYmUgZ2VuZXJhdGVkXG4gICAgICAgICAqL1xuICAgICAgICBjcmVhdGVJbWFnZVRodW1ibmFpbHM6IHRydWUsXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEluIE1CLiBXaGVuIHRoZSBmaWxlbmFtZSBleGNlZWRzIHRoaXMgbGltaXQsIHRoZSB0aHVtYm5haWwgd2lsbCBub3QgYmUgZ2VuZXJhdGVkLlxuICAgICAgICAgKi9cbiAgICAgICAgbWF4VGh1bWJuYWlsRmlsZXNpemU6IDEwLFxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBJZiBgbnVsbGAsIHRoZSByYXRpbyBvZiB0aGUgaW1hZ2Ugd2lsbCBiZSB1c2VkIHRvIGNhbGN1bGF0ZSBpdC5cbiAgICAgICAgICovXG4gICAgICAgIHRodW1ibmFpbFdpZHRoOiAxMjAsXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBzYW1lIGFzIGB0aHVtYm5haWxXaWR0aGAuIElmIGJvdGggYXJlIG51bGwsIGltYWdlcyB3aWxsIG5vdCBiZSByZXNpemVkLlxuICAgICAgICAgKi9cbiAgICAgICAgdGh1bWJuYWlsSGVpZ2h0OiAxMjAsXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEhvdyB0aGUgaW1hZ2VzIHNob3VsZCBiZSBzY2FsZWQgZG93biBpbiBjYXNlIGJvdGgsIGB0aHVtYm5haWxXaWR0aGAgYW5kIGB0aHVtYm5haWxIZWlnaHRgIGFyZSBwcm92aWRlZC5cbiAgICAgICAgICogQ2FuIGJlIGVpdGhlciBgY29udGFpbmAgb3IgYGNyb3BgLlxuICAgICAgICAgKi9cbiAgICAgICAgdGh1bWJuYWlsTWV0aG9kOiAnY3JvcCcsXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIElmIHNldCwgaW1hZ2VzIHdpbGwgYmUgcmVzaXplZCB0byB0aGVzZSBkaW1lbnNpb25zIGJlZm9yZSBiZWluZyAqKnVwbG9hZGVkKiouXG4gICAgICAgICAqIElmIG9ubHkgb25lLCBgcmVzaXplV2lkdGhgICoqb3IqKiBgcmVzaXplSGVpZ2h0YCBpcyBwcm92aWRlZCwgdGhlIG9yaWdpbmFsIGFzcGVjdFxuICAgICAgICAgKiByYXRpbyBvZiB0aGUgZmlsZSB3aWxsIGJlIHByZXNlcnZlZC5cbiAgICAgICAgICpcbiAgICAgICAgICogVGhlIGBvcHRpb25zLnRyYW5zZm9ybUZpbGVgIGZ1bmN0aW9uIHVzZXMgdGhlc2Ugb3B0aW9ucywgc28gaWYgdGhlIGB0cmFuc2Zvcm1GaWxlYCBmdW5jdGlvblxuICAgICAgICAgKiBpcyBvdmVycmlkZGVuLCB0aGVzZSBvcHRpb25zIGRvbid0IGRvIGFueXRoaW5nLlxuICAgICAgICAgKi9cbiAgICAgICAgcmVzaXplV2lkdGg6IG51bGwsXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFNlZSBgcmVzaXplV2lkdGhgLlxuICAgICAgICAgKi9cbiAgICAgICAgcmVzaXplSGVpZ2h0OiBudWxsLFxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgbWltZSB0eXBlIG9mIHRoZSByZXNpemVkIGltYWdlIChiZWZvcmUgaXQgZ2V0cyB1cGxvYWRlZCB0byB0aGUgc2VydmVyKS5cbiAgICAgICAgICogSWYgYG51bGxgIHRoZSBvcmlnaW5hbCBtaW1lIHR5cGUgd2lsbCBiZSB1c2VkLiBUbyBmb3JjZSBqcGVnLCBmb3IgZXhhbXBsZSwgdXNlIGBpbWFnZS9qcGVnYC5cbiAgICAgICAgICogU2VlIGByZXNpemVXaWR0aGAgZm9yIG1vcmUgaW5mb3JtYXRpb24uXG4gICAgICAgICAqL1xuICAgICAgICByZXNpemVNaW1lVHlwZTogbnVsbCxcblxuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHF1YWxpdHkgb2YgdGhlIHJlc2l6ZWQgaW1hZ2VzLiBTZWUgYHJlc2l6ZVdpZHRoYC5cbiAgICAgICAgICovXG4gICAgICAgIHJlc2l6ZVF1YWxpdHk6IDAuOCxcblxuICAgICAgICAvKipcbiAgICAgICAgICogSG93IHRoZSBpbWFnZXMgc2hvdWxkIGJlIHNjYWxlZCBkb3duIGluIGNhc2UgYm90aCwgYHJlc2l6ZVdpZHRoYCBhbmQgYHJlc2l6ZUhlaWdodGAgYXJlIHByb3ZpZGVkLlxuICAgICAgICAgKiBDYW4gYmUgZWl0aGVyIGBjb250YWluYCBvciBgY3JvcGAuXG4gICAgICAgICAqL1xuICAgICAgICByZXNpemVNZXRob2Q6ICdjb250YWluJyxcblxuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGJhc2UgdGhhdCBpcyB1c2VkIHRvIGNhbGN1bGF0ZSB0aGUgZmlsZXNpemUuIFlvdSBjYW4gY2hhbmdlIHRoaXMgdG9cbiAgICAgICAgICogMTAyNCBpZiB5b3Ugd291bGQgcmF0aGVyIGRpc3BsYXkga2liaWJ5dGVzLCBtZWJpYnl0ZXMsIGV0Yy4uLlxuICAgICAgICAgKiAxMDI0IGlzIHRlY2huaWNhbGx5IGluY29ycmVjdCwgYmVjYXVzZSBgMTAyNCBieXRlc2AgYXJlIGAxIGtpYmlieXRlYCBub3QgYDEga2lsb2J5dGVgLlxuICAgICAgICAgKiBZb3UgY2FuIGNoYW5nZSB0aGlzIHRvIGAxMDI0YCBpZiB5b3UgZG9uJ3QgY2FyZSBhYm91dCB2YWxpZGl0eS5cbiAgICAgICAgICovXG4gICAgICAgIGZpbGVzaXplQmFzZTogMTAwMCxcblxuICAgICAgICAvKipcbiAgICAgICAgICogQ2FuIGJlIHVzZWQgdG8gbGltaXQgdGhlIG1heGltdW0gbnVtYmVyIG9mIGZpbGVzIHRoYXQgd2lsbCBiZSBoYW5kbGVkIGJ5IHRoaXMgRHJvcHpvbmVcbiAgICAgICAgICovXG4gICAgICAgIG1heEZpbGVzOiBudWxsLFxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBBbiBvcHRpb25hbCBvYmplY3QgdG8gc2VuZCBhZGRpdGlvbmFsIGhlYWRlcnMgdG8gdGhlIHNlcnZlci4gRWc6XG4gICAgICAgICAqIGB7IFwiTXktQXdlc29tZS1IZWFkZXJcIjogXCJoZWFkZXIgdmFsdWVcIiB9YFxuICAgICAgICAgKi9cbiAgICAgICAgaGVhZGVyczogbnVsbCxcblxuICAgICAgICAvKipcbiAgICAgICAgICogSWYgYHRydWVgLCB0aGUgZHJvcHpvbmUgZWxlbWVudCBpdHNlbGYgd2lsbCBiZSBjbGlja2FibGUsIGlmIGBmYWxzZWBcbiAgICAgICAgICogbm90aGluZyB3aWxsIGJlIGNsaWNrYWJsZS5cbiAgICAgICAgICpcbiAgICAgICAgICogWW91IGNhbiBhbHNvIHBhc3MgYW4gSFRNTCBlbGVtZW50LCBhIENTUyBzZWxlY3RvciAoZm9yIG11bHRpcGxlIGVsZW1lbnRzKVxuICAgICAgICAgKiBvciBhbiBhcnJheSBvZiB0aG9zZS4gSW4gdGhhdCBjYXNlLCBhbGwgb2YgdGhvc2UgZWxlbWVudHMgd2lsbCB0cmlnZ2VyIGFuXG4gICAgICAgICAqIHVwbG9hZCB3aGVuIGNsaWNrZWQuXG4gICAgICAgICAqL1xuICAgICAgICBjbGlja2FibGU6IHRydWUsXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFdoZXRoZXIgaGlkZGVuIGZpbGVzIGluIGRpcmVjdG9yaWVzIHNob3VsZCBiZSBpZ25vcmVkLlxuICAgICAgICAgKi9cbiAgICAgICAgaWdub3JlSGlkZGVuRmlsZXM6IHRydWUsXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIG9mIGBhY2NlcHRgIGNoZWNrcyB0aGUgZmlsZSdzIG1pbWUgdHlwZSBvclxuICAgICAgICAgKiBleHRlbnNpb24gYWdhaW5zdCB0aGlzIGxpc3QuIFRoaXMgaXMgYSBjb21tYSBzZXBhcmF0ZWQgbGlzdCBvZiBtaW1lXG4gICAgICAgICAqIHR5cGVzIG9yIGZpbGUgZXh0ZW5zaW9ucy5cbiAgICAgICAgICpcbiAgICAgICAgICogRWcuOiBgaW1hZ2UvKixhcHBsaWNhdGlvbi9wZGYsLnBzZGBcbiAgICAgICAgICpcbiAgICAgICAgICogSWYgdGhlIERyb3B6b25lIGlzIGBjbGlja2FibGVgIHRoaXMgb3B0aW9uIHdpbGwgYWxzbyBiZSB1c2VkIGFzXG4gICAgICAgICAqIFtgYWNjZXB0YF0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9IVE1ML0VsZW1lbnQvaW5wdXQjYXR0ci1hY2NlcHQpXG4gICAgICAgICAqIHBhcmFtZXRlciBvbiB0aGUgaGlkZGVuIGZpbGUgaW5wdXQgYXMgd2VsbC5cbiAgICAgICAgICovXG4gICAgICAgIGFjY2VwdGVkRmlsZXM6IG51bGwsXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqICoqRGVwcmVjYXRlZCEqKlxuICAgICAgICAgKiBVc2UgYWNjZXB0ZWRGaWxlcyBpbnN0ZWFkLlxuICAgICAgICAgKi9cbiAgICAgICAgYWNjZXB0ZWRNaW1lVHlwZXM6IG51bGwsXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIElmIGZhbHNlLCBmaWxlcyB3aWxsIGJlIGFkZGVkIHRvIHRoZSBxdWV1ZSBidXQgdGhlIHF1ZXVlIHdpbGwgbm90IGJlXG4gICAgICAgICAqIHByb2Nlc3NlZCBhdXRvbWF0aWNhbGx5LlxuICAgICAgICAgKiBUaGlzIGNhbiBiZSB1c2VmdWwgaWYgeW91IG5lZWQgc29tZSBhZGRpdGlvbmFsIHVzZXIgaW5wdXQgYmVmb3JlIHNlbmRpbmdcbiAgICAgICAgICogZmlsZXMgKG9yIGlmIHlvdSB3YW50IHdhbnQgYWxsIGZpbGVzIHNlbnQgYXQgb25jZSkuXG4gICAgICAgICAqIElmIHlvdSdyZSByZWFkeSB0byBzZW5kIHRoZSBmaWxlIHNpbXBseSBjYWxsIGBteURyb3B6b25lLnByb2Nlc3NRdWV1ZSgpYC5cbiAgICAgICAgICpcbiAgICAgICAgICogU2VlIHRoZSBbZW5xdWV1aW5nIGZpbGUgdXBsb2Fkc10oI2VucXVldWluZy1maWxlLXVwbG9hZHMpIGRvY3VtZW50YXRpb25cbiAgICAgICAgICogc2VjdGlvbiBmb3IgbW9yZSBpbmZvcm1hdGlvbi5cbiAgICAgICAgICovXG4gICAgICAgIGF1dG9Qcm9jZXNzUXVldWU6IHRydWUsXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIElmIGZhbHNlLCBmaWxlcyBhZGRlZCB0byB0aGUgZHJvcHpvbmUgd2lsbCBub3QgYmUgcXVldWVkIGJ5IGRlZmF1bHQuXG4gICAgICAgICAqIFlvdSdsbCBoYXZlIHRvIGNhbGwgYGVucXVldWVGaWxlKGZpbGUpYCBtYW51YWxseS5cbiAgICAgICAgICovXG4gICAgICAgIGF1dG9RdWV1ZTogdHJ1ZSxcblxuICAgICAgICAvKipcbiAgICAgICAgICogSWYgYHRydWVgLCB0aGlzIHdpbGwgYWRkIGEgbGluayB0byBldmVyeSBmaWxlIHByZXZpZXcgdG8gcmVtb3ZlIG9yIGNhbmNlbCAoaWZcbiAgICAgICAgICogYWxyZWFkeSB1cGxvYWRpbmcpIHRoZSBmaWxlLiBUaGUgYGRpY3RDYW5jZWxVcGxvYWRgLCBgZGljdENhbmNlbFVwbG9hZENvbmZpcm1hdGlvbmBcbiAgICAgICAgICogYW5kIGBkaWN0UmVtb3ZlRmlsZWAgb3B0aW9ucyBhcmUgdXNlZCBmb3IgdGhlIHdvcmRpbmcuXG4gICAgICAgICAqL1xuICAgICAgICBhZGRSZW1vdmVMaW5rczogZmFsc2UsXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIERlZmluZXMgd2hlcmUgdG8gZGlzcGxheSB0aGUgZmlsZSBwcmV2aWV3cyDigJMgaWYgYG51bGxgIHRoZVxuICAgICAgICAgKiBEcm9wem9uZSBlbGVtZW50IGl0c2VsZiBpcyB1c2VkLiBDYW4gYmUgYSBwbGFpbiBgSFRNTEVsZW1lbnRgIG9yIGEgQ1NTXG4gICAgICAgICAqIHNlbGVjdG9yLiBUaGUgZWxlbWVudCBzaG91bGQgaGF2ZSB0aGUgYGRyb3B6b25lLXByZXZpZXdzYCBjbGFzcyBzb1xuICAgICAgICAgKiB0aGUgcHJldmlld3MgYXJlIGRpc3BsYXllZCBwcm9wZXJseS5cbiAgICAgICAgICovXG4gICAgICAgIHByZXZpZXdzQ29udGFpbmVyOiBudWxsLFxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGlzIGlzIHRoZSBlbGVtZW50IHRoZSBoaWRkZW4gaW5wdXQgZmllbGQgKHdoaWNoIGlzIHVzZWQgd2hlbiBjbGlja2luZyBvbiB0aGVcbiAgICAgICAgICogZHJvcHpvbmUgdG8gdHJpZ2dlciBmaWxlIHNlbGVjdGlvbikgd2lsbCBiZSBhcHBlbmRlZCB0by4gVGhpcyBtaWdodFxuICAgICAgICAgKiBiZSBpbXBvcnRhbnQgaW4gY2FzZSB5b3UgdXNlIGZyYW1ld29ya3MgdG8gc3dpdGNoIHRoZSBjb250ZW50IG9mIHlvdXIgcGFnZS5cbiAgICAgICAgICpcbiAgICAgICAgICogQ2FuIGJlIGEgc2VsZWN0b3Igc3RyaW5nLCBvciBhbiBlbGVtZW50IGRpcmVjdGx5LlxuICAgICAgICAgKi9cbiAgICAgICAgaGlkZGVuSW5wdXRDb250YWluZXI6IFwiYm9keVwiLFxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBJZiBudWxsLCBubyBjYXB0dXJlIHR5cGUgd2lsbCBiZSBzcGVjaWZpZWRcbiAgICAgICAgICogSWYgY2FtZXJhLCBtb2JpbGUgZGV2aWNlcyB3aWxsIHNraXAgdGhlIGZpbGUgc2VsZWN0aW9uIGFuZCBjaG9vc2UgY2FtZXJhXG4gICAgICAgICAqIElmIG1pY3JvcGhvbmUsIG1vYmlsZSBkZXZpY2VzIHdpbGwgc2tpcCB0aGUgZmlsZSBzZWxlY3Rpb24gYW5kIGNob29zZSB0aGUgbWljcm9waG9uZVxuICAgICAgICAgKiBJZiBjYW1jb3JkZXIsIG1vYmlsZSBkZXZpY2VzIHdpbGwgc2tpcCB0aGUgZmlsZSBzZWxlY3Rpb24gYW5kIGNob29zZSB0aGUgY2FtZXJhIGluIHZpZGVvIG1vZGVcbiAgICAgICAgICogT24gYXBwbGUgZGV2aWNlcyBtdWx0aXBsZSBtdXN0IGJlIHNldCB0byBmYWxzZS4gIEFjY2VwdGVkRmlsZXMgbWF5IG5lZWQgdG9cbiAgICAgICAgICogYmUgc2V0IHRvIGFuIGFwcHJvcHJpYXRlIG1pbWUgdHlwZSAoZS5nLiBcImltYWdlLypcIiwgXCJhdWRpby8qXCIsIG9yIFwidmlkZW8vKlwiKS5cbiAgICAgICAgICovXG4gICAgICAgIGNhcHR1cmU6IG51bGwsXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqICoqRGVwcmVjYXRlZCoqLiBVc2UgYHJlbmFtZUZpbGVgIGluc3RlYWQuXG4gICAgICAgICAqL1xuICAgICAgICByZW5hbWVGaWxlbmFtZTogbnVsbCxcblxuICAgICAgICAvKipcbiAgICAgICAgICogQSBmdW5jdGlvbiB0aGF0IGlzIGludm9rZWQgYmVmb3JlIHRoZSBmaWxlIGlzIHVwbG9hZGVkIHRvIHRoZSBzZXJ2ZXIgYW5kIHJlbmFtZXMgdGhlIGZpbGUuXG4gICAgICAgICAqIFRoaXMgZnVuY3Rpb24gZ2V0cyB0aGUgYEZpbGVgIGFzIGFyZ3VtZW50IGFuZCBjYW4gdXNlIHRoZSBgZmlsZS5uYW1lYC4gVGhlIGFjdHVhbCBuYW1lIG9mIHRoZVxuICAgICAgICAgKiBmaWxlIHRoYXQgZ2V0cyB1c2VkIGR1cmluZyB0aGUgdXBsb2FkIGNhbiBiZSBhY2Nlc3NlZCB0aHJvdWdoIGBmaWxlLnVwbG9hZC5maWxlbmFtZWAuXG4gICAgICAgICAqL1xuICAgICAgICByZW5hbWVGaWxlOiBudWxsLFxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBJZiBgdHJ1ZWAgdGhlIGZhbGxiYWNrIHdpbGwgYmUgZm9yY2VkLiBUaGlzIGlzIHZlcnkgdXNlZnVsIHRvIHRlc3QgeW91ciBzZXJ2ZXJcbiAgICAgICAgICogaW1wbGVtZW50YXRpb25zIGZpcnN0IGFuZCBtYWtlIHN1cmUgdGhhdCBldmVyeXRoaW5nIHdvcmtzIGFzXG4gICAgICAgICAqIGV4cGVjdGVkIHdpdGhvdXQgZHJvcHpvbmUgaWYgeW91IGV4cGVyaWVuY2UgcHJvYmxlbXMsIGFuZCB0byB0ZXN0XG4gICAgICAgICAqIGhvdyB5b3VyIGZhbGxiYWNrcyB3aWxsIGxvb2suXG4gICAgICAgICAqL1xuICAgICAgICBmb3JjZUZhbGxiYWNrOiBmYWxzZSxcblxuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHRleHQgdXNlZCBiZWZvcmUgYW55IGZpbGVzIGFyZSBkcm9wcGVkLlxuICAgICAgICAgKi9cbiAgICAgICAgZGljdERlZmF1bHRNZXNzYWdlOiBcIkRyb3AgZmlsZXMgaGVyZSB0byB1cGxvYWRcIixcblxuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHRleHQgdGhhdCByZXBsYWNlcyB0aGUgZGVmYXVsdCBtZXNzYWdlIHRleHQgaXQgdGhlIGJyb3dzZXIgaXMgbm90IHN1cHBvcnRlZC5cbiAgICAgICAgICovXG4gICAgICAgIGRpY3RGYWxsYmFja01lc3NhZ2U6IFwiWW91ciBicm93c2VyIGRvZXMgbm90IHN1cHBvcnQgZHJhZyduJ2Ryb3AgZmlsZSB1cGxvYWRzLlwiLFxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgdGV4dCB0aGF0IHdpbGwgYmUgYWRkZWQgYmVmb3JlIHRoZSBmYWxsYmFjayBmb3JtLlxuICAgICAgICAgKiBJZiB5b3UgcHJvdmlkZSBhICBmYWxsYmFjayBlbGVtZW50IHlvdXJzZWxmLCBvciBpZiB0aGlzIG9wdGlvbiBpcyBgbnVsbGAgdGhpcyB3aWxsXG4gICAgICAgICAqIGJlIGlnbm9yZWQuXG4gICAgICAgICAqL1xuICAgICAgICBkaWN0RmFsbGJhY2tUZXh0OiBcIlBsZWFzZSB1c2UgdGhlIGZhbGxiYWNrIGZvcm0gYmVsb3cgdG8gdXBsb2FkIHlvdXIgZmlsZXMgbGlrZSBpbiB0aGUgb2xkZW4gZGF5cy5cIixcblxuICAgICAgICAvKipcbiAgICAgICAgICogSWYgdGhlIGZpbGVzaXplIGlzIHRvbyBiaWcuXG4gICAgICAgICAqIGB7e2ZpbGVzaXplfX1gIGFuZCBge3ttYXhGaWxlc2l6ZX19YCB3aWxsIGJlIHJlcGxhY2VkIHdpdGggdGhlIHJlc3BlY3RpdmUgY29uZmlndXJhdGlvbiB2YWx1ZXMuXG4gICAgICAgICAqL1xuICAgICAgICBkaWN0RmlsZVRvb0JpZzogXCJGaWxlIGlzIHRvbyBiaWcgKHt7ZmlsZXNpemV9fU1pQikuIE1heCBmaWxlc2l6ZToge3ttYXhGaWxlc2l6ZX19TWlCLlwiLFxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBJZiB0aGUgZmlsZSBkb2Vzbid0IG1hdGNoIHRoZSBmaWxlIHR5cGUuXG4gICAgICAgICAqL1xuICAgICAgICBkaWN0SW52YWxpZEZpbGVUeXBlOiBcIllvdSBjYW4ndCB1cGxvYWQgZmlsZXMgb2YgdGhpcyB0eXBlLlwiLFxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBJZiB0aGUgc2VydmVyIHJlc3BvbnNlIHdhcyBpbnZhbGlkLlxuICAgICAgICAgKiBge3tzdGF0dXNDb2RlfX1gIHdpbGwgYmUgcmVwbGFjZWQgd2l0aCB0aGUgc2VydmVycyBzdGF0dXMgY29kZS5cbiAgICAgICAgICovXG4gICAgICAgIGRpY3RSZXNwb25zZUVycm9yOiBcIlNlcnZlciByZXNwb25kZWQgd2l0aCB7e3N0YXR1c0NvZGV9fSBjb2RlLlwiLFxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBJZiBgYWRkUmVtb3ZlTGlua3NgIGlzIHRydWUsIHRoZSB0ZXh0IHRvIGJlIHVzZWQgZm9yIHRoZSBjYW5jZWwgdXBsb2FkIGxpbmsuXG4gICAgICAgICAqL1xuICAgICAgICBkaWN0Q2FuY2VsVXBsb2FkOiBcIkNhbmNlbCB1cGxvYWRcIixcblxuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHRleHQgdGhhdCBpcyBkaXNwbGF5ZWQgaWYgYW4gdXBsb2FkIHdhcyBtYW51YWxseSBjYW5jZWxlZFxuICAgICAgICAgKi9cbiAgICAgICAgZGljdFVwbG9hZENhbmNlbGVkOiBcIlVwbG9hZCBjYW5jZWxlZC5cIixcblxuICAgICAgICAvKipcbiAgICAgICAgICogSWYgYGFkZFJlbW92ZUxpbmtzYCBpcyB0cnVlLCB0aGUgdGV4dCB0byBiZSB1c2VkIGZvciBjb25maXJtYXRpb24gd2hlbiBjYW5jZWxsaW5nIHVwbG9hZC5cbiAgICAgICAgICovXG4gICAgICAgIGRpY3RDYW5jZWxVcGxvYWRDb25maXJtYXRpb246IFwiQXJlIHlvdSBzdXJlIHlvdSB3YW50IHRvIGNhbmNlbCB0aGlzIHVwbG9hZD9cIixcblxuICAgICAgICAvKipcbiAgICAgICAgICogSWYgYGFkZFJlbW92ZUxpbmtzYCBpcyB0cnVlLCB0aGUgdGV4dCB0byBiZSB1c2VkIHRvIHJlbW92ZSBhIGZpbGUuXG4gICAgICAgICAqL1xuICAgICAgICBkaWN0UmVtb3ZlRmlsZTogXCJSZW1vdmUgZmlsZVwiLFxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBJZiB0aGlzIGlzIG5vdCBudWxsLCB0aGVuIHRoZSB1c2VyIHdpbGwgYmUgcHJvbXB0ZWQgYmVmb3JlIHJlbW92aW5nIGEgZmlsZS5cbiAgICAgICAgICovXG4gICAgICAgIGRpY3RSZW1vdmVGaWxlQ29uZmlybWF0aW9uOiBudWxsLFxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBEaXNwbGF5ZWQgaWYgYG1heEZpbGVzYCBpcyBzdCBhbmQgZXhjZWVkZWQuXG4gICAgICAgICAqIFRoZSBzdHJpbmcgYHt7bWF4RmlsZXN9fWAgd2lsbCBiZSByZXBsYWNlZCBieSB0aGUgY29uZmlndXJhdGlvbiB2YWx1ZS5cbiAgICAgICAgICovXG4gICAgICAgIGRpY3RNYXhGaWxlc0V4Y2VlZGVkOiBcIllvdSBjYW4gbm90IHVwbG9hZCBhbnkgbW9yZSBmaWxlcy5cIixcblxuICAgICAgICAvKipcbiAgICAgICAgICogQWxsb3dzIHlvdSB0byB0cmFuc2xhdGUgdGhlIGRpZmZlcmVudCB1bml0cy4gU3RhcnRpbmcgd2l0aCBgdGJgIGZvciB0ZXJhYnl0ZXMgYW5kIGdvaW5nIGRvd24gdG9cbiAgICAgICAgICogYGJgIGZvciBieXRlcy5cbiAgICAgICAgICovXG4gICAgICAgIGRpY3RGaWxlU2l6ZVVuaXRzOiB7XG4gICAgICAgICAgdGI6IFwiVEJcIixcbiAgICAgICAgICBnYjogXCJHQlwiLFxuICAgICAgICAgIG1iOiBcIk1CXCIsXG4gICAgICAgICAga2I6IFwiS0JcIixcbiAgICAgICAgICBiOiBcImJcIlxuICAgICAgICB9LFxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDYWxsZWQgd2hlbiBkcm9wem9uZSBpbml0aWFsaXplZFxuICAgICAgICAgKiBZb3UgY2FuIGFkZCBldmVudCBsaXN0ZW5lcnMgaGVyZVxuICAgICAgICAgKi9cbiAgICAgICAgaW5pdDogZnVuY3Rpb24gaW5pdCgpIHt9LFxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDYW4gYmUgYW4gKipvYmplY3QqKiBvZiBhZGRpdGlvbmFsIHBhcmFtZXRlcnMgdG8gdHJhbnNmZXIgdG8gdGhlIHNlcnZlciwgKipvcioqIGEgYEZ1bmN0aW9uYFxuICAgICAgICAgKiB0aGF0IGdldHMgaW52b2tlZCB3aXRoIHRoZSBgZmlsZXNgLCBgeGhyYCBhbmQsIGlmIGl0J3MgYSBjaHVua2VkIHVwbG9hZCwgYGNodW5rYCBhcmd1bWVudHMuIEluIGNhc2VcbiAgICAgICAgICogb2YgYSBmdW5jdGlvbiwgdGhpcyBuZWVkcyB0byByZXR1cm4gYSBtYXAuXG4gICAgICAgICAqXG4gICAgICAgICAqIFRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIGRvZXMgbm90aGluZyBmb3Igbm9ybWFsIHVwbG9hZHMsIGJ1dCBhZGRzIHJlbGV2YW50IGluZm9ybWF0aW9uIGZvclxuICAgICAgICAgKiBjaHVua2VkIHVwbG9hZHMuXG4gICAgICAgICAqXG4gICAgICAgICAqIFRoaXMgaXMgdGhlIHNhbWUgYXMgYWRkaW5nIGhpZGRlbiBpbnB1dCBmaWVsZHMgaW4gdGhlIGZvcm0gZWxlbWVudC5cbiAgICAgICAgICovXG4gICAgICAgIHBhcmFtczogZnVuY3Rpb24gcGFyYW1zKGZpbGVzLCB4aHIsIGNodW5rKSB7XG4gICAgICAgICAgaWYgKGNodW5rKSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICBkenV1aWQ6IGNodW5rLmZpbGUudXBsb2FkLnV1aWQsXG4gICAgICAgICAgICAgIGR6Y2h1bmtpbmRleDogY2h1bmsuaW5kZXgsXG4gICAgICAgICAgICAgIGR6dG90YWxmaWxlc2l6ZTogY2h1bmsuZmlsZS5zaXplLFxuICAgICAgICAgICAgICBkemNodW5rc2l6ZTogdGhpcy5vcHRpb25zLmNodW5rU2l6ZSxcbiAgICAgICAgICAgICAgZHp0b3RhbGNodW5rY291bnQ6IGNodW5rLmZpbGUudXBsb2FkLnRvdGFsQ2h1bmtDb3VudCxcbiAgICAgICAgICAgICAgZHpjaHVua2J5dGVvZmZzZXQ6IGNodW5rLmluZGV4ICogdGhpcy5vcHRpb25zLmNodW5rU2l6ZVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9XG4gICAgICAgIH0sXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEEgZnVuY3Rpb24gdGhhdCBnZXRzIGEgW2ZpbGVdKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvRE9NL0ZpbGUpXG4gICAgICAgICAqIGFuZCBhIGBkb25lYCBmdW5jdGlvbiBhcyBwYXJhbWV0ZXJzLlxuICAgICAgICAgKlxuICAgICAgICAgKiBJZiB0aGUgZG9uZSBmdW5jdGlvbiBpcyBpbnZva2VkIHdpdGhvdXQgYXJndW1lbnRzLCB0aGUgZmlsZSBpcyBcImFjY2VwdGVkXCIgYW5kIHdpbGxcbiAgICAgICAgICogYmUgcHJvY2Vzc2VkLiBJZiB5b3UgcGFzcyBhbiBlcnJvciBtZXNzYWdlLCB0aGUgZmlsZSBpcyByZWplY3RlZCwgYW5kIHRoZSBlcnJvclxuICAgICAgICAgKiBtZXNzYWdlIHdpbGwgYmUgZGlzcGxheWVkLlxuICAgICAgICAgKiBUaGlzIGZ1bmN0aW9uIHdpbGwgbm90IGJlIGNhbGxlZCBpZiB0aGUgZmlsZSBpcyB0b28gYmlnIG9yIGRvZXNuJ3QgbWF0Y2ggdGhlIG1pbWUgdHlwZXMuXG4gICAgICAgICAqL1xuICAgICAgICBhY2NlcHQ6IGZ1bmN0aW9uIGFjY2VwdChmaWxlLCBkb25lKSB7XG4gICAgICAgICAgcmV0dXJuIGRvbmUoKTtcbiAgICAgICAgfSxcblxuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGNhbGxiYWNrIHRoYXQgd2lsbCBiZSBpbnZva2VkIHdoZW4gYWxsIGNodW5rcyBoYXZlIGJlZW4gdXBsb2FkZWQgZm9yIGEgZmlsZS5cbiAgICAgICAgICogSXQgZ2V0cyB0aGUgZmlsZSBmb3Igd2hpY2ggdGhlIGNodW5rcyBoYXZlIGJlZW4gdXBsb2FkZWQgYXMgdGhlIGZpcnN0IHBhcmFtZXRlcixcbiAgICAgICAgICogYW5kIHRoZSBgZG9uZWAgZnVuY3Rpb24gYXMgc2Vjb25kLiBgZG9uZSgpYCBuZWVkcyB0byBiZSBpbnZva2VkIHdoZW4gZXZlcnl0aGluZ1xuICAgICAgICAgKiBuZWVkZWQgdG8gZmluaXNoIHRoZSB1cGxvYWQgcHJvY2VzcyBpcyBkb25lLlxuICAgICAgICAgKi9cbiAgICAgICAgY2h1bmtzVXBsb2FkZWQ6IGZ1bmN0aW9uIGNodW5rc1VwbG9hZGVkKGZpbGUsIGRvbmUpIHtcbiAgICAgICAgICBkb25lKCk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEdldHMgY2FsbGVkIHdoZW4gdGhlIGJyb3dzZXIgaXMgbm90IHN1cHBvcnRlZC5cbiAgICAgICAgICogVGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gc2hvd3MgdGhlIGZhbGxiYWNrIGlucHV0IGZpZWxkIGFuZCBhZGRzXG4gICAgICAgICAqIGEgdGV4dC5cbiAgICAgICAgICovXG4gICAgICAgIGZhbGxiYWNrOiBmdW5jdGlvbiBmYWxsYmFjaygpIHtcbiAgICAgICAgICAvLyBUaGlzIGNvZGUgc2hvdWxkIHBhc3MgaW4gSUU3Li4uIDooXG4gICAgICAgICAgdmFyIG1lc3NhZ2VFbGVtZW50O1xuICAgICAgICAgIHRoaXMuZWxlbWVudC5jbGFzc05hbWUgPSBcIlwiLmNvbmNhdCh0aGlzLmVsZW1lbnQuY2xhc3NOYW1lLCBcIiBkei1icm93c2VyLW5vdC1zdXBwb3J0ZWRcIik7XG4gICAgICAgICAgdmFyIF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24yID0gdHJ1ZTtcbiAgICAgICAgICB2YXIgX2RpZEl0ZXJhdG9yRXJyb3IyID0gZmFsc2U7XG4gICAgICAgICAgdmFyIF9pdGVyYXRvckVycm9yMiA9IHVuZGVmaW5lZDtcblxuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBmb3IgKHZhciBfaXRlcmF0b3IyID0gdGhpcy5lbGVtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKFwiZGl2XCIpW1N5bWJvbC5pdGVyYXRvcl0oKSwgX3N0ZXAyOyAhKF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24yID0gKF9zdGVwMiA9IF9pdGVyYXRvcjIubmV4dCgpKS5kb25lKTsgX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjIgPSB0cnVlKSB7XG4gICAgICAgICAgICAgIHZhciBjaGlsZCA9IF9zdGVwMi52YWx1ZTtcblxuICAgICAgICAgICAgICBpZiAoLyhefCApZHotbWVzc2FnZSgkfCApLy50ZXN0KGNoaWxkLmNsYXNzTmFtZSkpIHtcbiAgICAgICAgICAgICAgICBtZXNzYWdlRWxlbWVudCA9IGNoaWxkO1xuICAgICAgICAgICAgICAgIGNoaWxkLmNsYXNzTmFtZSA9IFwiZHotbWVzc2FnZVwiOyAvLyBSZW1vdmVzIHRoZSAnZHotZGVmYXVsdCcgY2xhc3NcblxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICBfZGlkSXRlcmF0b3JFcnJvcjIgPSB0cnVlO1xuICAgICAgICAgICAgX2l0ZXJhdG9yRXJyb3IyID0gZXJyO1xuICAgICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICBpZiAoIV9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24yICYmIF9pdGVyYXRvcjJbXCJyZXR1cm5cIl0gIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIF9pdGVyYXRvcjJbXCJyZXR1cm5cIl0oKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgICAgaWYgKF9kaWRJdGVyYXRvckVycm9yMikge1xuICAgICAgICAgICAgICAgIHRocm93IF9pdGVyYXRvckVycm9yMjtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmICghbWVzc2FnZUVsZW1lbnQpIHtcbiAgICAgICAgICAgIG1lc3NhZ2VFbGVtZW50ID0gRHJvcHpvbmUuY3JlYXRlRWxlbWVudChcIjxkaXYgY2xhc3M9XFxcImR6LW1lc3NhZ2VcXFwiPjxzcGFuPjwvc3Bhbj48L2Rpdj5cIik7XG4gICAgICAgICAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQobWVzc2FnZUVsZW1lbnQpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHZhciBzcGFuID0gbWVzc2FnZUVsZW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoXCJzcGFuXCIpWzBdO1xuXG4gICAgICAgICAgaWYgKHNwYW4pIHtcbiAgICAgICAgICAgIGlmIChzcGFuLnRleHRDb250ZW50ICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgc3Bhbi50ZXh0Q29udGVudCA9IHRoaXMub3B0aW9ucy5kaWN0RmFsbGJhY2tNZXNzYWdlO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChzcGFuLmlubmVyVGV4dCAhPSBudWxsKSB7XG4gICAgICAgICAgICAgIHNwYW4uaW5uZXJUZXh0ID0gdGhpcy5vcHRpb25zLmRpY3RGYWxsYmFja01lc3NhZ2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLmdldEZhbGxiYWNrRm9ybSgpKTtcbiAgICAgICAgfSxcblxuICAgICAgICAvKipcbiAgICAgICAgICogR2V0cyBjYWxsZWQgdG8gY2FsY3VsYXRlIHRoZSB0aHVtYm5haWwgZGltZW5zaW9ucy5cbiAgICAgICAgICpcbiAgICAgICAgICogSXQgZ2V0cyBgZmlsZWAsIGB3aWR0aGAgYW5kIGBoZWlnaHRgIChib3RoIG1heSBiZSBgbnVsbGApIGFzIHBhcmFtZXRlcnMgYW5kIG11c3QgcmV0dXJuIGFuIG9iamVjdCBjb250YWluaW5nOlxuICAgICAgICAgKlxuICAgICAgICAgKiAgLSBgc3JjV2lkdGhgICYgYHNyY0hlaWdodGAgKHJlcXVpcmVkKVxuICAgICAgICAgKiAgLSBgdHJnV2lkdGhgICYgYHRyZ0hlaWdodGAgKHJlcXVpcmVkKVxuICAgICAgICAgKiAgLSBgc3JjWGAgJiBgc3JjWWAgKG9wdGlvbmFsLCBkZWZhdWx0IGAwYClcbiAgICAgICAgICogIC0gYHRyZ1hgICYgYHRyZ1lgIChvcHRpb25hbCwgZGVmYXVsdCBgMGApXG4gICAgICAgICAqXG4gICAgICAgICAqIFRob3NlIHZhbHVlcyBhcmUgZ29pbmcgdG8gYmUgdXNlZCBieSBgY3R4LmRyYXdJbWFnZSgpYC5cbiAgICAgICAgICovXG4gICAgICAgIHJlc2l6ZTogZnVuY3Rpb24gcmVzaXplKGZpbGUsIHdpZHRoLCBoZWlnaHQsIHJlc2l6ZU1ldGhvZCkge1xuICAgICAgICAgIHZhciBpbmZvID0ge1xuICAgICAgICAgICAgc3JjWDogMCxcbiAgICAgICAgICAgIHNyY1k6IDAsXG4gICAgICAgICAgICBzcmNXaWR0aDogZmlsZS53aWR0aCxcbiAgICAgICAgICAgIHNyY0hlaWdodDogZmlsZS5oZWlnaHRcbiAgICAgICAgICB9O1xuICAgICAgICAgIHZhciBzcmNSYXRpbyA9IGZpbGUud2lkdGggLyBmaWxlLmhlaWdodDsgLy8gQXV0b21hdGljYWxseSBjYWxjdWxhdGUgZGltZW5zaW9ucyBpZiBub3Qgc3BlY2lmaWVkXG5cbiAgICAgICAgICBpZiAod2lkdGggPT0gbnVsbCAmJiBoZWlnaHQgPT0gbnVsbCkge1xuICAgICAgICAgICAgd2lkdGggPSBpbmZvLnNyY1dpZHRoO1xuICAgICAgICAgICAgaGVpZ2h0ID0gaW5mby5zcmNIZWlnaHQ7XG4gICAgICAgICAgfSBlbHNlIGlmICh3aWR0aCA9PSBudWxsKSB7XG4gICAgICAgICAgICB3aWR0aCA9IGhlaWdodCAqIHNyY1JhdGlvO1xuICAgICAgICAgIH0gZWxzZSBpZiAoaGVpZ2h0ID09IG51bGwpIHtcbiAgICAgICAgICAgIGhlaWdodCA9IHdpZHRoIC8gc3JjUmF0aW87XG4gICAgICAgICAgfSAvLyBNYWtlIHN1cmUgaW1hZ2VzIGFyZW4ndCB1cHNjYWxlZFxuXG5cbiAgICAgICAgICB3aWR0aCA9IE1hdGgubWluKHdpZHRoLCBpbmZvLnNyY1dpZHRoKTtcbiAgICAgICAgICBoZWlnaHQgPSBNYXRoLm1pbihoZWlnaHQsIGluZm8uc3JjSGVpZ2h0KTtcbiAgICAgICAgICB2YXIgdHJnUmF0aW8gPSB3aWR0aCAvIGhlaWdodDtcblxuICAgICAgICAgIGlmIChpbmZvLnNyY1dpZHRoID4gd2lkdGggfHwgaW5mby5zcmNIZWlnaHQgPiBoZWlnaHQpIHtcbiAgICAgICAgICAgIC8vIEltYWdlIGlzIGJpZ2dlciBhbmQgbmVlZHMgcmVzY2FsaW5nXG4gICAgICAgICAgICBpZiAocmVzaXplTWV0aG9kID09PSAnY3JvcCcpIHtcbiAgICAgICAgICAgICAgaWYgKHNyY1JhdGlvID4gdHJnUmF0aW8pIHtcbiAgICAgICAgICAgICAgICBpbmZvLnNyY0hlaWdodCA9IGZpbGUuaGVpZ2h0O1xuICAgICAgICAgICAgICAgIGluZm8uc3JjV2lkdGggPSBpbmZvLnNyY0hlaWdodCAqIHRyZ1JhdGlvO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGluZm8uc3JjV2lkdGggPSBmaWxlLndpZHRoO1xuICAgICAgICAgICAgICAgIGluZm8uc3JjSGVpZ2h0ID0gaW5mby5zcmNXaWR0aCAvIHRyZ1JhdGlvO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHJlc2l6ZU1ldGhvZCA9PT0gJ2NvbnRhaW4nKSB7XG4gICAgICAgICAgICAgIC8vIE1ldGhvZCAnY29udGFpbidcbiAgICAgICAgICAgICAgaWYgKHNyY1JhdGlvID4gdHJnUmF0aW8pIHtcbiAgICAgICAgICAgICAgICBoZWlnaHQgPSB3aWR0aCAvIHNyY1JhdGlvO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHdpZHRoID0gaGVpZ2h0ICogc3JjUmF0aW87XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gcmVzaXplTWV0aG9kICdcIi5jb25jYXQocmVzaXplTWV0aG9kLCBcIidcIikpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGluZm8uc3JjWCA9IChmaWxlLndpZHRoIC0gaW5mby5zcmNXaWR0aCkgLyAyO1xuICAgICAgICAgIGluZm8uc3JjWSA9IChmaWxlLmhlaWdodCAtIGluZm8uc3JjSGVpZ2h0KSAvIDI7XG4gICAgICAgICAgaW5mby50cmdXaWR0aCA9IHdpZHRoO1xuICAgICAgICAgIGluZm8udHJnSGVpZ2h0ID0gaGVpZ2h0O1xuICAgICAgICAgIHJldHVybiBpbmZvO1xuICAgICAgICB9LFxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDYW4gYmUgdXNlZCB0byB0cmFuc2Zvcm0gdGhlIGZpbGUgKGZvciBleGFtcGxlLCByZXNpemUgYW4gaW1hZ2UgaWYgbmVjZXNzYXJ5KS5cbiAgICAgICAgICpcbiAgICAgICAgICogVGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gdXNlcyBgcmVzaXplV2lkdGhgIGFuZCBgcmVzaXplSGVpZ2h0YCAoaWYgcHJvdmlkZWQpIGFuZCByZXNpemVzXG4gICAgICAgICAqIGltYWdlcyBhY2NvcmRpbmcgdG8gdGhvc2UgZGltZW5zaW9ucy5cbiAgICAgICAgICpcbiAgICAgICAgICogR2V0cyB0aGUgYGZpbGVgIGFzIHRoZSBmaXJzdCBwYXJhbWV0ZXIsIGFuZCBhIGBkb25lKClgIGZ1bmN0aW9uIGFzIHRoZSBzZWNvbmQsIHRoYXQgbmVlZHNcbiAgICAgICAgICogdG8gYmUgaW52b2tlZCB3aXRoIHRoZSBmaWxlIHdoZW4gdGhlIHRyYW5zZm9ybWF0aW9uIGlzIGRvbmUuXG4gICAgICAgICAqL1xuICAgICAgICB0cmFuc2Zvcm1GaWxlOiBmdW5jdGlvbiB0cmFuc2Zvcm1GaWxlKGZpbGUsIGRvbmUpIHtcbiAgICAgICAgICBpZiAoKHRoaXMub3B0aW9ucy5yZXNpemVXaWR0aCB8fCB0aGlzLm9wdGlvbnMucmVzaXplSGVpZ2h0KSAmJiBmaWxlLnR5cGUubWF0Y2goL2ltYWdlLiovKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMucmVzaXplSW1hZ2UoZmlsZSwgdGhpcy5vcHRpb25zLnJlc2l6ZVdpZHRoLCB0aGlzLm9wdGlvbnMucmVzaXplSGVpZ2h0LCB0aGlzLm9wdGlvbnMucmVzaXplTWV0aG9kLCBkb25lKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIGRvbmUoZmlsZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBBIHN0cmluZyB0aGF0IGNvbnRhaW5zIHRoZSB0ZW1wbGF0ZSB1c2VkIGZvciBlYWNoIGRyb3BwZWRcbiAgICAgICAgICogZmlsZS4gQ2hhbmdlIGl0IHRvIGZ1bGZpbGwgeW91ciBuZWVkcyBidXQgbWFrZSBzdXJlIHRvIHByb3Blcmx5XG4gICAgICAgICAqIHByb3ZpZGUgYWxsIGVsZW1lbnRzLlxuICAgICAgICAgKlxuICAgICAgICAgKiBJZiB5b3Ugd2FudCB0byB1c2UgYW4gYWN0dWFsIEhUTUwgZWxlbWVudCBpbnN0ZWFkIG9mIHByb3ZpZGluZyBhIFN0cmluZ1xuICAgICAgICAgKiBhcyBhIGNvbmZpZyBvcHRpb24sIHlvdSBjb3VsZCBjcmVhdGUgYSBkaXYgd2l0aCB0aGUgaWQgYHRwbGAsXG4gICAgICAgICAqIHB1dCB0aGUgdGVtcGxhdGUgaW5zaWRlIGl0IGFuZCBwcm92aWRlIHRoZSBlbGVtZW50IGxpa2UgdGhpczpcbiAgICAgICAgICpcbiAgICAgICAgICogICAgIGRvY3VtZW50XG4gICAgICAgICAqICAgICAgIC5xdWVyeVNlbGVjdG9yKCcjdHBsJylcbiAgICAgICAgICogICAgICAgLmlubmVySFRNTFxuICAgICAgICAgKlxuICAgICAgICAgKi9cbiAgICAgICAgcHJldmlld1RlbXBsYXRlOiBcIjxkaXYgY2xhc3M9XFxcImR6LXByZXZpZXcgZHotZmlsZS1wcmV2aWV3XFxcIj5cXG4gIDxkaXYgY2xhc3M9XFxcImR6LWltYWdlXFxcIj48aW1nIGRhdGEtZHotdGh1bWJuYWlsIC8+PC9kaXY+XFxuICA8ZGl2IGNsYXNzPVxcXCJkei1kZXRhaWxzXFxcIj5cXG4gICAgPGRpdiBjbGFzcz1cXFwiZHotc2l6ZVxcXCI+PHNwYW4gZGF0YS1kei1zaXplPjwvc3Bhbj48L2Rpdj5cXG4gICAgPGRpdiBjbGFzcz1cXFwiZHotZmlsZW5hbWVcXFwiPjxzcGFuIGRhdGEtZHotbmFtZT48L3NwYW4+PC9kaXY+XFxuICA8L2Rpdj5cXG4gIDxkaXYgY2xhc3M9XFxcImR6LXByb2dyZXNzXFxcIj48c3BhbiBjbGFzcz1cXFwiZHotdXBsb2FkXFxcIiBkYXRhLWR6LXVwbG9hZHByb2dyZXNzPjwvc3Bhbj48L2Rpdj5cXG4gIDxkaXYgY2xhc3M9XFxcImR6LWVycm9yLW1lc3NhZ2VcXFwiPjxzcGFuIGRhdGEtZHotZXJyb3JtZXNzYWdlPjwvc3Bhbj48L2Rpdj5cXG4gIDxkaXYgY2xhc3M9XFxcImR6LXN1Y2Nlc3MtbWFya1xcXCI+XFxuICAgIDxzdmcgd2lkdGg9XFxcIjU0cHhcXFwiIGhlaWdodD1cXFwiNTRweFxcXCIgdmlld0JveD1cXFwiMCAwIDU0IDU0XFxcIiB2ZXJzaW9uPVxcXCIxLjFcXFwiIHhtbG5zPVxcXCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1xcXCIgeG1sbnM6eGxpbms9XFxcImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmtcXFwiPlxcbiAgICAgIDx0aXRsZT5DaGVjazwvdGl0bGU+XFxuICAgICAgPGcgc3Ryb2tlPVxcXCJub25lXFxcIiBzdHJva2Utd2lkdGg9XFxcIjFcXFwiIGZpbGw9XFxcIm5vbmVcXFwiIGZpbGwtcnVsZT1cXFwiZXZlbm9kZFxcXCI+XFxuICAgICAgICA8cGF0aCBkPVxcXCJNMjMuNSwzMS44NDMxNDU4IEwxNy41ODUyNDE5LDI1LjkyODM4NzcgQzE2LjAyNDgyNTMsMjQuMzY3OTcxMSAxMy40OTEwMjk0LDI0LjM2NjgzNSAxMS45Mjg5MzIyLDI1LjkyODkzMjIgQzEwLjM3MDAxMzYsMjcuNDg3ODUwOCAxMC4zNjY1OTEyLDMwLjAyMzQ0NTUgMTEuOTI4Mzg3NywzMS41ODUyNDE5IEwyMC40MTQ3NTgxLDQwLjA3MTYxMjMgQzIwLjUxMzM5OTksNDAuMTcwMjU0MSAyMC42MTU5MzE1LDQwLjI2MjY2NDkgMjAuNzIxODYxNSw0MC4zNDg4NDM1IEMyMi4yODM1NjY5LDQxLjg3MjU2NTEgMjQuNzk0MjM0LDQxLjg2MjYyMDIgMjYuMzQ2MTU2NCw0MC4zMTA2OTc4IEw0My4zMTA2OTc4LDIzLjM0NjE1NjQgQzQ0Ljg3NzEwMjEsMjEuNzc5NzUyMSA0NC44NzU4MDU3LDE5LjI0ODM4ODcgNDMuMzEzNzA4NSwxNy42ODYyOTE1IEM0MS43NTQ3ODk5LDE2LjEyNzM3MjkgMzkuMjE3NjAzNSwxNi4xMjU1NDIyIDM3LjY1Mzg0MzYsMTcuNjg5MzAyMiBMMjMuNSwzMS44NDMxNDU4IFogTTI3LDUzIEM0MS4zNTk0MDM1LDUzIDUzLDQxLjM1OTQwMzUgNTMsMjcgQzUzLDEyLjY0MDU5NjUgNDEuMzU5NDAzNSwxIDI3LDEgQzEyLjY0MDU5NjUsMSAxLDEyLjY0MDU5NjUgMSwyNyBDMSw0MS4zNTk0MDM1IDEyLjY0MDU5NjUsNTMgMjcsNTMgWlxcXCIgc3Ryb2tlLW9wYWNpdHk9XFxcIjAuMTk4Nzk0MTU4XFxcIiBzdHJva2U9XFxcIiM3NDc0NzRcXFwiIGZpbGwtb3BhY2l0eT1cXFwiMC44MTY1MTk0NzVcXFwiIGZpbGw9XFxcIiNGRkZGRkZcXFwiPjwvcGF0aD5cXG4gICAgICA8L2c+XFxuICAgIDwvc3ZnPlxcbiAgPC9kaXY+XFxuICA8ZGl2IGNsYXNzPVxcXCJkei1lcnJvci1tYXJrXFxcIj5cXG4gICAgPHN2ZyB3aWR0aD1cXFwiNTRweFxcXCIgaGVpZ2h0PVxcXCI1NHB4XFxcIiB2aWV3Qm94PVxcXCIwIDAgNTQgNTRcXFwiIHZlcnNpb249XFxcIjEuMVxcXCIgeG1sbnM9XFxcImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXFxcIiB4bWxuczp4bGluaz1cXFwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1xcXCI+XFxuICAgICAgPHRpdGxlPkVycm9yPC90aXRsZT5cXG4gICAgICA8ZyBzdHJva2U9XFxcIm5vbmVcXFwiIHN0cm9rZS13aWR0aD1cXFwiMVxcXCIgZmlsbD1cXFwibm9uZVxcXCIgZmlsbC1ydWxlPVxcXCJldmVub2RkXFxcIj5cXG4gICAgICAgIDxnIHN0cm9rZT1cXFwiIzc0NzQ3NFxcXCIgc3Ryb2tlLW9wYWNpdHk9XFxcIjAuMTk4Nzk0MTU4XFxcIiBmaWxsPVxcXCIjRkZGRkZGXFxcIiBmaWxsLW9wYWNpdHk9XFxcIjAuODE2NTE5NDc1XFxcIj5cXG4gICAgICAgICAgPHBhdGggZD1cXFwiTTMyLjY1Njg1NDIsMjkgTDM4LjMxMDY5NzgsMjMuMzQ2MTU2NCBDMzkuODc3MTAyMSwyMS43Nzk3NTIxIDM5Ljg3NTgwNTcsMTkuMjQ4Mzg4NyAzOC4zMTM3MDg1LDE3LjY4NjI5MTUgQzM2Ljc1NDc4OTksMTYuMTI3MzcyOSAzNC4yMTc2MDM1LDE2LjEyNTU0MjIgMzIuNjUzODQzNiwxNy42ODkzMDIyIEwyNywyMy4zNDMxNDU4IEwyMS4zNDYxNTY0LDE3LjY4OTMwMjIgQzE5Ljc4MjM5NjUsMTYuMTI1NTQyMiAxNy4yNDUyMTAxLDE2LjEyNzM3MjkgMTUuNjg2MjkxNSwxNy42ODYyOTE1IEMxNC4xMjQxOTQzLDE5LjI0ODM4ODcgMTQuMTIyODk3OSwyMS43Nzk3NTIxIDE1LjY4OTMwMjIsMjMuMzQ2MTU2NCBMMjEuMzQzMTQ1OCwyOSBMMTUuNjg5MzAyMiwzNC42NTM4NDM2IEMxNC4xMjI4OTc5LDM2LjIyMDI0NzkgMTQuMTI0MTk0MywzOC43NTE2MTEzIDE1LjY4NjI5MTUsNDAuMzEzNzA4NSBDMTcuMjQ1MjEwMSw0MS44NzI2MjcxIDE5Ljc4MjM5NjUsNDEuODc0NDU3OCAyMS4zNDYxNTY0LDQwLjMxMDY5NzggTDI3LDM0LjY1Njg1NDIgTDMyLjY1Mzg0MzYsNDAuMzEwNjk3OCBDMzQuMjE3NjAzNSw0MS44NzQ0NTc4IDM2Ljc1NDc4OTksNDEuODcyNjI3MSAzOC4zMTM3MDg1LDQwLjMxMzcwODUgQzM5Ljg3NTgwNTcsMzguNzUxNjExMyAzOS44NzcxMDIxLDM2LjIyMDI0NzkgMzguMzEwNjk3OCwzNC42NTM4NDM2IEwzMi42NTY4NTQyLDI5IFogTTI3LDUzIEM0MS4zNTk0MDM1LDUzIDUzLDQxLjM1OTQwMzUgNTMsMjcgQzUzLDEyLjY0MDU5NjUgNDEuMzU5NDAzNSwxIDI3LDEgQzEyLjY0MDU5NjUsMSAxLDEyLjY0MDU5NjUgMSwyNyBDMSw0MS4zNTk0MDM1IDEyLjY0MDU5NjUsNTMgMjcsNTMgWlxcXCI+PC9wYXRoPlxcbiAgICAgICAgPC9nPlxcbiAgICAgIDwvZz5cXG4gICAgPC9zdmc+XFxuICA8L2Rpdj5cXG48L2Rpdj5cIixcbiAgICAgICAgLy8gRU5EIE9QVElPTlNcbiAgICAgICAgLy8gKFJlcXVpcmVkIGJ5IHRoZSBkcm9wem9uZSBkb2N1bWVudGF0aW9uIHBhcnNlcilcblxuICAgICAgICAvKlxuICAgICAgICAgVGhvc2UgZnVuY3Rpb25zIHJlZ2lzdGVyIHRoZW1zZWx2ZXMgdG8gdGhlIGV2ZW50cyBvbiBpbml0IGFuZCBoYW5kbGUgYWxsXG4gICAgICAgICB0aGUgdXNlciBpbnRlcmZhY2Ugc3BlY2lmaWMgc3R1ZmYuIE92ZXJ3cml0aW5nIHRoZW0gd29uJ3QgYnJlYWsgdGhlIHVwbG9hZFxuICAgICAgICAgYnV0IGNhbiBicmVhayB0aGUgd2F5IGl0J3MgZGlzcGxheWVkLlxuICAgICAgICAgWW91IGNhbiBvdmVyd3JpdGUgdGhlbSBpZiB5b3UgZG9uJ3QgbGlrZSB0aGUgZGVmYXVsdCBiZWhhdmlvci4gSWYgeW91IGp1c3RcbiAgICAgICAgIHdhbnQgdG8gYWRkIGFuIGFkZGl0aW9uYWwgZXZlbnQgaGFuZGxlciwgcmVnaXN0ZXIgaXQgb24gdGhlIGRyb3B6b25lIG9iamVjdFxuICAgICAgICAgYW5kIGRvbid0IG92ZXJ3cml0ZSB0aG9zZSBvcHRpb25zLlxuICAgICAgICAgKi9cbiAgICAgICAgLy8gVGhvc2UgYXJlIHNlbGYgZXhwbGFuYXRvcnkgYW5kIHNpbXBseSBjb25jZXJuIHRoZSBEcmFnbkRyb3AuXG4gICAgICAgIGRyb3A6IGZ1bmN0aW9uIGRyb3AoZSkge1xuICAgICAgICAgIHJldHVybiB0aGlzLmVsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZShcImR6LWRyYWctaG92ZXJcIik7XG4gICAgICAgIH0sXG4gICAgICAgIGRyYWdzdGFydDogZnVuY3Rpb24gZHJhZ3N0YXJ0KGUpIHt9LFxuICAgICAgICBkcmFnZW5kOiBmdW5jdGlvbiBkcmFnZW5kKGUpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5lbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoXCJkei1kcmFnLWhvdmVyXCIpO1xuICAgICAgICB9LFxuICAgICAgICBkcmFnZW50ZXI6IGZ1bmN0aW9uIGRyYWdlbnRlcihlKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuZWxlbWVudC5jbGFzc0xpc3QuYWRkKFwiZHotZHJhZy1ob3ZlclwiKTtcbiAgICAgICAgfSxcbiAgICAgICAgZHJhZ292ZXI6IGZ1bmN0aW9uIGRyYWdvdmVyKGUpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5lbGVtZW50LmNsYXNzTGlzdC5hZGQoXCJkei1kcmFnLWhvdmVyXCIpO1xuICAgICAgICB9LFxuICAgICAgICBkcmFnbGVhdmU6IGZ1bmN0aW9uIGRyYWdsZWF2ZShlKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuZWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKFwiZHotZHJhZy1ob3ZlclwiKTtcbiAgICAgICAgfSxcbiAgICAgICAgcGFzdGU6IGZ1bmN0aW9uIHBhc3RlKGUpIHt9LFxuICAgICAgICAvLyBDYWxsZWQgd2hlbmV2ZXIgdGhlcmUgYXJlIG5vIGZpbGVzIGxlZnQgaW4gdGhlIGRyb3B6b25lIGFueW1vcmUsIGFuZCB0aGVcbiAgICAgICAgLy8gZHJvcHpvbmUgc2hvdWxkIGJlIGRpc3BsYXllZCBhcyBpZiBpbiB0aGUgaW5pdGlhbCBzdGF0ZS5cbiAgICAgICAgcmVzZXQ6IGZ1bmN0aW9uIHJlc2V0KCkge1xuICAgICAgICAgIHJldHVybiB0aGlzLmVsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZShcImR6LXN0YXJ0ZWRcIik7XG4gICAgICAgIH0sXG4gICAgICAgIC8vIENhbGxlZCB3aGVuIGEgZmlsZSBpcyBhZGRlZCB0byB0aGUgcXVldWVcbiAgICAgICAgLy8gUmVjZWl2ZXMgYGZpbGVgXG4gICAgICAgIGFkZGVkZmlsZTogZnVuY3Rpb24gYWRkZWRmaWxlKGZpbGUpIHtcbiAgICAgICAgICB2YXIgX3RoaXMyID0gdGhpcztcblxuICAgICAgICAgIGlmICh0aGlzLmVsZW1lbnQgPT09IHRoaXMucHJldmlld3NDb250YWluZXIpIHtcbiAgICAgICAgICAgIHRoaXMuZWxlbWVudC5jbGFzc0xpc3QuYWRkKFwiZHotc3RhcnRlZFwiKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAodGhpcy5wcmV2aWV3c0NvbnRhaW5lcikge1xuICAgICAgICAgICAgZmlsZS5wcmV2aWV3RWxlbWVudCA9IERyb3B6b25lLmNyZWF0ZUVsZW1lbnQodGhpcy5vcHRpb25zLnByZXZpZXdUZW1wbGF0ZS50cmltKCkpO1xuICAgICAgICAgICAgZmlsZS5wcmV2aWV3VGVtcGxhdGUgPSBmaWxlLnByZXZpZXdFbGVtZW50OyAvLyBCYWNrd2FyZHMgY29tcGF0aWJpbGl0eVxuXG4gICAgICAgICAgICB0aGlzLnByZXZpZXdzQ29udGFpbmVyLmFwcGVuZENoaWxkKGZpbGUucHJldmlld0VsZW1lbnQpO1xuICAgICAgICAgICAgdmFyIF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24zID0gdHJ1ZTtcbiAgICAgICAgICAgIHZhciBfZGlkSXRlcmF0b3JFcnJvcjMgPSBmYWxzZTtcbiAgICAgICAgICAgIHZhciBfaXRlcmF0b3JFcnJvcjMgPSB1bmRlZmluZWQ7XG5cbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgIGZvciAodmFyIF9pdGVyYXRvcjMgPSBmaWxlLnByZXZpZXdFbGVtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoXCJbZGF0YS1kei1uYW1lXVwiKVtTeW1ib2wuaXRlcmF0b3JdKCksIF9zdGVwMzsgIShfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uMyA9IChfc3RlcDMgPSBfaXRlcmF0b3IzLm5leHQoKSkuZG9uZSk7IF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24zID0gdHJ1ZSkge1xuICAgICAgICAgICAgICAgIHZhciBub2RlID0gX3N0ZXAzLnZhbHVlO1xuICAgICAgICAgICAgICAgIG5vZGUudGV4dENvbnRlbnQgPSBmaWxlLm5hbWU7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICBfZGlkSXRlcmF0b3JFcnJvcjMgPSB0cnVlO1xuICAgICAgICAgICAgICBfaXRlcmF0b3JFcnJvcjMgPSBlcnI7XG4gICAgICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGlmICghX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjMgJiYgX2l0ZXJhdG9yM1tcInJldHVyblwiXSAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICBfaXRlcmF0b3IzW1wicmV0dXJuXCJdKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgICAgICAgIGlmIChfZGlkSXRlcmF0b3JFcnJvcjMpIHtcbiAgICAgICAgICAgICAgICAgIHRocm93IF9pdGVyYXRvckVycm9yMztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdmFyIF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb240ID0gdHJ1ZTtcbiAgICAgICAgICAgIHZhciBfZGlkSXRlcmF0b3JFcnJvcjQgPSBmYWxzZTtcbiAgICAgICAgICAgIHZhciBfaXRlcmF0b3JFcnJvcjQgPSB1bmRlZmluZWQ7XG5cbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgIGZvciAodmFyIF9pdGVyYXRvcjQgPSBmaWxlLnByZXZpZXdFbGVtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoXCJbZGF0YS1kei1zaXplXVwiKVtTeW1ib2wuaXRlcmF0b3JdKCksIF9zdGVwNDsgIShfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uNCA9IChfc3RlcDQgPSBfaXRlcmF0b3I0Lm5leHQoKSkuZG9uZSk7IF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb240ID0gdHJ1ZSkge1xuICAgICAgICAgICAgICAgIG5vZGUgPSBfc3RlcDQudmFsdWU7XG4gICAgICAgICAgICAgICAgbm9kZS5pbm5lckhUTUwgPSB0aGlzLmZpbGVzaXplKGZpbGUuc2l6ZSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICBfZGlkSXRlcmF0b3JFcnJvcjQgPSB0cnVlO1xuICAgICAgICAgICAgICBfaXRlcmF0b3JFcnJvcjQgPSBlcnI7XG4gICAgICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGlmICghX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjQgJiYgX2l0ZXJhdG9yNFtcInJldHVyblwiXSAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICBfaXRlcmF0b3I0W1wicmV0dXJuXCJdKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgICAgICAgIGlmIChfZGlkSXRlcmF0b3JFcnJvcjQpIHtcbiAgICAgICAgICAgICAgICAgIHRocm93IF9pdGVyYXRvckVycm9yNDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5hZGRSZW1vdmVMaW5rcykge1xuICAgICAgICAgICAgICBmaWxlLl9yZW1vdmVMaW5rID0gRHJvcHpvbmUuY3JlYXRlRWxlbWVudChcIjxhIGNsYXNzPVxcXCJkei1yZW1vdmVcXFwiIGhyZWY9XFxcImphdmFzY3JpcHQ6dW5kZWZpbmVkO1xcXCIgZGF0YS1kei1yZW1vdmU+XCIuY29uY2F0KHRoaXMub3B0aW9ucy5kaWN0UmVtb3ZlRmlsZSwgXCI8L2E+XCIpKTtcbiAgICAgICAgICAgICAgZmlsZS5wcmV2aWV3RWxlbWVudC5hcHBlbmRDaGlsZChmaWxlLl9yZW1vdmVMaW5rKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdmFyIHJlbW92ZUZpbGVFdmVudCA9IGZ1bmN0aW9uIHJlbW92ZUZpbGVFdmVudChlKSB7XG4gICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcblxuICAgICAgICAgICAgICBpZiAoZmlsZS5zdGF0dXMgPT09IERyb3B6b25lLlVQTE9BRElORykge1xuICAgICAgICAgICAgICAgIHJldHVybiBEcm9wem9uZS5jb25maXJtKF90aGlzMi5vcHRpb25zLmRpY3RDYW5jZWxVcGxvYWRDb25maXJtYXRpb24sIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgIHJldHVybiBfdGhpczIucmVtb3ZlRmlsZShmaWxlKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpZiAoX3RoaXMyLm9wdGlvbnMuZGljdFJlbW92ZUZpbGVDb25maXJtYXRpb24pIHtcbiAgICAgICAgICAgICAgICAgIHJldHVybiBEcm9wem9uZS5jb25maXJtKF90aGlzMi5vcHRpb25zLmRpY3RSZW1vdmVGaWxlQ29uZmlybWF0aW9uLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBfdGhpczIucmVtb3ZlRmlsZShmaWxlKTtcbiAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICByZXR1cm4gX3RoaXMyLnJlbW92ZUZpbGUoZmlsZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB2YXIgX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjUgPSB0cnVlO1xuICAgICAgICAgICAgdmFyIF9kaWRJdGVyYXRvckVycm9yNSA9IGZhbHNlO1xuICAgICAgICAgICAgdmFyIF9pdGVyYXRvckVycm9yNSA9IHVuZGVmaW5lZDtcblxuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgZm9yICh2YXIgX2l0ZXJhdG9yNSA9IGZpbGUucHJldmlld0VsZW1lbnQucXVlcnlTZWxlY3RvckFsbChcIltkYXRhLWR6LXJlbW92ZV1cIilbU3ltYm9sLml0ZXJhdG9yXSgpLCBfc3RlcDU7ICEoX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjUgPSAoX3N0ZXA1ID0gX2l0ZXJhdG9yNS5uZXh0KCkpLmRvbmUpOyBfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uNSA9IHRydWUpIHtcbiAgICAgICAgICAgICAgICB2YXIgcmVtb3ZlTGluayA9IF9zdGVwNS52YWx1ZTtcbiAgICAgICAgICAgICAgICByZW1vdmVMaW5rLmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLCByZW1vdmVGaWxlRXZlbnQpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgX2RpZEl0ZXJhdG9yRXJyb3I1ID0gdHJ1ZTtcbiAgICAgICAgICAgICAgX2l0ZXJhdG9yRXJyb3I1ID0gZXJyO1xuICAgICAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBpZiAoIV9pdGVyYXRvck5vcm1hbENvbXBsZXRpb241ICYmIF9pdGVyYXRvcjVbXCJyZXR1cm5cIl0gIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgX2l0ZXJhdG9yNVtcInJldHVyblwiXSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgICAgICBpZiAoX2RpZEl0ZXJhdG9yRXJyb3I1KSB7XG4gICAgICAgICAgICAgICAgICB0aHJvdyBfaXRlcmF0b3JFcnJvcjU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICAvLyBDYWxsZWQgd2hlbmV2ZXIgYSBmaWxlIGlzIHJlbW92ZWQuXG4gICAgICAgIHJlbW92ZWRmaWxlOiBmdW5jdGlvbiByZW1vdmVkZmlsZShmaWxlKSB7XG4gICAgICAgICAgaWYgKGZpbGUucHJldmlld0VsZW1lbnQgIT0gbnVsbCAmJiBmaWxlLnByZXZpZXdFbGVtZW50LnBhcmVudE5vZGUgIT0gbnVsbCkge1xuICAgICAgICAgICAgZmlsZS5wcmV2aWV3RWxlbWVudC5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKGZpbGUucHJldmlld0VsZW1lbnQpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiB0aGlzLl91cGRhdGVNYXhGaWxlc1JlYWNoZWRDbGFzcygpO1xuICAgICAgICB9LFxuICAgICAgICAvLyBDYWxsZWQgd2hlbiBhIHRodW1ibmFpbCBoYXMgYmVlbiBnZW5lcmF0ZWRcbiAgICAgICAgLy8gUmVjZWl2ZXMgYGZpbGVgIGFuZCBgZGF0YVVybGBcbiAgICAgICAgdGh1bWJuYWlsOiBmdW5jdGlvbiB0aHVtYm5haWwoZmlsZSwgZGF0YVVybCkge1xuICAgICAgICAgIGlmIChmaWxlLnByZXZpZXdFbGVtZW50KSB7XG4gICAgICAgICAgICBmaWxlLnByZXZpZXdFbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoXCJkei1maWxlLXByZXZpZXdcIik7XG4gICAgICAgICAgICB2YXIgX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjYgPSB0cnVlO1xuICAgICAgICAgICAgdmFyIF9kaWRJdGVyYXRvckVycm9yNiA9IGZhbHNlO1xuICAgICAgICAgICAgdmFyIF9pdGVyYXRvckVycm9yNiA9IHVuZGVmaW5lZDtcblxuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgZm9yICh2YXIgX2l0ZXJhdG9yNiA9IGZpbGUucHJldmlld0VsZW1lbnQucXVlcnlTZWxlY3RvckFsbChcIltkYXRhLWR6LXRodW1ibmFpbF1cIilbU3ltYm9sLml0ZXJhdG9yXSgpLCBfc3RlcDY7ICEoX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjYgPSAoX3N0ZXA2ID0gX2l0ZXJhdG9yNi5uZXh0KCkpLmRvbmUpOyBfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uNiA9IHRydWUpIHtcbiAgICAgICAgICAgICAgICB2YXIgdGh1bWJuYWlsRWxlbWVudCA9IF9zdGVwNi52YWx1ZTtcbiAgICAgICAgICAgICAgICB0aHVtYm5haWxFbGVtZW50LmFsdCA9IGZpbGUubmFtZTtcbiAgICAgICAgICAgICAgICB0aHVtYm5haWxFbGVtZW50LnNyYyA9IGRhdGFVcmw7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICBfZGlkSXRlcmF0b3JFcnJvcjYgPSB0cnVlO1xuICAgICAgICAgICAgICBfaXRlcmF0b3JFcnJvcjYgPSBlcnI7XG4gICAgICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGlmICghX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjYgJiYgX2l0ZXJhdG9yNltcInJldHVyblwiXSAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICBfaXRlcmF0b3I2W1wicmV0dXJuXCJdKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgICAgICAgIGlmIChfZGlkSXRlcmF0b3JFcnJvcjYpIHtcbiAgICAgICAgICAgICAgICAgIHRocm93IF9pdGVyYXRvckVycm9yNjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICByZXR1cm4gZmlsZS5wcmV2aWV3RWxlbWVudC5jbGFzc0xpc3QuYWRkKFwiZHotaW1hZ2UtcHJldmlld1wiKTtcbiAgICAgICAgICAgIH0sIDEpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgLy8gQ2FsbGVkIHdoZW5ldmVyIGFuIGVycm9yIG9jY3Vyc1xuICAgICAgICAvLyBSZWNlaXZlcyBgZmlsZWAgYW5kIGBtZXNzYWdlYFxuICAgICAgICBlcnJvcjogZnVuY3Rpb24gZXJyb3IoZmlsZSwgbWVzc2FnZSkge1xuICAgICAgICAgIGlmIChmaWxlLnByZXZpZXdFbGVtZW50KSB7XG4gICAgICAgICAgICBmaWxlLnByZXZpZXdFbGVtZW50LmNsYXNzTGlzdC5hZGQoXCJkei1lcnJvclwiKTtcblxuICAgICAgICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlICE9PSBcIlN0cmluZ1wiICYmIG1lc3NhZ2UuZXJyb3IpIHtcbiAgICAgICAgICAgICAgbWVzc2FnZSA9IG1lc3NhZ2UuZXJyb3I7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhciBfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uNyA9IHRydWU7XG4gICAgICAgICAgICB2YXIgX2RpZEl0ZXJhdG9yRXJyb3I3ID0gZmFsc2U7XG4gICAgICAgICAgICB2YXIgX2l0ZXJhdG9yRXJyb3I3ID0gdW5kZWZpbmVkO1xuXG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICBmb3IgKHZhciBfaXRlcmF0b3I3ID0gZmlsZS5wcmV2aWV3RWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsKFwiW2RhdGEtZHotZXJyb3JtZXNzYWdlXVwiKVtTeW1ib2wuaXRlcmF0b3JdKCksIF9zdGVwNzsgIShfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uNyA9IChfc3RlcDcgPSBfaXRlcmF0b3I3Lm5leHQoKSkuZG9uZSk7IF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb243ID0gdHJ1ZSkge1xuICAgICAgICAgICAgICAgIHZhciBub2RlID0gX3N0ZXA3LnZhbHVlO1xuICAgICAgICAgICAgICAgIG5vZGUudGV4dENvbnRlbnQgPSBtZXNzYWdlO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgX2RpZEl0ZXJhdG9yRXJyb3I3ID0gdHJ1ZTtcbiAgICAgICAgICAgICAgX2l0ZXJhdG9yRXJyb3I3ID0gZXJyO1xuICAgICAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBpZiAoIV9pdGVyYXRvck5vcm1hbENvbXBsZXRpb243ICYmIF9pdGVyYXRvcjdbXCJyZXR1cm5cIl0gIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgX2l0ZXJhdG9yN1tcInJldHVyblwiXSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgICAgICBpZiAoX2RpZEl0ZXJhdG9yRXJyb3I3KSB7XG4gICAgICAgICAgICAgICAgICB0aHJvdyBfaXRlcmF0b3JFcnJvcjc7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBlcnJvcm11bHRpcGxlOiBmdW5jdGlvbiBlcnJvcm11bHRpcGxlKCkge30sXG4gICAgICAgIC8vIENhbGxlZCB3aGVuIGEgZmlsZSBnZXRzIHByb2Nlc3NlZC4gU2luY2UgdGhlcmUgaXMgYSBjdWUsIG5vdCBhbGwgYWRkZWRcbiAgICAgICAgLy8gZmlsZXMgYXJlIHByb2Nlc3NlZCBpbW1lZGlhdGVseS5cbiAgICAgICAgLy8gUmVjZWl2ZXMgYGZpbGVgXG4gICAgICAgIHByb2Nlc3Npbmc6IGZ1bmN0aW9uIHByb2Nlc3NpbmcoZmlsZSkge1xuICAgICAgICAgIGlmIChmaWxlLnByZXZpZXdFbGVtZW50KSB7XG4gICAgICAgICAgICBmaWxlLnByZXZpZXdFbGVtZW50LmNsYXNzTGlzdC5hZGQoXCJkei1wcm9jZXNzaW5nXCIpO1xuXG4gICAgICAgICAgICBpZiAoZmlsZS5fcmVtb3ZlTGluaykge1xuICAgICAgICAgICAgICByZXR1cm4gZmlsZS5fcmVtb3ZlTGluay5pbm5lckhUTUwgPSB0aGlzLm9wdGlvbnMuZGljdENhbmNlbFVwbG9hZDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIHByb2Nlc3NpbmdtdWx0aXBsZTogZnVuY3Rpb24gcHJvY2Vzc2luZ211bHRpcGxlKCkge30sXG4gICAgICAgIC8vIENhbGxlZCB3aGVuZXZlciB0aGUgdXBsb2FkIHByb2dyZXNzIGdldHMgdXBkYXRlZC5cbiAgICAgICAgLy8gUmVjZWl2ZXMgYGZpbGVgLCBgcHJvZ3Jlc3NgIChwZXJjZW50YWdlIDAtMTAwKSBhbmQgYGJ5dGVzU2VudGAuXG4gICAgICAgIC8vIFRvIGdldCB0aGUgdG90YWwgbnVtYmVyIG9mIGJ5dGVzIG9mIHRoZSBmaWxlLCB1c2UgYGZpbGUuc2l6ZWBcbiAgICAgICAgdXBsb2FkcHJvZ3Jlc3M6IGZ1bmN0aW9uIHVwbG9hZHByb2dyZXNzKGZpbGUsIHByb2dyZXNzLCBieXRlc1NlbnQpIHtcbiAgICAgICAgICBpZiAoZmlsZS5wcmV2aWV3RWxlbWVudCkge1xuICAgICAgICAgICAgdmFyIF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb244ID0gdHJ1ZTtcbiAgICAgICAgICAgIHZhciBfZGlkSXRlcmF0b3JFcnJvcjggPSBmYWxzZTtcbiAgICAgICAgICAgIHZhciBfaXRlcmF0b3JFcnJvcjggPSB1bmRlZmluZWQ7XG5cbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgIGZvciAodmFyIF9pdGVyYXRvcjggPSBmaWxlLnByZXZpZXdFbGVtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoXCJbZGF0YS1kei11cGxvYWRwcm9ncmVzc11cIilbU3ltYm9sLml0ZXJhdG9yXSgpLCBfc3RlcDg7ICEoX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjggPSAoX3N0ZXA4ID0gX2l0ZXJhdG9yOC5uZXh0KCkpLmRvbmUpOyBfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uOCA9IHRydWUpIHtcbiAgICAgICAgICAgICAgICB2YXIgbm9kZSA9IF9zdGVwOC52YWx1ZTtcbiAgICAgICAgICAgICAgICBub2RlLm5vZGVOYW1lID09PSAnUFJPR1JFU1MnID8gbm9kZS52YWx1ZSA9IHByb2dyZXNzIDogbm9kZS5zdHlsZS53aWR0aCA9IFwiXCIuY29uY2F0KHByb2dyZXNzLCBcIiVcIik7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICBfZGlkSXRlcmF0b3JFcnJvcjggPSB0cnVlO1xuICAgICAgICAgICAgICBfaXRlcmF0b3JFcnJvcjggPSBlcnI7XG4gICAgICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGlmICghX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjggJiYgX2l0ZXJhdG9yOFtcInJldHVyblwiXSAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICBfaXRlcmF0b3I4W1wicmV0dXJuXCJdKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgICAgICAgIGlmIChfZGlkSXRlcmF0b3JFcnJvcjgpIHtcbiAgICAgICAgICAgICAgICAgIHRocm93IF9pdGVyYXRvckVycm9yODtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIC8vIENhbGxlZCB3aGVuZXZlciB0aGUgdG90YWwgdXBsb2FkIHByb2dyZXNzIGdldHMgdXBkYXRlZC5cbiAgICAgICAgLy8gQ2FsbGVkIHdpdGggdG90YWxVcGxvYWRQcm9ncmVzcyAoMC0xMDApLCB0b3RhbEJ5dGVzIGFuZCB0b3RhbEJ5dGVzU2VudFxuICAgICAgICB0b3RhbHVwbG9hZHByb2dyZXNzOiBmdW5jdGlvbiB0b3RhbHVwbG9hZHByb2dyZXNzKCkge30sXG4gICAgICAgIC8vIENhbGxlZCBqdXN0IGJlZm9yZSB0aGUgZmlsZSBpcyBzZW50LiBHZXRzIHRoZSBgeGhyYCBvYmplY3QgYXMgc2Vjb25kXG4gICAgICAgIC8vIHBhcmFtZXRlciwgc28geW91IGNhbiBtb2RpZnkgaXQgKGZvciBleGFtcGxlIHRvIGFkZCBhIENTUkYgdG9rZW4pIGFuZCBhXG4gICAgICAgIC8vIGBmb3JtRGF0YWAgb2JqZWN0IHRvIGFkZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uLlxuICAgICAgICBzZW5kaW5nOiBmdW5jdGlvbiBzZW5kaW5nKCkge30sXG4gICAgICAgIHNlbmRpbmdtdWx0aXBsZTogZnVuY3Rpb24gc2VuZGluZ211bHRpcGxlKCkge30sXG4gICAgICAgIC8vIFdoZW4gdGhlIGNvbXBsZXRlIHVwbG9hZCBpcyBmaW5pc2hlZCBhbmQgc3VjY2Vzc2Z1bFxuICAgICAgICAvLyBSZWNlaXZlcyBgZmlsZWBcbiAgICAgICAgc3VjY2VzczogZnVuY3Rpb24gc3VjY2VzcyhmaWxlKSB7XG4gICAgICAgICAgaWYgKGZpbGUucHJldmlld0VsZW1lbnQpIHtcbiAgICAgICAgICAgIHJldHVybiBmaWxlLnByZXZpZXdFbGVtZW50LmNsYXNzTGlzdC5hZGQoXCJkei1zdWNjZXNzXCIpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgc3VjY2Vzc211bHRpcGxlOiBmdW5jdGlvbiBzdWNjZXNzbXVsdGlwbGUoKSB7fSxcbiAgICAgICAgLy8gV2hlbiB0aGUgdXBsb2FkIGlzIGNhbmNlbGVkLlxuICAgICAgICBjYW5jZWxlZDogZnVuY3Rpb24gY2FuY2VsZWQoZmlsZSkge1xuICAgICAgICAgIHJldHVybiB0aGlzLmVtaXQoXCJlcnJvclwiLCBmaWxlLCB0aGlzLm9wdGlvbnMuZGljdFVwbG9hZENhbmNlbGVkKTtcbiAgICAgICAgfSxcbiAgICAgICAgY2FuY2VsZWRtdWx0aXBsZTogZnVuY3Rpb24gY2FuY2VsZWRtdWx0aXBsZSgpIHt9LFxuICAgICAgICAvLyBXaGVuIHRoZSB1cGxvYWQgaXMgZmluaXNoZWQsIGVpdGhlciB3aXRoIHN1Y2Nlc3Mgb3IgYW4gZXJyb3IuXG4gICAgICAgIC8vIFJlY2VpdmVzIGBmaWxlYFxuICAgICAgICBjb21wbGV0ZTogZnVuY3Rpb24gY29tcGxldGUoZmlsZSkge1xuICAgICAgICAgIGlmIChmaWxlLl9yZW1vdmVMaW5rKSB7XG4gICAgICAgICAgICBmaWxlLl9yZW1vdmVMaW5rLmlubmVySFRNTCA9IHRoaXMub3B0aW9ucy5kaWN0UmVtb3ZlRmlsZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoZmlsZS5wcmV2aWV3RWxlbWVudCkge1xuICAgICAgICAgICAgcmV0dXJuIGZpbGUucHJldmlld0VsZW1lbnQuY2xhc3NMaXN0LmFkZChcImR6LWNvbXBsZXRlXCIpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgY29tcGxldGVtdWx0aXBsZTogZnVuY3Rpb24gY29tcGxldGVtdWx0aXBsZSgpIHt9LFxuICAgICAgICBtYXhmaWxlc2V4Y2VlZGVkOiBmdW5jdGlvbiBtYXhmaWxlc2V4Y2VlZGVkKCkge30sXG4gICAgICAgIG1heGZpbGVzcmVhY2hlZDogZnVuY3Rpb24gbWF4ZmlsZXNyZWFjaGVkKCkge30sXG4gICAgICAgIHF1ZXVlY29tcGxldGU6IGZ1bmN0aW9uIHF1ZXVlY29tcGxldGUoKSB7fSxcbiAgICAgICAgYWRkZWRmaWxlczogZnVuY3Rpb24gYWRkZWRmaWxlcygpIHt9XG4gICAgICB9O1xuICAgICAgdGhpcy5wcm90b3R5cGUuX3RodW1ibmFpbFF1ZXVlID0gW107XG4gICAgICB0aGlzLnByb3RvdHlwZS5fcHJvY2Vzc2luZ1RodW1ibmFpbCA9IGZhbHNlO1xuICAgIH0gLy8gZ2xvYmFsIHV0aWxpdHlcblxuICB9LCB7XG4gICAga2V5OiBcImV4dGVuZFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBleHRlbmQodGFyZ2V0KSB7XG4gICAgICBmb3IgKHZhciBfbGVuMiA9IGFyZ3VtZW50cy5sZW5ndGgsIG9iamVjdHMgPSBuZXcgQXJyYXkoX2xlbjIgPiAxID8gX2xlbjIgLSAxIDogMCksIF9rZXkyID0gMTsgX2tleTIgPCBfbGVuMjsgX2tleTIrKykge1xuICAgICAgICBvYmplY3RzW19rZXkyIC0gMV0gPSBhcmd1bWVudHNbX2tleTJdO1xuICAgICAgfVxuXG4gICAgICBmb3IgKHZhciBfaSA9IDAsIF9vYmplY3RzID0gb2JqZWN0czsgX2kgPCBfb2JqZWN0cy5sZW5ndGg7IF9pKyspIHtcbiAgICAgICAgdmFyIG9iamVjdCA9IF9vYmplY3RzW19pXTtcblxuICAgICAgICBmb3IgKHZhciBrZXkgaW4gb2JqZWN0KSB7XG4gICAgICAgICAgdmFyIHZhbCA9IG9iamVjdFtrZXldO1xuICAgICAgICAgIHRhcmdldFtrZXldID0gdmFsO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0YXJnZXQ7XG4gICAgfVxuICB9XSk7XG5cbiAgZnVuY3Rpb24gRHJvcHpvbmUoZWwsIG9wdGlvbnMpIHtcbiAgICB2YXIgX3RoaXM7XG5cbiAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgRHJvcHpvbmUpO1xuXG4gICAgX3RoaXMgPSBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybih0aGlzLCBfZ2V0UHJvdG90eXBlT2YoRHJvcHpvbmUpLmNhbGwodGhpcykpO1xuICAgIHZhciBmYWxsYmFjaywgbGVmdDtcbiAgICBfdGhpcy5lbGVtZW50ID0gZWw7IC8vIEZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eSBzaW5jZSB0aGUgdmVyc2lvbiB3YXMgaW4gdGhlIHByb3RvdHlwZSBwcmV2aW91c2x5XG5cbiAgICBfdGhpcy52ZXJzaW9uID0gRHJvcHpvbmUudmVyc2lvbjtcbiAgICBfdGhpcy5kZWZhdWx0T3B0aW9ucy5wcmV2aWV3VGVtcGxhdGUgPSBfdGhpcy5kZWZhdWx0T3B0aW9ucy5wcmV2aWV3VGVtcGxhdGUucmVwbGFjZSgvXFxuKi9nLCBcIlwiKTtcbiAgICBfdGhpcy5jbGlja2FibGVFbGVtZW50cyA9IFtdO1xuICAgIF90aGlzLmxpc3RlbmVycyA9IFtdO1xuICAgIF90aGlzLmZpbGVzID0gW107IC8vIEFsbCBmaWxlc1xuXG4gICAgaWYgKHR5cGVvZiBfdGhpcy5lbGVtZW50ID09PSBcInN0cmluZ1wiKSB7XG4gICAgICBfdGhpcy5lbGVtZW50ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihfdGhpcy5lbGVtZW50KTtcbiAgICB9IC8vIE5vdCBjaGVja2luZyBpZiBpbnN0YW5jZSBvZiBIVE1MRWxlbWVudCBvciBFbGVtZW50IHNpbmNlIElFOSBpcyBleHRyZW1lbHkgd2VpcmQuXG5cblxuICAgIGlmICghX3RoaXMuZWxlbWVudCB8fCBfdGhpcy5lbGVtZW50Lm5vZGVUeXBlID09IG51bGwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgZHJvcHpvbmUgZWxlbWVudC5cIik7XG4gICAgfVxuXG4gICAgaWYgKF90aGlzLmVsZW1lbnQuZHJvcHpvbmUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkRyb3B6b25lIGFscmVhZHkgYXR0YWNoZWQuXCIpO1xuICAgIH0gLy8gTm93IGFkZCB0aGlzIGRyb3B6b25lIHRvIHRoZSBpbnN0YW5jZXMuXG5cblxuICAgIERyb3B6b25lLmluc3RhbmNlcy5wdXNoKF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQoX3RoaXMpKTsgLy8gUHV0IHRoZSBkcm9wem9uZSBpbnNpZGUgdGhlIGVsZW1lbnQgaXRzZWxmLlxuXG4gICAgX3RoaXMuZWxlbWVudC5kcm9wem9uZSA9IF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQoX3RoaXMpO1xuICAgIHZhciBlbGVtZW50T3B0aW9ucyA9IChsZWZ0ID0gRHJvcHpvbmUub3B0aW9uc0ZvckVsZW1lbnQoX3RoaXMuZWxlbWVudCkpICE9IG51bGwgPyBsZWZ0IDoge307XG4gICAgX3RoaXMub3B0aW9ucyA9IERyb3B6b25lLmV4dGVuZCh7fSwgX3RoaXMuZGVmYXVsdE9wdGlvbnMsIGVsZW1lbnRPcHRpb25zLCBvcHRpb25zICE9IG51bGwgPyBvcHRpb25zIDoge30pOyAvLyBJZiB0aGUgYnJvd3NlciBmYWlsZWQsIGp1c3QgY2FsbCB0aGUgZmFsbGJhY2sgYW5kIGxlYXZlXG5cbiAgICBpZiAoX3RoaXMub3B0aW9ucy5mb3JjZUZhbGxiYWNrIHx8ICFEcm9wem9uZS5pc0Jyb3dzZXJTdXBwb3J0ZWQoKSkge1xuICAgICAgcmV0dXJuIF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuKF90aGlzLCBfdGhpcy5vcHRpb25zLmZhbGxiYWNrLmNhbGwoX2Fzc2VydFRoaXNJbml0aWFsaXplZChfdGhpcykpKTtcbiAgICB9IC8vIEBvcHRpb25zLnVybCA9IEBlbGVtZW50LmdldEF0dHJpYnV0ZSBcImFjdGlvblwiIHVubGVzcyBAb3B0aW9ucy51cmw/XG5cblxuICAgIGlmIChfdGhpcy5vcHRpb25zLnVybCA9PSBudWxsKSB7XG4gICAgICBfdGhpcy5vcHRpb25zLnVybCA9IF90aGlzLmVsZW1lbnQuZ2V0QXR0cmlidXRlKFwiYWN0aW9uXCIpO1xuICAgIH1cblxuICAgIGlmICghX3RoaXMub3B0aW9ucy51cmwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk5vIFVSTCBwcm92aWRlZC5cIik7XG4gICAgfVxuXG4gICAgaWYgKF90aGlzLm9wdGlvbnMuYWNjZXB0ZWRGaWxlcyAmJiBfdGhpcy5vcHRpb25zLmFjY2VwdGVkTWltZVR5cGVzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJZb3UgY2FuJ3QgcHJvdmlkZSBib3RoICdhY2NlcHRlZEZpbGVzJyBhbmQgJ2FjY2VwdGVkTWltZVR5cGVzJy4gJ2FjY2VwdGVkTWltZVR5cGVzJyBpcyBkZXByZWNhdGVkLlwiKTtcbiAgICB9XG5cbiAgICBpZiAoX3RoaXMub3B0aW9ucy51cGxvYWRNdWx0aXBsZSAmJiBfdGhpcy5vcHRpb25zLmNodW5raW5nKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1lvdSBjYW5ub3Qgc2V0IGJvdGg6IHVwbG9hZE11bHRpcGxlIGFuZCBjaHVua2luZy4nKTtcbiAgICB9IC8vIEJhY2t3YXJkcyBjb21wYXRpYmlsaXR5XG5cblxuICAgIGlmIChfdGhpcy5vcHRpb25zLmFjY2VwdGVkTWltZVR5cGVzKSB7XG4gICAgICBfdGhpcy5vcHRpb25zLmFjY2VwdGVkRmlsZXMgPSBfdGhpcy5vcHRpb25zLmFjY2VwdGVkTWltZVR5cGVzO1xuICAgICAgZGVsZXRlIF90aGlzLm9wdGlvbnMuYWNjZXB0ZWRNaW1lVHlwZXM7XG4gICAgfSAvLyBCYWNrd2FyZHMgY29tcGF0aWJpbGl0eVxuXG5cbiAgICBpZiAoX3RoaXMub3B0aW9ucy5yZW5hbWVGaWxlbmFtZSAhPSBudWxsKSB7XG4gICAgICBfdGhpcy5vcHRpb25zLnJlbmFtZUZpbGUgPSBmdW5jdGlvbiAoZmlsZSkge1xuICAgICAgICByZXR1cm4gX3RoaXMub3B0aW9ucy5yZW5hbWVGaWxlbmFtZS5jYWxsKF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQoX3RoaXMpLCBmaWxlLm5hbWUsIGZpbGUpO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICBfdGhpcy5vcHRpb25zLm1ldGhvZCA9IF90aGlzLm9wdGlvbnMubWV0aG9kLnRvVXBwZXJDYXNlKCk7XG5cbiAgICBpZiAoKGZhbGxiYWNrID0gX3RoaXMuZ2V0RXhpc3RpbmdGYWxsYmFjaygpKSAmJiBmYWxsYmFjay5wYXJlbnROb2RlKSB7XG4gICAgICAvLyBSZW1vdmUgdGhlIGZhbGxiYWNrXG4gICAgICBmYWxsYmFjay5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKGZhbGxiYWNrKTtcbiAgICB9IC8vIERpc3BsYXkgcHJldmlld3MgaW4gdGhlIHByZXZpZXdzQ29udGFpbmVyIGVsZW1lbnQgb3IgdGhlIERyb3B6b25lIGVsZW1lbnQgdW5sZXNzIGV4cGxpY2l0bHkgc2V0IHRvIGZhbHNlXG5cblxuICAgIGlmIChfdGhpcy5vcHRpb25zLnByZXZpZXdzQ29udGFpbmVyICE9PSBmYWxzZSkge1xuICAgICAgaWYgKF90aGlzLm9wdGlvbnMucHJldmlld3NDb250YWluZXIpIHtcbiAgICAgICAgX3RoaXMucHJldmlld3NDb250YWluZXIgPSBEcm9wem9uZS5nZXRFbGVtZW50KF90aGlzLm9wdGlvbnMucHJldmlld3NDb250YWluZXIsIFwicHJldmlld3NDb250YWluZXJcIik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBfdGhpcy5wcmV2aWV3c0NvbnRhaW5lciA9IF90aGlzLmVsZW1lbnQ7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKF90aGlzLm9wdGlvbnMuY2xpY2thYmxlKSB7XG4gICAgICBpZiAoX3RoaXMub3B0aW9ucy5jbGlja2FibGUgPT09IHRydWUpIHtcbiAgICAgICAgX3RoaXMuY2xpY2thYmxlRWxlbWVudHMgPSBbX3RoaXMuZWxlbWVudF07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBfdGhpcy5jbGlja2FibGVFbGVtZW50cyA9IERyb3B6b25lLmdldEVsZW1lbnRzKF90aGlzLm9wdGlvbnMuY2xpY2thYmxlLCBcImNsaWNrYWJsZVwiKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBfdGhpcy5pbml0KCk7XG5cbiAgICByZXR1cm4gX3RoaXM7XG4gIH0gLy8gUmV0dXJucyBhbGwgZmlsZXMgdGhhdCBoYXZlIGJlZW4gYWNjZXB0ZWRcblxuXG4gIF9jcmVhdGVDbGFzcyhEcm9wem9uZSwgW3tcbiAgICBrZXk6IFwiZ2V0QWNjZXB0ZWRGaWxlc1wiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBnZXRBY2NlcHRlZEZpbGVzKCkge1xuICAgICAgcmV0dXJuIHRoaXMuZmlsZXMuZmlsdGVyKGZ1bmN0aW9uIChmaWxlKSB7XG4gICAgICAgIHJldHVybiBmaWxlLmFjY2VwdGVkO1xuICAgICAgfSkubWFwKGZ1bmN0aW9uIChmaWxlKSB7XG4gICAgICAgIHJldHVybiBmaWxlO1xuICAgICAgfSk7XG4gICAgfSAvLyBSZXR1cm5zIGFsbCBmaWxlcyB0aGF0IGhhdmUgYmVlbiByZWplY3RlZFxuICAgIC8vIE5vdCBzdXJlIHdoZW4gdGhhdCdzIGdvaW5nIHRvIGJlIHVzZWZ1bCwgYnV0IGFkZGVkIGZvciBjb21wbGV0ZW5lc3MuXG5cbiAgfSwge1xuICAgIGtleTogXCJnZXRSZWplY3RlZEZpbGVzXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGdldFJlamVjdGVkRmlsZXMoKSB7XG4gICAgICByZXR1cm4gdGhpcy5maWxlcy5maWx0ZXIoZnVuY3Rpb24gKGZpbGUpIHtcbiAgICAgICAgcmV0dXJuICFmaWxlLmFjY2VwdGVkO1xuICAgICAgfSkubWFwKGZ1bmN0aW9uIChmaWxlKSB7XG4gICAgICAgIHJldHVybiBmaWxlO1xuICAgICAgfSk7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcImdldEZpbGVzV2l0aFN0YXR1c1wiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBnZXRGaWxlc1dpdGhTdGF0dXMoc3RhdHVzKSB7XG4gICAgICByZXR1cm4gdGhpcy5maWxlcy5maWx0ZXIoZnVuY3Rpb24gKGZpbGUpIHtcbiAgICAgICAgcmV0dXJuIGZpbGUuc3RhdHVzID09PSBzdGF0dXM7XG4gICAgICB9KS5tYXAoZnVuY3Rpb24gKGZpbGUpIHtcbiAgICAgICAgcmV0dXJuIGZpbGU7XG4gICAgICB9KTtcbiAgICB9IC8vIFJldHVybnMgYWxsIGZpbGVzIHRoYXQgYXJlIGluIHRoZSBxdWV1ZVxuXG4gIH0sIHtcbiAgICBrZXk6IFwiZ2V0UXVldWVkRmlsZXNcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gZ2V0UXVldWVkRmlsZXMoKSB7XG4gICAgICByZXR1cm4gdGhpcy5nZXRGaWxlc1dpdGhTdGF0dXMoRHJvcHpvbmUuUVVFVUVEKTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiZ2V0VXBsb2FkaW5nRmlsZXNcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gZ2V0VXBsb2FkaW5nRmlsZXMoKSB7XG4gICAgICByZXR1cm4gdGhpcy5nZXRGaWxlc1dpdGhTdGF0dXMoRHJvcHpvbmUuVVBMT0FESU5HKTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiZ2V0QWRkZWRGaWxlc1wiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBnZXRBZGRlZEZpbGVzKCkge1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0RmlsZXNXaXRoU3RhdHVzKERyb3B6b25lLkFEREVEKTtcbiAgICB9IC8vIEZpbGVzIHRoYXQgYXJlIGVpdGhlciBxdWV1ZWQgb3IgdXBsb2FkaW5nXG5cbiAgfSwge1xuICAgIGtleTogXCJnZXRBY3RpdmVGaWxlc1wiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBnZXRBY3RpdmVGaWxlcygpIHtcbiAgICAgIHJldHVybiB0aGlzLmZpbGVzLmZpbHRlcihmdW5jdGlvbiAoZmlsZSkge1xuICAgICAgICByZXR1cm4gZmlsZS5zdGF0dXMgPT09IERyb3B6b25lLlVQTE9BRElORyB8fCBmaWxlLnN0YXR1cyA9PT0gRHJvcHpvbmUuUVVFVUVEO1xuICAgICAgfSkubWFwKGZ1bmN0aW9uIChmaWxlKSB7XG4gICAgICAgIHJldHVybiBmaWxlO1xuICAgICAgfSk7XG4gICAgfSAvLyBUaGUgZnVuY3Rpb24gdGhhdCBnZXRzIGNhbGxlZCB3aGVuIERyb3B6b25lIGlzIGluaXRpYWxpemVkLiBZb3VcbiAgICAvLyBjYW4gKGFuZCBzaG91bGQpIHNldHVwIGV2ZW50IGxpc3RlbmVycyBpbnNpZGUgdGhpcyBmdW5jdGlvbi5cblxuICB9LCB7XG4gICAga2V5OiBcImluaXRcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gaW5pdCgpIHtcbiAgICAgIHZhciBfdGhpczMgPSB0aGlzO1xuXG4gICAgICAvLyBJbiBjYXNlIGl0IGlzbid0IHNldCBhbHJlYWR5XG4gICAgICBpZiAodGhpcy5lbGVtZW50LnRhZ05hbWUgPT09IFwiZm9ybVwiKSB7XG4gICAgICAgIHRoaXMuZWxlbWVudC5zZXRBdHRyaWJ1dGUoXCJlbmN0eXBlXCIsIFwibXVsdGlwYXJ0L2Zvcm0tZGF0YVwiKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMuZWxlbWVudC5jbGFzc0xpc3QuY29udGFpbnMoXCJkcm9wem9uZVwiKSAmJiAhdGhpcy5lbGVtZW50LnF1ZXJ5U2VsZWN0b3IoXCIuZHotbWVzc2FnZVwiKSkge1xuICAgICAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQoRHJvcHpvbmUuY3JlYXRlRWxlbWVudChcIjxkaXYgY2xhc3M9XFxcImR6LWRlZmF1bHQgZHotbWVzc2FnZVxcXCI+PGJ1dHRvbiBjbGFzcz1cXFwiZHotYnV0dG9uXFxcIiB0eXBlPVxcXCJidXR0b25cXFwiPlwiLmNvbmNhdCh0aGlzLm9wdGlvbnMuZGljdERlZmF1bHRNZXNzYWdlLCBcIjwvYnV0dG9uPjwvZGl2PlwiKSkpO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5jbGlja2FibGVFbGVtZW50cy5sZW5ndGgpIHtcbiAgICAgICAgdmFyIHNldHVwSGlkZGVuRmlsZUlucHV0ID0gZnVuY3Rpb24gc2V0dXBIaWRkZW5GaWxlSW5wdXQoKSB7XG4gICAgICAgICAgaWYgKF90aGlzMy5oaWRkZW5GaWxlSW5wdXQpIHtcbiAgICAgICAgICAgIF90aGlzMy5oaWRkZW5GaWxlSW5wdXQucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChfdGhpczMuaGlkZGVuRmlsZUlucHV0KTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBfdGhpczMuaGlkZGVuRmlsZUlucHV0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImlucHV0XCIpO1xuXG4gICAgICAgICAgX3RoaXMzLmhpZGRlbkZpbGVJbnB1dC5zZXRBdHRyaWJ1dGUoXCJ0eXBlXCIsIFwiZmlsZVwiKTtcblxuICAgICAgICAgIGlmIChfdGhpczMub3B0aW9ucy5tYXhGaWxlcyA9PT0gbnVsbCB8fCBfdGhpczMub3B0aW9ucy5tYXhGaWxlcyA+IDEpIHtcbiAgICAgICAgICAgIF90aGlzMy5oaWRkZW5GaWxlSW5wdXQuc2V0QXR0cmlidXRlKFwibXVsdGlwbGVcIiwgXCJtdWx0aXBsZVwiKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBfdGhpczMuaGlkZGVuRmlsZUlucHV0LmNsYXNzTmFtZSA9IFwiZHotaGlkZGVuLWlucHV0XCI7XG5cbiAgICAgICAgICBpZiAoX3RoaXMzLm9wdGlvbnMuYWNjZXB0ZWRGaWxlcyAhPT0gbnVsbCkge1xuICAgICAgICAgICAgX3RoaXMzLmhpZGRlbkZpbGVJbnB1dC5zZXRBdHRyaWJ1dGUoXCJhY2NlcHRcIiwgX3RoaXMzLm9wdGlvbnMuYWNjZXB0ZWRGaWxlcyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKF90aGlzMy5vcHRpb25zLmNhcHR1cmUgIT09IG51bGwpIHtcbiAgICAgICAgICAgIF90aGlzMy5oaWRkZW5GaWxlSW5wdXQuc2V0QXR0cmlidXRlKFwiY2FwdHVyZVwiLCBfdGhpczMub3B0aW9ucy5jYXB0dXJlKTtcbiAgICAgICAgICB9IC8vIE5vdCBzZXR0aW5nIGBkaXNwbGF5PVwibm9uZVwiYCBiZWNhdXNlIHNvbWUgYnJvd3NlcnMgZG9uJ3QgYWNjZXB0IGNsaWNrc1xuICAgICAgICAgIC8vIG9uIGVsZW1lbnRzIHRoYXQgYXJlbid0IGRpc3BsYXllZC5cblxuXG4gICAgICAgICAgX3RoaXMzLmhpZGRlbkZpbGVJbnB1dC5zdHlsZS52aXNpYmlsaXR5ID0gXCJoaWRkZW5cIjtcbiAgICAgICAgICBfdGhpczMuaGlkZGVuRmlsZUlucHV0LnN0eWxlLnBvc2l0aW9uID0gXCJhYnNvbHV0ZVwiO1xuICAgICAgICAgIF90aGlzMy5oaWRkZW5GaWxlSW5wdXQuc3R5bGUudG9wID0gXCIwXCI7XG4gICAgICAgICAgX3RoaXMzLmhpZGRlbkZpbGVJbnB1dC5zdHlsZS5sZWZ0ID0gXCIwXCI7XG4gICAgICAgICAgX3RoaXMzLmhpZGRlbkZpbGVJbnB1dC5zdHlsZS5oZWlnaHQgPSBcIjBcIjtcbiAgICAgICAgICBfdGhpczMuaGlkZGVuRmlsZUlucHV0LnN0eWxlLndpZHRoID0gXCIwXCI7XG4gICAgICAgICAgRHJvcHpvbmUuZ2V0RWxlbWVudChfdGhpczMub3B0aW9ucy5oaWRkZW5JbnB1dENvbnRhaW5lciwgJ2hpZGRlbklucHV0Q29udGFpbmVyJykuYXBwZW5kQ2hpbGQoX3RoaXMzLmhpZGRlbkZpbGVJbnB1dCk7XG4gICAgICAgICAgcmV0dXJuIF90aGlzMy5oaWRkZW5GaWxlSW5wdXQuYWRkRXZlbnRMaXN0ZW5lcihcImNoYW5nZVwiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgZmlsZXMgPSBfdGhpczMuaGlkZGVuRmlsZUlucHV0LmZpbGVzO1xuXG4gICAgICAgICAgICBpZiAoZmlsZXMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgIHZhciBfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uOSA9IHRydWU7XG4gICAgICAgICAgICAgIHZhciBfZGlkSXRlcmF0b3JFcnJvcjkgPSBmYWxzZTtcbiAgICAgICAgICAgICAgdmFyIF9pdGVyYXRvckVycm9yOSA9IHVuZGVmaW5lZDtcblxuICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGZvciAodmFyIF9pdGVyYXRvcjkgPSBmaWxlc1tTeW1ib2wuaXRlcmF0b3JdKCksIF9zdGVwOTsgIShfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uOSA9IChfc3RlcDkgPSBfaXRlcmF0b3I5Lm5leHQoKSkuZG9uZSk7IF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb245ID0gdHJ1ZSkge1xuICAgICAgICAgICAgICAgICAgdmFyIGZpbGUgPSBfc3RlcDkudmFsdWU7XG5cbiAgICAgICAgICAgICAgICAgIF90aGlzMy5hZGRGaWxlKGZpbGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgICAgX2RpZEl0ZXJhdG9yRXJyb3I5ID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBfaXRlcmF0b3JFcnJvcjkgPSBlcnI7XG4gICAgICAgICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgIGlmICghX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjkgJiYgX2l0ZXJhdG9yOVtcInJldHVyblwiXSAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIF9pdGVyYXRvcjlbXCJyZXR1cm5cIl0oKTtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgICAgICAgICAgaWYgKF9kaWRJdGVyYXRvckVycm9yOSkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBfaXRlcmF0b3JFcnJvcjk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIF90aGlzMy5lbWl0KFwiYWRkZWRmaWxlc1wiLCBmaWxlcyk7XG5cbiAgICAgICAgICAgIHJldHVybiBzZXR1cEhpZGRlbkZpbGVJbnB1dCgpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9O1xuXG4gICAgICAgIHNldHVwSGlkZGVuRmlsZUlucHV0KCk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuVVJMID0gd2luZG93LlVSTCAhPT0gbnVsbCA/IHdpbmRvdy5VUkwgOiB3aW5kb3cud2Via2l0VVJMOyAvLyBTZXR1cCBhbGwgZXZlbnQgbGlzdGVuZXJzIG9uIHRoZSBEcm9wem9uZSBvYmplY3QgaXRzZWxmLlxuICAgICAgLy8gVGhleSdyZSBub3QgaW4gQHNldHVwRXZlbnRMaXN0ZW5lcnMoKSBiZWNhdXNlIHRoZXkgc2hvdWxkbid0IGJlIHJlbW92ZWRcbiAgICAgIC8vIGFnYWluIHdoZW4gdGhlIGRyb3B6b25lIGdldHMgZGlzYWJsZWQuXG5cbiAgICAgIHZhciBfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uMTAgPSB0cnVlO1xuICAgICAgdmFyIF9kaWRJdGVyYXRvckVycm9yMTAgPSBmYWxzZTtcbiAgICAgIHZhciBfaXRlcmF0b3JFcnJvcjEwID0gdW5kZWZpbmVkO1xuXG4gICAgICB0cnkge1xuICAgICAgICBmb3IgKHZhciBfaXRlcmF0b3IxMCA9IHRoaXMuZXZlbnRzW1N5bWJvbC5pdGVyYXRvcl0oKSwgX3N0ZXAxMDsgIShfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uMTAgPSAoX3N0ZXAxMCA9IF9pdGVyYXRvcjEwLm5leHQoKSkuZG9uZSk7IF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24xMCA9IHRydWUpIHtcbiAgICAgICAgICB2YXIgZXZlbnROYW1lID0gX3N0ZXAxMC52YWx1ZTtcbiAgICAgICAgICB0aGlzLm9uKGV2ZW50TmFtZSwgdGhpcy5vcHRpb25zW2V2ZW50TmFtZV0pO1xuICAgICAgICB9XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgX2RpZEl0ZXJhdG9yRXJyb3IxMCA9IHRydWU7XG4gICAgICAgIF9pdGVyYXRvckVycm9yMTAgPSBlcnI7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGlmICghX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjEwICYmIF9pdGVyYXRvcjEwW1wicmV0dXJuXCJdICE9IG51bGwpIHtcbiAgICAgICAgICAgIF9pdGVyYXRvcjEwW1wicmV0dXJuXCJdKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgIGlmIChfZGlkSXRlcmF0b3JFcnJvcjEwKSB7XG4gICAgICAgICAgICB0aHJvdyBfaXRlcmF0b3JFcnJvcjEwO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICB0aGlzLm9uKFwidXBsb2FkcHJvZ3Jlc3NcIiwgZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gX3RoaXMzLnVwZGF0ZVRvdGFsVXBsb2FkUHJvZ3Jlc3MoKTtcbiAgICAgIH0pO1xuICAgICAgdGhpcy5vbihcInJlbW92ZWRmaWxlXCIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIF90aGlzMy51cGRhdGVUb3RhbFVwbG9hZFByb2dyZXNzKCk7XG4gICAgICB9KTtcbiAgICAgIHRoaXMub24oXCJjYW5jZWxlZFwiLCBmdW5jdGlvbiAoZmlsZSkge1xuICAgICAgICByZXR1cm4gX3RoaXMzLmVtaXQoXCJjb21wbGV0ZVwiLCBmaWxlKTtcbiAgICAgIH0pOyAvLyBFbWl0IGEgYHF1ZXVlY29tcGxldGVgIGV2ZW50IGlmIGFsbCBmaWxlcyBmaW5pc2hlZCB1cGxvYWRpbmcuXG5cbiAgICAgIHRoaXMub24oXCJjb21wbGV0ZVwiLCBmdW5jdGlvbiAoZmlsZSkge1xuICAgICAgICBpZiAoX3RoaXMzLmdldEFkZGVkRmlsZXMoKS5sZW5ndGggPT09IDAgJiYgX3RoaXMzLmdldFVwbG9hZGluZ0ZpbGVzKCkubGVuZ3RoID09PSAwICYmIF90aGlzMy5nZXRRdWV1ZWRGaWxlcygpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIC8vIFRoaXMgbmVlZHMgdG8gYmUgZGVmZXJyZWQgc28gdGhhdCBgcXVldWVjb21wbGV0ZWAgcmVhbGx5IHRyaWdnZXJzIGFmdGVyIGBjb21wbGV0ZWBcbiAgICAgICAgICByZXR1cm4gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gX3RoaXMzLmVtaXQoXCJxdWV1ZWNvbXBsZXRlXCIpO1xuICAgICAgICAgIH0sIDApO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgdmFyIGNvbnRhaW5zRmlsZXMgPSBmdW5jdGlvbiBjb250YWluc0ZpbGVzKGUpIHtcbiAgICAgICAgcmV0dXJuIGUuZGF0YVRyYW5zZmVyLnR5cGVzICYmIGUuZGF0YVRyYW5zZmVyLnR5cGVzLnNvbWUoZnVuY3Rpb24gKHR5cGUpIHtcbiAgICAgICAgICByZXR1cm4gdHlwZSA9PSBcIkZpbGVzXCI7XG4gICAgICAgIH0pO1xuICAgICAgfTtcblxuICAgICAgdmFyIG5vUHJvcGFnYXRpb24gPSBmdW5jdGlvbiBub1Byb3BhZ2F0aW9uKGUpIHtcbiAgICAgICAgLy8gSWYgdGhlcmUgYXJlIG5vIGZpbGVzLCB3ZSBkb24ndCB3YW50IHRvIHN0b3BcbiAgICAgICAgLy8gcHJvcGFnYXRpb24gc28gd2UgZG9uJ3QgaW50ZXJmZXJlIHdpdGggb3RoZXJcbiAgICAgICAgLy8gZHJhZyBhbmQgZHJvcCBiZWhhdmlvdXIuXG4gICAgICAgIGlmICghY29udGFpbnNGaWxlcyhlKSkgcmV0dXJuO1xuICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuXG4gICAgICAgIGlmIChlLnByZXZlbnREZWZhdWx0KSB7XG4gICAgICAgICAgcmV0dXJuIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gZS5yZXR1cm5WYWx1ZSA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9OyAvLyBDcmVhdGUgdGhlIGxpc3RlbmVyc1xuXG5cbiAgICAgIHRoaXMubGlzdGVuZXJzID0gW3tcbiAgICAgICAgZWxlbWVudDogdGhpcy5lbGVtZW50LFxuICAgICAgICBldmVudHM6IHtcbiAgICAgICAgICBcImRyYWdzdGFydFwiOiBmdW5jdGlvbiBkcmFnc3RhcnQoZSkge1xuICAgICAgICAgICAgcmV0dXJuIF90aGlzMy5lbWl0KFwiZHJhZ3N0YXJ0XCIsIGUpO1xuICAgICAgICAgIH0sXG4gICAgICAgICAgXCJkcmFnZW50ZXJcIjogZnVuY3Rpb24gZHJhZ2VudGVyKGUpIHtcbiAgICAgICAgICAgIG5vUHJvcGFnYXRpb24oZSk7XG4gICAgICAgICAgICByZXR1cm4gX3RoaXMzLmVtaXQoXCJkcmFnZW50ZXJcIiwgZSk7XG4gICAgICAgICAgfSxcbiAgICAgICAgICBcImRyYWdvdmVyXCI6IGZ1bmN0aW9uIGRyYWdvdmVyKGUpIHtcbiAgICAgICAgICAgIC8vIE1ha2VzIGl0IHBvc3NpYmxlIHRvIGRyYWcgZmlsZXMgZnJvbSBjaHJvbWUncyBkb3dubG9hZCBiYXJcbiAgICAgICAgICAgIC8vIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMTk1MjY0MzAvZHJhZy1hbmQtZHJvcC1maWxlLXVwbG9hZHMtZnJvbS1jaHJvbWUtZG93bmxvYWRzLWJhclxuICAgICAgICAgICAgLy8gVHJ5IGlzIHJlcXVpcmVkIHRvIHByZXZlbnQgYnVnIGluIEludGVybmV0IEV4cGxvcmVyIDExIChTQ1JJUFQ2NTUzNSBleGNlcHRpb24pXG4gICAgICAgICAgICB2YXIgZWZjdDtcblxuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgZWZjdCA9IGUuZGF0YVRyYW5zZmVyLmVmZmVjdEFsbG93ZWQ7XG4gICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge31cblxuICAgICAgICAgICAgZS5kYXRhVHJhbnNmZXIuZHJvcEVmZmVjdCA9ICdtb3ZlJyA9PT0gZWZjdCB8fCAnbGlua01vdmUnID09PSBlZmN0ID8gJ21vdmUnIDogJ2NvcHknO1xuICAgICAgICAgICAgbm9Qcm9wYWdhdGlvbihlKTtcbiAgICAgICAgICAgIHJldHVybiBfdGhpczMuZW1pdChcImRyYWdvdmVyXCIsIGUpO1xuICAgICAgICAgIH0sXG4gICAgICAgICAgXCJkcmFnbGVhdmVcIjogZnVuY3Rpb24gZHJhZ2xlYXZlKGUpIHtcbiAgICAgICAgICAgIHJldHVybiBfdGhpczMuZW1pdChcImRyYWdsZWF2ZVwiLCBlKTtcbiAgICAgICAgICB9LFxuICAgICAgICAgIFwiZHJvcFwiOiBmdW5jdGlvbiBkcm9wKGUpIHtcbiAgICAgICAgICAgIG5vUHJvcGFnYXRpb24oZSk7XG4gICAgICAgICAgICByZXR1cm4gX3RoaXMzLmRyb3AoZSk7XG4gICAgICAgICAgfSxcbiAgICAgICAgICBcImRyYWdlbmRcIjogZnVuY3Rpb24gZHJhZ2VuZChlKSB7XG4gICAgICAgICAgICByZXR1cm4gX3RoaXMzLmVtaXQoXCJkcmFnZW5kXCIsIGUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSAvLyBUaGlzIGlzIGRpc2FibGVkIHJpZ2h0IG5vdywgYmVjYXVzZSB0aGUgYnJvd3NlcnMgZG9uJ3QgaW1wbGVtZW50IGl0IHByb3Blcmx5LlxuICAgICAgICAvLyBcInBhc3RlXCI6IChlKSA9PlxuICAgICAgICAvLyAgIG5vUHJvcGFnYXRpb24gZVxuICAgICAgICAvLyAgIEBwYXN0ZSBlXG5cbiAgICAgIH1dO1xuICAgICAgdGhpcy5jbGlja2FibGVFbGVtZW50cy5mb3JFYWNoKGZ1bmN0aW9uIChjbGlja2FibGVFbGVtZW50KSB7XG4gICAgICAgIHJldHVybiBfdGhpczMubGlzdGVuZXJzLnB1c2goe1xuICAgICAgICAgIGVsZW1lbnQ6IGNsaWNrYWJsZUVsZW1lbnQsXG4gICAgICAgICAgZXZlbnRzOiB7XG4gICAgICAgICAgICBcImNsaWNrXCI6IGZ1bmN0aW9uIGNsaWNrKGV2dCkge1xuICAgICAgICAgICAgICAvLyBPbmx5IHRoZSBhY3R1YWwgZHJvcHpvbmUgb3IgdGhlIG1lc3NhZ2UgZWxlbWVudCBzaG91bGQgdHJpZ2dlciBmaWxlIHNlbGVjdGlvblxuICAgICAgICAgICAgICBpZiAoY2xpY2thYmxlRWxlbWVudCAhPT0gX3RoaXMzLmVsZW1lbnQgfHwgZXZ0LnRhcmdldCA9PT0gX3RoaXMzLmVsZW1lbnQgfHwgRHJvcHpvbmUuZWxlbWVudEluc2lkZShldnQudGFyZ2V0LCBfdGhpczMuZWxlbWVudC5xdWVyeVNlbGVjdG9yKFwiLmR6LW1lc3NhZ2VcIikpKSB7XG4gICAgICAgICAgICAgICAgX3RoaXMzLmhpZGRlbkZpbGVJbnB1dC5jbGljaygpOyAvLyBGb3J3YXJkIHRoZSBjbGlja1xuXG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgICB0aGlzLmVuYWJsZSgpO1xuICAgICAgcmV0dXJuIHRoaXMub3B0aW9ucy5pbml0LmNhbGwodGhpcyk7XG4gICAgfSAvLyBOb3QgZnVsbHkgdGVzdGVkIHlldFxuXG4gIH0sIHtcbiAgICBrZXk6IFwiZGVzdHJveVwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBkZXN0cm95KCkge1xuICAgICAgdGhpcy5kaXNhYmxlKCk7XG4gICAgICB0aGlzLnJlbW92ZUFsbEZpbGVzKHRydWUpO1xuXG4gICAgICBpZiAodGhpcy5oaWRkZW5GaWxlSW5wdXQgIT0gbnVsbCA/IHRoaXMuaGlkZGVuRmlsZUlucHV0LnBhcmVudE5vZGUgOiB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhpcy5oaWRkZW5GaWxlSW5wdXQucGFyZW50Tm9kZS5yZW1vdmVDaGlsZCh0aGlzLmhpZGRlbkZpbGVJbnB1dCk7XG4gICAgICAgIHRoaXMuaGlkZGVuRmlsZUlucHV0ID0gbnVsbDtcbiAgICAgIH1cblxuICAgICAgZGVsZXRlIHRoaXMuZWxlbWVudC5kcm9wem9uZTtcbiAgICAgIHJldHVybiBEcm9wem9uZS5pbnN0YW5jZXMuc3BsaWNlKERyb3B6b25lLmluc3RhbmNlcy5pbmRleE9mKHRoaXMpLCAxKTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwidXBkYXRlVG90YWxVcGxvYWRQcm9ncmVzc1wiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiB1cGRhdGVUb3RhbFVwbG9hZFByb2dyZXNzKCkge1xuICAgICAgdmFyIHRvdGFsVXBsb2FkUHJvZ3Jlc3M7XG4gICAgICB2YXIgdG90YWxCeXRlc1NlbnQgPSAwO1xuICAgICAgdmFyIHRvdGFsQnl0ZXMgPSAwO1xuICAgICAgdmFyIGFjdGl2ZUZpbGVzID0gdGhpcy5nZXRBY3RpdmVGaWxlcygpO1xuXG4gICAgICBpZiAoYWN0aXZlRmlsZXMubGVuZ3RoKSB7XG4gICAgICAgIHZhciBfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uMTEgPSB0cnVlO1xuICAgICAgICB2YXIgX2RpZEl0ZXJhdG9yRXJyb3IxMSA9IGZhbHNlO1xuICAgICAgICB2YXIgX2l0ZXJhdG9yRXJyb3IxMSA9IHVuZGVmaW5lZDtcblxuICAgICAgICB0cnkge1xuICAgICAgICAgIGZvciAodmFyIF9pdGVyYXRvcjExID0gdGhpcy5nZXRBY3RpdmVGaWxlcygpW1N5bWJvbC5pdGVyYXRvcl0oKSwgX3N0ZXAxMTsgIShfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uMTEgPSAoX3N0ZXAxMSA9IF9pdGVyYXRvcjExLm5leHQoKSkuZG9uZSk7IF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24xMSA9IHRydWUpIHtcbiAgICAgICAgICAgIHZhciBmaWxlID0gX3N0ZXAxMS52YWx1ZTtcbiAgICAgICAgICAgIHRvdGFsQnl0ZXNTZW50ICs9IGZpbGUudXBsb2FkLmJ5dGVzU2VudDtcbiAgICAgICAgICAgIHRvdGFsQnl0ZXMgKz0gZmlsZS51cGxvYWQudG90YWw7XG4gICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICBfZGlkSXRlcmF0b3JFcnJvcjExID0gdHJ1ZTtcbiAgICAgICAgICBfaXRlcmF0b3JFcnJvcjExID0gZXJyO1xuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBpZiAoIV9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24xMSAmJiBfaXRlcmF0b3IxMVtcInJldHVyblwiXSAhPSBudWxsKSB7XG4gICAgICAgICAgICAgIF9pdGVyYXRvcjExW1wicmV0dXJuXCJdKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgIGlmIChfZGlkSXRlcmF0b3JFcnJvcjExKSB7XG4gICAgICAgICAgICAgIHRocm93IF9pdGVyYXRvckVycm9yMTE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdG90YWxVcGxvYWRQcm9ncmVzcyA9IDEwMCAqIHRvdGFsQnl0ZXNTZW50IC8gdG90YWxCeXRlcztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRvdGFsVXBsb2FkUHJvZ3Jlc3MgPSAxMDA7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzLmVtaXQoXCJ0b3RhbHVwbG9hZHByb2dyZXNzXCIsIHRvdGFsVXBsb2FkUHJvZ3Jlc3MsIHRvdGFsQnl0ZXMsIHRvdGFsQnl0ZXNTZW50KTtcbiAgICB9IC8vIEBvcHRpb25zLnBhcmFtTmFtZSBjYW4gYmUgYSBmdW5jdGlvbiB0YWtpbmcgb25lIHBhcmFtZXRlciByYXRoZXIgdGhhbiBhIHN0cmluZy5cbiAgICAvLyBBIHBhcmFtZXRlciBuYW1lIGZvciBhIGZpbGUgaXMgb2J0YWluZWQgc2ltcGx5IGJ5IGNhbGxpbmcgdGhpcyB3aXRoIGFuIGluZGV4IG51bWJlci5cblxuICB9LCB7XG4gICAga2V5OiBcIl9nZXRQYXJhbU5hbWVcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gX2dldFBhcmFtTmFtZShuKSB7XG4gICAgICBpZiAodHlwZW9mIHRoaXMub3B0aW9ucy5wYXJhbU5hbWUgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICByZXR1cm4gdGhpcy5vcHRpb25zLnBhcmFtTmFtZShuKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBcIlwiLmNvbmNhdCh0aGlzLm9wdGlvbnMucGFyYW1OYW1lKS5jb25jYXQodGhpcy5vcHRpb25zLnVwbG9hZE11bHRpcGxlID8gXCJbXCIuY29uY2F0KG4sIFwiXVwiKSA6IFwiXCIpO1xuICAgICAgfVxuICAgIH0gLy8gSWYgQG9wdGlvbnMucmVuYW1lRmlsZSBpcyBhIGZ1bmN0aW9uLFxuICAgIC8vIHRoZSBmdW5jdGlvbiB3aWxsIGJlIHVzZWQgdG8gcmVuYW1lIHRoZSBmaWxlLm5hbWUgYmVmb3JlIGFwcGVuZGluZyBpdCB0byB0aGUgZm9ybURhdGFcblxuICB9LCB7XG4gICAga2V5OiBcIl9yZW5hbWVGaWxlXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIF9yZW5hbWVGaWxlKGZpbGUpIHtcbiAgICAgIGlmICh0eXBlb2YgdGhpcy5vcHRpb25zLnJlbmFtZUZpbGUgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICByZXR1cm4gZmlsZS5uYW1lO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcy5vcHRpb25zLnJlbmFtZUZpbGUoZmlsZSk7XG4gICAgfSAvLyBSZXR1cm5zIGEgZm9ybSB0aGF0IGNhbiBiZSB1c2VkIGFzIGZhbGxiYWNrIGlmIHRoZSBicm93c2VyIGRvZXMgbm90IHN1cHBvcnQgRHJhZ25Ecm9wXG4gICAgLy9cbiAgICAvLyBJZiB0aGUgZHJvcHpvbmUgaXMgYWxyZWFkeSBhIGZvcm0sIG9ubHkgdGhlIGlucHV0IGZpZWxkIGFuZCBidXR0b24gYXJlIHJldHVybmVkLiBPdGhlcndpc2UgYSBjb21wbGV0ZSBmb3JtIGVsZW1lbnQgaXMgcHJvdmlkZWQuXG4gICAgLy8gVGhpcyBjb2RlIGhhcyB0byBwYXNzIGluIElFNyA6KFxuXG4gIH0sIHtcbiAgICBrZXk6IFwiZ2V0RmFsbGJhY2tGb3JtXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGdldEZhbGxiYWNrRm9ybSgpIHtcbiAgICAgIHZhciBleGlzdGluZ0ZhbGxiYWNrLCBmb3JtO1xuXG4gICAgICBpZiAoZXhpc3RpbmdGYWxsYmFjayA9IHRoaXMuZ2V0RXhpc3RpbmdGYWxsYmFjaygpKSB7XG4gICAgICAgIHJldHVybiBleGlzdGluZ0ZhbGxiYWNrO1xuICAgICAgfVxuXG4gICAgICB2YXIgZmllbGRzU3RyaW5nID0gXCI8ZGl2IGNsYXNzPVxcXCJkei1mYWxsYmFja1xcXCI+XCI7XG5cbiAgICAgIGlmICh0aGlzLm9wdGlvbnMuZGljdEZhbGxiYWNrVGV4dCkge1xuICAgICAgICBmaWVsZHNTdHJpbmcgKz0gXCI8cD5cIi5jb25jYXQodGhpcy5vcHRpb25zLmRpY3RGYWxsYmFja1RleHQsIFwiPC9wPlwiKTtcbiAgICAgIH1cblxuICAgICAgZmllbGRzU3RyaW5nICs9IFwiPGlucHV0IHR5cGU9XFxcImZpbGVcXFwiIG5hbWU9XFxcIlwiLmNvbmNhdCh0aGlzLl9nZXRQYXJhbU5hbWUoMCksIFwiXFxcIiBcIikuY29uY2F0KHRoaXMub3B0aW9ucy51cGxvYWRNdWx0aXBsZSA/ICdtdWx0aXBsZT1cIm11bHRpcGxlXCInIDogdW5kZWZpbmVkLCBcIiAvPjxpbnB1dCB0eXBlPVxcXCJzdWJtaXRcXFwiIHZhbHVlPVxcXCJVcGxvYWQhXFxcIj48L2Rpdj5cIik7XG4gICAgICB2YXIgZmllbGRzID0gRHJvcHpvbmUuY3JlYXRlRWxlbWVudChmaWVsZHNTdHJpbmcpO1xuXG4gICAgICBpZiAodGhpcy5lbGVtZW50LnRhZ05hbWUgIT09IFwiRk9STVwiKSB7XG4gICAgICAgIGZvcm0gPSBEcm9wem9uZS5jcmVhdGVFbGVtZW50KFwiPGZvcm0gYWN0aW9uPVxcXCJcIi5jb25jYXQodGhpcy5vcHRpb25zLnVybCwgXCJcXFwiIGVuY3R5cGU9XFxcIm11bHRpcGFydC9mb3JtLWRhdGFcXFwiIG1ldGhvZD1cXFwiXCIpLmNvbmNhdCh0aGlzLm9wdGlvbnMubWV0aG9kLCBcIlxcXCI+PC9mb3JtPlwiKSk7XG4gICAgICAgIGZvcm0uYXBwZW5kQ2hpbGQoZmllbGRzKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIE1ha2Ugc3VyZSB0aGF0IHRoZSBlbmN0eXBlIGFuZCBtZXRob2QgYXR0cmlidXRlcyBhcmUgc2V0IHByb3Blcmx5XG4gICAgICAgIHRoaXMuZWxlbWVudC5zZXRBdHRyaWJ1dGUoXCJlbmN0eXBlXCIsIFwibXVsdGlwYXJ0L2Zvcm0tZGF0YVwiKTtcbiAgICAgICAgdGhpcy5lbGVtZW50LnNldEF0dHJpYnV0ZShcIm1ldGhvZFwiLCB0aGlzLm9wdGlvbnMubWV0aG9kKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGZvcm0gIT0gbnVsbCA/IGZvcm0gOiBmaWVsZHM7XG4gICAgfSAvLyBSZXR1cm5zIHRoZSBmYWxsYmFjayBlbGVtZW50cyBpZiB0aGV5IGV4aXN0IGFscmVhZHlcbiAgICAvL1xuICAgIC8vIFRoaXMgY29kZSBoYXMgdG8gcGFzcyBpbiBJRTcgOihcblxuICB9LCB7XG4gICAga2V5OiBcImdldEV4aXN0aW5nRmFsbGJhY2tcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gZ2V0RXhpc3RpbmdGYWxsYmFjaygpIHtcbiAgICAgIHZhciBnZXRGYWxsYmFjayA9IGZ1bmN0aW9uIGdldEZhbGxiYWNrKGVsZW1lbnRzKSB7XG4gICAgICAgIHZhciBfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uMTIgPSB0cnVlO1xuICAgICAgICB2YXIgX2RpZEl0ZXJhdG9yRXJyb3IxMiA9IGZhbHNlO1xuICAgICAgICB2YXIgX2l0ZXJhdG9yRXJyb3IxMiA9IHVuZGVmaW5lZDtcblxuICAgICAgICB0cnkge1xuICAgICAgICAgIGZvciAodmFyIF9pdGVyYXRvcjEyID0gZWxlbWVudHNbU3ltYm9sLml0ZXJhdG9yXSgpLCBfc3RlcDEyOyAhKF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24xMiA9IChfc3RlcDEyID0gX2l0ZXJhdG9yMTIubmV4dCgpKS5kb25lKTsgX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjEyID0gdHJ1ZSkge1xuICAgICAgICAgICAgdmFyIGVsID0gX3N0ZXAxMi52YWx1ZTtcblxuICAgICAgICAgICAgaWYgKC8oXnwgKWZhbGxiYWNrKCR8ICkvLnRlc3QoZWwuY2xhc3NOYW1lKSkge1xuICAgICAgICAgICAgICByZXR1cm4gZWw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICBfZGlkSXRlcmF0b3JFcnJvcjEyID0gdHJ1ZTtcbiAgICAgICAgICBfaXRlcmF0b3JFcnJvcjEyID0gZXJyO1xuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBpZiAoIV9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24xMiAmJiBfaXRlcmF0b3IxMltcInJldHVyblwiXSAhPSBudWxsKSB7XG4gICAgICAgICAgICAgIF9pdGVyYXRvcjEyW1wicmV0dXJuXCJdKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgIGlmIChfZGlkSXRlcmF0b3JFcnJvcjEyKSB7XG4gICAgICAgICAgICAgIHRocm93IF9pdGVyYXRvckVycm9yMTI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICBmb3IgKHZhciBfaTIgPSAwLCBfYXJyID0gW1wiZGl2XCIsIFwiZm9ybVwiXTsgX2kyIDwgX2Fyci5sZW5ndGg7IF9pMisrKSB7XG4gICAgICAgIHZhciB0YWdOYW1lID0gX2FycltfaTJdO1xuICAgICAgICB2YXIgZmFsbGJhY2s7XG5cbiAgICAgICAgaWYgKGZhbGxiYWNrID0gZ2V0RmFsbGJhY2sodGhpcy5lbGVtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKHRhZ05hbWUpKSkge1xuICAgICAgICAgIHJldHVybiBmYWxsYmFjaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gLy8gQWN0aXZhdGVzIGFsbCBsaXN0ZW5lcnMgc3RvcmVkIGluIEBsaXN0ZW5lcnNcblxuICB9LCB7XG4gICAga2V5OiBcInNldHVwRXZlbnRMaXN0ZW5lcnNcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gc2V0dXBFdmVudExpc3RlbmVycygpIHtcbiAgICAgIHJldHVybiB0aGlzLmxpc3RlbmVycy5tYXAoZnVuY3Rpb24gKGVsZW1lbnRMaXN0ZW5lcnMpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICB2YXIgcmVzdWx0ID0gW107XG5cbiAgICAgICAgICBmb3IgKHZhciBldmVudCBpbiBlbGVtZW50TGlzdGVuZXJzLmV2ZW50cykge1xuICAgICAgICAgICAgdmFyIGxpc3RlbmVyID0gZWxlbWVudExpc3RlbmVycy5ldmVudHNbZXZlbnRdO1xuICAgICAgICAgICAgcmVzdWx0LnB1c2goZWxlbWVudExpc3RlbmVycy5lbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoZXZlbnQsIGxpc3RlbmVyLCBmYWxzZSkpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgIH0oKTtcbiAgICAgIH0pO1xuICAgIH0gLy8gRGVhY3RpdmF0ZXMgYWxsIGxpc3RlbmVycyBzdG9yZWQgaW4gQGxpc3RlbmVyc1xuXG4gIH0sIHtcbiAgICBrZXk6IFwicmVtb3ZlRXZlbnRMaXN0ZW5lcnNcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gcmVtb3ZlRXZlbnRMaXN0ZW5lcnMoKSB7XG4gICAgICByZXR1cm4gdGhpcy5saXN0ZW5lcnMubWFwKGZ1bmN0aW9uIChlbGVtZW50TGlzdGVuZXJzKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgdmFyIHJlc3VsdCA9IFtdO1xuXG4gICAgICAgICAgZm9yICh2YXIgZXZlbnQgaW4gZWxlbWVudExpc3RlbmVycy5ldmVudHMpIHtcbiAgICAgICAgICAgIHZhciBsaXN0ZW5lciA9IGVsZW1lbnRMaXN0ZW5lcnMuZXZlbnRzW2V2ZW50XTtcbiAgICAgICAgICAgIHJlc3VsdC5wdXNoKGVsZW1lbnRMaXN0ZW5lcnMuZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKGV2ZW50LCBsaXN0ZW5lciwgZmFsc2UpKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICB9KCk7XG4gICAgICB9KTtcbiAgICB9IC8vIFJlbW92ZXMgYWxsIGV2ZW50IGxpc3RlbmVycyBhbmQgY2FuY2VscyBhbGwgZmlsZXMgaW4gdGhlIHF1ZXVlIG9yIGJlaW5nIHByb2Nlc3NlZC5cblxuICB9LCB7XG4gICAga2V5OiBcImRpc2FibGVcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gZGlzYWJsZSgpIHtcbiAgICAgIHZhciBfdGhpczQgPSB0aGlzO1xuXG4gICAgICB0aGlzLmNsaWNrYWJsZUVsZW1lbnRzLmZvckVhY2goZnVuY3Rpb24gKGVsZW1lbnQpIHtcbiAgICAgICAgcmV0dXJuIGVsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZShcImR6LWNsaWNrYWJsZVwiKTtcbiAgICAgIH0pO1xuICAgICAgdGhpcy5yZW1vdmVFdmVudExpc3RlbmVycygpO1xuICAgICAgdGhpcy5kaXNhYmxlZCA9IHRydWU7XG4gICAgICByZXR1cm4gdGhpcy5maWxlcy5tYXAoZnVuY3Rpb24gKGZpbGUpIHtcbiAgICAgICAgcmV0dXJuIF90aGlzNC5jYW5jZWxVcGxvYWQoZmlsZSk7XG4gICAgICB9KTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiZW5hYmxlXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGVuYWJsZSgpIHtcbiAgICAgIGRlbGV0ZSB0aGlzLmRpc2FibGVkO1xuICAgICAgdGhpcy5jbGlja2FibGVFbGVtZW50cy5mb3JFYWNoKGZ1bmN0aW9uIChlbGVtZW50KSB7XG4gICAgICAgIHJldHVybiBlbGVtZW50LmNsYXNzTGlzdC5hZGQoXCJkei1jbGlja2FibGVcIik7XG4gICAgICB9KTtcbiAgICAgIHJldHVybiB0aGlzLnNldHVwRXZlbnRMaXN0ZW5lcnMoKTtcbiAgICB9IC8vIFJldHVybnMgYSBuaWNlbHkgZm9ybWF0dGVkIGZpbGVzaXplXG5cbiAgfSwge1xuICAgIGtleTogXCJmaWxlc2l6ZVwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBmaWxlc2l6ZShzaXplKSB7XG4gICAgICB2YXIgc2VsZWN0ZWRTaXplID0gMDtcbiAgICAgIHZhciBzZWxlY3RlZFVuaXQgPSBcImJcIjtcblxuICAgICAgaWYgKHNpemUgPiAwKSB7XG4gICAgICAgIHZhciB1bml0cyA9IFsndGInLCAnZ2InLCAnbWInLCAna2InLCAnYiddO1xuXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdW5pdHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICB2YXIgdW5pdCA9IHVuaXRzW2ldO1xuICAgICAgICAgIHZhciBjdXRvZmYgPSBNYXRoLnBvdyh0aGlzLm9wdGlvbnMuZmlsZXNpemVCYXNlLCA0IC0gaSkgLyAxMDtcblxuICAgICAgICAgIGlmIChzaXplID49IGN1dG9mZikge1xuICAgICAgICAgICAgc2VsZWN0ZWRTaXplID0gc2l6ZSAvIE1hdGgucG93KHRoaXMub3B0aW9ucy5maWxlc2l6ZUJhc2UsIDQgLSBpKTtcbiAgICAgICAgICAgIHNlbGVjdGVkVW5pdCA9IHVuaXQ7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBzZWxlY3RlZFNpemUgPSBNYXRoLnJvdW5kKDEwICogc2VsZWN0ZWRTaXplKSAvIDEwOyAvLyBDdXR0aW5nIG9mIGRpZ2l0c1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gXCI8c3Ryb25nPlwiLmNvbmNhdChzZWxlY3RlZFNpemUsIFwiPC9zdHJvbmc+IFwiKS5jb25jYXQodGhpcy5vcHRpb25zLmRpY3RGaWxlU2l6ZVVuaXRzW3NlbGVjdGVkVW5pdF0pO1xuICAgIH0gLy8gQWRkcyBvciByZW1vdmVzIHRoZSBgZHotbWF4LWZpbGVzLXJlYWNoZWRgIGNsYXNzIGZyb20gdGhlIGZvcm0uXG5cbiAgfSwge1xuICAgIGtleTogXCJfdXBkYXRlTWF4RmlsZXNSZWFjaGVkQ2xhc3NcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gX3VwZGF0ZU1heEZpbGVzUmVhY2hlZENsYXNzKCkge1xuICAgICAgaWYgKHRoaXMub3B0aW9ucy5tYXhGaWxlcyAhPSBudWxsICYmIHRoaXMuZ2V0QWNjZXB0ZWRGaWxlcygpLmxlbmd0aCA+PSB0aGlzLm9wdGlvbnMubWF4RmlsZXMpIHtcbiAgICAgICAgaWYgKHRoaXMuZ2V0QWNjZXB0ZWRGaWxlcygpLmxlbmd0aCA9PT0gdGhpcy5vcHRpb25zLm1heEZpbGVzKSB7XG4gICAgICAgICAgdGhpcy5lbWl0KCdtYXhmaWxlc3JlYWNoZWQnLCB0aGlzLmZpbGVzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzLmVsZW1lbnQuY2xhc3NMaXN0LmFkZChcImR6LW1heC1maWxlcy1yZWFjaGVkXCIpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKFwiZHotbWF4LWZpbGVzLXJlYWNoZWRcIik7XG4gICAgICB9XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcImRyb3BcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gZHJvcChlKSB7XG4gICAgICBpZiAoIWUuZGF0YVRyYW5zZmVyKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdGhpcy5lbWl0KFwiZHJvcFwiLCBlKTsgLy8gQ29udmVydCB0aGUgRmlsZUxpc3QgdG8gYW4gQXJyYXlcbiAgICAgIC8vIFRoaXMgaXMgbmVjZXNzYXJ5IGZvciBJRTExXG5cbiAgICAgIHZhciBmaWxlcyA9IFtdO1xuXG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGUuZGF0YVRyYW5zZmVyLmZpbGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGZpbGVzW2ldID0gZS5kYXRhVHJhbnNmZXIuZmlsZXNbaV07XG4gICAgICB9IC8vIEV2ZW4gaWYgaXQncyBhIGZvbGRlciwgZmlsZXMubGVuZ3RoIHdpbGwgY29udGFpbiB0aGUgZm9sZGVycy5cblxuXG4gICAgICBpZiAoZmlsZXMubGVuZ3RoKSB7XG4gICAgICAgIHZhciBpdGVtcyA9IGUuZGF0YVRyYW5zZmVyLml0ZW1zO1xuXG4gICAgICAgIGlmIChpdGVtcyAmJiBpdGVtcy5sZW5ndGggJiYgaXRlbXNbMF0ud2Via2l0R2V0QXNFbnRyeSAhPSBudWxsKSB7XG4gICAgICAgICAgLy8gVGhlIGJyb3dzZXIgc3VwcG9ydHMgZHJvcHBpbmcgb2YgZm9sZGVycywgc28gaGFuZGxlIGl0ZW1zIGluc3RlYWQgb2YgZmlsZXNcbiAgICAgICAgICB0aGlzLl9hZGRGaWxlc0Zyb21JdGVtcyhpdGVtcyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5oYW5kbGVGaWxlcyhmaWxlcyk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgdGhpcy5lbWl0KFwiYWRkZWRmaWxlc1wiLCBmaWxlcyk7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcInBhc3RlXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHBhc3RlKGUpIHtcbiAgICAgIGlmIChfX2d1YXJkX18oZSAhPSBudWxsID8gZS5jbGlwYm9hcmREYXRhIDogdW5kZWZpbmVkLCBmdW5jdGlvbiAoeCkge1xuICAgICAgICByZXR1cm4geC5pdGVtcztcbiAgICAgIH0pID09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB0aGlzLmVtaXQoXCJwYXN0ZVwiLCBlKTtcbiAgICAgIHZhciBpdGVtcyA9IGUuY2xpcGJvYXJkRGF0YS5pdGVtcztcblxuICAgICAgaWYgKGl0ZW1zLmxlbmd0aCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYWRkRmlsZXNGcm9tSXRlbXMoaXRlbXMpO1xuICAgICAgfVxuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJoYW5kbGVGaWxlc1wiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBoYW5kbGVGaWxlcyhmaWxlcykge1xuICAgICAgdmFyIF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24xMyA9IHRydWU7XG4gICAgICB2YXIgX2RpZEl0ZXJhdG9yRXJyb3IxMyA9IGZhbHNlO1xuICAgICAgdmFyIF9pdGVyYXRvckVycm9yMTMgPSB1bmRlZmluZWQ7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGZvciAodmFyIF9pdGVyYXRvcjEzID0gZmlsZXNbU3ltYm9sLml0ZXJhdG9yXSgpLCBfc3RlcDEzOyAhKF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24xMyA9IChfc3RlcDEzID0gX2l0ZXJhdG9yMTMubmV4dCgpKS5kb25lKTsgX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjEzID0gdHJ1ZSkge1xuICAgICAgICAgIHZhciBmaWxlID0gX3N0ZXAxMy52YWx1ZTtcbiAgICAgICAgICB0aGlzLmFkZEZpbGUoZmlsZSk7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBfZGlkSXRlcmF0b3JFcnJvcjEzID0gdHJ1ZTtcbiAgICAgICAgX2l0ZXJhdG9yRXJyb3IxMyA9IGVycjtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgaWYgKCFfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uMTMgJiYgX2l0ZXJhdG9yMTNbXCJyZXR1cm5cIl0gIT0gbnVsbCkge1xuICAgICAgICAgICAgX2l0ZXJhdG9yMTNbXCJyZXR1cm5cIl0oKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgaWYgKF9kaWRJdGVyYXRvckVycm9yMTMpIHtcbiAgICAgICAgICAgIHRocm93IF9pdGVyYXRvckVycm9yMTM7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSAvLyBXaGVuIGEgZm9sZGVyIGlzIGRyb3BwZWQgKG9yIGZpbGVzIGFyZSBwYXN0ZWQpLCBpdGVtcyBtdXN0IGJlIGhhbmRsZWRcbiAgICAvLyBpbnN0ZWFkIG9mIGZpbGVzLlxuXG4gIH0sIHtcbiAgICBrZXk6IFwiX2FkZEZpbGVzRnJvbUl0ZW1zXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIF9hZGRGaWxlc0Zyb21JdGVtcyhpdGVtcykge1xuICAgICAgdmFyIF90aGlzNSA9IHRoaXM7XG5cbiAgICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciByZXN1bHQgPSBbXTtcbiAgICAgICAgdmFyIF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24xNCA9IHRydWU7XG4gICAgICAgIHZhciBfZGlkSXRlcmF0b3JFcnJvcjE0ID0gZmFsc2U7XG4gICAgICAgIHZhciBfaXRlcmF0b3JFcnJvcjE0ID0gdW5kZWZpbmVkO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgZm9yICh2YXIgX2l0ZXJhdG9yMTQgPSBpdGVtc1tTeW1ib2wuaXRlcmF0b3JdKCksIF9zdGVwMTQ7ICEoX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjE0ID0gKF9zdGVwMTQgPSBfaXRlcmF0b3IxNC5uZXh0KCkpLmRvbmUpOyBfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uMTQgPSB0cnVlKSB7XG4gICAgICAgICAgICB2YXIgaXRlbSA9IF9zdGVwMTQudmFsdWU7XG4gICAgICAgICAgICB2YXIgZW50cnk7XG5cbiAgICAgICAgICAgIGlmIChpdGVtLndlYmtpdEdldEFzRW50cnkgIT0gbnVsbCAmJiAoZW50cnkgPSBpdGVtLndlYmtpdEdldEFzRW50cnkoKSkpIHtcbiAgICAgICAgICAgICAgaWYgKGVudHJ5LmlzRmlsZSkge1xuICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKF90aGlzNS5hZGRGaWxlKGl0ZW0uZ2V0QXNGaWxlKCkpKTtcbiAgICAgICAgICAgICAgfSBlbHNlIGlmIChlbnRyeS5pc0RpcmVjdG9yeSkge1xuICAgICAgICAgICAgICAgIC8vIEFwcGVuZCBhbGwgZmlsZXMgZnJvbSB0aGF0IGRpcmVjdG9yeSB0byBmaWxlc1xuICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKF90aGlzNS5fYWRkRmlsZXNGcm9tRGlyZWN0b3J5KGVudHJ5LCBlbnRyeS5uYW1lKSk7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0LnB1c2godW5kZWZpbmVkKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmIChpdGVtLmdldEFzRmlsZSAhPSBudWxsKSB7XG4gICAgICAgICAgICAgIGlmIChpdGVtLmtpbmQgPT0gbnVsbCB8fCBpdGVtLmtpbmQgPT09IFwiZmlsZVwiKSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0LnB1c2goX3RoaXM1LmFkZEZpbGUoaXRlbS5nZXRBc0ZpbGUoKSkpO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKHVuZGVmaW5lZCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHJlc3VsdC5wdXNoKHVuZGVmaW5lZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICBfZGlkSXRlcmF0b3JFcnJvcjE0ID0gdHJ1ZTtcbiAgICAgICAgICBfaXRlcmF0b3JFcnJvcjE0ID0gZXJyO1xuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBpZiAoIV9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24xNCAmJiBfaXRlcmF0b3IxNFtcInJldHVyblwiXSAhPSBudWxsKSB7XG4gICAgICAgICAgICAgIF9pdGVyYXRvcjE0W1wicmV0dXJuXCJdKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgIGlmIChfZGlkSXRlcmF0b3JFcnJvcjE0KSB7XG4gICAgICAgICAgICAgIHRocm93IF9pdGVyYXRvckVycm9yMTQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH0oKTtcbiAgICB9IC8vIEdvZXMgdGhyb3VnaCB0aGUgZGlyZWN0b3J5LCBhbmQgYWRkcyBlYWNoIGZpbGUgaXQgZmluZHMgcmVjdXJzaXZlbHlcblxuICB9LCB7XG4gICAga2V5OiBcIl9hZGRGaWxlc0Zyb21EaXJlY3RvcnlcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gX2FkZEZpbGVzRnJvbURpcmVjdG9yeShkaXJlY3RvcnksIHBhdGgpIHtcbiAgICAgIHZhciBfdGhpczYgPSB0aGlzO1xuXG4gICAgICB2YXIgZGlyUmVhZGVyID0gZGlyZWN0b3J5LmNyZWF0ZVJlYWRlcigpO1xuXG4gICAgICB2YXIgZXJyb3JIYW5kbGVyID0gZnVuY3Rpb24gZXJyb3JIYW5kbGVyKGVycm9yKSB7XG4gICAgICAgIHJldHVybiBfX2d1YXJkTWV0aG9kX18oY29uc29sZSwgJ2xvZycsIGZ1bmN0aW9uIChvKSB7XG4gICAgICAgICAgcmV0dXJuIG8ubG9nKGVycm9yKTtcbiAgICAgICAgfSk7XG4gICAgICB9O1xuXG4gICAgICB2YXIgcmVhZEVudHJpZXMgPSBmdW5jdGlvbiByZWFkRW50cmllcygpIHtcbiAgICAgICAgcmV0dXJuIGRpclJlYWRlci5yZWFkRW50cmllcyhmdW5jdGlvbiAoZW50cmllcykge1xuICAgICAgICAgIGlmIChlbnRyaWVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHZhciBfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uMTUgPSB0cnVlO1xuICAgICAgICAgICAgdmFyIF9kaWRJdGVyYXRvckVycm9yMTUgPSBmYWxzZTtcbiAgICAgICAgICAgIHZhciBfaXRlcmF0b3JFcnJvcjE1ID0gdW5kZWZpbmVkO1xuXG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICBmb3IgKHZhciBfaXRlcmF0b3IxNSA9IGVudHJpZXNbU3ltYm9sLml0ZXJhdG9yXSgpLCBfc3RlcDE1OyAhKF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24xNSA9IChfc3RlcDE1ID0gX2l0ZXJhdG9yMTUubmV4dCgpKS5kb25lKTsgX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjE1ID0gdHJ1ZSkge1xuICAgICAgICAgICAgICAgIHZhciBlbnRyeSA9IF9zdGVwMTUudmFsdWU7XG5cbiAgICAgICAgICAgICAgICBpZiAoZW50cnkuaXNGaWxlKSB7XG4gICAgICAgICAgICAgICAgICBlbnRyeS5maWxlKGZ1bmN0aW9uIChmaWxlKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfdGhpczYub3B0aW9ucy5pZ25vcmVIaWRkZW5GaWxlcyAmJiBmaWxlLm5hbWUuc3Vic3RyaW5nKDAsIDEpID09PSAnLicpIHtcbiAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBmaWxlLmZ1bGxQYXRoID0gXCJcIi5jb25jYXQocGF0aCwgXCIvXCIpLmNvbmNhdChmaWxlLm5hbWUpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gX3RoaXM2LmFkZEZpbGUoZmlsZSk7XG4gICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGVudHJ5LmlzRGlyZWN0b3J5KSB7XG4gICAgICAgICAgICAgICAgICBfdGhpczYuX2FkZEZpbGVzRnJvbURpcmVjdG9yeShlbnRyeSwgXCJcIi5jb25jYXQocGF0aCwgXCIvXCIpLmNvbmNhdChlbnRyeS5uYW1lKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9IC8vIFJlY3Vyc2l2ZWx5IGNhbGwgcmVhZEVudHJpZXMoKSBhZ2Fpbiwgc2luY2UgYnJvd3NlciBvbmx5IGhhbmRsZVxuICAgICAgICAgICAgICAvLyB0aGUgZmlyc3QgMTAwIGVudHJpZXMuXG4gICAgICAgICAgICAgIC8vIFNlZTogaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0RpcmVjdG9yeVJlYWRlciNyZWFkRW50cmllc1xuXG4gICAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgX2RpZEl0ZXJhdG9yRXJyb3IxNSA9IHRydWU7XG4gICAgICAgICAgICAgIF9pdGVyYXRvckVycm9yMTUgPSBlcnI7XG4gICAgICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGlmICghX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjE1ICYmIF9pdGVyYXRvcjE1W1wicmV0dXJuXCJdICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgIF9pdGVyYXRvcjE1W1wicmV0dXJuXCJdKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgICAgICAgIGlmIChfZGlkSXRlcmF0b3JFcnJvcjE1KSB7XG4gICAgICAgICAgICAgICAgICB0aHJvdyBfaXRlcmF0b3JFcnJvcjE1O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZWFkRW50cmllcygpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9LCBlcnJvckhhbmRsZXIpO1xuICAgICAgfTtcblxuICAgICAgcmV0dXJuIHJlYWRFbnRyaWVzKCk7XG4gICAgfSAvLyBJZiBgZG9uZSgpYCBpcyBjYWxsZWQgd2l0aG91dCBhcmd1bWVudCB0aGUgZmlsZSBpcyBhY2NlcHRlZFxuICAgIC8vIElmIHlvdSBjYWxsIGl0IHdpdGggYW4gZXJyb3IgbWVzc2FnZSwgdGhlIGZpbGUgaXMgcmVqZWN0ZWRcbiAgICAvLyAoVGhpcyBhbGxvd3MgZm9yIGFzeW5jaHJvbm91cyB2YWxpZGF0aW9uKVxuICAgIC8vXG4gICAgLy8gVGhpcyBmdW5jdGlvbiBjaGVja3MgdGhlIGZpbGVzaXplLCBhbmQgaWYgdGhlIGZpbGUudHlwZSBwYXNzZXMgdGhlXG4gICAgLy8gYGFjY2VwdGVkRmlsZXNgIGNoZWNrLlxuXG4gIH0sIHtcbiAgICBrZXk6IFwiYWNjZXB0XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGFjY2VwdChmaWxlLCBkb25lKSB7XG4gICAgICBpZiAodGhpcy5vcHRpb25zLm1heEZpbGVzaXplICYmIGZpbGUuc2l6ZSA+IHRoaXMub3B0aW9ucy5tYXhGaWxlc2l6ZSAqIDEwMjQgKiAxMDI0KSB7XG4gICAgICAgIGRvbmUodGhpcy5vcHRpb25zLmRpY3RGaWxlVG9vQmlnLnJlcGxhY2UoXCJ7e2ZpbGVzaXplfX1cIiwgTWF0aC5yb3VuZChmaWxlLnNpemUgLyAxMDI0IC8gMTAuMjQpIC8gMTAwKS5yZXBsYWNlKFwie3ttYXhGaWxlc2l6ZX19XCIsIHRoaXMub3B0aW9ucy5tYXhGaWxlc2l6ZSkpO1xuICAgICAgfSBlbHNlIGlmICghRHJvcHpvbmUuaXNWYWxpZEZpbGUoZmlsZSwgdGhpcy5vcHRpb25zLmFjY2VwdGVkRmlsZXMpKSB7XG4gICAgICAgIGRvbmUodGhpcy5vcHRpb25zLmRpY3RJbnZhbGlkRmlsZVR5cGUpO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLm9wdGlvbnMubWF4RmlsZXMgIT0gbnVsbCAmJiB0aGlzLmdldEFjY2VwdGVkRmlsZXMoKS5sZW5ndGggPj0gdGhpcy5vcHRpb25zLm1heEZpbGVzKSB7XG4gICAgICAgIGRvbmUodGhpcy5vcHRpb25zLmRpY3RNYXhGaWxlc0V4Y2VlZGVkLnJlcGxhY2UoXCJ7e21heEZpbGVzfX1cIiwgdGhpcy5vcHRpb25zLm1heEZpbGVzKSk7XG4gICAgICAgIHRoaXMuZW1pdChcIm1heGZpbGVzZXhjZWVkZWRcIiwgZmlsZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLm9wdGlvbnMuYWNjZXB0LmNhbGwodGhpcywgZmlsZSwgZG9uZSk7XG4gICAgICB9XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcImFkZEZpbGVcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gYWRkRmlsZShmaWxlKSB7XG4gICAgICB2YXIgX3RoaXM3ID0gdGhpcztcblxuICAgICAgZmlsZS51cGxvYWQgPSB7XG4gICAgICAgIHV1aWQ6IERyb3B6b25lLnV1aWR2NCgpLFxuICAgICAgICBwcm9ncmVzczogMCxcbiAgICAgICAgLy8gU2V0dGluZyB0aGUgdG90YWwgdXBsb2FkIHNpemUgdG8gZmlsZS5zaXplIGZvciB0aGUgYmVnaW5uaW5nXG4gICAgICAgIC8vIEl0J3MgYWN0dWFsIGRpZmZlcmVudCB0aGFuIHRoZSBzaXplIHRvIGJlIHRyYW5zbWl0dGVkLlxuICAgICAgICB0b3RhbDogZmlsZS5zaXplLFxuICAgICAgICBieXRlc1NlbnQ6IDAsXG4gICAgICAgIGZpbGVuYW1lOiB0aGlzLl9yZW5hbWVGaWxlKGZpbGUpIC8vIE5vdCBzZXR0aW5nIGNodW5raW5nIGluZm9ybWF0aW9uIGhlcmUsIGJlY2F1c2UgdGhlIGFjdXRhbCBkYXRhIOKAlCBhbmRcbiAgICAgICAgLy8gdGh1cyB0aGUgY2h1bmtzIOKAlCBtaWdodCBjaGFuZ2UgaWYgYG9wdGlvbnMudHJhbnNmb3JtRmlsZWAgaXMgc2V0XG4gICAgICAgIC8vIGFuZCBkb2VzIHNvbWV0aGluZyB0byB0aGUgZGF0YS5cblxuICAgICAgfTtcbiAgICAgIHRoaXMuZmlsZXMucHVzaChmaWxlKTtcbiAgICAgIGZpbGUuc3RhdHVzID0gRHJvcHpvbmUuQURERUQ7XG4gICAgICB0aGlzLmVtaXQoXCJhZGRlZGZpbGVcIiwgZmlsZSk7XG5cbiAgICAgIHRoaXMuX2VucXVldWVUaHVtYm5haWwoZmlsZSk7XG5cbiAgICAgIHRoaXMuYWNjZXB0KGZpbGUsIGZ1bmN0aW9uIChlcnJvcikge1xuICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICBmaWxlLmFjY2VwdGVkID0gZmFsc2U7XG5cbiAgICAgICAgICBfdGhpczcuX2Vycm9yUHJvY2Vzc2luZyhbZmlsZV0sIGVycm9yKTsgLy8gV2lsbCBzZXQgdGhlIGZpbGUuc3RhdHVzXG5cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBmaWxlLmFjY2VwdGVkID0gdHJ1ZTtcblxuICAgICAgICAgIGlmIChfdGhpczcub3B0aW9ucy5hdXRvUXVldWUpIHtcbiAgICAgICAgICAgIF90aGlzNy5lbnF1ZXVlRmlsZShmaWxlKTtcbiAgICAgICAgICB9IC8vIFdpbGwgc2V0IC5hY2NlcHRlZCA9IHRydWVcblxuICAgICAgICB9XG5cbiAgICAgICAgX3RoaXM3Ll91cGRhdGVNYXhGaWxlc1JlYWNoZWRDbGFzcygpO1xuICAgICAgfSk7XG4gICAgfSAvLyBXcmFwcGVyIGZvciBlbnF1ZXVlRmlsZVxuXG4gIH0sIHtcbiAgICBrZXk6IFwiZW5xdWV1ZUZpbGVzXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGVucXVldWVGaWxlcyhmaWxlcykge1xuICAgICAgdmFyIF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24xNiA9IHRydWU7XG4gICAgICB2YXIgX2RpZEl0ZXJhdG9yRXJyb3IxNiA9IGZhbHNlO1xuICAgICAgdmFyIF9pdGVyYXRvckVycm9yMTYgPSB1bmRlZmluZWQ7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGZvciAodmFyIF9pdGVyYXRvcjE2ID0gZmlsZXNbU3ltYm9sLml0ZXJhdG9yXSgpLCBfc3RlcDE2OyAhKF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24xNiA9IChfc3RlcDE2ID0gX2l0ZXJhdG9yMTYubmV4dCgpKS5kb25lKTsgX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjE2ID0gdHJ1ZSkge1xuICAgICAgICAgIHZhciBmaWxlID0gX3N0ZXAxNi52YWx1ZTtcbiAgICAgICAgICB0aGlzLmVucXVldWVGaWxlKGZpbGUpO1xuICAgICAgICB9XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgX2RpZEl0ZXJhdG9yRXJyb3IxNiA9IHRydWU7XG4gICAgICAgIF9pdGVyYXRvckVycm9yMTYgPSBlcnI7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGlmICghX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjE2ICYmIF9pdGVyYXRvcjE2W1wicmV0dXJuXCJdICE9IG51bGwpIHtcbiAgICAgICAgICAgIF9pdGVyYXRvcjE2W1wicmV0dXJuXCJdKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgIGlmIChfZGlkSXRlcmF0b3JFcnJvcjE2KSB7XG4gICAgICAgICAgICB0aHJvdyBfaXRlcmF0b3JFcnJvcjE2O1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiZW5xdWV1ZUZpbGVcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gZW5xdWV1ZUZpbGUoZmlsZSkge1xuICAgICAgdmFyIF90aGlzOCA9IHRoaXM7XG5cbiAgICAgIGlmIChmaWxlLnN0YXR1cyA9PT0gRHJvcHpvbmUuQURERUQgJiYgZmlsZS5hY2NlcHRlZCA9PT0gdHJ1ZSkge1xuICAgICAgICBmaWxlLnN0YXR1cyA9IERyb3B6b25lLlFVRVVFRDtcblxuICAgICAgICBpZiAodGhpcy5vcHRpb25zLmF1dG9Qcm9jZXNzUXVldWUpIHtcbiAgICAgICAgICByZXR1cm4gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gX3RoaXM4LnByb2Nlc3NRdWV1ZSgpO1xuICAgICAgICAgIH0sIDApOyAvLyBEZWZlcnJpbmcgdGhlIGNhbGxcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhpcyBmaWxlIGNhbid0IGJlIHF1ZXVlZCBiZWNhdXNlIGl0IGhhcyBhbHJlYWR5IGJlZW4gcHJvY2Vzc2VkIG9yIHdhcyByZWplY3RlZC5cIik7XG4gICAgICB9XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcIl9lbnF1ZXVlVGh1bWJuYWlsXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIF9lbnF1ZXVlVGh1bWJuYWlsKGZpbGUpIHtcbiAgICAgIHZhciBfdGhpczkgPSB0aGlzO1xuXG4gICAgICBpZiAodGhpcy5vcHRpb25zLmNyZWF0ZUltYWdlVGh1bWJuYWlscyAmJiBmaWxlLnR5cGUubWF0Y2goL2ltYWdlLiovKSAmJiBmaWxlLnNpemUgPD0gdGhpcy5vcHRpb25zLm1heFRodW1ibmFpbEZpbGVzaXplICogMTAyNCAqIDEwMjQpIHtcbiAgICAgICAgdGhpcy5fdGh1bWJuYWlsUXVldWUucHVzaChmaWxlKTtcblxuICAgICAgICByZXR1cm4gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgcmV0dXJuIF90aGlzOS5fcHJvY2Vzc1RodW1ibmFpbFF1ZXVlKCk7XG4gICAgICAgIH0sIDApOyAvLyBEZWZlcnJpbmcgdGhlIGNhbGxcbiAgICAgIH1cbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiX3Byb2Nlc3NUaHVtYm5haWxRdWV1ZVwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBfcHJvY2Vzc1RodW1ibmFpbFF1ZXVlKCkge1xuICAgICAgdmFyIF90aGlzMTAgPSB0aGlzO1xuXG4gICAgICBpZiAodGhpcy5fcHJvY2Vzc2luZ1RodW1ibmFpbCB8fCB0aGlzLl90aHVtYm5haWxRdWV1ZS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB0aGlzLl9wcm9jZXNzaW5nVGh1bWJuYWlsID0gdHJ1ZTtcblxuICAgICAgdmFyIGZpbGUgPSB0aGlzLl90aHVtYm5haWxRdWV1ZS5zaGlmdCgpO1xuXG4gICAgICByZXR1cm4gdGhpcy5jcmVhdGVUaHVtYm5haWwoZmlsZSwgdGhpcy5vcHRpb25zLnRodW1ibmFpbFdpZHRoLCB0aGlzLm9wdGlvbnMudGh1bWJuYWlsSGVpZ2h0LCB0aGlzLm9wdGlvbnMudGh1bWJuYWlsTWV0aG9kLCB0cnVlLCBmdW5jdGlvbiAoZGF0YVVybCkge1xuICAgICAgICBfdGhpczEwLmVtaXQoXCJ0aHVtYm5haWxcIiwgZmlsZSwgZGF0YVVybCk7XG5cbiAgICAgICAgX3RoaXMxMC5fcHJvY2Vzc2luZ1RodW1ibmFpbCA9IGZhbHNlO1xuICAgICAgICByZXR1cm4gX3RoaXMxMC5fcHJvY2Vzc1RodW1ibmFpbFF1ZXVlKCk7XG4gICAgICB9KTtcbiAgICB9IC8vIENhbiBiZSBjYWxsZWQgYnkgdGhlIHVzZXIgdG8gcmVtb3ZlIGEgZmlsZVxuXG4gIH0sIHtcbiAgICBrZXk6IFwicmVtb3ZlRmlsZVwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiByZW1vdmVGaWxlKGZpbGUpIHtcbiAgICAgIGlmIChmaWxlLnN0YXR1cyA9PT0gRHJvcHpvbmUuVVBMT0FESU5HKSB7XG4gICAgICAgIHRoaXMuY2FuY2VsVXBsb2FkKGZpbGUpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLmZpbGVzID0gd2l0aG91dCh0aGlzLmZpbGVzLCBmaWxlKTtcbiAgICAgIHRoaXMuZW1pdChcInJlbW92ZWRmaWxlXCIsIGZpbGUpO1xuXG4gICAgICBpZiAodGhpcy5maWxlcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW1pdChcInJlc2V0XCIpO1xuICAgICAgfVxuICAgIH0gLy8gUmVtb3ZlcyBhbGwgZmlsZXMgdGhhdCBhcmVuJ3QgY3VycmVudGx5IHByb2Nlc3NlZCBmcm9tIHRoZSBsaXN0XG5cbiAgfSwge1xuICAgIGtleTogXCJyZW1vdmVBbGxGaWxlc1wiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiByZW1vdmVBbGxGaWxlcyhjYW5jZWxJZk5lY2Vzc2FyeSkge1xuICAgICAgLy8gQ3JlYXRlIGEgY29weSBvZiBmaWxlcyBzaW5jZSByZW1vdmVGaWxlKCkgY2hhbmdlcyB0aGUgQGZpbGVzIGFycmF5LlxuICAgICAgaWYgKGNhbmNlbElmTmVjZXNzYXJ5ID09IG51bGwpIHtcbiAgICAgICAgY2FuY2VsSWZOZWNlc3NhcnkgPSBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgdmFyIF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24xNyA9IHRydWU7XG4gICAgICB2YXIgX2RpZEl0ZXJhdG9yRXJyb3IxNyA9IGZhbHNlO1xuICAgICAgdmFyIF9pdGVyYXRvckVycm9yMTcgPSB1bmRlZmluZWQ7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGZvciAodmFyIF9pdGVyYXRvcjE3ID0gdGhpcy5maWxlcy5zbGljZSgpW1N5bWJvbC5pdGVyYXRvcl0oKSwgX3N0ZXAxNzsgIShfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uMTcgPSAoX3N0ZXAxNyA9IF9pdGVyYXRvcjE3Lm5leHQoKSkuZG9uZSk7IF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24xNyA9IHRydWUpIHtcbiAgICAgICAgICB2YXIgZmlsZSA9IF9zdGVwMTcudmFsdWU7XG5cbiAgICAgICAgICBpZiAoZmlsZS5zdGF0dXMgIT09IERyb3B6b25lLlVQTE9BRElORyB8fCBjYW5jZWxJZk5lY2Vzc2FyeSkge1xuICAgICAgICAgICAgdGhpcy5yZW1vdmVGaWxlKGZpbGUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIF9kaWRJdGVyYXRvckVycm9yMTcgPSB0cnVlO1xuICAgICAgICBfaXRlcmF0b3JFcnJvcjE3ID0gZXJyO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBpZiAoIV9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24xNyAmJiBfaXRlcmF0b3IxN1tcInJldHVyblwiXSAhPSBudWxsKSB7XG4gICAgICAgICAgICBfaXRlcmF0b3IxN1tcInJldHVyblwiXSgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICBpZiAoX2RpZEl0ZXJhdG9yRXJyb3IxNykge1xuICAgICAgICAgICAgdGhyb3cgX2l0ZXJhdG9yRXJyb3IxNztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfSAvLyBSZXNpemVzIGFuIGltYWdlIGJlZm9yZSBpdCBnZXRzIHNlbnQgdG8gdGhlIHNlcnZlci4gVGhpcyBmdW5jdGlvbiBpcyB0aGUgZGVmYXVsdCBiZWhhdmlvciBvZlxuICAgIC8vIGBvcHRpb25zLnRyYW5zZm9ybUZpbGVgIGlmIGByZXNpemVXaWR0aGAgb3IgYHJlc2l6ZUhlaWdodGAgYXJlIHNldC4gVGhlIGNhbGxiYWNrIGlzIGludm9rZWQgd2l0aFxuICAgIC8vIHRoZSByZXNpemVkIGJsb2IuXG5cbiAgfSwge1xuICAgIGtleTogXCJyZXNpemVJbWFnZVwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiByZXNpemVJbWFnZShmaWxlLCB3aWR0aCwgaGVpZ2h0LCByZXNpemVNZXRob2QsIGNhbGxiYWNrKSB7XG4gICAgICB2YXIgX3RoaXMxMSA9IHRoaXM7XG5cbiAgICAgIHJldHVybiB0aGlzLmNyZWF0ZVRodW1ibmFpbChmaWxlLCB3aWR0aCwgaGVpZ2h0LCByZXNpemVNZXRob2QsIHRydWUsIGZ1bmN0aW9uIChkYXRhVXJsLCBjYW52YXMpIHtcbiAgICAgICAgaWYgKGNhbnZhcyA9PSBudWxsKSB7XG4gICAgICAgICAgLy8gVGhlIGltYWdlIGhhcyBub3QgYmVlbiByZXNpemVkXG4gICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKGZpbGUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZhciByZXNpemVNaW1lVHlwZSA9IF90aGlzMTEub3B0aW9ucy5yZXNpemVNaW1lVHlwZTtcblxuICAgICAgICAgIGlmIChyZXNpemVNaW1lVHlwZSA9PSBudWxsKSB7XG4gICAgICAgICAgICByZXNpemVNaW1lVHlwZSA9IGZpbGUudHlwZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB2YXIgcmVzaXplZERhdGFVUkwgPSBjYW52YXMudG9EYXRhVVJMKHJlc2l6ZU1pbWVUeXBlLCBfdGhpczExLm9wdGlvbnMucmVzaXplUXVhbGl0eSk7XG5cbiAgICAgICAgICBpZiAocmVzaXplTWltZVR5cGUgPT09ICdpbWFnZS9qcGVnJyB8fCByZXNpemVNaW1lVHlwZSA9PT0gJ2ltYWdlL2pwZycpIHtcbiAgICAgICAgICAgIC8vIE5vdyBhZGQgdGhlIG9yaWdpbmFsIEVYSUYgaW5mb3JtYXRpb25cbiAgICAgICAgICAgIHJlc2l6ZWREYXRhVVJMID0gRXhpZlJlc3RvcmUucmVzdG9yZShmaWxlLmRhdGFVUkwsIHJlc2l6ZWREYXRhVVJMKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gY2FsbGJhY2soRHJvcHpvbmUuZGF0YVVSSXRvQmxvYihyZXNpemVkRGF0YVVSTCkpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiY3JlYXRlVGh1bWJuYWlsXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGNyZWF0ZVRodW1ibmFpbChmaWxlLCB3aWR0aCwgaGVpZ2h0LCByZXNpemVNZXRob2QsIGZpeE9yaWVudGF0aW9uLCBjYWxsYmFjaykge1xuICAgICAgdmFyIF90aGlzMTIgPSB0aGlzO1xuXG4gICAgICB2YXIgZmlsZVJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7XG5cbiAgICAgIGZpbGVSZWFkZXIub25sb2FkID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBmaWxlLmRhdGFVUkwgPSBmaWxlUmVhZGVyLnJlc3VsdDsgLy8gRG9uJ3QgYm90aGVyIGNyZWF0aW5nIGEgdGh1bWJuYWlsIGZvciBTVkcgaW1hZ2VzIHNpbmNlIHRoZXkncmUgdmVjdG9yXG5cbiAgICAgICAgaWYgKGZpbGUudHlwZSA9PT0gXCJpbWFnZS9zdmcreG1sXCIpIHtcbiAgICAgICAgICBpZiAoY2FsbGJhY2sgIT0gbnVsbCkge1xuICAgICAgICAgICAgY2FsbGJhY2soZmlsZVJlYWRlci5yZXN1bHQpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIF90aGlzMTIuY3JlYXRlVGh1bWJuYWlsRnJvbVVybChmaWxlLCB3aWR0aCwgaGVpZ2h0LCByZXNpemVNZXRob2QsIGZpeE9yaWVudGF0aW9uLCBjYWxsYmFjayk7XG4gICAgICB9O1xuXG4gICAgICBmaWxlUmVhZGVyLnJlYWRBc0RhdGFVUkwoZmlsZSk7XG4gICAgfSAvLyBgbW9ja0ZpbGVgIG5lZWRzIHRvIGhhdmUgdGhlc2UgYXR0cmlidXRlczpcbiAgICAvLyBcbiAgICAvLyAgICAgeyBuYW1lOiAnbmFtZScsIHNpemU6IDEyMzQ1LCBpbWFnZVVybDogJycgfVxuICAgIC8vXG4gICAgLy8gYGNhbGxiYWNrYCB3aWxsIGJlIGludm9rZWQgd2hlbiB0aGUgaW1hZ2UgaGFzIGJlZW4gZG93bmxvYWRlZCBhbmQgZGlzcGxheWVkLlxuICAgIC8vIGBjcm9zc09yaWdpbmAgd2lsbCBiZSBhZGRlZCB0byB0aGUgYGltZ2AgdGFnIHdoZW4gYWNjZXNzaW5nIHRoZSBmaWxlLlxuXG4gIH0sIHtcbiAgICBrZXk6IFwiZGlzcGxheUV4aXN0aW5nRmlsZVwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBkaXNwbGF5RXhpc3RpbmdGaWxlKG1vY2tGaWxlLCBpbWFnZVVybCwgY2FsbGJhY2ssIGNyb3NzT3JpZ2luKSB7XG4gICAgICB2YXIgX3RoaXMxMyA9IHRoaXM7XG5cbiAgICAgIHZhciByZXNpemVUaHVtYm5haWwgPSBhcmd1bWVudHMubGVuZ3RoID4gNCAmJiBhcmd1bWVudHNbNF0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1s0XSA6IHRydWU7XG4gICAgICB0aGlzLmVtaXQoXCJhZGRlZGZpbGVcIiwgbW9ja0ZpbGUpO1xuICAgICAgdGhpcy5lbWl0KFwiY29tcGxldGVcIiwgbW9ja0ZpbGUpO1xuXG4gICAgICBpZiAoIXJlc2l6ZVRodW1ibmFpbCkge1xuICAgICAgICB0aGlzLmVtaXQoXCJ0aHVtYm5haWxcIiwgbW9ja0ZpbGUsIGltYWdlVXJsKTtcbiAgICAgICAgaWYgKGNhbGxiYWNrKSBjYWxsYmFjaygpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmFyIG9uRG9uZSA9IGZ1bmN0aW9uIG9uRG9uZSh0aHVtYm5haWwpIHtcbiAgICAgICAgICBfdGhpczEzLmVtaXQoJ3RodW1ibmFpbCcsIG1vY2tGaWxlLCB0aHVtYm5haWwpO1xuXG4gICAgICAgICAgaWYgKGNhbGxiYWNrKSBjYWxsYmFjaygpO1xuICAgICAgICB9O1xuXG4gICAgICAgIG1vY2tGaWxlLmRhdGFVUkwgPSBpbWFnZVVybDtcbiAgICAgICAgdGhpcy5jcmVhdGVUaHVtYm5haWxGcm9tVXJsKG1vY2tGaWxlLCB0aGlzLm9wdGlvbnMudGh1bWJuYWlsV2lkdGgsIHRoaXMub3B0aW9ucy50aHVtYm5haWxIZWlnaHQsIHRoaXMub3B0aW9ucy5yZXNpemVNZXRob2QsIHRoaXMub3B0aW9ucy5maXhPcmllbnRhdGlvbiwgb25Eb25lLCBjcm9zc09yaWdpbik7XG4gICAgICB9XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcImNyZWF0ZVRodW1ibmFpbEZyb21VcmxcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gY3JlYXRlVGh1bWJuYWlsRnJvbVVybChmaWxlLCB3aWR0aCwgaGVpZ2h0LCByZXNpemVNZXRob2QsIGZpeE9yaWVudGF0aW9uLCBjYWxsYmFjaywgY3Jvc3NPcmlnaW4pIHtcbiAgICAgIHZhciBfdGhpczE0ID0gdGhpcztcblxuICAgICAgLy8gTm90IHVzaW5nIGBuZXcgSW1hZ2VgIGhlcmUgYmVjYXVzZSBvZiBhIGJ1ZyBpbiBsYXRlc3QgQ2hyb21lIHZlcnNpb25zLlxuICAgICAgLy8gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9lbnlvL2Ryb3B6b25lL3B1bGwvMjI2XG4gICAgICB2YXIgaW1nID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImltZ1wiKTtcblxuICAgICAgaWYgKGNyb3NzT3JpZ2luKSB7XG4gICAgICAgIGltZy5jcm9zc09yaWdpbiA9IGNyb3NzT3JpZ2luO1xuICAgICAgfVxuXG4gICAgICBpbWcub25sb2FkID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgbG9hZEV4aWYgPSBmdW5jdGlvbiBsb2FkRXhpZihjYWxsYmFjaykge1xuICAgICAgICAgIHJldHVybiBjYWxsYmFjaygxKTtcbiAgICAgICAgfTtcblxuICAgICAgICBpZiAodHlwZW9mIEVYSUYgIT09ICd1bmRlZmluZWQnICYmIEVYSUYgIT09IG51bGwgJiYgZml4T3JpZW50YXRpb24pIHtcbiAgICAgICAgICBsb2FkRXhpZiA9IGZ1bmN0aW9uIGxvYWRFeGlmKGNhbGxiYWNrKSB7XG4gICAgICAgICAgICByZXR1cm4gRVhJRi5nZXREYXRhKGltZywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICByZXR1cm4gY2FsbGJhY2soRVhJRi5nZXRUYWcodGhpcywgJ09yaWVudGF0aW9uJykpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBsb2FkRXhpZihmdW5jdGlvbiAob3JpZW50YXRpb24pIHtcbiAgICAgICAgICBmaWxlLndpZHRoID0gaW1nLndpZHRoO1xuICAgICAgICAgIGZpbGUuaGVpZ2h0ID0gaW1nLmhlaWdodDtcblxuICAgICAgICAgIHZhciByZXNpemVJbmZvID0gX3RoaXMxNC5vcHRpb25zLnJlc2l6ZS5jYWxsKF90aGlzMTQsIGZpbGUsIHdpZHRoLCBoZWlnaHQsIHJlc2l6ZU1ldGhvZCk7XG5cbiAgICAgICAgICB2YXIgY2FudmFzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImNhbnZhc1wiKTtcbiAgICAgICAgICB2YXIgY3R4ID0gY2FudmFzLmdldENvbnRleHQoXCIyZFwiKTtcbiAgICAgICAgICBjYW52YXMud2lkdGggPSByZXNpemVJbmZvLnRyZ1dpZHRoO1xuICAgICAgICAgIGNhbnZhcy5oZWlnaHQgPSByZXNpemVJbmZvLnRyZ0hlaWdodDtcblxuICAgICAgICAgIGlmIChvcmllbnRhdGlvbiA+IDQpIHtcbiAgICAgICAgICAgIGNhbnZhcy53aWR0aCA9IHJlc2l6ZUluZm8udHJnSGVpZ2h0O1xuICAgICAgICAgICAgY2FudmFzLmhlaWdodCA9IHJlc2l6ZUluZm8udHJnV2lkdGg7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgc3dpdGNoIChvcmllbnRhdGlvbikge1xuICAgICAgICAgICAgY2FzZSAyOlxuICAgICAgICAgICAgICAvLyBob3Jpem9udGFsIGZsaXBcbiAgICAgICAgICAgICAgY3R4LnRyYW5zbGF0ZShjYW52YXMud2lkdGgsIDApO1xuICAgICAgICAgICAgICBjdHguc2NhbGUoLTEsIDEpO1xuICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgY2FzZSAzOlxuICAgICAgICAgICAgICAvLyAxODDCsCByb3RhdGUgbGVmdFxuICAgICAgICAgICAgICBjdHgudHJhbnNsYXRlKGNhbnZhcy53aWR0aCwgY2FudmFzLmhlaWdodCk7XG4gICAgICAgICAgICAgIGN0eC5yb3RhdGUoTWF0aC5QSSk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgICBjYXNlIDQ6XG4gICAgICAgICAgICAgIC8vIHZlcnRpY2FsIGZsaXBcbiAgICAgICAgICAgICAgY3R4LnRyYW5zbGF0ZSgwLCBjYW52YXMuaGVpZ2h0KTtcbiAgICAgICAgICAgICAgY3R4LnNjYWxlKDEsIC0xKTtcbiAgICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICAgIGNhc2UgNTpcbiAgICAgICAgICAgICAgLy8gdmVydGljYWwgZmxpcCArIDkwIHJvdGF0ZSByaWdodFxuICAgICAgICAgICAgICBjdHgucm90YXRlKDAuNSAqIE1hdGguUEkpO1xuICAgICAgICAgICAgICBjdHguc2NhbGUoMSwgLTEpO1xuICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgY2FzZSA2OlxuICAgICAgICAgICAgICAvLyA5MMKwIHJvdGF0ZSByaWdodFxuICAgICAgICAgICAgICBjdHgucm90YXRlKDAuNSAqIE1hdGguUEkpO1xuICAgICAgICAgICAgICBjdHgudHJhbnNsYXRlKDAsIC1jYW52YXMud2lkdGgpO1xuICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgY2FzZSA3OlxuICAgICAgICAgICAgICAvLyBob3Jpem9udGFsIGZsaXAgKyA5MCByb3RhdGUgcmlnaHRcbiAgICAgICAgICAgICAgY3R4LnJvdGF0ZSgwLjUgKiBNYXRoLlBJKTtcbiAgICAgICAgICAgICAgY3R4LnRyYW5zbGF0ZShjYW52YXMuaGVpZ2h0LCAtY2FudmFzLndpZHRoKTtcbiAgICAgICAgICAgICAgY3R4LnNjYWxlKC0xLCAxKTtcbiAgICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICAgIGNhc2UgODpcbiAgICAgICAgICAgICAgLy8gOTDCsCByb3RhdGUgbGVmdFxuICAgICAgICAgICAgICBjdHgucm90YXRlKC0wLjUgKiBNYXRoLlBJKTtcbiAgICAgICAgICAgICAgY3R4LnRyYW5zbGF0ZSgtY2FudmFzLmhlaWdodCwgMCk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH0gLy8gVGhpcyBpcyBhIGJ1Z2ZpeCBmb3IgaU9TJyBzY2FsaW5nIGJ1Zy5cblxuXG4gICAgICAgICAgZHJhd0ltYWdlSU9TRml4KGN0eCwgaW1nLCByZXNpemVJbmZvLnNyY1ggIT0gbnVsbCA/IHJlc2l6ZUluZm8uc3JjWCA6IDAsIHJlc2l6ZUluZm8uc3JjWSAhPSBudWxsID8gcmVzaXplSW5mby5zcmNZIDogMCwgcmVzaXplSW5mby5zcmNXaWR0aCwgcmVzaXplSW5mby5zcmNIZWlnaHQsIHJlc2l6ZUluZm8udHJnWCAhPSBudWxsID8gcmVzaXplSW5mby50cmdYIDogMCwgcmVzaXplSW5mby50cmdZICE9IG51bGwgPyByZXNpemVJbmZvLnRyZ1kgOiAwLCByZXNpemVJbmZvLnRyZ1dpZHRoLCByZXNpemVJbmZvLnRyZ0hlaWdodCk7XG4gICAgICAgICAgdmFyIHRodW1ibmFpbCA9IGNhbnZhcy50b0RhdGFVUkwoXCJpbWFnZS9wbmdcIik7XG5cbiAgICAgICAgICBpZiAoY2FsbGJhY2sgIT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKHRodW1ibmFpbCwgY2FudmFzKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfTtcblxuICAgICAgaWYgKGNhbGxiYWNrICE9IG51bGwpIHtcbiAgICAgICAgaW1nLm9uZXJyb3IgPSBjYWxsYmFjaztcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGltZy5zcmMgPSBmaWxlLmRhdGFVUkw7XG4gICAgfSAvLyBHb2VzIHRocm91Z2ggdGhlIHF1ZXVlIGFuZCBwcm9jZXNzZXMgZmlsZXMgaWYgdGhlcmUgYXJlbid0IHRvbyBtYW55IGFscmVhZHkuXG5cbiAgfSwge1xuICAgIGtleTogXCJwcm9jZXNzUXVldWVcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gcHJvY2Vzc1F1ZXVlKCkge1xuICAgICAgdmFyIHBhcmFsbGVsVXBsb2FkcyA9IHRoaXMub3B0aW9ucy5wYXJhbGxlbFVwbG9hZHM7XG4gICAgICB2YXIgcHJvY2Vzc2luZ0xlbmd0aCA9IHRoaXMuZ2V0VXBsb2FkaW5nRmlsZXMoKS5sZW5ndGg7XG4gICAgICB2YXIgaSA9IHByb2Nlc3NpbmdMZW5ndGg7IC8vIFRoZXJlIGFyZSBhbHJlYWR5IGF0IGxlYXN0IGFzIG1hbnkgZmlsZXMgdXBsb2FkaW5nIHRoYW4gc2hvdWxkIGJlXG5cbiAgICAgIGlmIChwcm9jZXNzaW5nTGVuZ3RoID49IHBhcmFsbGVsVXBsb2Fkcykge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHZhciBxdWV1ZWRGaWxlcyA9IHRoaXMuZ2V0UXVldWVkRmlsZXMoKTtcblxuICAgICAgaWYgKCEocXVldWVkRmlsZXMubGVuZ3RoID4gMCkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5vcHRpb25zLnVwbG9hZE11bHRpcGxlKSB7XG4gICAgICAgIC8vIFRoZSBmaWxlcyBzaG91bGQgYmUgdXBsb2FkZWQgaW4gb25lIHJlcXVlc3RcbiAgICAgICAgcmV0dXJuIHRoaXMucHJvY2Vzc0ZpbGVzKHF1ZXVlZEZpbGVzLnNsaWNlKDAsIHBhcmFsbGVsVXBsb2FkcyAtIHByb2Nlc3NpbmdMZW5ndGgpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHdoaWxlIChpIDwgcGFyYWxsZWxVcGxvYWRzKSB7XG4gICAgICAgICAgaWYgKCFxdWV1ZWRGaWxlcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9IC8vIE5vdGhpbmcgbGVmdCB0byBwcm9jZXNzXG5cblxuICAgICAgICAgIHRoaXMucHJvY2Vzc0ZpbGUocXVldWVkRmlsZXMuc2hpZnQoKSk7XG4gICAgICAgICAgaSsrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSAvLyBXcmFwcGVyIGZvciBgcHJvY2Vzc0ZpbGVzYFxuXG4gIH0sIHtcbiAgICBrZXk6IFwicHJvY2Vzc0ZpbGVcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gcHJvY2Vzc0ZpbGUoZmlsZSkge1xuICAgICAgcmV0dXJuIHRoaXMucHJvY2Vzc0ZpbGVzKFtmaWxlXSk7XG4gICAgfSAvLyBMb2FkcyB0aGUgZmlsZSwgdGhlbiBjYWxscyBmaW5pc2hlZExvYWRpbmcoKVxuXG4gIH0sIHtcbiAgICBrZXk6IFwicHJvY2Vzc0ZpbGVzXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHByb2Nlc3NGaWxlcyhmaWxlcykge1xuICAgICAgdmFyIF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24xOCA9IHRydWU7XG4gICAgICB2YXIgX2RpZEl0ZXJhdG9yRXJyb3IxOCA9IGZhbHNlO1xuICAgICAgdmFyIF9pdGVyYXRvckVycm9yMTggPSB1bmRlZmluZWQ7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGZvciAodmFyIF9pdGVyYXRvcjE4ID0gZmlsZXNbU3ltYm9sLml0ZXJhdG9yXSgpLCBfc3RlcDE4OyAhKF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24xOCA9IChfc3RlcDE4ID0gX2l0ZXJhdG9yMTgubmV4dCgpKS5kb25lKTsgX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjE4ID0gdHJ1ZSkge1xuICAgICAgICAgIHZhciBmaWxlID0gX3N0ZXAxOC52YWx1ZTtcbiAgICAgICAgICBmaWxlLnByb2Nlc3NpbmcgPSB0cnVlOyAvLyBCYWNrd2FyZHMgY29tcGF0aWJpbGl0eVxuXG4gICAgICAgICAgZmlsZS5zdGF0dXMgPSBEcm9wem9uZS5VUExPQURJTkc7XG4gICAgICAgICAgdGhpcy5lbWl0KFwicHJvY2Vzc2luZ1wiLCBmaWxlKTtcbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIF9kaWRJdGVyYXRvckVycm9yMTggPSB0cnVlO1xuICAgICAgICBfaXRlcmF0b3JFcnJvcjE4ID0gZXJyO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBpZiAoIV9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24xOCAmJiBfaXRlcmF0b3IxOFtcInJldHVyblwiXSAhPSBudWxsKSB7XG4gICAgICAgICAgICBfaXRlcmF0b3IxOFtcInJldHVyblwiXSgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICBpZiAoX2RpZEl0ZXJhdG9yRXJyb3IxOCkge1xuICAgICAgICAgICAgdGhyb3cgX2l0ZXJhdG9yRXJyb3IxODtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMub3B0aW9ucy51cGxvYWRNdWx0aXBsZSkge1xuICAgICAgICB0aGlzLmVtaXQoXCJwcm9jZXNzaW5nbXVsdGlwbGVcIiwgZmlsZXMpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcy51cGxvYWRGaWxlcyhmaWxlcyk7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcIl9nZXRGaWxlc1dpdGhYaHJcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gX2dldEZpbGVzV2l0aFhocih4aHIpIHtcbiAgICAgIHZhciBmaWxlcztcbiAgICAgIHJldHVybiBmaWxlcyA9IHRoaXMuZmlsZXMuZmlsdGVyKGZ1bmN0aW9uIChmaWxlKSB7XG4gICAgICAgIHJldHVybiBmaWxlLnhociA9PT0geGhyO1xuICAgICAgfSkubWFwKGZ1bmN0aW9uIChmaWxlKSB7XG4gICAgICAgIHJldHVybiBmaWxlO1xuICAgICAgfSk7XG4gICAgfSAvLyBDYW5jZWxzIHRoZSBmaWxlIHVwbG9hZCBhbmQgc2V0cyB0aGUgc3RhdHVzIHRvIENBTkNFTEVEXG4gICAgLy8gKippZioqIHRoZSBmaWxlIGlzIGFjdHVhbGx5IGJlaW5nIHVwbG9hZGVkLlxuICAgIC8vIElmIGl0J3Mgc3RpbGwgaW4gdGhlIHF1ZXVlLCB0aGUgZmlsZSBpcyBiZWluZyByZW1vdmVkIGZyb20gaXQgYW5kIHRoZSBzdGF0dXNcbiAgICAvLyBzZXQgdG8gQ0FOQ0VMRUQuXG5cbiAgfSwge1xuICAgIGtleTogXCJjYW5jZWxVcGxvYWRcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gY2FuY2VsVXBsb2FkKGZpbGUpIHtcbiAgICAgIGlmIChmaWxlLnN0YXR1cyA9PT0gRHJvcHpvbmUuVVBMT0FESU5HKSB7XG4gICAgICAgIHZhciBncm91cGVkRmlsZXMgPSB0aGlzLl9nZXRGaWxlc1dpdGhYaHIoZmlsZS54aHIpO1xuXG4gICAgICAgIHZhciBfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uMTkgPSB0cnVlO1xuICAgICAgICB2YXIgX2RpZEl0ZXJhdG9yRXJyb3IxOSA9IGZhbHNlO1xuICAgICAgICB2YXIgX2l0ZXJhdG9yRXJyb3IxOSA9IHVuZGVmaW5lZDtcblxuICAgICAgICB0cnkge1xuICAgICAgICAgIGZvciAodmFyIF9pdGVyYXRvcjE5ID0gZ3JvdXBlZEZpbGVzW1N5bWJvbC5pdGVyYXRvcl0oKSwgX3N0ZXAxOTsgIShfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uMTkgPSAoX3N0ZXAxOSA9IF9pdGVyYXRvcjE5Lm5leHQoKSkuZG9uZSk7IF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24xOSA9IHRydWUpIHtcbiAgICAgICAgICAgIHZhciBncm91cGVkRmlsZSA9IF9zdGVwMTkudmFsdWU7XG4gICAgICAgICAgICBncm91cGVkRmlsZS5zdGF0dXMgPSBEcm9wem9uZS5DQU5DRUxFRDtcbiAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgIF9kaWRJdGVyYXRvckVycm9yMTkgPSB0cnVlO1xuICAgICAgICAgIF9pdGVyYXRvckVycm9yMTkgPSBlcnI7XG4gICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGlmICghX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjE5ICYmIF9pdGVyYXRvcjE5W1wicmV0dXJuXCJdICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgX2l0ZXJhdG9yMTlbXCJyZXR1cm5cIl0oKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgICAgaWYgKF9kaWRJdGVyYXRvckVycm9yMTkpIHtcbiAgICAgICAgICAgICAgdGhyb3cgX2l0ZXJhdG9yRXJyb3IxOTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIGZpbGUueGhyICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgIGZpbGUueGhyLmFib3J0KCk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjIwID0gdHJ1ZTtcbiAgICAgICAgdmFyIF9kaWRJdGVyYXRvckVycm9yMjAgPSBmYWxzZTtcbiAgICAgICAgdmFyIF9pdGVyYXRvckVycm9yMjAgPSB1bmRlZmluZWQ7XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBmb3IgKHZhciBfaXRlcmF0b3IyMCA9IGdyb3VwZWRGaWxlc1tTeW1ib2wuaXRlcmF0b3JdKCksIF9zdGVwMjA7ICEoX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjIwID0gKF9zdGVwMjAgPSBfaXRlcmF0b3IyMC5uZXh0KCkpLmRvbmUpOyBfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uMjAgPSB0cnVlKSB7XG4gICAgICAgICAgICB2YXIgX2dyb3VwZWRGaWxlID0gX3N0ZXAyMC52YWx1ZTtcbiAgICAgICAgICAgIHRoaXMuZW1pdChcImNhbmNlbGVkXCIsIF9ncm91cGVkRmlsZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICBfZGlkSXRlcmF0b3JFcnJvcjIwID0gdHJ1ZTtcbiAgICAgICAgICBfaXRlcmF0b3JFcnJvcjIwID0gZXJyO1xuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBpZiAoIV9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24yMCAmJiBfaXRlcmF0b3IyMFtcInJldHVyblwiXSAhPSBudWxsKSB7XG4gICAgICAgICAgICAgIF9pdGVyYXRvcjIwW1wicmV0dXJuXCJdKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgIGlmIChfZGlkSXRlcmF0b3JFcnJvcjIwKSB7XG4gICAgICAgICAgICAgIHRocm93IF9pdGVyYXRvckVycm9yMjA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy51cGxvYWRNdWx0aXBsZSkge1xuICAgICAgICAgIHRoaXMuZW1pdChcImNhbmNlbGVkbXVsdGlwbGVcIiwgZ3JvdXBlZEZpbGVzKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChmaWxlLnN0YXR1cyA9PT0gRHJvcHpvbmUuQURERUQgfHwgZmlsZS5zdGF0dXMgPT09IERyb3B6b25lLlFVRVVFRCkge1xuICAgICAgICBmaWxlLnN0YXR1cyA9IERyb3B6b25lLkNBTkNFTEVEO1xuICAgICAgICB0aGlzLmVtaXQoXCJjYW5jZWxlZFwiLCBmaWxlKTtcblxuICAgICAgICBpZiAodGhpcy5vcHRpb25zLnVwbG9hZE11bHRpcGxlKSB7XG4gICAgICAgICAgdGhpcy5lbWl0KFwiY2FuY2VsZWRtdWx0aXBsZVwiLCBbZmlsZV0pO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLm9wdGlvbnMuYXV0b1Byb2Nlc3NRdWV1ZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5wcm9jZXNzUXVldWUoKTtcbiAgICAgIH1cbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwicmVzb2x2ZU9wdGlvblwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiByZXNvbHZlT3B0aW9uKG9wdGlvbikge1xuICAgICAgaWYgKHR5cGVvZiBvcHRpb24gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgZm9yICh2YXIgX2xlbjMgPSBhcmd1bWVudHMubGVuZ3RoLCBhcmdzID0gbmV3IEFycmF5KF9sZW4zID4gMSA/IF9sZW4zIC0gMSA6IDApLCBfa2V5MyA9IDE7IF9rZXkzIDwgX2xlbjM7IF9rZXkzKyspIHtcbiAgICAgICAgICBhcmdzW19rZXkzIC0gMV0gPSBhcmd1bWVudHNbX2tleTNdO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG9wdGlvbi5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIG9wdGlvbjtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwidXBsb2FkRmlsZVwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiB1cGxvYWRGaWxlKGZpbGUpIHtcbiAgICAgIHJldHVybiB0aGlzLnVwbG9hZEZpbGVzKFtmaWxlXSk7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcInVwbG9hZEZpbGVzXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHVwbG9hZEZpbGVzKGZpbGVzKSB7XG4gICAgICB2YXIgX3RoaXMxNSA9IHRoaXM7XG5cbiAgICAgIHRoaXMuX3RyYW5zZm9ybUZpbGVzKGZpbGVzLCBmdW5jdGlvbiAodHJhbnNmb3JtZWRGaWxlcykge1xuICAgICAgICBpZiAoX3RoaXMxNS5vcHRpb25zLmNodW5raW5nKSB7XG4gICAgICAgICAgLy8gQ2h1bmtpbmcgaXMgbm90IGFsbG93ZWQgdG8gYmUgdXNlZCB3aXRoIGB1cGxvYWRNdWx0aXBsZWAgc28gd2Uga25vd1xuICAgICAgICAgIC8vIHRoYXQgdGhlcmUgaXMgb25seSBfX29uZV9fZmlsZS5cbiAgICAgICAgICB2YXIgdHJhbnNmb3JtZWRGaWxlID0gdHJhbnNmb3JtZWRGaWxlc1swXTtcbiAgICAgICAgICBmaWxlc1swXS51cGxvYWQuY2h1bmtlZCA9IF90aGlzMTUub3B0aW9ucy5jaHVua2luZyAmJiAoX3RoaXMxNS5vcHRpb25zLmZvcmNlQ2h1bmtpbmcgfHwgdHJhbnNmb3JtZWRGaWxlLnNpemUgPiBfdGhpczE1Lm9wdGlvbnMuY2h1bmtTaXplKTtcbiAgICAgICAgICBmaWxlc1swXS51cGxvYWQudG90YWxDaHVua0NvdW50ID0gTWF0aC5jZWlsKHRyYW5zZm9ybWVkRmlsZS5zaXplIC8gX3RoaXMxNS5vcHRpb25zLmNodW5rU2l6ZSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZmlsZXNbMF0udXBsb2FkLmNodW5rZWQpIHtcbiAgICAgICAgICAvLyBUaGlzIGZpbGUgc2hvdWxkIGJlIHNlbnQgaW4gY2h1bmtzIVxuICAgICAgICAgIC8vIElmIHRoZSBjaHVua2luZyBvcHRpb24gaXMgc2V0LCB3ZSAqKmtub3cqKiB0aGF0IHRoZXJlIGNhbiBvbmx5IGJlICoqb25lKiogZmlsZSwgc2luY2VcbiAgICAgICAgICAvLyB1cGxvYWRNdWx0aXBsZSBpcyBub3QgYWxsb3dlZCB3aXRoIHRoaXMgb3B0aW9uLlxuICAgICAgICAgIHZhciBmaWxlID0gZmlsZXNbMF07XG4gICAgICAgICAgdmFyIF90cmFuc2Zvcm1lZEZpbGUgPSB0cmFuc2Zvcm1lZEZpbGVzWzBdO1xuICAgICAgICAgIHZhciBzdGFydGVkQ2h1bmtDb3VudCA9IDA7XG4gICAgICAgICAgZmlsZS51cGxvYWQuY2h1bmtzID0gW107XG5cbiAgICAgICAgICB2YXIgaGFuZGxlTmV4dENodW5rID0gZnVuY3Rpb24gaGFuZGxlTmV4dENodW5rKCkge1xuICAgICAgICAgICAgdmFyIGNodW5rSW5kZXggPSAwOyAvLyBGaW5kIHRoZSBuZXh0IGl0ZW0gaW4gZmlsZS51cGxvYWQuY2h1bmtzIHRoYXQgaXMgbm90IGRlZmluZWQgeWV0LlxuXG4gICAgICAgICAgICB3aGlsZSAoZmlsZS51cGxvYWQuY2h1bmtzW2NodW5rSW5kZXhdICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgY2h1bmtJbmRleCsrO1xuICAgICAgICAgICAgfSAvLyBUaGlzIG1lYW5zLCB0aGF0IGFsbCBjaHVua3MgaGF2ZSBhbHJlYWR5IGJlZW4gc3RhcnRlZC5cblxuXG4gICAgICAgICAgICBpZiAoY2h1bmtJbmRleCA+PSBmaWxlLnVwbG9hZC50b3RhbENodW5rQ291bnQpIHJldHVybjtcbiAgICAgICAgICAgIHN0YXJ0ZWRDaHVua0NvdW50Kys7XG4gICAgICAgICAgICB2YXIgc3RhcnQgPSBjaHVua0luZGV4ICogX3RoaXMxNS5vcHRpb25zLmNodW5rU2l6ZTtcbiAgICAgICAgICAgIHZhciBlbmQgPSBNYXRoLm1pbihzdGFydCArIF90aGlzMTUub3B0aW9ucy5jaHVua1NpemUsIGZpbGUuc2l6ZSk7XG4gICAgICAgICAgICB2YXIgZGF0YUJsb2NrID0ge1xuICAgICAgICAgICAgICBuYW1lOiBfdGhpczE1Ll9nZXRQYXJhbU5hbWUoMCksXG4gICAgICAgICAgICAgIGRhdGE6IF90cmFuc2Zvcm1lZEZpbGUud2Via2l0U2xpY2UgPyBfdHJhbnNmb3JtZWRGaWxlLndlYmtpdFNsaWNlKHN0YXJ0LCBlbmQpIDogX3RyYW5zZm9ybWVkRmlsZS5zbGljZShzdGFydCwgZW5kKSxcbiAgICAgICAgICAgICAgZmlsZW5hbWU6IGZpbGUudXBsb2FkLmZpbGVuYW1lLFxuICAgICAgICAgICAgICBjaHVua0luZGV4OiBjaHVua0luZGV4XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgZmlsZS51cGxvYWQuY2h1bmtzW2NodW5rSW5kZXhdID0ge1xuICAgICAgICAgICAgICBmaWxlOiBmaWxlLFxuICAgICAgICAgICAgICBpbmRleDogY2h1bmtJbmRleCxcbiAgICAgICAgICAgICAgZGF0YUJsb2NrOiBkYXRhQmxvY2ssXG4gICAgICAgICAgICAgIC8vIEluIGNhc2Ugd2Ugd2FudCB0byByZXRyeS5cbiAgICAgICAgICAgICAgc3RhdHVzOiBEcm9wem9uZS5VUExPQURJTkcsXG4gICAgICAgICAgICAgIHByb2dyZXNzOiAwLFxuICAgICAgICAgICAgICByZXRyaWVzOiAwIC8vIFRoZSBudW1iZXIgb2YgdGltZXMgdGhpcyBibG9jayBoYXMgYmVlbiByZXRyaWVkLlxuXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBfdGhpczE1Ll91cGxvYWREYXRhKGZpbGVzLCBbZGF0YUJsb2NrXSk7XG4gICAgICAgICAgfTtcblxuICAgICAgICAgIGZpbGUudXBsb2FkLmZpbmlzaGVkQ2h1bmtVcGxvYWQgPSBmdW5jdGlvbiAoY2h1bmspIHtcbiAgICAgICAgICAgIHZhciBhbGxGaW5pc2hlZCA9IHRydWU7XG4gICAgICAgICAgICBjaHVuay5zdGF0dXMgPSBEcm9wem9uZS5TVUNDRVNTOyAvLyBDbGVhciB0aGUgZGF0YSBmcm9tIHRoZSBjaHVua1xuXG4gICAgICAgICAgICBjaHVuay5kYXRhQmxvY2sgPSBudWxsOyAvLyBMZWF2aW5nIHRoaXMgcmVmZXJlbmNlIHRvIHhociBpbnRhY3QgaGVyZSB3aWxsIGNhdXNlIG1lbW9yeSBsZWFrcyBpbiBzb21lIGJyb3dzZXJzXG5cbiAgICAgICAgICAgIGNodW5rLnhociA9IG51bGw7XG5cbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZmlsZS51cGxvYWQudG90YWxDaHVua0NvdW50OyBpKyspIHtcbiAgICAgICAgICAgICAgaWYgKGZpbGUudXBsb2FkLmNodW5rc1tpXSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGhhbmRsZU5leHRDaHVuaygpO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgaWYgKGZpbGUudXBsb2FkLmNodW5rc1tpXS5zdGF0dXMgIT09IERyb3B6b25lLlNVQ0NFU1MpIHtcbiAgICAgICAgICAgICAgICBhbGxGaW5pc2hlZCA9IGZhbHNlO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChhbGxGaW5pc2hlZCkge1xuICAgICAgICAgICAgICBfdGhpczE1Lm9wdGlvbnMuY2h1bmtzVXBsb2FkZWQoZmlsZSwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIF90aGlzMTUuX2ZpbmlzaGVkKGZpbGVzLCAnJywgbnVsbCk7XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH07XG5cbiAgICAgICAgICBpZiAoX3RoaXMxNS5vcHRpb25zLnBhcmFsbGVsQ2h1bmtVcGxvYWRzKSB7XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGZpbGUudXBsb2FkLnRvdGFsQ2h1bmtDb3VudDsgaSsrKSB7XG4gICAgICAgICAgICAgIGhhbmRsZU5leHRDaHVuaygpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBoYW5kbGVOZXh0Q2h1bmsoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdmFyIGRhdGFCbG9ja3MgPSBbXTtcblxuICAgICAgICAgIGZvciAodmFyIF9pMyA9IDA7IF9pMyA8IGZpbGVzLmxlbmd0aDsgX2kzKyspIHtcbiAgICAgICAgICAgIGRhdGFCbG9ja3NbX2kzXSA9IHtcbiAgICAgICAgICAgICAgbmFtZTogX3RoaXMxNS5fZ2V0UGFyYW1OYW1lKF9pMyksXG4gICAgICAgICAgICAgIGRhdGE6IHRyYW5zZm9ybWVkRmlsZXNbX2kzXSxcbiAgICAgICAgICAgICAgZmlsZW5hbWU6IGZpbGVzW19pM10udXBsb2FkLmZpbGVuYW1lXG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH1cblxuICAgICAgICAgIF90aGlzMTUuX3VwbG9hZERhdGEoZmlsZXMsIGRhdGFCbG9ja3MpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9IC8vLyBSZXR1cm5zIHRoZSByaWdodCBjaHVuayBmb3IgZ2l2ZW4gZmlsZSBhbmQgeGhyXG5cbiAgfSwge1xuICAgIGtleTogXCJfZ2V0Q2h1bmtcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gX2dldENodW5rKGZpbGUsIHhocikge1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBmaWxlLnVwbG9hZC50b3RhbENodW5rQ291bnQ7IGkrKykge1xuICAgICAgICBpZiAoZmlsZS51cGxvYWQuY2h1bmtzW2ldICE9PSB1bmRlZmluZWQgJiYgZmlsZS51cGxvYWQuY2h1bmtzW2ldLnhociA9PT0geGhyKSB7XG4gICAgICAgICAgcmV0dXJuIGZpbGUudXBsb2FkLmNodW5rc1tpXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gLy8gVGhpcyBmdW5jdGlvbiBhY3R1YWxseSB1cGxvYWRzIHRoZSBmaWxlKHMpIHRvIHRoZSBzZXJ2ZXIuXG4gICAgLy8gSWYgZGF0YUJsb2NrcyBjb250YWlucyB0aGUgYWN0dWFsIGRhdGEgdG8gdXBsb2FkIChtZWFuaW5nLCB0aGF0IHRoaXMgY291bGQgZWl0aGVyIGJlIHRyYW5zZm9ybWVkXG4gICAgLy8gZmlsZXMsIG9yIGluZGl2aWR1YWwgY2h1bmtzIGZvciBjaHVua2VkIHVwbG9hZCkuXG5cbiAgfSwge1xuICAgIGtleTogXCJfdXBsb2FkRGF0YVwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBfdXBsb2FkRGF0YShmaWxlcywgZGF0YUJsb2Nrcykge1xuICAgICAgdmFyIF90aGlzMTYgPSB0aGlzO1xuXG4gICAgICB2YXIgeGhyID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7IC8vIFB1dCB0aGUgeGhyIG9iamVjdCBpbiB0aGUgZmlsZSBvYmplY3RzIHRvIGJlIGFibGUgdG8gcmVmZXJlbmNlIGl0IGxhdGVyLlxuXG4gICAgICB2YXIgX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjIxID0gdHJ1ZTtcbiAgICAgIHZhciBfZGlkSXRlcmF0b3JFcnJvcjIxID0gZmFsc2U7XG4gICAgICB2YXIgX2l0ZXJhdG9yRXJyb3IyMSA9IHVuZGVmaW5lZDtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgZm9yICh2YXIgX2l0ZXJhdG9yMjEgPSBmaWxlc1tTeW1ib2wuaXRlcmF0b3JdKCksIF9zdGVwMjE7ICEoX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjIxID0gKF9zdGVwMjEgPSBfaXRlcmF0b3IyMS5uZXh0KCkpLmRvbmUpOyBfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uMjEgPSB0cnVlKSB7XG4gICAgICAgICAgdmFyIGZpbGUgPSBfc3RlcDIxLnZhbHVlO1xuICAgICAgICAgIGZpbGUueGhyID0geGhyO1xuICAgICAgICB9XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgX2RpZEl0ZXJhdG9yRXJyb3IyMSA9IHRydWU7XG4gICAgICAgIF9pdGVyYXRvckVycm9yMjEgPSBlcnI7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGlmICghX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjIxICYmIF9pdGVyYXRvcjIxW1wicmV0dXJuXCJdICE9IG51bGwpIHtcbiAgICAgICAgICAgIF9pdGVyYXRvcjIxW1wicmV0dXJuXCJdKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgIGlmIChfZGlkSXRlcmF0b3JFcnJvcjIxKSB7XG4gICAgICAgICAgICB0aHJvdyBfaXRlcmF0b3JFcnJvcjIxO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoZmlsZXNbMF0udXBsb2FkLmNodW5rZWQpIHtcbiAgICAgICAgLy8gUHV0IHRoZSB4aHIgb2JqZWN0IGluIHRoZSByaWdodCBjaHVuayBvYmplY3QsIHNvIGl0IGNhbiBiZSBhc3NvY2lhdGVkIGxhdGVyLCBhbmQgZm91bmQgd2l0aCBfZ2V0Q2h1bmtcbiAgICAgICAgZmlsZXNbMF0udXBsb2FkLmNodW5rc1tkYXRhQmxvY2tzWzBdLmNodW5rSW5kZXhdLnhociA9IHhocjtcbiAgICAgIH1cblxuICAgICAgdmFyIG1ldGhvZCA9IHRoaXMucmVzb2x2ZU9wdGlvbih0aGlzLm9wdGlvbnMubWV0aG9kLCBmaWxlcyk7XG4gICAgICB2YXIgdXJsID0gdGhpcy5yZXNvbHZlT3B0aW9uKHRoaXMub3B0aW9ucy51cmwsIGZpbGVzKTtcbiAgICAgIHhoci5vcGVuKG1ldGhvZCwgdXJsLCB0cnVlKTsgLy8gU2V0dGluZyB0aGUgdGltZW91dCBhZnRlciBvcGVuIGJlY2F1c2Ugb2YgSUUxMSBpc3N1ZTogaHR0cHM6Ly9naXRsYWIuY29tL21lbm8vZHJvcHpvbmUvaXNzdWVzLzhcblxuICAgICAgeGhyLnRpbWVvdXQgPSB0aGlzLnJlc29sdmVPcHRpb24odGhpcy5vcHRpb25zLnRpbWVvdXQsIGZpbGVzKTsgLy8gSGFzIHRvIGJlIGFmdGVyIGAub3BlbigpYC4gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9lbnlvL2Ryb3B6b25lL2lzc3Vlcy8xNzlcblxuICAgICAgeGhyLndpdGhDcmVkZW50aWFscyA9ICEhdGhpcy5vcHRpb25zLndpdGhDcmVkZW50aWFscztcblxuICAgICAgeGhyLm9ubG9hZCA9IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIF90aGlzMTYuX2ZpbmlzaGVkVXBsb2FkaW5nKGZpbGVzLCB4aHIsIGUpO1xuICAgICAgfTtcblxuICAgICAgeGhyLm9udGltZW91dCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgX3RoaXMxNi5faGFuZGxlVXBsb2FkRXJyb3IoZmlsZXMsIHhociwgXCJSZXF1ZXN0IHRpbWVkb3V0IGFmdGVyIFwiLmNvbmNhdChfdGhpczE2Lm9wdGlvbnMudGltZW91dCwgXCIgc2Vjb25kc1wiKSk7XG4gICAgICB9O1xuXG4gICAgICB4aHIub25lcnJvciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgX3RoaXMxNi5faGFuZGxlVXBsb2FkRXJyb3IoZmlsZXMsIHhocik7XG4gICAgICB9OyAvLyBTb21lIGJyb3dzZXJzIGRvIG5vdCBoYXZlIHRoZSAudXBsb2FkIHByb3BlcnR5XG5cblxuICAgICAgdmFyIHByb2dyZXNzT2JqID0geGhyLnVwbG9hZCAhPSBudWxsID8geGhyLnVwbG9hZCA6IHhocjtcblxuICAgICAgcHJvZ3Jlc3NPYmoub25wcm9ncmVzcyA9IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIHJldHVybiBfdGhpczE2Ll91cGRhdGVGaWxlc1VwbG9hZFByb2dyZXNzKGZpbGVzLCB4aHIsIGUpO1xuICAgICAgfTtcblxuICAgICAgdmFyIGhlYWRlcnMgPSB7XG4gICAgICAgIFwiQWNjZXB0XCI6IFwiYXBwbGljYXRpb24vanNvblwiLFxuICAgICAgICBcIkNhY2hlLUNvbnRyb2xcIjogXCJuby1jYWNoZVwiLFxuICAgICAgICBcIlgtUmVxdWVzdGVkLVdpdGhcIjogXCJYTUxIdHRwUmVxdWVzdFwiXG4gICAgICB9O1xuXG4gICAgICBpZiAodGhpcy5vcHRpb25zLmhlYWRlcnMpIHtcbiAgICAgICAgRHJvcHpvbmUuZXh0ZW5kKGhlYWRlcnMsIHRoaXMub3B0aW9ucy5oZWFkZXJzKTtcbiAgICAgIH1cblxuICAgICAgZm9yICh2YXIgaGVhZGVyTmFtZSBpbiBoZWFkZXJzKSB7XG4gICAgICAgIHZhciBoZWFkZXJWYWx1ZSA9IGhlYWRlcnNbaGVhZGVyTmFtZV07XG5cbiAgICAgICAgaWYgKGhlYWRlclZhbHVlKSB7XG4gICAgICAgICAgeGhyLnNldFJlcXVlc3RIZWFkZXIoaGVhZGVyTmFtZSwgaGVhZGVyVmFsdWUpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHZhciBmb3JtRGF0YSA9IG5ldyBGb3JtRGF0YSgpOyAvLyBBZGRpbmcgYWxsIEBvcHRpb25zIHBhcmFtZXRlcnNcblxuICAgICAgaWYgKHRoaXMub3B0aW9ucy5wYXJhbXMpIHtcbiAgICAgICAgdmFyIGFkZGl0aW9uYWxQYXJhbXMgPSB0aGlzLm9wdGlvbnMucGFyYW1zO1xuXG4gICAgICAgIGlmICh0eXBlb2YgYWRkaXRpb25hbFBhcmFtcyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgIGFkZGl0aW9uYWxQYXJhbXMgPSBhZGRpdGlvbmFsUGFyYW1zLmNhbGwodGhpcywgZmlsZXMsIHhociwgZmlsZXNbMF0udXBsb2FkLmNodW5rZWQgPyB0aGlzLl9nZXRDaHVuayhmaWxlc1swXSwgeGhyKSA6IG51bGwpO1xuICAgICAgICB9XG5cbiAgICAgICAgZm9yICh2YXIga2V5IGluIGFkZGl0aW9uYWxQYXJhbXMpIHtcbiAgICAgICAgICB2YXIgdmFsdWUgPSBhZGRpdGlvbmFsUGFyYW1zW2tleV07XG4gICAgICAgICAgZm9ybURhdGEuYXBwZW5kKGtleSwgdmFsdWUpO1xuICAgICAgICB9XG4gICAgICB9IC8vIExldCB0aGUgdXNlciBhZGQgYWRkaXRpb25hbCBkYXRhIGlmIG5lY2Vzc2FyeVxuXG5cbiAgICAgIHZhciBfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uMjIgPSB0cnVlO1xuICAgICAgdmFyIF9kaWRJdGVyYXRvckVycm9yMjIgPSBmYWxzZTtcbiAgICAgIHZhciBfaXRlcmF0b3JFcnJvcjIyID0gdW5kZWZpbmVkO1xuXG4gICAgICB0cnkge1xuICAgICAgICBmb3IgKHZhciBfaXRlcmF0b3IyMiA9IGZpbGVzW1N5bWJvbC5pdGVyYXRvcl0oKSwgX3N0ZXAyMjsgIShfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uMjIgPSAoX3N0ZXAyMiA9IF9pdGVyYXRvcjIyLm5leHQoKSkuZG9uZSk7IF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24yMiA9IHRydWUpIHtcbiAgICAgICAgICB2YXIgX2ZpbGUgPSBfc3RlcDIyLnZhbHVlO1xuICAgICAgICAgIHRoaXMuZW1pdChcInNlbmRpbmdcIiwgX2ZpbGUsIHhociwgZm9ybURhdGEpO1xuICAgICAgICB9XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgX2RpZEl0ZXJhdG9yRXJyb3IyMiA9IHRydWU7XG4gICAgICAgIF9pdGVyYXRvckVycm9yMjIgPSBlcnI7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGlmICghX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjIyICYmIF9pdGVyYXRvcjIyW1wicmV0dXJuXCJdICE9IG51bGwpIHtcbiAgICAgICAgICAgIF9pdGVyYXRvcjIyW1wicmV0dXJuXCJdKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgIGlmIChfZGlkSXRlcmF0b3JFcnJvcjIyKSB7XG4gICAgICAgICAgICB0aHJvdyBfaXRlcmF0b3JFcnJvcjIyO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5vcHRpb25zLnVwbG9hZE11bHRpcGxlKSB7XG4gICAgICAgIHRoaXMuZW1pdChcInNlbmRpbmdtdWx0aXBsZVwiLCBmaWxlcywgeGhyLCBmb3JtRGF0YSk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuX2FkZEZvcm1FbGVtZW50RGF0YShmb3JtRGF0YSk7IC8vIEZpbmFsbHkgYWRkIHRoZSBmaWxlc1xuICAgICAgLy8gSGFzIHRvIGJlIGxhc3QgYmVjYXVzZSBzb21lIHNlcnZlcnMgKGVnOiBTMykgZXhwZWN0IHRoZSBmaWxlIHRvIGJlIHRoZSBsYXN0IHBhcmFtZXRlclxuXG5cbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZGF0YUJsb2Nrcy5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgZGF0YUJsb2NrID0gZGF0YUJsb2Nrc1tpXTtcbiAgICAgICAgZm9ybURhdGEuYXBwZW5kKGRhdGFCbG9jay5uYW1lLCBkYXRhQmxvY2suZGF0YSwgZGF0YUJsb2NrLmZpbGVuYW1lKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5zdWJtaXRSZXF1ZXN0KHhociwgZm9ybURhdGEsIGZpbGVzKTtcbiAgICB9IC8vIFRyYW5zZm9ybXMgYWxsIGZpbGVzIHdpdGggdGhpcy5vcHRpb25zLnRyYW5zZm9ybUZpbGUgYW5kIGludm9rZXMgZG9uZSB3aXRoIHRoZSB0cmFuc2Zvcm1lZCBmaWxlcyB3aGVuIGRvbmUuXG5cbiAgfSwge1xuICAgIGtleTogXCJfdHJhbnNmb3JtRmlsZXNcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gX3RyYW5zZm9ybUZpbGVzKGZpbGVzLCBkb25lKSB7XG4gICAgICB2YXIgX3RoaXMxNyA9IHRoaXM7XG5cbiAgICAgIHZhciB0cmFuc2Zvcm1lZEZpbGVzID0gW107IC8vIENsdW1zeSB3YXkgb2YgaGFuZGxpbmcgYXN5bmNocm9ub3VzIGNhbGxzLCB1bnRpbCBJIGdldCB0byBhZGQgYSBwcm9wZXIgRnV0dXJlIGxpYnJhcnkuXG5cbiAgICAgIHZhciBkb25lQ291bnRlciA9IDA7XG5cbiAgICAgIHZhciBfbG9vcCA9IGZ1bmN0aW9uIF9sb29wKGkpIHtcbiAgICAgICAgX3RoaXMxNy5vcHRpb25zLnRyYW5zZm9ybUZpbGUuY2FsbChfdGhpczE3LCBmaWxlc1tpXSwgZnVuY3Rpb24gKHRyYW5zZm9ybWVkRmlsZSkge1xuICAgICAgICAgIHRyYW5zZm9ybWVkRmlsZXNbaV0gPSB0cmFuc2Zvcm1lZEZpbGU7XG5cbiAgICAgICAgICBpZiAoKytkb25lQ291bnRlciA9PT0gZmlsZXMubGVuZ3RoKSB7XG4gICAgICAgICAgICBkb25lKHRyYW5zZm9ybWVkRmlsZXMpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9O1xuXG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGZpbGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIF9sb29wKGkpO1xuICAgICAgfVxuICAgIH0gLy8gVGFrZXMgY2FyZSBvZiBhZGRpbmcgb3RoZXIgaW5wdXQgZWxlbWVudHMgb2YgdGhlIGZvcm0gdG8gdGhlIEFKQVggcmVxdWVzdFxuXG4gIH0sIHtcbiAgICBrZXk6IFwiX2FkZEZvcm1FbGVtZW50RGF0YVwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBfYWRkRm9ybUVsZW1lbnREYXRhKGZvcm1EYXRhKSB7XG4gICAgICAvLyBUYWtlIGNhcmUgb2Ygb3RoZXIgaW5wdXQgZWxlbWVudHNcbiAgICAgIGlmICh0aGlzLmVsZW1lbnQudGFnTmFtZSA9PT0gXCJGT1JNXCIpIHtcbiAgICAgICAgdmFyIF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24yMyA9IHRydWU7XG4gICAgICAgIHZhciBfZGlkSXRlcmF0b3JFcnJvcjIzID0gZmFsc2U7XG4gICAgICAgIHZhciBfaXRlcmF0b3JFcnJvcjIzID0gdW5kZWZpbmVkO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgZm9yICh2YXIgX2l0ZXJhdG9yMjMgPSB0aGlzLmVsZW1lbnQucXVlcnlTZWxlY3RvckFsbChcImlucHV0LCB0ZXh0YXJlYSwgc2VsZWN0LCBidXR0b25cIilbU3ltYm9sLml0ZXJhdG9yXSgpLCBfc3RlcDIzOyAhKF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24yMyA9IChfc3RlcDIzID0gX2l0ZXJhdG9yMjMubmV4dCgpKS5kb25lKTsgX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjIzID0gdHJ1ZSkge1xuICAgICAgICAgICAgdmFyIGlucHV0ID0gX3N0ZXAyMy52YWx1ZTtcbiAgICAgICAgICAgIHZhciBpbnB1dE5hbWUgPSBpbnB1dC5nZXRBdHRyaWJ1dGUoXCJuYW1lXCIpO1xuICAgICAgICAgICAgdmFyIGlucHV0VHlwZSA9IGlucHV0LmdldEF0dHJpYnV0ZShcInR5cGVcIik7XG4gICAgICAgICAgICBpZiAoaW5wdXRUeXBlKSBpbnB1dFR5cGUgPSBpbnB1dFR5cGUudG9Mb3dlckNhc2UoKTsgLy8gSWYgdGhlIGlucHV0IGRvZXNuJ3QgaGF2ZSBhIG5hbWUsIHdlIGNhbid0IHVzZSBpdC5cblxuICAgICAgICAgICAgaWYgKHR5cGVvZiBpbnB1dE5hbWUgPT09ICd1bmRlZmluZWQnIHx8IGlucHV0TmFtZSA9PT0gbnVsbCkgY29udGludWU7XG5cbiAgICAgICAgICAgIGlmIChpbnB1dC50YWdOYW1lID09PSBcIlNFTEVDVFwiICYmIGlucHV0Lmhhc0F0dHJpYnV0ZShcIm11bHRpcGxlXCIpKSB7XG4gICAgICAgICAgICAgIC8vIFBvc3NpYmx5IG11bHRpcGxlIHZhbHVlc1xuICAgICAgICAgICAgICB2YXIgX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjI0ID0gdHJ1ZTtcbiAgICAgICAgICAgICAgdmFyIF9kaWRJdGVyYXRvckVycm9yMjQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgdmFyIF9pdGVyYXRvckVycm9yMjQgPSB1bmRlZmluZWQ7XG5cbiAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBfaXRlcmF0b3IyNCA9IGlucHV0Lm9wdGlvbnNbU3ltYm9sLml0ZXJhdG9yXSgpLCBfc3RlcDI0OyAhKF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24yNCA9IChfc3RlcDI0ID0gX2l0ZXJhdG9yMjQubmV4dCgpKS5kb25lKTsgX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjI0ID0gdHJ1ZSkge1xuICAgICAgICAgICAgICAgICAgdmFyIG9wdGlvbiA9IF9zdGVwMjQudmFsdWU7XG5cbiAgICAgICAgICAgICAgICAgIGlmIChvcHRpb24uc2VsZWN0ZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgZm9ybURhdGEuYXBwZW5kKGlucHV0TmFtZSwgb3B0aW9uLnZhbHVlKTtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgIF9kaWRJdGVyYXRvckVycm9yMjQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIF9pdGVyYXRvckVycm9yMjQgPSBlcnI7XG4gICAgICAgICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgIGlmICghX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjI0ICYmIF9pdGVyYXRvcjI0W1wicmV0dXJuXCJdICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgX2l0ZXJhdG9yMjRbXCJyZXR1cm5cIl0oKTtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgICAgICAgICAgaWYgKF9kaWRJdGVyYXRvckVycm9yMjQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgX2l0ZXJhdG9yRXJyb3IyNDtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAoIWlucHV0VHlwZSB8fCBpbnB1dFR5cGUgIT09IFwiY2hlY2tib3hcIiAmJiBpbnB1dFR5cGUgIT09IFwicmFkaW9cIiB8fCBpbnB1dC5jaGVja2VkKSB7XG4gICAgICAgICAgICAgIGZvcm1EYXRhLmFwcGVuZChpbnB1dE5hbWUsIGlucHV0LnZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgIF9kaWRJdGVyYXRvckVycm9yMjMgPSB0cnVlO1xuICAgICAgICAgIF9pdGVyYXRvckVycm9yMjMgPSBlcnI7XG4gICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGlmICghX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjIzICYmIF9pdGVyYXRvcjIzW1wicmV0dXJuXCJdICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgX2l0ZXJhdG9yMjNbXCJyZXR1cm5cIl0oKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgICAgaWYgKF9kaWRJdGVyYXRvckVycm9yMjMpIHtcbiAgICAgICAgICAgICAgdGhyb3cgX2l0ZXJhdG9yRXJyb3IyMztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IC8vIEludm9rZWQgd2hlbiB0aGVyZSBpcyBuZXcgcHJvZ3Jlc3MgaW5mb3JtYXRpb24gYWJvdXQgZ2l2ZW4gZmlsZXMuXG4gICAgLy8gSWYgZSBpcyBub3QgcHJvdmlkZWQsIGl0IGlzIGFzc3VtZWQgdGhhdCB0aGUgdXBsb2FkIGlzIGZpbmlzaGVkLlxuXG4gIH0sIHtcbiAgICBrZXk6IFwiX3VwZGF0ZUZpbGVzVXBsb2FkUHJvZ3Jlc3NcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gX3VwZGF0ZUZpbGVzVXBsb2FkUHJvZ3Jlc3MoZmlsZXMsIHhociwgZSkge1xuICAgICAgdmFyIHByb2dyZXNzO1xuXG4gICAgICBpZiAodHlwZW9mIGUgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIHByb2dyZXNzID0gMTAwICogZS5sb2FkZWQgLyBlLnRvdGFsO1xuXG4gICAgICAgIGlmIChmaWxlc1swXS51cGxvYWQuY2h1bmtlZCkge1xuICAgICAgICAgIHZhciBmaWxlID0gZmlsZXNbMF07IC8vIFNpbmNlIHRoaXMgaXMgYSBjaHVua2VkIHVwbG9hZCwgd2UgbmVlZCB0byB1cGRhdGUgdGhlIGFwcHJvcHJpYXRlIGNodW5rIHByb2dyZXNzLlxuXG4gICAgICAgICAgdmFyIGNodW5rID0gdGhpcy5fZ2V0Q2h1bmsoZmlsZSwgeGhyKTtcblxuICAgICAgICAgIGNodW5rLnByb2dyZXNzID0gcHJvZ3Jlc3M7XG4gICAgICAgICAgY2h1bmsudG90YWwgPSBlLnRvdGFsO1xuICAgICAgICAgIGNodW5rLmJ5dGVzU2VudCA9IGUubG9hZGVkO1xuICAgICAgICAgIHZhciBmaWxlUHJvZ3Jlc3MgPSAwLFxuICAgICAgICAgICAgICBmaWxlVG90YWwsXG4gICAgICAgICAgICAgIGZpbGVCeXRlc1NlbnQ7XG4gICAgICAgICAgZmlsZS51cGxvYWQucHJvZ3Jlc3MgPSAwO1xuICAgICAgICAgIGZpbGUudXBsb2FkLnRvdGFsID0gMDtcbiAgICAgICAgICBmaWxlLnVwbG9hZC5ieXRlc1NlbnQgPSAwO1xuXG4gICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBmaWxlLnVwbG9hZC50b3RhbENodW5rQ291bnQ7IGkrKykge1xuICAgICAgICAgICAgaWYgKGZpbGUudXBsb2FkLmNodW5rc1tpXSAhPT0gdW5kZWZpbmVkICYmIGZpbGUudXBsb2FkLmNodW5rc1tpXS5wcm9ncmVzcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgIGZpbGUudXBsb2FkLnByb2dyZXNzICs9IGZpbGUudXBsb2FkLmNodW5rc1tpXS5wcm9ncmVzcztcbiAgICAgICAgICAgICAgZmlsZS51cGxvYWQudG90YWwgKz0gZmlsZS51cGxvYWQuY2h1bmtzW2ldLnRvdGFsO1xuICAgICAgICAgICAgICBmaWxlLnVwbG9hZC5ieXRlc1NlbnQgKz0gZmlsZS51cGxvYWQuY2h1bmtzW2ldLmJ5dGVzU2VudDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBmaWxlLnVwbG9hZC5wcm9ncmVzcyA9IGZpbGUudXBsb2FkLnByb2dyZXNzIC8gZmlsZS51cGxvYWQudG90YWxDaHVua0NvdW50O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZhciBfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uMjUgPSB0cnVlO1xuICAgICAgICAgIHZhciBfZGlkSXRlcmF0b3JFcnJvcjI1ID0gZmFsc2U7XG4gICAgICAgICAgdmFyIF9pdGVyYXRvckVycm9yMjUgPSB1bmRlZmluZWQ7XG5cbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgZm9yICh2YXIgX2l0ZXJhdG9yMjUgPSBmaWxlc1tTeW1ib2wuaXRlcmF0b3JdKCksIF9zdGVwMjU7ICEoX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjI1ID0gKF9zdGVwMjUgPSBfaXRlcmF0b3IyNS5uZXh0KCkpLmRvbmUpOyBfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uMjUgPSB0cnVlKSB7XG4gICAgICAgICAgICAgIHZhciBfZmlsZTIgPSBfc3RlcDI1LnZhbHVlO1xuICAgICAgICAgICAgICBfZmlsZTIudXBsb2FkLnByb2dyZXNzID0gcHJvZ3Jlc3M7XG4gICAgICAgICAgICAgIF9maWxlMi51cGxvYWQudG90YWwgPSBlLnRvdGFsO1xuICAgICAgICAgICAgICBfZmlsZTIudXBsb2FkLmJ5dGVzU2VudCA9IGUubG9hZGVkO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgX2RpZEl0ZXJhdG9yRXJyb3IyNSA9IHRydWU7XG4gICAgICAgICAgICBfaXRlcmF0b3JFcnJvcjI1ID0gZXJyO1xuICAgICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICBpZiAoIV9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24yNSAmJiBfaXRlcmF0b3IyNVtcInJldHVyblwiXSAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgX2l0ZXJhdG9yMjVbXCJyZXR1cm5cIl0oKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgICAgaWYgKF9kaWRJdGVyYXRvckVycm9yMjUpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBfaXRlcmF0b3JFcnJvcjI1O1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdmFyIF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24yNiA9IHRydWU7XG4gICAgICAgIHZhciBfZGlkSXRlcmF0b3JFcnJvcjI2ID0gZmFsc2U7XG4gICAgICAgIHZhciBfaXRlcmF0b3JFcnJvcjI2ID0gdW5kZWZpbmVkO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgZm9yICh2YXIgX2l0ZXJhdG9yMjYgPSBmaWxlc1tTeW1ib2wuaXRlcmF0b3JdKCksIF9zdGVwMjY7ICEoX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjI2ID0gKF9zdGVwMjYgPSBfaXRlcmF0b3IyNi5uZXh0KCkpLmRvbmUpOyBfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uMjYgPSB0cnVlKSB7XG4gICAgICAgICAgICB2YXIgX2ZpbGUzID0gX3N0ZXAyNi52YWx1ZTtcbiAgICAgICAgICAgIHRoaXMuZW1pdChcInVwbG9hZHByb2dyZXNzXCIsIF9maWxlMywgX2ZpbGUzLnVwbG9hZC5wcm9ncmVzcywgX2ZpbGUzLnVwbG9hZC5ieXRlc1NlbnQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgX2RpZEl0ZXJhdG9yRXJyb3IyNiA9IHRydWU7XG4gICAgICAgICAgX2l0ZXJhdG9yRXJyb3IyNiA9IGVycjtcbiAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgaWYgKCFfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uMjYgJiYgX2l0ZXJhdG9yMjZbXCJyZXR1cm5cIl0gIT0gbnVsbCkge1xuICAgICAgICAgICAgICBfaXRlcmF0b3IyNltcInJldHVyblwiXSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgICBpZiAoX2RpZEl0ZXJhdG9yRXJyb3IyNikge1xuICAgICAgICAgICAgICB0aHJvdyBfaXRlcmF0b3JFcnJvcjI2O1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gQ2FsbGVkIHdoZW4gdGhlIGZpbGUgZmluaXNoZWQgdXBsb2FkaW5nXG4gICAgICAgIHZhciBhbGxGaWxlc0ZpbmlzaGVkID0gdHJ1ZTtcbiAgICAgICAgcHJvZ3Jlc3MgPSAxMDA7XG4gICAgICAgIHZhciBfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uMjcgPSB0cnVlO1xuICAgICAgICB2YXIgX2RpZEl0ZXJhdG9yRXJyb3IyNyA9IGZhbHNlO1xuICAgICAgICB2YXIgX2l0ZXJhdG9yRXJyb3IyNyA9IHVuZGVmaW5lZDtcblxuICAgICAgICB0cnkge1xuICAgICAgICAgIGZvciAodmFyIF9pdGVyYXRvcjI3ID0gZmlsZXNbU3ltYm9sLml0ZXJhdG9yXSgpLCBfc3RlcDI3OyAhKF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24yNyA9IChfc3RlcDI3ID0gX2l0ZXJhdG9yMjcubmV4dCgpKS5kb25lKTsgX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjI3ID0gdHJ1ZSkge1xuICAgICAgICAgICAgdmFyIF9maWxlNCA9IF9zdGVwMjcudmFsdWU7XG5cbiAgICAgICAgICAgIGlmIChfZmlsZTQudXBsb2FkLnByb2dyZXNzICE9PSAxMDAgfHwgX2ZpbGU0LnVwbG9hZC5ieXRlc1NlbnQgIT09IF9maWxlNC51cGxvYWQudG90YWwpIHtcbiAgICAgICAgICAgICAgYWxsRmlsZXNGaW5pc2hlZCA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBfZmlsZTQudXBsb2FkLnByb2dyZXNzID0gcHJvZ3Jlc3M7XG4gICAgICAgICAgICBfZmlsZTQudXBsb2FkLmJ5dGVzU2VudCA9IF9maWxlNC51cGxvYWQudG90YWw7XG4gICAgICAgICAgfSAvLyBOb3RoaW5nIHRvIGRvLCBhbGwgZmlsZXMgYWxyZWFkeSBhdCAxMDAlXG5cbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgX2RpZEl0ZXJhdG9yRXJyb3IyNyA9IHRydWU7XG4gICAgICAgICAgX2l0ZXJhdG9yRXJyb3IyNyA9IGVycjtcbiAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgaWYgKCFfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uMjcgJiYgX2l0ZXJhdG9yMjdbXCJyZXR1cm5cIl0gIT0gbnVsbCkge1xuICAgICAgICAgICAgICBfaXRlcmF0b3IyN1tcInJldHVyblwiXSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgICBpZiAoX2RpZEl0ZXJhdG9yRXJyb3IyNykge1xuICAgICAgICAgICAgICB0aHJvdyBfaXRlcmF0b3JFcnJvcjI3O1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChhbGxGaWxlc0ZpbmlzaGVkKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24yOCA9IHRydWU7XG4gICAgICAgIHZhciBfZGlkSXRlcmF0b3JFcnJvcjI4ID0gZmFsc2U7XG4gICAgICAgIHZhciBfaXRlcmF0b3JFcnJvcjI4ID0gdW5kZWZpbmVkO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgZm9yICh2YXIgX2l0ZXJhdG9yMjggPSBmaWxlc1tTeW1ib2wuaXRlcmF0b3JdKCksIF9zdGVwMjg7ICEoX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjI4ID0gKF9zdGVwMjggPSBfaXRlcmF0b3IyOC5uZXh0KCkpLmRvbmUpOyBfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uMjggPSB0cnVlKSB7XG4gICAgICAgICAgICB2YXIgX2ZpbGU1ID0gX3N0ZXAyOC52YWx1ZTtcbiAgICAgICAgICAgIHRoaXMuZW1pdChcInVwbG9hZHByb2dyZXNzXCIsIF9maWxlNSwgcHJvZ3Jlc3MsIF9maWxlNS51cGxvYWQuYnl0ZXNTZW50KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgIF9kaWRJdGVyYXRvckVycm9yMjggPSB0cnVlO1xuICAgICAgICAgIF9pdGVyYXRvckVycm9yMjggPSBlcnI7XG4gICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGlmICghX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjI4ICYmIF9pdGVyYXRvcjI4W1wicmV0dXJuXCJdICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgX2l0ZXJhdG9yMjhbXCJyZXR1cm5cIl0oKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgICAgaWYgKF9kaWRJdGVyYXRvckVycm9yMjgpIHtcbiAgICAgICAgICAgICAgdGhyb3cgX2l0ZXJhdG9yRXJyb3IyODtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiX2ZpbmlzaGVkVXBsb2FkaW5nXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIF9maW5pc2hlZFVwbG9hZGluZyhmaWxlcywgeGhyLCBlKSB7XG4gICAgICB2YXIgcmVzcG9uc2U7XG5cbiAgICAgIGlmIChmaWxlc1swXS5zdGF0dXMgPT09IERyb3B6b25lLkNBTkNFTEVEKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKHhoci5yZWFkeVN0YXRlICE9PSA0KSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKHhoci5yZXNwb25zZVR5cGUgIT09ICdhcnJheWJ1ZmZlcicgJiYgeGhyLnJlc3BvbnNlVHlwZSAhPT0gJ2Jsb2InKSB7XG4gICAgICAgIHJlc3BvbnNlID0geGhyLnJlc3BvbnNlVGV4dDtcblxuICAgICAgICBpZiAoeGhyLmdldFJlc3BvbnNlSGVhZGVyKFwiY29udGVudC10eXBlXCIpICYmIH54aHIuZ2V0UmVzcG9uc2VIZWFkZXIoXCJjb250ZW50LXR5cGVcIikuaW5kZXhPZihcImFwcGxpY2F0aW9uL2pzb25cIikpIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgcmVzcG9uc2UgPSBKU09OLnBhcnNlKHJlc3BvbnNlKTtcbiAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgZSA9IGVycm9yO1xuICAgICAgICAgICAgcmVzcG9uc2UgPSBcIkludmFsaWQgSlNPTiByZXNwb25zZSBmcm9tIHNlcnZlci5cIjtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgdGhpcy5fdXBkYXRlRmlsZXNVcGxvYWRQcm9ncmVzcyhmaWxlcyk7XG5cbiAgICAgIGlmICghKDIwMCA8PSB4aHIuc3RhdHVzICYmIHhoci5zdGF0dXMgPCAzMDApKSB7XG4gICAgICAgIHRoaXMuX2hhbmRsZVVwbG9hZEVycm9yKGZpbGVzLCB4aHIsIHJlc3BvbnNlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChmaWxlc1swXS51cGxvYWQuY2h1bmtlZCkge1xuICAgICAgICAgIGZpbGVzWzBdLnVwbG9hZC5maW5pc2hlZENodW5rVXBsb2FkKHRoaXMuX2dldENodW5rKGZpbGVzWzBdLCB4aHIpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLl9maW5pc2hlZChmaWxlcywgcmVzcG9uc2UsIGUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcIl9oYW5kbGVVcGxvYWRFcnJvclwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBfaGFuZGxlVXBsb2FkRXJyb3IoZmlsZXMsIHhociwgcmVzcG9uc2UpIHtcbiAgICAgIGlmIChmaWxlc1swXS5zdGF0dXMgPT09IERyb3B6b25lLkNBTkNFTEVEKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKGZpbGVzWzBdLnVwbG9hZC5jaHVua2VkICYmIHRoaXMub3B0aW9ucy5yZXRyeUNodW5rcykge1xuICAgICAgICB2YXIgY2h1bmsgPSB0aGlzLl9nZXRDaHVuayhmaWxlc1swXSwgeGhyKTtcblxuICAgICAgICBpZiAoY2h1bmsucmV0cmllcysrIDwgdGhpcy5vcHRpb25zLnJldHJ5Q2h1bmtzTGltaXQpIHtcbiAgICAgICAgICB0aGlzLl91cGxvYWREYXRhKGZpbGVzLCBbY2h1bmsuZGF0YUJsb2NrXSk7XG5cbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc29sZS53YXJuKCdSZXRyaWVkIHRoaXMgY2h1bmsgdG9vIG9mdGVuLiBHaXZpbmcgdXAuJyk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgdGhpcy5fZXJyb3JQcm9jZXNzaW5nKGZpbGVzLCByZXNwb25zZSB8fCB0aGlzLm9wdGlvbnMuZGljdFJlc3BvbnNlRXJyb3IucmVwbGFjZShcInt7c3RhdHVzQ29kZX19XCIsIHhoci5zdGF0dXMpLCB4aHIpO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJzdWJtaXRSZXF1ZXN0XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHN1Ym1pdFJlcXVlc3QoeGhyLCBmb3JtRGF0YSwgZmlsZXMpIHtcbiAgICAgIHhoci5zZW5kKGZvcm1EYXRhKTtcbiAgICB9IC8vIENhbGxlZCBpbnRlcm5hbGx5IHdoZW4gcHJvY2Vzc2luZyBpcyBmaW5pc2hlZC5cbiAgICAvLyBJbmRpdmlkdWFsIGNhbGxiYWNrcyBoYXZlIHRvIGJlIGNhbGxlZCBpbiB0aGUgYXBwcm9wcmlhdGUgc2VjdGlvbnMuXG5cbiAgfSwge1xuICAgIGtleTogXCJfZmluaXNoZWRcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gX2ZpbmlzaGVkKGZpbGVzLCByZXNwb25zZVRleHQsIGUpIHtcbiAgICAgIHZhciBfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uMjkgPSB0cnVlO1xuICAgICAgdmFyIF9kaWRJdGVyYXRvckVycm9yMjkgPSBmYWxzZTtcbiAgICAgIHZhciBfaXRlcmF0b3JFcnJvcjI5ID0gdW5kZWZpbmVkO1xuXG4gICAgICB0cnkge1xuICAgICAgICBmb3IgKHZhciBfaXRlcmF0b3IyOSA9IGZpbGVzW1N5bWJvbC5pdGVyYXRvcl0oKSwgX3N0ZXAyOTsgIShfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uMjkgPSAoX3N0ZXAyOSA9IF9pdGVyYXRvcjI5Lm5leHQoKSkuZG9uZSk7IF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24yOSA9IHRydWUpIHtcbiAgICAgICAgICB2YXIgZmlsZSA9IF9zdGVwMjkudmFsdWU7XG4gICAgICAgICAgZmlsZS5zdGF0dXMgPSBEcm9wem9uZS5TVUNDRVNTO1xuICAgICAgICAgIHRoaXMuZW1pdChcInN1Y2Nlc3NcIiwgZmlsZSwgcmVzcG9uc2VUZXh0LCBlKTtcbiAgICAgICAgICB0aGlzLmVtaXQoXCJjb21wbGV0ZVwiLCBmaWxlKTtcbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIF9kaWRJdGVyYXRvckVycm9yMjkgPSB0cnVlO1xuICAgICAgICBfaXRlcmF0b3JFcnJvcjI5ID0gZXJyO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBpZiAoIV9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24yOSAmJiBfaXRlcmF0b3IyOVtcInJldHVyblwiXSAhPSBudWxsKSB7XG4gICAgICAgICAgICBfaXRlcmF0b3IyOVtcInJldHVyblwiXSgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICBpZiAoX2RpZEl0ZXJhdG9yRXJyb3IyOSkge1xuICAgICAgICAgICAgdGhyb3cgX2l0ZXJhdG9yRXJyb3IyOTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMub3B0aW9ucy51cGxvYWRNdWx0aXBsZSkge1xuICAgICAgICB0aGlzLmVtaXQoXCJzdWNjZXNzbXVsdGlwbGVcIiwgZmlsZXMsIHJlc3BvbnNlVGV4dCwgZSk7XG4gICAgICAgIHRoaXMuZW1pdChcImNvbXBsZXRlbXVsdGlwbGVcIiwgZmlsZXMpO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5vcHRpb25zLmF1dG9Qcm9jZXNzUXVldWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucHJvY2Vzc1F1ZXVlKCk7XG4gICAgICB9XG4gICAgfSAvLyBDYWxsZWQgaW50ZXJuYWxseSB3aGVuIHByb2Nlc3NpbmcgaXMgZmluaXNoZWQuXG4gICAgLy8gSW5kaXZpZHVhbCBjYWxsYmFja3MgaGF2ZSB0byBiZSBjYWxsZWQgaW4gdGhlIGFwcHJvcHJpYXRlIHNlY3Rpb25zLlxuXG4gIH0sIHtcbiAgICBrZXk6IFwiX2Vycm9yUHJvY2Vzc2luZ1wiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBfZXJyb3JQcm9jZXNzaW5nKGZpbGVzLCBtZXNzYWdlLCB4aHIpIHtcbiAgICAgIHZhciBfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uMzAgPSB0cnVlO1xuICAgICAgdmFyIF9kaWRJdGVyYXRvckVycm9yMzAgPSBmYWxzZTtcbiAgICAgIHZhciBfaXRlcmF0b3JFcnJvcjMwID0gdW5kZWZpbmVkO1xuXG4gICAgICB0cnkge1xuICAgICAgICBmb3IgKHZhciBfaXRlcmF0b3IzMCA9IGZpbGVzW1N5bWJvbC5pdGVyYXRvcl0oKSwgX3N0ZXAzMDsgIShfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uMzAgPSAoX3N0ZXAzMCA9IF9pdGVyYXRvcjMwLm5leHQoKSkuZG9uZSk7IF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24zMCA9IHRydWUpIHtcbiAgICAgICAgICB2YXIgZmlsZSA9IF9zdGVwMzAudmFsdWU7XG4gICAgICAgICAgZmlsZS5zdGF0dXMgPSBEcm9wem9uZS5FUlJPUjtcbiAgICAgICAgICB0aGlzLmVtaXQoXCJlcnJvclwiLCBmaWxlLCBtZXNzYWdlLCB4aHIpO1xuICAgICAgICAgIHRoaXMuZW1pdChcImNvbXBsZXRlXCIsIGZpbGUpO1xuICAgICAgICB9XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgX2RpZEl0ZXJhdG9yRXJyb3IzMCA9IHRydWU7XG4gICAgICAgIF9pdGVyYXRvckVycm9yMzAgPSBlcnI7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGlmICghX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjMwICYmIF9pdGVyYXRvcjMwW1wicmV0dXJuXCJdICE9IG51bGwpIHtcbiAgICAgICAgICAgIF9pdGVyYXRvcjMwW1wicmV0dXJuXCJdKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgIGlmIChfZGlkSXRlcmF0b3JFcnJvcjMwKSB7XG4gICAgICAgICAgICB0aHJvdyBfaXRlcmF0b3JFcnJvcjMwO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5vcHRpb25zLnVwbG9hZE11bHRpcGxlKSB7XG4gICAgICAgIHRoaXMuZW1pdChcImVycm9ybXVsdGlwbGVcIiwgZmlsZXMsIG1lc3NhZ2UsIHhocik7XG4gICAgICAgIHRoaXMuZW1pdChcImNvbXBsZXRlbXVsdGlwbGVcIiwgZmlsZXMpO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5vcHRpb25zLmF1dG9Qcm9jZXNzUXVldWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucHJvY2Vzc1F1ZXVlKCk7XG4gICAgICB9XG4gICAgfVxuICB9XSwgW3tcbiAgICBrZXk6IFwidXVpZHY0XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHV1aWR2NCgpIHtcbiAgICAgIHJldHVybiAneHh4eHh4eHgteHh4eC00eHh4LXl4eHgteHh4eHh4eHh4eHh4Jy5yZXBsYWNlKC9beHldL2csIGZ1bmN0aW9uIChjKSB7XG4gICAgICAgIHZhciByID0gTWF0aC5yYW5kb20oKSAqIDE2IHwgMCxcbiAgICAgICAgICAgIHYgPSBjID09PSAneCcgPyByIDogciAmIDB4MyB8IDB4ODtcbiAgICAgICAgcmV0dXJuIHYudG9TdHJpbmcoMTYpO1xuICAgICAgfSk7XG4gICAgfVxuICB9XSk7XG5cbiAgcmV0dXJuIERyb3B6b25lO1xufShFbWl0dGVyKTtcblxuRHJvcHpvbmUuaW5pdENsYXNzKCk7XG5Ecm9wem9uZS52ZXJzaW9uID0gXCI1LjcuMFwiOyAvLyBUaGlzIGlzIGEgbWFwIG9mIG9wdGlvbnMgZm9yIHlvdXIgZGlmZmVyZW50IGRyb3B6b25lcy4gQWRkIGNvbmZpZ3VyYXRpb25zXG4vLyB0byB0aGlzIG9iamVjdCBmb3IgeW91ciBkaWZmZXJlbnQgZHJvcHpvbmUgZWxlbWVucy5cbi8vXG4vLyBFeGFtcGxlOlxuLy9cbi8vICAgICBEcm9wem9uZS5vcHRpb25zLm15RHJvcHpvbmVFbGVtZW50SWQgPSB7IG1heEZpbGVzaXplOiAxIH07XG4vL1xuLy8gVG8gZGlzYWJsZSBhdXRvRGlzY292ZXIgZm9yIGEgc3BlY2lmaWMgZWxlbWVudCwgeW91IGNhbiBzZXQgYGZhbHNlYCBhcyBhbiBvcHRpb246XG4vL1xuLy8gICAgIERyb3B6b25lLm9wdGlvbnMubXlEaXNhYmxlZEVsZW1lbnRJZCA9IGZhbHNlO1xuLy9cbi8vIEFuZCBpbiBodG1sOlxuLy9cbi8vICAgICA8Zm9ybSBhY3Rpb249XCIvdXBsb2FkXCIgaWQ9XCJteS1kcm9wem9uZS1lbGVtZW50LWlkXCIgY2xhc3M9XCJkcm9wem9uZVwiPjwvZm9ybT5cblxuRHJvcHpvbmUub3B0aW9ucyA9IHt9OyAvLyBSZXR1cm5zIHRoZSBvcHRpb25zIGZvciBhbiBlbGVtZW50IG9yIHVuZGVmaW5lZCBpZiBub25lIGF2YWlsYWJsZS5cblxuRHJvcHpvbmUub3B0aW9uc0ZvckVsZW1lbnQgPSBmdW5jdGlvbiAoZWxlbWVudCkge1xuICAvLyBHZXQgdGhlIGBEcm9wem9uZS5vcHRpb25zLmVsZW1lbnRJZGAgZm9yIHRoaXMgZWxlbWVudCBpZiBpdCBleGlzdHNcbiAgaWYgKGVsZW1lbnQuZ2V0QXR0cmlidXRlKFwiaWRcIikpIHtcbiAgICByZXR1cm4gRHJvcHpvbmUub3B0aW9uc1tjYW1lbGl6ZShlbGVtZW50LmdldEF0dHJpYnV0ZShcImlkXCIpKV07XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxufTsgLy8gSG9sZHMgYSBsaXN0IG9mIGFsbCBkcm9wem9uZSBpbnN0YW5jZXNcblxuXG5Ecm9wem9uZS5pbnN0YW5jZXMgPSBbXTsgLy8gUmV0dXJucyB0aGUgZHJvcHpvbmUgZm9yIGdpdmVuIGVsZW1lbnQgaWYgYW55XG5cbkRyb3B6b25lLmZvckVsZW1lbnQgPSBmdW5jdGlvbiAoZWxlbWVudCkge1xuICBpZiAodHlwZW9mIGVsZW1lbnQgPT09IFwic3RyaW5nXCIpIHtcbiAgICBlbGVtZW50ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihlbGVtZW50KTtcbiAgfVxuXG4gIGlmICgoZWxlbWVudCAhPSBudWxsID8gZWxlbWVudC5kcm9wem9uZSA6IHVuZGVmaW5lZCkgPT0gbnVsbCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcIk5vIERyb3B6b25lIGZvdW5kIGZvciBnaXZlbiBlbGVtZW50LiBUaGlzIGlzIHByb2JhYmx5IGJlY2F1c2UgeW91J3JlIHRyeWluZyB0byBhY2Nlc3MgaXQgYmVmb3JlIERyb3B6b25lIGhhZCB0aGUgdGltZSB0byBpbml0aWFsaXplLiBVc2UgdGhlIGBpbml0YCBvcHRpb24gdG8gc2V0dXAgYW55IGFkZGl0aW9uYWwgb2JzZXJ2ZXJzIG9uIHlvdXIgRHJvcHpvbmUuXCIpO1xuICB9XG5cbiAgcmV0dXJuIGVsZW1lbnQuZHJvcHpvbmU7XG59OyAvLyBTZXQgdG8gZmFsc2UgaWYgeW91IGRvbid0IHdhbnQgRHJvcHpvbmUgdG8gYXV0b21hdGljYWxseSBmaW5kIGFuZCBhdHRhY2ggdG8gLmRyb3B6b25lIGVsZW1lbnRzLlxuXG5cbkRyb3B6b25lLmF1dG9EaXNjb3ZlciA9IHRydWU7IC8vIExvb2tzIGZvciBhbGwgLmRyb3B6b25lIGVsZW1lbnRzIGFuZCBjcmVhdGVzIGEgZHJvcHpvbmUgZm9yIHRoZW1cblxuRHJvcHpvbmUuZGlzY292ZXIgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBkcm9wem9uZXM7XG5cbiAgaWYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwpIHtcbiAgICBkcm9wem9uZXMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKFwiLmRyb3B6b25lXCIpO1xuICB9IGVsc2Uge1xuICAgIGRyb3B6b25lcyA9IFtdOyAvLyBJRSA6KFxuXG4gICAgdmFyIGNoZWNrRWxlbWVudHMgPSBmdW5jdGlvbiBjaGVja0VsZW1lbnRzKGVsZW1lbnRzKSB7XG4gICAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgcmVzdWx0ID0gW107XG4gICAgICAgIHZhciBfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uMzEgPSB0cnVlO1xuICAgICAgICB2YXIgX2RpZEl0ZXJhdG9yRXJyb3IzMSA9IGZhbHNlO1xuICAgICAgICB2YXIgX2l0ZXJhdG9yRXJyb3IzMSA9IHVuZGVmaW5lZDtcblxuICAgICAgICB0cnkge1xuICAgICAgICAgIGZvciAodmFyIF9pdGVyYXRvcjMxID0gZWxlbWVudHNbU3ltYm9sLml0ZXJhdG9yXSgpLCBfc3RlcDMxOyAhKF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24zMSA9IChfc3RlcDMxID0gX2l0ZXJhdG9yMzEubmV4dCgpKS5kb25lKTsgX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjMxID0gdHJ1ZSkge1xuICAgICAgICAgICAgdmFyIGVsID0gX3N0ZXAzMS52YWx1ZTtcblxuICAgICAgICAgICAgaWYgKC8oXnwgKWRyb3B6b25lKCR8ICkvLnRlc3QoZWwuY2xhc3NOYW1lKSkge1xuICAgICAgICAgICAgICByZXN1bHQucHVzaChkcm9wem9uZXMucHVzaChlbCkpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgcmVzdWx0LnB1c2godW5kZWZpbmVkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgIF9kaWRJdGVyYXRvckVycm9yMzEgPSB0cnVlO1xuICAgICAgICAgIF9pdGVyYXRvckVycm9yMzEgPSBlcnI7XG4gICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGlmICghX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjMxICYmIF9pdGVyYXRvcjMxW1wicmV0dXJuXCJdICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgX2l0ZXJhdG9yMzFbXCJyZXR1cm5cIl0oKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgICAgaWYgKF9kaWRJdGVyYXRvckVycm9yMzEpIHtcbiAgICAgICAgICAgICAgdGhyb3cgX2l0ZXJhdG9yRXJyb3IzMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfSgpO1xuICAgIH07XG5cbiAgICBjaGVja0VsZW1lbnRzKGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKFwiZGl2XCIpKTtcbiAgICBjaGVja0VsZW1lbnRzKGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKFwiZm9ybVwiKSk7XG4gIH1cblxuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIHZhciByZXN1bHQgPSBbXTtcbiAgICB2YXIgX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjMyID0gdHJ1ZTtcbiAgICB2YXIgX2RpZEl0ZXJhdG9yRXJyb3IzMiA9IGZhbHNlO1xuICAgIHZhciBfaXRlcmF0b3JFcnJvcjMyID0gdW5kZWZpbmVkO1xuXG4gICAgdHJ5IHtcbiAgICAgIGZvciAodmFyIF9pdGVyYXRvcjMyID0gZHJvcHpvbmVzW1N5bWJvbC5pdGVyYXRvcl0oKSwgX3N0ZXAzMjsgIShfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uMzIgPSAoX3N0ZXAzMiA9IF9pdGVyYXRvcjMyLm5leHQoKSkuZG9uZSk7IF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24zMiA9IHRydWUpIHtcbiAgICAgICAgdmFyIGRyb3B6b25lID0gX3N0ZXAzMi52YWx1ZTtcblxuICAgICAgICAvLyBDcmVhdGUgYSBkcm9wem9uZSB1bmxlc3MgYXV0byBkaXNjb3ZlciBoYXMgYmVlbiBkaXNhYmxlZCBmb3Igc3BlY2lmaWMgZWxlbWVudFxuICAgICAgICBpZiAoRHJvcHpvbmUub3B0aW9uc0ZvckVsZW1lbnQoZHJvcHpvbmUpICE9PSBmYWxzZSkge1xuICAgICAgICAgIHJlc3VsdC5wdXNoKG5ldyBEcm9wem9uZShkcm9wem9uZSkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJlc3VsdC5wdXNoKHVuZGVmaW5lZCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIF9kaWRJdGVyYXRvckVycm9yMzIgPSB0cnVlO1xuICAgICAgX2l0ZXJhdG9yRXJyb3IzMiA9IGVycjtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgaWYgKCFfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uMzIgJiYgX2l0ZXJhdG9yMzJbXCJyZXR1cm5cIl0gIT0gbnVsbCkge1xuICAgICAgICAgIF9pdGVyYXRvcjMyW1wicmV0dXJuXCJdKCk7XG4gICAgICAgIH1cbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIGlmIChfZGlkSXRlcmF0b3JFcnJvcjMyKSB7XG4gICAgICAgICAgdGhyb3cgX2l0ZXJhdG9yRXJyb3IzMjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH0oKTtcbn07IC8vIFNpbmNlIHRoZSB3aG9sZSBEcmFnJ24nRHJvcCBBUEkgaXMgcHJldHR5IG5ldywgc29tZSBicm93c2VycyBpbXBsZW1lbnQgaXQsXG4vLyBidXQgbm90IGNvcnJlY3RseS5cbi8vIFNvIEkgY3JlYXRlZCBhIGJsYWNrbGlzdCBvZiB1c2VyQWdlbnRzLiBZZXMsIHllcy4gQnJvd3NlciBzbmlmZmluZywgSSBrbm93LlxuLy8gQnV0IHdoYXQgdG8gZG8gd2hlbiBicm93c2VycyAqdGhlb3JldGljYWxseSogc3VwcG9ydCBhbiBBUEksIGJ1dCBjcmFzaFxuLy8gd2hlbiB1c2luZyBpdC5cbi8vXG4vLyBUaGlzIGlzIGEgbGlzdCBvZiByZWd1bGFyIGV4cHJlc3Npb25zIHRlc3RlZCBhZ2FpbnN0IG5hdmlnYXRvci51c2VyQWdlbnRcbi8vXG4vLyAqKiBJdCBzaG91bGQgb25seSBiZSB1c2VkIG9uIGJyb3dzZXIgdGhhdCAqZG8qIHN1cHBvcnQgdGhlIEFQSSwgYnV0XG4vLyBpbmNvcnJlY3RseSAqKlxuLy9cblxuXG5Ecm9wem9uZS5ibGFja2xpc3RlZEJyb3dzZXJzID0gWy8vIFRoZSBtYWMgb3MgYW5kIHdpbmRvd3MgcGhvbmUgdmVyc2lvbiBvZiBvcGVyYSAxMiBzZWVtcyB0byBoYXZlIGEgcHJvYmxlbSB3aXRoIHRoZSBGaWxlIGRyYWcnbidkcm9wIEFQSS5cbi9vcGVyYS4qKE1hY2ludG9zaHxXaW5kb3dzIFBob25lKS4qdmVyc2lvblxcLzEyL2ldOyAvLyBDaGVja3MgaWYgdGhlIGJyb3dzZXIgaXMgc3VwcG9ydGVkXG5cbkRyb3B6b25lLmlzQnJvd3NlclN1cHBvcnRlZCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIGNhcGFibGVCcm93c2VyID0gdHJ1ZTtcblxuICBpZiAod2luZG93LkZpbGUgJiYgd2luZG93LkZpbGVSZWFkZXIgJiYgd2luZG93LkZpbGVMaXN0ICYmIHdpbmRvdy5CbG9iICYmIHdpbmRvdy5Gb3JtRGF0YSAmJiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKSB7XG4gICAgaWYgKCEoXCJjbGFzc0xpc3RcIiBpbiBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiYVwiKSkpIHtcbiAgICAgIGNhcGFibGVCcm93c2VyID0gZmFsc2U7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFRoZSBicm93c2VyIHN1cHBvcnRzIHRoZSBBUEksIGJ1dCBtYXkgYmUgYmxhY2tsaXN0ZWQuXG4gICAgICB2YXIgX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjMzID0gdHJ1ZTtcbiAgICAgIHZhciBfZGlkSXRlcmF0b3JFcnJvcjMzID0gZmFsc2U7XG4gICAgICB2YXIgX2l0ZXJhdG9yRXJyb3IzMyA9IHVuZGVmaW5lZDtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgZm9yICh2YXIgX2l0ZXJhdG9yMzMgPSBEcm9wem9uZS5ibGFja2xpc3RlZEJyb3dzZXJzW1N5bWJvbC5pdGVyYXRvcl0oKSwgX3N0ZXAzMzsgIShfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uMzMgPSAoX3N0ZXAzMyA9IF9pdGVyYXRvcjMzLm5leHQoKSkuZG9uZSk7IF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24zMyA9IHRydWUpIHtcbiAgICAgICAgICB2YXIgcmVnZXggPSBfc3RlcDMzLnZhbHVlO1xuXG4gICAgICAgICAgaWYgKHJlZ2V4LnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCkpIHtcbiAgICAgICAgICAgIGNhcGFibGVCcm93c2VyID0gZmFsc2U7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBfZGlkSXRlcmF0b3JFcnJvcjMzID0gdHJ1ZTtcbiAgICAgICAgX2l0ZXJhdG9yRXJyb3IzMyA9IGVycjtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgaWYgKCFfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uMzMgJiYgX2l0ZXJhdG9yMzNbXCJyZXR1cm5cIl0gIT0gbnVsbCkge1xuICAgICAgICAgICAgX2l0ZXJhdG9yMzNbXCJyZXR1cm5cIl0oKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgaWYgKF9kaWRJdGVyYXRvckVycm9yMzMpIHtcbiAgICAgICAgICAgIHRocm93IF9pdGVyYXRvckVycm9yMzM7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGNhcGFibGVCcm93c2VyID0gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gY2FwYWJsZUJyb3dzZXI7XG59O1xuXG5Ecm9wem9uZS5kYXRhVVJJdG9CbG9iID0gZnVuY3Rpb24gKGRhdGFVUkkpIHtcbiAgLy8gY29udmVydCBiYXNlNjQgdG8gcmF3IGJpbmFyeSBkYXRhIGhlbGQgaW4gYSBzdHJpbmdcbiAgLy8gZG9lc24ndCBoYW5kbGUgVVJMRW5jb2RlZCBEYXRhVVJJcyAtIHNlZSBTTyBhbnN3ZXIgIzY4NTAyNzYgZm9yIGNvZGUgdGhhdCBkb2VzIHRoaXNcbiAgdmFyIGJ5dGVTdHJpbmcgPSBhdG9iKGRhdGFVUkkuc3BsaXQoJywnKVsxXSk7IC8vIHNlcGFyYXRlIG91dCB0aGUgbWltZSBjb21wb25lbnRcblxuICB2YXIgbWltZVN0cmluZyA9IGRhdGFVUkkuc3BsaXQoJywnKVswXS5zcGxpdCgnOicpWzFdLnNwbGl0KCc7JylbMF07IC8vIHdyaXRlIHRoZSBieXRlcyBvZiB0aGUgc3RyaW5nIHRvIGFuIEFycmF5QnVmZmVyXG5cbiAgdmFyIGFiID0gbmV3IEFycmF5QnVmZmVyKGJ5dGVTdHJpbmcubGVuZ3RoKTtcbiAgdmFyIGlhID0gbmV3IFVpbnQ4QXJyYXkoYWIpO1xuXG4gIGZvciAodmFyIGkgPSAwLCBlbmQgPSBieXRlU3RyaW5nLmxlbmd0aCwgYXNjID0gMCA8PSBlbmQ7IGFzYyA/IGkgPD0gZW5kIDogaSA+PSBlbmQ7IGFzYyA/IGkrKyA6IGktLSkge1xuICAgIGlhW2ldID0gYnl0ZVN0cmluZy5jaGFyQ29kZUF0KGkpO1xuICB9IC8vIHdyaXRlIHRoZSBBcnJheUJ1ZmZlciB0byBhIGJsb2JcblxuXG4gIHJldHVybiBuZXcgQmxvYihbYWJdLCB7XG4gICAgdHlwZTogbWltZVN0cmluZ1xuICB9KTtcbn07IC8vIFJldHVybnMgYW4gYXJyYXkgd2l0aG91dCB0aGUgcmVqZWN0ZWQgaXRlbVxuXG5cbnZhciB3aXRob3V0ID0gZnVuY3Rpb24gd2l0aG91dChsaXN0LCByZWplY3RlZEl0ZW0pIHtcbiAgcmV0dXJuIGxpc3QuZmlsdGVyKGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgcmV0dXJuIGl0ZW0gIT09IHJlamVjdGVkSXRlbTtcbiAgfSkubWFwKGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgcmV0dXJuIGl0ZW07XG4gIH0pO1xufTsgLy8gYWJjLWRlZl9naGkgLT4gYWJjRGVmR2hpXG5cblxudmFyIGNhbWVsaXplID0gZnVuY3Rpb24gY2FtZWxpemUoc3RyKSB7XG4gIHJldHVybiBzdHIucmVwbGFjZSgvW1xcLV9dKFxcdykvZywgZnVuY3Rpb24gKG1hdGNoKSB7XG4gICAgcmV0dXJuIG1hdGNoLmNoYXJBdCgxKS50b1VwcGVyQ2FzZSgpO1xuICB9KTtcbn07IC8vIENyZWF0ZXMgYW4gZWxlbWVudCBmcm9tIHN0cmluZ1xuXG5cbkRyb3B6b25lLmNyZWF0ZUVsZW1lbnQgPSBmdW5jdGlvbiAoc3RyaW5nKSB7XG4gIHZhciBkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuICBkaXYuaW5uZXJIVE1MID0gc3RyaW5nO1xuICByZXR1cm4gZGl2LmNoaWxkTm9kZXNbMF07XG59OyAvLyBUZXN0cyBpZiBnaXZlbiBlbGVtZW50IGlzIGluc2lkZSAob3Igc2ltcGx5IGlzKSB0aGUgY29udGFpbmVyXG5cblxuRHJvcHpvbmUuZWxlbWVudEluc2lkZSA9IGZ1bmN0aW9uIChlbGVtZW50LCBjb250YWluZXIpIHtcbiAgaWYgKGVsZW1lbnQgPT09IGNvbnRhaW5lcikge1xuICAgIHJldHVybiB0cnVlO1xuICB9IC8vIENvZmZlZXNjcmlwdCBkb2Vzbid0IHN1cHBvcnQgZG8vd2hpbGUgbG9vcHNcblxuXG4gIHdoaWxlIChlbGVtZW50ID0gZWxlbWVudC5wYXJlbnROb2RlKSB7XG4gICAgaWYgKGVsZW1lbnQgPT09IGNvbnRhaW5lcikge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGZhbHNlO1xufTtcblxuRHJvcHpvbmUuZ2V0RWxlbWVudCA9IGZ1bmN0aW9uIChlbCwgbmFtZSkge1xuICB2YXIgZWxlbWVudDtcblxuICBpZiAodHlwZW9mIGVsID09PSBcInN0cmluZ1wiKSB7XG4gICAgZWxlbWVudCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoZWwpO1xuICB9IGVsc2UgaWYgKGVsLm5vZGVUeXBlICE9IG51bGwpIHtcbiAgICBlbGVtZW50ID0gZWw7XG4gIH1cblxuICBpZiAoZWxlbWVudCA9PSBudWxsKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCBgXCIuY29uY2F0KG5hbWUsIFwiYCBvcHRpb24gcHJvdmlkZWQuIFBsZWFzZSBwcm92aWRlIGEgQ1NTIHNlbGVjdG9yIG9yIGEgcGxhaW4gSFRNTCBlbGVtZW50LlwiKSk7XG4gIH1cblxuICByZXR1cm4gZWxlbWVudDtcbn07XG5cbkRyb3B6b25lLmdldEVsZW1lbnRzID0gZnVuY3Rpb24gKGVscywgbmFtZSkge1xuICB2YXIgZWwsIGVsZW1lbnRzO1xuXG4gIGlmIChlbHMgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgIGVsZW1lbnRzID0gW107XG5cbiAgICB0cnkge1xuICAgICAgdmFyIF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24zNCA9IHRydWU7XG4gICAgICB2YXIgX2RpZEl0ZXJhdG9yRXJyb3IzNCA9IGZhbHNlO1xuICAgICAgdmFyIF9pdGVyYXRvckVycm9yMzQgPSB1bmRlZmluZWQ7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGZvciAodmFyIF9pdGVyYXRvcjM0ID0gZWxzW1N5bWJvbC5pdGVyYXRvcl0oKSwgX3N0ZXAzNDsgIShfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uMzQgPSAoX3N0ZXAzNCA9IF9pdGVyYXRvcjM0Lm5leHQoKSkuZG9uZSk7IF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24zNCA9IHRydWUpIHtcbiAgICAgICAgICBlbCA9IF9zdGVwMzQudmFsdWU7XG4gICAgICAgICAgZWxlbWVudHMucHVzaCh0aGlzLmdldEVsZW1lbnQoZWwsIG5hbWUpKTtcbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIF9kaWRJdGVyYXRvckVycm9yMzQgPSB0cnVlO1xuICAgICAgICBfaXRlcmF0b3JFcnJvcjM0ID0gZXJyO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBpZiAoIV9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24zNCAmJiBfaXRlcmF0b3IzNFtcInJldHVyblwiXSAhPSBudWxsKSB7XG4gICAgICAgICAgICBfaXRlcmF0b3IzNFtcInJldHVyblwiXSgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICBpZiAoX2RpZEl0ZXJhdG9yRXJyb3IzNCkge1xuICAgICAgICAgICAgdGhyb3cgX2l0ZXJhdG9yRXJyb3IzNDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBlbGVtZW50cyA9IG51bGw7XG4gICAgfVxuICB9IGVsc2UgaWYgKHR5cGVvZiBlbHMgPT09IFwic3RyaW5nXCIpIHtcbiAgICBlbGVtZW50cyA9IFtdO1xuICAgIHZhciBfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uMzUgPSB0cnVlO1xuICAgIHZhciBfZGlkSXRlcmF0b3JFcnJvcjM1ID0gZmFsc2U7XG4gICAgdmFyIF9pdGVyYXRvckVycm9yMzUgPSB1bmRlZmluZWQ7XG5cbiAgICB0cnkge1xuICAgICAgZm9yICh2YXIgX2l0ZXJhdG9yMzUgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKGVscylbU3ltYm9sLml0ZXJhdG9yXSgpLCBfc3RlcDM1OyAhKF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24zNSA9IChfc3RlcDM1ID0gX2l0ZXJhdG9yMzUubmV4dCgpKS5kb25lKTsgX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjM1ID0gdHJ1ZSkge1xuICAgICAgICBlbCA9IF9zdGVwMzUudmFsdWU7XG4gICAgICAgIGVsZW1lbnRzLnB1c2goZWwpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgX2RpZEl0ZXJhdG9yRXJyb3IzNSA9IHRydWU7XG4gICAgICBfaXRlcmF0b3JFcnJvcjM1ID0gZXJyO1xuICAgIH0gZmluYWxseSB7XG4gICAgICB0cnkge1xuICAgICAgICBpZiAoIV9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24zNSAmJiBfaXRlcmF0b3IzNVtcInJldHVyblwiXSAhPSBudWxsKSB7XG4gICAgICAgICAgX2l0ZXJhdG9yMzVbXCJyZXR1cm5cIl0oKTtcbiAgICAgICAgfVxuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgaWYgKF9kaWRJdGVyYXRvckVycm9yMzUpIHtcbiAgICAgICAgICB0aHJvdyBfaXRlcmF0b3JFcnJvcjM1O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9IGVsc2UgaWYgKGVscy5ub2RlVHlwZSAhPSBudWxsKSB7XG4gICAgZWxlbWVudHMgPSBbZWxzXTtcbiAgfVxuXG4gIGlmIChlbGVtZW50cyA9PSBudWxsIHx8ICFlbGVtZW50cy5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIGBcIi5jb25jYXQobmFtZSwgXCJgIG9wdGlvbiBwcm92aWRlZC4gUGxlYXNlIHByb3ZpZGUgYSBDU1Mgc2VsZWN0b3IsIGEgcGxhaW4gSFRNTCBlbGVtZW50IG9yIGEgbGlzdCBvZiB0aG9zZS5cIikpO1xuICB9XG5cbiAgcmV0dXJuIGVsZW1lbnRzO1xufTsgLy8gQXNrcyB0aGUgdXNlciB0aGUgcXVlc3Rpb24gYW5kIGNhbGxzIGFjY2VwdGVkIG9yIHJlamVjdGVkIGFjY29yZGluZ2x5XG4vL1xuLy8gVGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24ganVzdCB1c2VzIGB3aW5kb3cuY29uZmlybWAgYW5kIHRoZW4gY2FsbHMgdGhlXG4vLyBhcHByb3ByaWF0ZSBjYWxsYmFjay5cblxuXG5Ecm9wem9uZS5jb25maXJtID0gZnVuY3Rpb24gKHF1ZXN0aW9uLCBhY2NlcHRlZCwgcmVqZWN0ZWQpIHtcbiAgaWYgKHdpbmRvdy5jb25maXJtKHF1ZXN0aW9uKSkge1xuICAgIHJldHVybiBhY2NlcHRlZCgpO1xuICB9IGVsc2UgaWYgKHJlamVjdGVkICE9IG51bGwpIHtcbiAgICByZXR1cm4gcmVqZWN0ZWQoKTtcbiAgfVxufTsgLy8gVmFsaWRhdGVzIHRoZSBtaW1lIHR5cGUgbGlrZSB0aGlzOlxuLy9cbi8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvSFRNTC9FbGVtZW50L2lucHV0I2F0dHItYWNjZXB0XG5cblxuRHJvcHpvbmUuaXNWYWxpZEZpbGUgPSBmdW5jdGlvbiAoZmlsZSwgYWNjZXB0ZWRGaWxlcykge1xuICBpZiAoIWFjY2VwdGVkRmlsZXMpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSAvLyBJZiB0aGVyZSBhcmUgbm8gYWNjZXB0ZWQgbWltZSB0eXBlcywgaXQncyBPS1xuXG5cbiAgYWNjZXB0ZWRGaWxlcyA9IGFjY2VwdGVkRmlsZXMuc3BsaXQoXCIsXCIpO1xuICB2YXIgbWltZVR5cGUgPSBmaWxlLnR5cGU7XG4gIHZhciBiYXNlTWltZVR5cGUgPSBtaW1lVHlwZS5yZXBsYWNlKC9cXC8uKiQvLCBcIlwiKTtcbiAgdmFyIF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24zNiA9IHRydWU7XG4gIHZhciBfZGlkSXRlcmF0b3JFcnJvcjM2ID0gZmFsc2U7XG4gIHZhciBfaXRlcmF0b3JFcnJvcjM2ID0gdW5kZWZpbmVkO1xuXG4gIHRyeSB7XG4gICAgZm9yICh2YXIgX2l0ZXJhdG9yMzYgPSBhY2NlcHRlZEZpbGVzW1N5bWJvbC5pdGVyYXRvcl0oKSwgX3N0ZXAzNjsgIShfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uMzYgPSAoX3N0ZXAzNiA9IF9pdGVyYXRvcjM2Lm5leHQoKSkuZG9uZSk7IF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24zNiA9IHRydWUpIHtcbiAgICAgIHZhciB2YWxpZFR5cGUgPSBfc3RlcDM2LnZhbHVlO1xuICAgICAgdmFsaWRUeXBlID0gdmFsaWRUeXBlLnRyaW0oKTtcblxuICAgICAgaWYgKHZhbGlkVHlwZS5jaGFyQXQoMCkgPT09IFwiLlwiKSB7XG4gICAgICAgIGlmIChmaWxlLm5hbWUudG9Mb3dlckNhc2UoKS5pbmRleE9mKHZhbGlkVHlwZS50b0xvd2VyQ2FzZSgpLCBmaWxlLm5hbWUubGVuZ3RoIC0gdmFsaWRUeXBlLmxlbmd0aCkgIT09IC0xKSB7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoL1xcL1xcKiQvLnRlc3QodmFsaWRUeXBlKSkge1xuICAgICAgICAvLyBUaGlzIGlzIHNvbWV0aGluZyBsaWtlIGEgaW1hZ2UvKiBtaW1lIHR5cGVcbiAgICAgICAgaWYgKGJhc2VNaW1lVHlwZSA9PT0gdmFsaWRUeXBlLnJlcGxhY2UoL1xcLy4qJC8sIFwiXCIpKSB7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChtaW1lVHlwZSA9PT0gdmFsaWRUeXBlKSB7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIF9kaWRJdGVyYXRvckVycm9yMzYgPSB0cnVlO1xuICAgIF9pdGVyYXRvckVycm9yMzYgPSBlcnI7XG4gIH0gZmluYWxseSB7XG4gICAgdHJ5IHtcbiAgICAgIGlmICghX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjM2ICYmIF9pdGVyYXRvcjM2W1wicmV0dXJuXCJdICE9IG51bGwpIHtcbiAgICAgICAgX2l0ZXJhdG9yMzZbXCJyZXR1cm5cIl0oKTtcbiAgICAgIH1cbiAgICB9IGZpbmFsbHkge1xuICAgICAgaWYgKF9kaWRJdGVyYXRvckVycm9yMzYpIHtcbiAgICAgICAgdGhyb3cgX2l0ZXJhdG9yRXJyb3IzNjtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59OyAvLyBBdWdtZW50IGpRdWVyeVxuXG5cbmlmICh0eXBlb2YgalF1ZXJ5ICE9PSAndW5kZWZpbmVkJyAmJiBqUXVlcnkgIT09IG51bGwpIHtcbiAgalF1ZXJ5LmZuLmRyb3B6b25lID0gZnVuY3Rpb24gKG9wdGlvbnMpIHtcbiAgICByZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIHJldHVybiBuZXcgRHJvcHpvbmUodGhpcywgb3B0aW9ucyk7XG4gICAgfSk7XG4gIH07XG59XG5cbmlmICh0eXBlb2YgbW9kdWxlICE9PSAndW5kZWZpbmVkJyAmJiBtb2R1bGUgIT09IG51bGwpIHtcbiAgbW9kdWxlLmV4cG9ydHMgPSBEcm9wem9uZTtcbn0gZWxzZSB7XG4gIHdpbmRvdy5Ecm9wem9uZSA9IERyb3B6b25lO1xufSAvLyBEcm9wem9uZSBmaWxlIHN0YXR1cyBjb2Rlc1xuXG5cbkRyb3B6b25lLkFEREVEID0gXCJhZGRlZFwiO1xuRHJvcHpvbmUuUVVFVUVEID0gXCJxdWV1ZWRcIjsgLy8gRm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5LiBOb3csIGlmIGEgZmlsZSBpcyBhY2NlcHRlZCwgaXQncyBlaXRoZXIgcXVldWVkXG4vLyBvciB1cGxvYWRpbmcuXG5cbkRyb3B6b25lLkFDQ0VQVEVEID0gRHJvcHpvbmUuUVVFVUVEO1xuRHJvcHpvbmUuVVBMT0FESU5HID0gXCJ1cGxvYWRpbmdcIjtcbkRyb3B6b25lLlBST0NFU1NJTkcgPSBEcm9wem9uZS5VUExPQURJTkc7IC8vIGFsaWFzXG5cbkRyb3B6b25lLkNBTkNFTEVEID0gXCJjYW5jZWxlZFwiO1xuRHJvcHpvbmUuRVJST1IgPSBcImVycm9yXCI7XG5Ecm9wem9uZS5TVUNDRVNTID0gXCJzdWNjZXNzXCI7XG4vKlxuXG4gQnVnZml4IGZvciBpT1MgNiBhbmQgN1xuIFNvdXJjZTogaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy8xMTkyOTA5OS9odG1sNS1jYW52YXMtZHJhd2ltYWdlLXJhdGlvLWJ1Zy1pb3NcbiBiYXNlZCBvbiB0aGUgd29yayBvZiBodHRwczovL2dpdGh1Yi5jb20vc3RvbWl0YS9pb3MtaW1hZ2VmaWxlLW1lZ2FwaXhlbFxuXG4gKi9cbi8vIERldGVjdGluZyB2ZXJ0aWNhbCBzcXVhc2ggaW4gbG9hZGVkIGltYWdlLlxuLy8gRml4ZXMgYSBidWcgd2hpY2ggc3F1YXNoIGltYWdlIHZlcnRpY2FsbHkgd2hpbGUgZHJhd2luZyBpbnRvIGNhbnZhcyBmb3Igc29tZSBpbWFnZXMuXG4vLyBUaGlzIGlzIGEgYnVnIGluIGlPUzYgZGV2aWNlcy4gVGhpcyBmdW5jdGlvbiBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9zdG9taXRhL2lvcy1pbWFnZWZpbGUtbWVnYXBpeGVsXG5cbnZhciBkZXRlY3RWZXJ0aWNhbFNxdWFzaCA9IGZ1bmN0aW9uIGRldGVjdFZlcnRpY2FsU3F1YXNoKGltZykge1xuICB2YXIgaXcgPSBpbWcubmF0dXJhbFdpZHRoO1xuICB2YXIgaWggPSBpbWcubmF0dXJhbEhlaWdodDtcbiAgdmFyIGNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJjYW52YXNcIik7XG4gIGNhbnZhcy53aWR0aCA9IDE7XG4gIGNhbnZhcy5oZWlnaHQgPSBpaDtcbiAgdmFyIGN0eCA9IGNhbnZhcy5nZXRDb250ZXh0KFwiMmRcIik7XG4gIGN0eC5kcmF3SW1hZ2UoaW1nLCAwLCAwKTtcblxuICB2YXIgX2N0eCRnZXRJbWFnZURhdGEgPSBjdHguZ2V0SW1hZ2VEYXRhKDEsIDAsIDEsIGloKSxcbiAgICAgIGRhdGEgPSBfY3R4JGdldEltYWdlRGF0YS5kYXRhOyAvLyBzZWFyY2ggaW1hZ2UgZWRnZSBwaXhlbCBwb3NpdGlvbiBpbiBjYXNlIGl0IGlzIHNxdWFzaGVkIHZlcnRpY2FsbHkuXG5cblxuICB2YXIgc3kgPSAwO1xuICB2YXIgZXkgPSBpaDtcbiAgdmFyIHB5ID0gaWg7XG5cbiAgd2hpbGUgKHB5ID4gc3kpIHtcbiAgICB2YXIgYWxwaGEgPSBkYXRhWyhweSAtIDEpICogNCArIDNdO1xuXG4gICAgaWYgKGFscGhhID09PSAwKSB7XG4gICAgICBleSA9IHB5O1xuICAgIH0gZWxzZSB7XG4gICAgICBzeSA9IHB5O1xuICAgIH1cblxuICAgIHB5ID0gZXkgKyBzeSA+PiAxO1xuICB9XG5cbiAgdmFyIHJhdGlvID0gcHkgLyBpaDtcblxuICBpZiAocmF0aW8gPT09IDApIHtcbiAgICByZXR1cm4gMTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gcmF0aW87XG4gIH1cbn07IC8vIEEgcmVwbGFjZW1lbnQgZm9yIGNvbnRleHQuZHJhd0ltYWdlXG4vLyAoYXJncyBhcmUgZm9yIHNvdXJjZSBhbmQgZGVzdGluYXRpb24pLlxuXG5cbnZhciBkcmF3SW1hZ2VJT1NGaXggPSBmdW5jdGlvbiBkcmF3SW1hZ2VJT1NGaXgoY3R4LCBpbWcsIHN4LCBzeSwgc3csIHNoLCBkeCwgZHksIGR3LCBkaCkge1xuICB2YXIgdmVydFNxdWFzaFJhdGlvID0gZGV0ZWN0VmVydGljYWxTcXVhc2goaW1nKTtcbiAgcmV0dXJuIGN0eC5kcmF3SW1hZ2UoaW1nLCBzeCwgc3ksIHN3LCBzaCwgZHgsIGR5LCBkdywgZGggLyB2ZXJ0U3F1YXNoUmF0aW8pO1xufTsgLy8gQmFzZWQgb24gTWluaWZ5SnBlZ1xuLy8gU291cmNlOiBodHRwOi8vd3d3LnBlcnJ5LmN6L2ZpbGVzL0V4aWZSZXN0b3Jlci5qc1xuLy8gaHR0cDovL2VsaWNvbi5ibG9nNTcuZmMyLmNvbS9ibG9nLWVudHJ5LTIwNi5odG1sXG5cblxudmFyIEV4aWZSZXN0b3JlID1cbi8qI19fUFVSRV9fKi9cbmZ1bmN0aW9uICgpIHtcbiAgZnVuY3Rpb24gRXhpZlJlc3RvcmUoKSB7XG4gICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIEV4aWZSZXN0b3JlKTtcbiAgfVxuXG4gIF9jcmVhdGVDbGFzcyhFeGlmUmVzdG9yZSwgbnVsbCwgW3tcbiAgICBrZXk6IFwiaW5pdENsYXNzXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGluaXRDbGFzcygpIHtcbiAgICAgIHRoaXMuS0VZX1NUUiA9ICdBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSsvPSc7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcImVuY29kZTY0XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGVuY29kZTY0KGlucHV0KSB7XG4gICAgICB2YXIgb3V0cHV0ID0gJyc7XG4gICAgICB2YXIgY2hyMSA9IHVuZGVmaW5lZDtcbiAgICAgIHZhciBjaHIyID0gdW5kZWZpbmVkO1xuICAgICAgdmFyIGNocjMgPSAnJztcbiAgICAgIHZhciBlbmMxID0gdW5kZWZpbmVkO1xuICAgICAgdmFyIGVuYzIgPSB1bmRlZmluZWQ7XG4gICAgICB2YXIgZW5jMyA9IHVuZGVmaW5lZDtcbiAgICAgIHZhciBlbmM0ID0gJyc7XG4gICAgICB2YXIgaSA9IDA7XG5cbiAgICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgIGNocjEgPSBpbnB1dFtpKytdO1xuICAgICAgICBjaHIyID0gaW5wdXRbaSsrXTtcbiAgICAgICAgY2hyMyA9IGlucHV0W2krK107XG4gICAgICAgIGVuYzEgPSBjaHIxID4+IDI7XG4gICAgICAgIGVuYzIgPSAoY2hyMSAmIDMpIDw8IDQgfCBjaHIyID4+IDQ7XG4gICAgICAgIGVuYzMgPSAoY2hyMiAmIDE1KSA8PCAyIHwgY2hyMyA+PiA2O1xuICAgICAgICBlbmM0ID0gY2hyMyAmIDYzO1xuXG4gICAgICAgIGlmIChpc05hTihjaHIyKSkge1xuICAgICAgICAgIGVuYzMgPSBlbmM0ID0gNjQ7XG4gICAgICAgIH0gZWxzZSBpZiAoaXNOYU4oY2hyMykpIHtcbiAgICAgICAgICBlbmM0ID0gNjQ7XG4gICAgICAgIH1cblxuICAgICAgICBvdXRwdXQgPSBvdXRwdXQgKyB0aGlzLktFWV9TVFIuY2hhckF0KGVuYzEpICsgdGhpcy5LRVlfU1RSLmNoYXJBdChlbmMyKSArIHRoaXMuS0VZX1NUUi5jaGFyQXQoZW5jMykgKyB0aGlzLktFWV9TVFIuY2hhckF0KGVuYzQpO1xuICAgICAgICBjaHIxID0gY2hyMiA9IGNocjMgPSAnJztcbiAgICAgICAgZW5jMSA9IGVuYzIgPSBlbmMzID0gZW5jNCA9ICcnO1xuXG4gICAgICAgIGlmICghKGkgPCBpbnB1dC5sZW5ndGgpKSB7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIG91dHB1dDtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwicmVzdG9yZVwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiByZXN0b3JlKG9yaWdGaWxlQmFzZTY0LCByZXNpemVkRmlsZUJhc2U2NCkge1xuICAgICAgaWYgKCFvcmlnRmlsZUJhc2U2NC5tYXRjaCgnZGF0YTppbWFnZS9qcGVnO2Jhc2U2NCwnKSkge1xuICAgICAgICByZXR1cm4gcmVzaXplZEZpbGVCYXNlNjQ7XG4gICAgICB9XG5cbiAgICAgIHZhciByYXdJbWFnZSA9IHRoaXMuZGVjb2RlNjQob3JpZ0ZpbGVCYXNlNjQucmVwbGFjZSgnZGF0YTppbWFnZS9qcGVnO2Jhc2U2NCwnLCAnJykpO1xuICAgICAgdmFyIHNlZ21lbnRzID0gdGhpcy5zbGljZTJTZWdtZW50cyhyYXdJbWFnZSk7XG4gICAgICB2YXIgaW1hZ2UgPSB0aGlzLmV4aWZNYW5pcHVsYXRpb24ocmVzaXplZEZpbGVCYXNlNjQsIHNlZ21lbnRzKTtcbiAgICAgIHJldHVybiBcImRhdGE6aW1hZ2UvanBlZztiYXNlNjQsXCIuY29uY2F0KHRoaXMuZW5jb2RlNjQoaW1hZ2UpKTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiZXhpZk1hbmlwdWxhdGlvblwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBleGlmTWFuaXB1bGF0aW9uKHJlc2l6ZWRGaWxlQmFzZTY0LCBzZWdtZW50cykge1xuICAgICAgdmFyIGV4aWZBcnJheSA9IHRoaXMuZ2V0RXhpZkFycmF5KHNlZ21lbnRzKTtcbiAgICAgIHZhciBuZXdJbWFnZUFycmF5ID0gdGhpcy5pbnNlcnRFeGlmKHJlc2l6ZWRGaWxlQmFzZTY0LCBleGlmQXJyYXkpO1xuICAgICAgdmFyIGFCdWZmZXIgPSBuZXcgVWludDhBcnJheShuZXdJbWFnZUFycmF5KTtcbiAgICAgIHJldHVybiBhQnVmZmVyO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJnZXRFeGlmQXJyYXlcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gZ2V0RXhpZkFycmF5KHNlZ21lbnRzKSB7XG4gICAgICB2YXIgc2VnID0gdW5kZWZpbmVkO1xuICAgICAgdmFyIHggPSAwO1xuXG4gICAgICB3aGlsZSAoeCA8IHNlZ21lbnRzLmxlbmd0aCkge1xuICAgICAgICBzZWcgPSBzZWdtZW50c1t4XTtcblxuICAgICAgICBpZiAoc2VnWzBdID09PSAyNTUgJiBzZWdbMV0gPT09IDIyNSkge1xuICAgICAgICAgIHJldHVybiBzZWc7XG4gICAgICAgIH1cblxuICAgICAgICB4Kys7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiaW5zZXJ0RXhpZlwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBpbnNlcnRFeGlmKHJlc2l6ZWRGaWxlQmFzZTY0LCBleGlmQXJyYXkpIHtcbiAgICAgIHZhciBpbWFnZURhdGEgPSByZXNpemVkRmlsZUJhc2U2NC5yZXBsYWNlKCdkYXRhOmltYWdlL2pwZWc7YmFzZTY0LCcsICcnKTtcbiAgICAgIHZhciBidWYgPSB0aGlzLmRlY29kZTY0KGltYWdlRGF0YSk7XG4gICAgICB2YXIgc2VwYXJhdGVQb2ludCA9IGJ1Zi5pbmRleE9mKDI1NSwgMyk7XG4gICAgICB2YXIgbWFlID0gYnVmLnNsaWNlKDAsIHNlcGFyYXRlUG9pbnQpO1xuICAgICAgdmFyIGF0byA9IGJ1Zi5zbGljZShzZXBhcmF0ZVBvaW50KTtcbiAgICAgIHZhciBhcnJheSA9IG1hZTtcbiAgICAgIGFycmF5ID0gYXJyYXkuY29uY2F0KGV4aWZBcnJheSk7XG4gICAgICBhcnJheSA9IGFycmF5LmNvbmNhdChhdG8pO1xuICAgICAgcmV0dXJuIGFycmF5O1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJzbGljZTJTZWdtZW50c1wiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBzbGljZTJTZWdtZW50cyhyYXdJbWFnZUFycmF5KSB7XG4gICAgICB2YXIgaGVhZCA9IDA7XG4gICAgICB2YXIgc2VnbWVudHMgPSBbXTtcblxuICAgICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgdmFyIGxlbmd0aDtcblxuICAgICAgICBpZiAocmF3SW1hZ2VBcnJheVtoZWFkXSA9PT0gMjU1ICYgcmF3SW1hZ2VBcnJheVtoZWFkICsgMV0gPT09IDIxOCkge1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHJhd0ltYWdlQXJyYXlbaGVhZF0gPT09IDI1NSAmIHJhd0ltYWdlQXJyYXlbaGVhZCArIDFdID09PSAyMTYpIHtcbiAgICAgICAgICBoZWFkICs9IDI7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbGVuZ3RoID0gcmF3SW1hZ2VBcnJheVtoZWFkICsgMl0gKiAyNTYgKyByYXdJbWFnZUFycmF5W2hlYWQgKyAzXTtcbiAgICAgICAgICB2YXIgZW5kUG9pbnQgPSBoZWFkICsgbGVuZ3RoICsgMjtcbiAgICAgICAgICB2YXIgc2VnID0gcmF3SW1hZ2VBcnJheS5zbGljZShoZWFkLCBlbmRQb2ludCk7XG4gICAgICAgICAgc2VnbWVudHMucHVzaChzZWcpO1xuICAgICAgICAgIGhlYWQgPSBlbmRQb2ludDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChoZWFkID4gcmF3SW1hZ2VBcnJheS5sZW5ndGgpIHtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gc2VnbWVudHM7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcImRlY29kZTY0XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGRlY29kZTY0KGlucHV0KSB7XG4gICAgICB2YXIgb3V0cHV0ID0gJyc7XG4gICAgICB2YXIgY2hyMSA9IHVuZGVmaW5lZDtcbiAgICAgIHZhciBjaHIyID0gdW5kZWZpbmVkO1xuICAgICAgdmFyIGNocjMgPSAnJztcbiAgICAgIHZhciBlbmMxID0gdW5kZWZpbmVkO1xuICAgICAgdmFyIGVuYzIgPSB1bmRlZmluZWQ7XG4gICAgICB2YXIgZW5jMyA9IHVuZGVmaW5lZDtcbiAgICAgIHZhciBlbmM0ID0gJyc7XG4gICAgICB2YXIgaSA9IDA7XG4gICAgICB2YXIgYnVmID0gW107IC8vIHJlbW92ZSBhbGwgY2hhcmFjdGVycyB0aGF0IGFyZSBub3QgQS1aLCBhLXosIDAtOSwgKywgLywgb3IgPVxuXG4gICAgICB2YXIgYmFzZTY0dGVzdCA9IC9bXkEtWmEtejAtOVxcK1xcL1xcPV0vZztcblxuICAgICAgaWYgKGJhc2U2NHRlc3QuZXhlYyhpbnB1dCkpIHtcbiAgICAgICAgY29uc29sZS53YXJuKCdUaGVyZSB3ZXJlIGludmFsaWQgYmFzZTY0IGNoYXJhY3RlcnMgaW4gdGhlIGlucHV0IHRleHQuXFxuVmFsaWQgYmFzZTY0IGNoYXJhY3RlcnMgYXJlIEEtWiwgYS16LCAwLTksIFxcJytcXCcsIFxcJy9cXCcsYW5kIFxcJz1cXCdcXG5FeHBlY3QgZXJyb3JzIGluIGRlY29kaW5nLicpO1xuICAgICAgfVxuXG4gICAgICBpbnB1dCA9IGlucHV0LnJlcGxhY2UoL1teQS1aYS16MC05XFwrXFwvXFw9XS9nLCAnJyk7XG5cbiAgICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgIGVuYzEgPSB0aGlzLktFWV9TVFIuaW5kZXhPZihpbnB1dC5jaGFyQXQoaSsrKSk7XG4gICAgICAgIGVuYzIgPSB0aGlzLktFWV9TVFIuaW5kZXhPZihpbnB1dC5jaGFyQXQoaSsrKSk7XG4gICAgICAgIGVuYzMgPSB0aGlzLktFWV9TVFIuaW5kZXhPZihpbnB1dC5jaGFyQXQoaSsrKSk7XG4gICAgICAgIGVuYzQgPSB0aGlzLktFWV9TVFIuaW5kZXhPZihpbnB1dC5jaGFyQXQoaSsrKSk7XG4gICAgICAgIGNocjEgPSBlbmMxIDw8IDIgfCBlbmMyID4+IDQ7XG4gICAgICAgIGNocjIgPSAoZW5jMiAmIDE1KSA8PCA0IHwgZW5jMyA+PiAyO1xuICAgICAgICBjaHIzID0gKGVuYzMgJiAzKSA8PCA2IHwgZW5jNDtcbiAgICAgICAgYnVmLnB1c2goY2hyMSk7XG5cbiAgICAgICAgaWYgKGVuYzMgIT09IDY0KSB7XG4gICAgICAgICAgYnVmLnB1c2goY2hyMik7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZW5jNCAhPT0gNjQpIHtcbiAgICAgICAgICBidWYucHVzaChjaHIzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNocjEgPSBjaHIyID0gY2hyMyA9ICcnO1xuICAgICAgICBlbmMxID0gZW5jMiA9IGVuYzMgPSBlbmM0ID0gJyc7XG5cbiAgICAgICAgaWYgKCEoaSA8IGlucHV0Lmxlbmd0aCkpIHtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gYnVmO1xuICAgIH1cbiAgfV0pO1xuXG4gIHJldHVybiBFeGlmUmVzdG9yZTtcbn0oKTtcblxuRXhpZlJlc3RvcmUuaW5pdENsYXNzKCk7XG4vKlxuICogY29udGVudGxvYWRlZC5qc1xuICpcbiAqIEF1dGhvcjogRGllZ28gUGVyaW5pIChkaWVnby5wZXJpbmkgYXQgZ21haWwuY29tKVxuICogU3VtbWFyeTogY3Jvc3MtYnJvd3NlciB3cmFwcGVyIGZvciBET01Db250ZW50TG9hZGVkXG4gKiBVcGRhdGVkOiAyMDEwMTAyMFxuICogTGljZW5zZTogTUlUXG4gKiBWZXJzaW9uOiAxLjJcbiAqXG4gKiBVUkw6XG4gKiBodHRwOi8vamF2YXNjcmlwdC5ud2JveC5jb20vQ29udGVudExvYWRlZC9cbiAqIGh0dHA6Ly9qYXZhc2NyaXB0Lm53Ym94LmNvbS9Db250ZW50TG9hZGVkL01JVC1MSUNFTlNFXG4gKi9cbi8vIEB3aW4gd2luZG93IHJlZmVyZW5jZVxuLy8gQGZuIGZ1bmN0aW9uIHJlZmVyZW5jZVxuXG52YXIgY29udGVudExvYWRlZCA9IGZ1bmN0aW9uIGNvbnRlbnRMb2FkZWQod2luLCBmbikge1xuICB2YXIgZG9uZSA9IGZhbHNlO1xuICB2YXIgdG9wID0gdHJ1ZTtcbiAgdmFyIGRvYyA9IHdpbi5kb2N1bWVudDtcbiAgdmFyIHJvb3QgPSBkb2MuZG9jdW1lbnRFbGVtZW50O1xuICB2YXIgYWRkID0gZG9jLmFkZEV2ZW50TGlzdGVuZXIgPyBcImFkZEV2ZW50TGlzdGVuZXJcIiA6IFwiYXR0YWNoRXZlbnRcIjtcbiAgdmFyIHJlbSA9IGRvYy5hZGRFdmVudExpc3RlbmVyID8gXCJyZW1vdmVFdmVudExpc3RlbmVyXCIgOiBcImRldGFjaEV2ZW50XCI7XG4gIHZhciBwcmUgPSBkb2MuYWRkRXZlbnRMaXN0ZW5lciA/IFwiXCIgOiBcIm9uXCI7XG5cbiAgdmFyIGluaXQgPSBmdW5jdGlvbiBpbml0KGUpIHtcbiAgICBpZiAoZS50eXBlID09PSBcInJlYWR5c3RhdGVjaGFuZ2VcIiAmJiBkb2MucmVhZHlTdGF0ZSAhPT0gXCJjb21wbGV0ZVwiKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgKGUudHlwZSA9PT0gXCJsb2FkXCIgPyB3aW4gOiBkb2MpW3JlbV0ocHJlICsgZS50eXBlLCBpbml0LCBmYWxzZSk7XG5cbiAgICBpZiAoIWRvbmUgJiYgKGRvbmUgPSB0cnVlKSkge1xuICAgICAgcmV0dXJuIGZuLmNhbGwod2luLCBlLnR5cGUgfHwgZSk7XG4gICAgfVxuICB9O1xuXG4gIHZhciBwb2xsID0gZnVuY3Rpb24gcG9sbCgpIHtcbiAgICB0cnkge1xuICAgICAgcm9vdC5kb1Njcm9sbChcImxlZnRcIik7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgc2V0VGltZW91dChwb2xsLCA1MCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgcmV0dXJuIGluaXQoXCJwb2xsXCIpO1xuICB9O1xuXG4gIGlmIChkb2MucmVhZHlTdGF0ZSAhPT0gXCJjb21wbGV0ZVwiKSB7XG4gICAgaWYgKGRvYy5jcmVhdGVFdmVudE9iamVjdCAmJiByb290LmRvU2Nyb2xsKSB7XG4gICAgICB0cnkge1xuICAgICAgICB0b3AgPSAhd2luLmZyYW1lRWxlbWVudDtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7fVxuXG4gICAgICBpZiAodG9wKSB7XG4gICAgICAgIHBvbGwoKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBkb2NbYWRkXShwcmUgKyBcIkRPTUNvbnRlbnRMb2FkZWRcIiwgaW5pdCwgZmFsc2UpO1xuICAgIGRvY1thZGRdKHByZSArIFwicmVhZHlzdGF0ZWNoYW5nZVwiLCBpbml0LCBmYWxzZSk7XG4gICAgcmV0dXJuIHdpblthZGRdKHByZSArIFwibG9hZFwiLCBpbml0LCBmYWxzZSk7XG4gIH1cbn07IC8vIEFzIGEgc2luZ2xlIGZ1bmN0aW9uIHRvIGJlIGFibGUgdG8gd3JpdGUgdGVzdHMuXG5cblxuRHJvcHpvbmUuX2F1dG9EaXNjb3ZlckZ1bmN0aW9uID0gZnVuY3Rpb24gKCkge1xuICBpZiAoRHJvcHpvbmUuYXV0b0Rpc2NvdmVyKSB7XG4gICAgcmV0dXJuIERyb3B6b25lLmRpc2NvdmVyKCk7XG4gIH1cbn07XG5cbmNvbnRlbnRMb2FkZWQod2luZG93LCBEcm9wem9uZS5fYXV0b0Rpc2NvdmVyRnVuY3Rpb24pO1xuXG5mdW5jdGlvbiBfX2d1YXJkX18odmFsdWUsIHRyYW5zZm9ybSkge1xuICByZXR1cm4gdHlwZW9mIHZhbHVlICE9PSAndW5kZWZpbmVkJyAmJiB2YWx1ZSAhPT0gbnVsbCA/IHRyYW5zZm9ybSh2YWx1ZSkgOiB1bmRlZmluZWQ7XG59XG5cbmZ1bmN0aW9uIF9fZ3VhcmRNZXRob2RfXyhvYmosIG1ldGhvZE5hbWUsIHRyYW5zZm9ybSkge1xuICBpZiAodHlwZW9mIG9iaiAhPT0gJ3VuZGVmaW5lZCcgJiYgb2JqICE9PSBudWxsICYmIHR5cGVvZiBvYmpbbWV0aG9kTmFtZV0gPT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gdHJhbnNmb3JtKG9iaiwgbWV0aG9kTmFtZSk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxufVxuIl0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/dropzone/dist/dropzone.js\n");
-
-/***/ }),
-
-/***/ "./node_modules/exif-js/exif.js":
-/*!**************************************!*\
- !*** ./node_modules/exif-js/exif.js ***!
- \**************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-eval("var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function() {\n\n var debug = false;\n\n var root = this;\n\n var EXIF = function(obj) {\n if (obj instanceof EXIF) return obj;\n if (!(this instanceof EXIF)) return new EXIF(obj);\n this.EXIFwrapped = obj;\n };\n\n if (true) {\n if ( true && module.exports) {\n exports = module.exports = EXIF;\n }\n exports.EXIF = EXIF;\n } else {}\n\n var ExifTags = EXIF.Tags = {\n\n // version tags\n 0x9000 : \"ExifVersion\", // EXIF version\n 0xA000 : \"FlashpixVersion\", // Flashpix format version\n\n // colorspace tags\n 0xA001 : \"ColorSpace\", // Color space information tag\n\n // image configuration\n 0xA002 : \"PixelXDimension\", // Valid width of meaningful image\n 0xA003 : \"PixelYDimension\", // Valid height of meaningful image\n 0x9101 : \"ComponentsConfiguration\", // Information about channels\n 0x9102 : \"CompressedBitsPerPixel\", // Compressed bits per pixel\n\n // user information\n 0x927C : \"MakerNote\", // Any desired information written by the manufacturer\n 0x9286 : \"UserComment\", // Comments by user\n\n // related file\n 0xA004 : \"RelatedSoundFile\", // Name of related sound file\n\n // date and time\n 0x9003 : \"DateTimeOriginal\", // Date and time when the original image was generated\n 0x9004 : \"DateTimeDigitized\", // Date and time when the image was stored digitally\n 0x9290 : \"SubsecTime\", // Fractions of seconds for DateTime\n 0x9291 : \"SubsecTimeOriginal\", // Fractions of seconds for DateTimeOriginal\n 0x9292 : \"SubsecTimeDigitized\", // Fractions of seconds for DateTimeDigitized\n\n // picture-taking conditions\n 0x829A : \"ExposureTime\", // Exposure time (in seconds)\n 0x829D : \"FNumber\", // F number\n 0x8822 : \"ExposureProgram\", // Exposure program\n 0x8824 : \"SpectralSensitivity\", // Spectral sensitivity\n 0x8827 : \"ISOSpeedRatings\", // ISO speed rating\n 0x8828 : \"OECF\", // Optoelectric conversion factor\n 0x9201 : \"ShutterSpeedValue\", // Shutter speed\n 0x9202 : \"ApertureValue\", // Lens aperture\n 0x9203 : \"BrightnessValue\", // Value of brightness\n 0x9204 : \"ExposureBias\", // Exposure bias\n 0x9205 : \"MaxApertureValue\", // Smallest F number of lens\n 0x9206 : \"SubjectDistance\", // Distance to subject in meters\n 0x9207 : \"MeteringMode\", // Metering mode\n 0x9208 : \"LightSource\", // Kind of light source\n 0x9209 : \"Flash\", // Flash status\n 0x9214 : \"SubjectArea\", // Location and area of main subject\n 0x920A : \"FocalLength\", // Focal length of the lens in mm\n 0xA20B : \"FlashEnergy\", // Strobe energy in BCPS\n 0xA20C : \"SpatialFrequencyResponse\", //\n 0xA20E : \"FocalPlaneXResolution\", // Number of pixels in width direction per FocalPlaneResolutionUnit\n 0xA20F : \"FocalPlaneYResolution\", // Number of pixels in height direction per FocalPlaneResolutionUnit\n 0xA210 : \"FocalPlaneResolutionUnit\", // Unit for measuring FocalPlaneXResolution and FocalPlaneYResolution\n 0xA214 : \"SubjectLocation\", // Location of subject in image\n 0xA215 : \"ExposureIndex\", // Exposure index selected on camera\n 0xA217 : \"SensingMethod\", // Image sensor type\n 0xA300 : \"FileSource\", // Image source (3 == DSC)\n 0xA301 : \"SceneType\", // Scene type (1 == directly photographed)\n 0xA302 : \"CFAPattern\", // Color filter array geometric pattern\n 0xA401 : \"CustomRendered\", // Special processing\n 0xA402 : \"ExposureMode\", // Exposure mode\n 0xA403 : \"WhiteBalance\", // 1 = auto white balance, 2 = manual\n 0xA404 : \"DigitalZoomRation\", // Digital zoom ratio\n 0xA405 : \"FocalLengthIn35mmFilm\", // Equivalent foacl length assuming 35mm film camera (in mm)\n 0xA406 : \"SceneCaptureType\", // Type of scene\n 0xA407 : \"GainControl\", // Degree of overall image gain adjustment\n 0xA408 : \"Contrast\", // Direction of contrast processing applied by camera\n 0xA409 : \"Saturation\", // Direction of saturation processing applied by camera\n 0xA40A : \"Sharpness\", // Direction of sharpness processing applied by camera\n 0xA40B : \"DeviceSettingDescription\", //\n 0xA40C : \"SubjectDistanceRange\", // Distance to subject\n\n // other tags\n 0xA005 : \"InteroperabilityIFDPointer\",\n 0xA420 : \"ImageUniqueID\" // Identifier assigned uniquely to each image\n };\n\n var TiffTags = EXIF.TiffTags = {\n 0x0100 : \"ImageWidth\",\n 0x0101 : \"ImageHeight\",\n 0x8769 : \"ExifIFDPointer\",\n 0x8825 : \"GPSInfoIFDPointer\",\n 0xA005 : \"InteroperabilityIFDPointer\",\n 0x0102 : \"BitsPerSample\",\n 0x0103 : \"Compression\",\n 0x0106 : \"PhotometricInterpretation\",\n 0x0112 : \"Orientation\",\n 0x0115 : \"SamplesPerPixel\",\n 0x011C : \"PlanarConfiguration\",\n 0x0212 : \"YCbCrSubSampling\",\n 0x0213 : \"YCbCrPositioning\",\n 0x011A : \"XResolution\",\n 0x011B : \"YResolution\",\n 0x0128 : \"ResolutionUnit\",\n 0x0111 : \"StripOffsets\",\n 0x0116 : \"RowsPerStrip\",\n 0x0117 : \"StripByteCounts\",\n 0x0201 : \"JPEGInterchangeFormat\",\n 0x0202 : \"JPEGInterchangeFormatLength\",\n 0x012D : \"TransferFunction\",\n 0x013E : \"WhitePoint\",\n 0x013F : \"PrimaryChromaticities\",\n 0x0211 : \"YCbCrCoefficients\",\n 0x0214 : \"ReferenceBlackWhite\",\n 0x0132 : \"DateTime\",\n 0x010E : \"ImageDescription\",\n 0x010F : \"Make\",\n 0x0110 : \"Model\",\n 0x0131 : \"Software\",\n 0x013B : \"Artist\",\n 0x8298 : \"Copyright\"\n };\n\n var GPSTags = EXIF.GPSTags = {\n 0x0000 : \"GPSVersionID\",\n 0x0001 : \"GPSLatitudeRef\",\n 0x0002 : \"GPSLatitude\",\n 0x0003 : \"GPSLongitudeRef\",\n 0x0004 : \"GPSLongitude\",\n 0x0005 : \"GPSAltitudeRef\",\n 0x0006 : \"GPSAltitude\",\n 0x0007 : \"GPSTimeStamp\",\n 0x0008 : \"GPSSatellites\",\n 0x0009 : \"GPSStatus\",\n 0x000A : \"GPSMeasureMode\",\n 0x000B : \"GPSDOP\",\n 0x000C : \"GPSSpeedRef\",\n 0x000D : \"GPSSpeed\",\n 0x000E : \"GPSTrackRef\",\n 0x000F : \"GPSTrack\",\n 0x0010 : \"GPSImgDirectionRef\",\n 0x0011 : \"GPSImgDirection\",\n 0x0012 : \"GPSMapDatum\",\n 0x0013 : \"GPSDestLatitudeRef\",\n 0x0014 : \"GPSDestLatitude\",\n 0x0015 : \"GPSDestLongitudeRef\",\n 0x0016 : \"GPSDestLongitude\",\n 0x0017 : \"GPSDestBearingRef\",\n 0x0018 : \"GPSDestBearing\",\n 0x0019 : \"GPSDestDistanceRef\",\n 0x001A : \"GPSDestDistance\",\n 0x001B : \"GPSProcessingMethod\",\n 0x001C : \"GPSAreaInformation\",\n 0x001D : \"GPSDateStamp\",\n 0x001E : \"GPSDifferential\"\n };\n\n // EXIF 2.3 Spec\n var IFD1Tags = EXIF.IFD1Tags = {\n 0x0100: \"ImageWidth\",\n 0x0101: \"ImageHeight\",\n 0x0102: \"BitsPerSample\",\n 0x0103: \"Compression\",\n 0x0106: \"PhotometricInterpretation\",\n 0x0111: \"StripOffsets\",\n 0x0112: \"Orientation\",\n 0x0115: \"SamplesPerPixel\",\n 0x0116: \"RowsPerStrip\",\n 0x0117: \"StripByteCounts\",\n 0x011A: \"XResolution\",\n 0x011B: \"YResolution\",\n 0x011C: \"PlanarConfiguration\",\n 0x0128: \"ResolutionUnit\",\n 0x0201: \"JpegIFOffset\", // When image format is JPEG, this value show offset to JPEG data stored.(aka \"ThumbnailOffset\" or \"JPEGInterchangeFormat\")\n 0x0202: \"JpegIFByteCount\", // When image format is JPEG, this value shows data size of JPEG image (aka \"ThumbnailLength\" or \"JPEGInterchangeFormatLength\")\n 0x0211: \"YCbCrCoefficients\",\n 0x0212: \"YCbCrSubSampling\",\n 0x0213: \"YCbCrPositioning\",\n 0x0214: \"ReferenceBlackWhite\"\n };\n\n var StringValues = EXIF.StringValues = {\n ExposureProgram : {\n 0 : \"Not defined\",\n 1 : \"Manual\",\n 2 : \"Normal program\",\n 3 : \"Aperture priority\",\n 4 : \"Shutter priority\",\n 5 : \"Creative program\",\n 6 : \"Action program\",\n 7 : \"Portrait mode\",\n 8 : \"Landscape mode\"\n },\n MeteringMode : {\n 0 : \"Unknown\",\n 1 : \"Average\",\n 2 : \"CenterWeightedAverage\",\n 3 : \"Spot\",\n 4 : \"MultiSpot\",\n 5 : \"Pattern\",\n 6 : \"Partial\",\n 255 : \"Other\"\n },\n LightSource : {\n 0 : \"Unknown\",\n 1 : \"Daylight\",\n 2 : \"Fluorescent\",\n 3 : \"Tungsten (incandescent light)\",\n 4 : \"Flash\",\n 9 : \"Fine weather\",\n 10 : \"Cloudy weather\",\n 11 : \"Shade\",\n 12 : \"Daylight fluorescent (D 5700 - 7100K)\",\n 13 : \"Day white fluorescent (N 4600 - 5400K)\",\n 14 : \"Cool white fluorescent (W 3900 - 4500K)\",\n 15 : \"White fluorescent (WW 3200 - 3700K)\",\n 17 : \"Standard light A\",\n 18 : \"Standard light B\",\n 19 : \"Standard light C\",\n 20 : \"D55\",\n 21 : \"D65\",\n 22 : \"D75\",\n 23 : \"D50\",\n 24 : \"ISO studio tungsten\",\n 255 : \"Other\"\n },\n Flash : {\n 0x0000 : \"Flash did not fire\",\n 0x0001 : \"Flash fired\",\n 0x0005 : \"Strobe return light not detected\",\n 0x0007 : \"Strobe return light detected\",\n 0x0009 : \"Flash fired, compulsory flash mode\",\n 0x000D : \"Flash fired, compulsory flash mode, return light not detected\",\n 0x000F : \"Flash fired, compulsory flash mode, return light detected\",\n 0x0010 : \"Flash did not fire, compulsory flash mode\",\n 0x0018 : \"Flash did not fire, auto mode\",\n 0x0019 : \"Flash fired, auto mode\",\n 0x001D : \"Flash fired, auto mode, return light not detected\",\n 0x001F : \"Flash fired, auto mode, return light detected\",\n 0x0020 : \"No flash function\",\n 0x0041 : \"Flash fired, red-eye reduction mode\",\n 0x0045 : \"Flash fired, red-eye reduction mode, return light not detected\",\n 0x0047 : \"Flash fired, red-eye reduction mode, return light detected\",\n 0x0049 : \"Flash fired, compulsory flash mode, red-eye reduction mode\",\n 0x004D : \"Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected\",\n 0x004F : \"Flash fired, compulsory flash mode, red-eye reduction mode, return light detected\",\n 0x0059 : \"Flash fired, auto mode, red-eye reduction mode\",\n 0x005D : \"Flash fired, auto mode, return light not detected, red-eye reduction mode\",\n 0x005F : \"Flash fired, auto mode, return light detected, red-eye reduction mode\"\n },\n SensingMethod : {\n 1 : \"Not defined\",\n 2 : \"One-chip color area sensor\",\n 3 : \"Two-chip color area sensor\",\n 4 : \"Three-chip color area sensor\",\n 5 : \"Color sequential area sensor\",\n 7 : \"Trilinear sensor\",\n 8 : \"Color sequential linear sensor\"\n },\n SceneCaptureType : {\n 0 : \"Standard\",\n 1 : \"Landscape\",\n 2 : \"Portrait\",\n 3 : \"Night scene\"\n },\n SceneType : {\n 1 : \"Directly photographed\"\n },\n CustomRendered : {\n 0 : \"Normal process\",\n 1 : \"Custom process\"\n },\n WhiteBalance : {\n 0 : \"Auto white balance\",\n 1 : \"Manual white balance\"\n },\n GainControl : {\n 0 : \"None\",\n 1 : \"Low gain up\",\n 2 : \"High gain up\",\n 3 : \"Low gain down\",\n 4 : \"High gain down\"\n },\n Contrast : {\n 0 : \"Normal\",\n 1 : \"Soft\",\n 2 : \"Hard\"\n },\n Saturation : {\n 0 : \"Normal\",\n 1 : \"Low saturation\",\n 2 : \"High saturation\"\n },\n Sharpness : {\n 0 : \"Normal\",\n 1 : \"Soft\",\n 2 : \"Hard\"\n },\n SubjectDistanceRange : {\n 0 : \"Unknown\",\n 1 : \"Macro\",\n 2 : \"Close view\",\n 3 : \"Distant view\"\n },\n FileSource : {\n 3 : \"DSC\"\n },\n\n Components : {\n 0 : \"\",\n 1 : \"Y\",\n 2 : \"Cb\",\n 3 : \"Cr\",\n 4 : \"R\",\n 5 : \"G\",\n 6 : \"B\"\n }\n };\n\n function addEvent(element, event, handler) {\n if (element.addEventListener) {\n element.addEventListener(event, handler, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + event, handler);\n }\n }\n\n function imageHasData(img) {\n return !!(img.exifdata);\n }\n\n\n function base64ToArrayBuffer(base64, contentType) {\n contentType = contentType || base64.match(/^data\\:([^\\;]+)\\;base64,/mi)[1] || ''; // e.g. 'data:image/jpeg;base64,...' => 'image/jpeg'\n base64 = base64.replace(/^data\\:([^\\;]+)\\;base64,/gmi, '');\n var binary = atob(base64);\n var len = binary.length;\n var buffer = new ArrayBuffer(len);\n var view = new Uint8Array(buffer);\n for (var i = 0; i < len; i++) {\n view[i] = binary.charCodeAt(i);\n }\n return buffer;\n }\n\n function objectURLToBlob(url, callback) {\n var http = new XMLHttpRequest();\n http.open(\"GET\", url, true);\n http.responseType = \"blob\";\n http.onload = function(e) {\n if (this.status == 200 || this.status === 0) {\n callback(this.response);\n }\n };\n http.send();\n }\n\n function getImageData(img, callback) {\n function handleBinaryFile(binFile) {\n var data = findEXIFinJPEG(binFile);\n img.exifdata = data || {};\n var iptcdata = findIPTCinJPEG(binFile);\n img.iptcdata = iptcdata || {};\n if (EXIF.isXmpEnabled) {\n var xmpdata= findXMPinJPEG(binFile);\n img.xmpdata = xmpdata || {}; \n }\n if (callback) {\n callback.call(img);\n }\n }\n\n if (img.src) {\n if (/^data\\:/i.test(img.src)) { // Data URI\n var arrayBuffer = base64ToArrayBuffer(img.src);\n handleBinaryFile(arrayBuffer);\n\n } else if (/^blob\\:/i.test(img.src)) { // Object URL\n var fileReader = new FileReader();\n fileReader.onload = function(e) {\n handleBinaryFile(e.target.result);\n };\n objectURLToBlob(img.src, function (blob) {\n fileReader.readAsArrayBuffer(blob);\n });\n } else {\n var http = new XMLHttpRequest();\n http.onload = function() {\n if (this.status == 200 || this.status === 0) {\n handleBinaryFile(http.response);\n } else {\n throw \"Could not load image\";\n }\n http = null;\n };\n http.open(\"GET\", img.src, true);\n http.responseType = \"arraybuffer\";\n http.send(null);\n }\n } else if (self.FileReader && (img instanceof self.Blob || img instanceof self.File)) {\n var fileReader = new FileReader();\n fileReader.onload = function(e) {\n if (debug) console.log(\"Got file of length \" + e.target.result.byteLength);\n handleBinaryFile(e.target.result);\n };\n\n fileReader.readAsArrayBuffer(img);\n }\n }\n\n function findEXIFinJPEG(file) {\n var dataView = new DataView(file);\n\n if (debug) console.log(\"Got file of length \" + file.byteLength);\n if ((dataView.getUint8(0) != 0xFF) || (dataView.getUint8(1) != 0xD8)) {\n if (debug) console.log(\"Not a valid JPEG\");\n return false; // not a valid jpeg\n }\n\n var offset = 2,\n length = file.byteLength,\n marker;\n\n while (offset < length) {\n if (dataView.getUint8(offset) != 0xFF) {\n if (debug) console.log(\"Not a valid marker at offset \" + offset + \", found: \" + dataView.getUint8(offset));\n return false; // not a valid marker, something is wrong\n }\n\n marker = dataView.getUint8(offset + 1);\n if (debug) console.log(marker);\n\n // we could implement handling for other markers here,\n // but we're only looking for 0xFFE1 for EXIF data\n\n if (marker == 225) {\n if (debug) console.log(\"Found 0xFFE1 marker\");\n\n return readEXIFData(dataView, offset + 4, dataView.getUint16(offset + 2) - 2);\n\n // offset += 2 + file.getShortAt(offset+2, true);\n\n } else {\n offset += 2 + dataView.getUint16(offset+2);\n }\n\n }\n\n }\n\n function findIPTCinJPEG(file) {\n var dataView = new DataView(file);\n\n if (debug) console.log(\"Got file of length \" + file.byteLength);\n if ((dataView.getUint8(0) != 0xFF) || (dataView.getUint8(1) != 0xD8)) {\n if (debug) console.log(\"Not a valid JPEG\");\n return false; // not a valid jpeg\n }\n\n var offset = 2,\n length = file.byteLength;\n\n\n var isFieldSegmentStart = function(dataView, offset){\n return (\n dataView.getUint8(offset) === 0x38 &&\n dataView.getUint8(offset+1) === 0x42 &&\n dataView.getUint8(offset+2) === 0x49 &&\n dataView.getUint8(offset+3) === 0x4D &&\n dataView.getUint8(offset+4) === 0x04 &&\n dataView.getUint8(offset+5) === 0x04\n );\n };\n\n while (offset < length) {\n\n if ( isFieldSegmentStart(dataView, offset )){\n\n // Get the length of the name header (which is padded to an even number of bytes)\n var nameHeaderLength = dataView.getUint8(offset+7);\n if(nameHeaderLength % 2 !== 0) nameHeaderLength += 1;\n // Check for pre photoshop 6 format\n if(nameHeaderLength === 0) {\n // Always 4\n nameHeaderLength = 4;\n }\n\n var startOffset = offset + 8 + nameHeaderLength;\n var sectionLength = dataView.getUint16(offset + 6 + nameHeaderLength);\n\n return readIPTCData(file, startOffset, sectionLength);\n\n break;\n\n }\n\n\n // Not the marker, continue searching\n offset++;\n\n }\n\n }\n var IptcFieldMap = {\n 0x78 : 'caption',\n 0x6E : 'credit',\n 0x19 : 'keywords',\n 0x37 : 'dateCreated',\n 0x50 : 'byline',\n 0x55 : 'bylineTitle',\n 0x7A : 'captionWriter',\n 0x69 : 'headline',\n 0x74 : 'copyright',\n 0x0F : 'category'\n };\n function readIPTCData(file, startOffset, sectionLength){\n var dataView = new DataView(file);\n var data = {};\n var fieldValue, fieldName, dataSize, segmentType, segmentSize;\n var segmentStartPos = startOffset;\n while(segmentStartPos < startOffset+sectionLength) {\n if(dataView.getUint8(segmentStartPos) === 0x1C && dataView.getUint8(segmentStartPos+1) === 0x02){\n segmentType = dataView.getUint8(segmentStartPos+2);\n if(segmentType in IptcFieldMap) {\n dataSize = dataView.getInt16(segmentStartPos+3);\n segmentSize = dataSize + 5;\n fieldName = IptcFieldMap[segmentType];\n fieldValue = getStringFromDB(dataView, segmentStartPos+5, dataSize);\n // Check if we already stored a value with this name\n if(data.hasOwnProperty(fieldName)) {\n // Value already stored with this name, create multivalue field\n if(data[fieldName] instanceof Array) {\n data[fieldName].push(fieldValue);\n }\n else {\n data[fieldName] = [data[fieldName], fieldValue];\n }\n }\n else {\n data[fieldName] = fieldValue;\n }\n }\n\n }\n segmentStartPos++;\n }\n return data;\n }\n\n\n\n function readTags(file, tiffStart, dirStart, strings, bigEnd) {\n var entries = file.getUint16(dirStart, !bigEnd),\n tags = {},\n entryOffset, tag,\n i;\n\n for (i=0;i 4 ? valueOffset : (entryOffset + 8);\n vals = [];\n for (n=0;n 4 ? valueOffset : (entryOffset + 8);\n return getStringFromDB(file, offset, numValues-1);\n\n case 3: // short, 16 bit int\n if (numValues == 1) {\n return file.getUint16(entryOffset + 8, !bigEnd);\n } else {\n offset = numValues > 2 ? valueOffset : (entryOffset + 8);\n vals = [];\n for (n=0;n dataView.byteLength) { // this should not happen\n // console.log('******** IFD1Offset is outside the bounds of the DataView ********');\n return {};\n }\n // console.log('******* thumbnail IFD offset (IFD1) is: %s', IFD1OffsetPointer);\n\n var thumbTags = readTags(dataView, tiffStart, tiffStart + IFD1OffsetPointer, IFD1Tags, bigEnd)\n\n // EXIF 2.3 specification for JPEG format thumbnail\n\n // If the value of Compression(0x0103) Tag in IFD1 is '6', thumbnail image format is JPEG.\n // Most of Exif image uses JPEG format for thumbnail. In that case, you can get offset of thumbnail\n // by JpegIFOffset(0x0201) Tag in IFD1, size of thumbnail by JpegIFByteCount(0x0202) Tag.\n // Data format is ordinary JPEG format, starts from 0xFFD8 and ends by 0xFFD9. It seems that\n // JPEG format and 160x120pixels of size are recommended thumbnail format for Exif2.1 or later.\n\n if (thumbTags['Compression']) {\n // console.log('Thumbnail image found!');\n\n switch (thumbTags['Compression']) {\n case 6:\n // console.log('Thumbnail image format is JPEG');\n if (thumbTags.JpegIFOffset && thumbTags.JpegIFByteCount) {\n // extract the thumbnail\n var tOffset = tiffStart + thumbTags.JpegIFOffset;\n var tLength = thumbTags.JpegIFByteCount;\n thumbTags['blob'] = new Blob([new Uint8Array(dataView.buffer, tOffset, tLength)], {\n type: 'image/jpeg'\n });\n }\n break;\n\n case 1:\n console.log(\"Thumbnail image format is TIFF, which is not implemented.\");\n break;\n default:\n console.log(\"Unknown thumbnail image format '%s'\", thumbTags['Compression']);\n }\n }\n else if (thumbTags['PhotometricInterpretation'] == 2) {\n console.log(\"Thumbnail image format is RGB, which is not implemented.\");\n }\n return thumbTags;\n }\n\n function getStringFromDB(buffer, start, length) {\n var outstr = \"\";\n for (n = start; n < start+length; n++) {\n outstr += String.fromCharCode(buffer.getUint8(n));\n }\n return outstr;\n }\n\n function readEXIFData(file, start) {\n if (getStringFromDB(file, start, 4) != \"Exif\") {\n if (debug) console.log(\"Not valid EXIF data! \" + getStringFromDB(file, start, 4));\n return false;\n }\n\n var bigEnd,\n tags, tag,\n exifData, gpsData,\n tiffOffset = start + 6;\n\n // test for TIFF validity and endianness\n if (file.getUint16(tiffOffset) == 0x4949) {\n bigEnd = false;\n } else if (file.getUint16(tiffOffset) == 0x4D4D) {\n bigEnd = true;\n } else {\n if (debug) console.log(\"Not valid TIFF data! (no 0x4949 or 0x4D4D)\");\n return false;\n }\n\n if (file.getUint16(tiffOffset+2, !bigEnd) != 0x002A) {\n if (debug) console.log(\"Not valid TIFF data! (no 0x002A)\");\n return false;\n }\n\n var firstIFDOffset = file.getUint32(tiffOffset+4, !bigEnd);\n\n if (firstIFDOffset < 0x00000008) {\n if (debug) console.log(\"Not valid TIFF data! (First offset less than 8)\", file.getUint32(tiffOffset+4, !bigEnd));\n return false;\n }\n\n tags = readTags(file, tiffOffset, tiffOffset + firstIFDOffset, TiffTags, bigEnd);\n\n if (tags.ExifIFDPointer) {\n exifData = readTags(file, tiffOffset, tiffOffset + tags.ExifIFDPointer, ExifTags, bigEnd);\n for (tag in exifData) {\n switch (tag) {\n case \"LightSource\" :\n case \"Flash\" :\n case \"MeteringMode\" :\n case \"ExposureProgram\" :\n case \"SensingMethod\" :\n case \"SceneCaptureType\" :\n case \"SceneType\" :\n case \"CustomRendered\" :\n case \"WhiteBalance\" :\n case \"GainControl\" :\n case \"Contrast\" :\n case \"Saturation\" :\n case \"Sharpness\" :\n case \"SubjectDistanceRange\" :\n case \"FileSource\" :\n exifData[tag] = StringValues[tag][exifData[tag]];\n break;\n\n case \"ExifVersion\" :\n case \"FlashpixVersion\" :\n exifData[tag] = String.fromCharCode(exifData[tag][0], exifData[tag][1], exifData[tag][2], exifData[tag][3]);\n break;\n\n case \"ComponentsConfiguration\" :\n exifData[tag] =\n StringValues.Components[exifData[tag][0]] +\n StringValues.Components[exifData[tag][1]] +\n StringValues.Components[exifData[tag][2]] +\n StringValues.Components[exifData[tag][3]];\n break;\n }\n tags[tag] = exifData[tag];\n }\n }\n\n if (tags.GPSInfoIFDPointer) {\n gpsData = readTags(file, tiffOffset, tiffOffset + tags.GPSInfoIFDPointer, GPSTags, bigEnd);\n for (tag in gpsData) {\n switch (tag) {\n case \"GPSVersionID\" :\n gpsData[tag] = gpsData[tag][0] +\n \".\" + gpsData[tag][1] +\n \".\" + gpsData[tag][2] +\n \".\" + gpsData[tag][3];\n break;\n }\n tags[tag] = gpsData[tag];\n }\n }\n\n // extract thumbnail\n tags['thumbnail'] = readThumbnailImage(file, tiffOffset, firstIFDOffset, bigEnd);\n\n return tags;\n }\n\n function findXMPinJPEG(file) {\n\n if (!('DOMParser' in self)) {\n // console.warn('XML parsing not supported without DOMParser');\n return;\n }\n var dataView = new DataView(file);\n\n if (debug) console.log(\"Got file of length \" + file.byteLength);\n if ((dataView.getUint8(0) != 0xFF) || (dataView.getUint8(1) != 0xD8)) {\n if (debug) console.log(\"Not a valid JPEG\");\n return false; // not a valid jpeg\n }\n\n var offset = 2,\n length = file.byteLength,\n dom = new DOMParser();\n\n while (offset < (length-4)) {\n if (getStringFromDB(dataView, offset, 4) == \"http\") {\n var startOffset = offset - 1;\n var sectionLength = dataView.getUint16(offset - 2) - 1;\n var xmpString = getStringFromDB(dataView, startOffset, sectionLength)\n var xmpEndIndex = xmpString.indexOf('xmpmeta>') + 8;\n xmpString = xmpString.substring( xmpString.indexOf( ' 0) {\n json['@attributes'] = {};\n for (var j = 0; j < xml.attributes.length; j++) {\n var attribute = xml.attributes.item(j);\n json['@attributes'][attribute.nodeName] = attribute.nodeValue;\n }\n }\n } else if (xml.nodeType == 3) { // text node\n return xml.nodeValue;\n }\n \n // deal with children\n if (xml.hasChildNodes()) {\n for(var i = 0; i < xml.childNodes.length; i++) {\n var child = xml.childNodes.item(i);\n var nodeName = child.nodeName;\n if (json[nodeName] == null) {\n json[nodeName] = xml2json(child);\n } else {\n if (json[nodeName].push == null) {\n var old = json[nodeName];\n json[nodeName] = [];\n json[nodeName].push(old);\n }\n json[nodeName].push(xml2json(child));\n }\n }\n }\n \n return json;\n }\n\n function xml2Object(xml) {\n try {\n var obj = {};\n if (xml.children.length > 0) {\n for (var i = 0; i < xml.children.length; i++) {\n var item = xml.children.item(i);\n var attributes = item.attributes;\n for(var idx in attributes) {\n var itemAtt = attributes[idx];\n var dataKey = itemAtt.nodeName;\n var dataValue = itemAtt.nodeValue;\n\n if(dataKey !== undefined) {\n obj[dataKey] = dataValue;\n }\n }\n var nodeName = item.nodeName;\n\n if (typeof (obj[nodeName]) == \"undefined\") {\n obj[nodeName] = xml2json(item);\n } else {\n if (typeof (obj[nodeName].push) == \"undefined\") {\n var old = obj[nodeName];\n\n obj[nodeName] = [];\n obj[nodeName].push(old);\n }\n obj[nodeName].push(xml2json(item));\n }\n }\n } else {\n obj = xml.textContent;\n }\n return obj;\n } catch (e) {\n console.log(e.message);\n }\n }\n\n EXIF.enableXmp = function() {\n EXIF.isXmpEnabled = true;\n }\n\n EXIF.disableXmp = function() {\n EXIF.isXmpEnabled = false;\n }\n\n EXIF.getData = function(img, callback) {\n if (((self.Image && img instanceof self.Image)\n || (self.HTMLImageElement && img instanceof self.HTMLImageElement))\n && !img.complete)\n return false;\n\n if (!imageHasData(img)) {\n getImageData(img, callback);\n } else {\n if (callback) {\n callback.call(img);\n }\n }\n return true;\n }\n\n EXIF.getTag = function(img, tag) {\n if (!imageHasData(img)) return;\n return img.exifdata[tag];\n }\n \n EXIF.getIptcTag = function(img, tag) {\n if (!imageHasData(img)) return;\n return img.iptcdata[tag];\n }\n\n EXIF.getAllTags = function(img) {\n if (!imageHasData(img)) return {};\n var a,\n data = img.exifdata,\n tags = {};\n for (a in data) {\n if (data.hasOwnProperty(a)) {\n tags[a] = data[a];\n }\n }\n return tags;\n }\n \n EXIF.getAllIptcTags = function(img) {\n if (!imageHasData(img)) return {};\n var a,\n data = img.iptcdata,\n tags = {};\n for (a in data) {\n if (data.hasOwnProperty(a)) {\n tags[a] = data[a];\n }\n }\n return tags;\n }\n\n EXIF.pretty = function(img) {\n if (!imageHasData(img)) return \"\";\n var a,\n data = img.exifdata,\n strPretty = \"\";\n for (a in data) {\n if (data.hasOwnProperty(a)) {\n if (typeof data[a] == \"object\") {\n if (data[a] instanceof Number) {\n strPretty += a + \" : \" + data[a] + \" [\" + data[a].numerator + \"/\" + data[a].denominator + \"]\\r\\n\";\n } else {\n strPretty += a + \" : [\" + data[a].length + \" values]\\r\\n\";\n }\n } else {\n strPretty += a + \" : \" + data[a] + \"\\r\\n\";\n }\n }\n }\n return strPretty;\n }\n\n EXIF.readFromBinaryFile = function(file) {\n return findEXIFinJPEG(file);\n }\n\n if (true) {\n !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = (function() {\n return EXIF;\n }).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),\n\t\t\t\t__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n }\n}.call(this));\n\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvZXhpZi1qcy9leGlmLmpzPzZmNDUiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxRQUFRLElBQThCO0FBQ3RDLFlBQVksS0FBNkI7QUFDekM7QUFDQTtBQUNBO0FBQ0EsS0FBSyxNQUFNLEVBRU47O0FBRUw7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0EsU0FBUzs7QUFFVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7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O0FBQ0E7O0FBRUEsd0VBQXdFO0FBQ3hFOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJEQUEyRDtBQUMzRDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCO0FBQ3pCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSx1QkFBdUIsa0JBQWtCO0FBQ3pDO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLHdCQUF3QjtBQUN4Qjs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLGdDQUFnQztBQUNoQztBQUNBO0FBQ0EsMkJBQTJCLDJCQUEyQjtBQUN0RDtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVMsOEJBQThCO0FBQ3ZDO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLHdCQUF3QiwyQkFBMkI7QUFDbkQ7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIseUJBQXlCO0FBQ3REO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0EsV0FBVztBQUNYO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsUUFBUSxJQUEwQztBQUNsRCxRQUFRLGlDQUFrQixFQUFFLG1DQUFFO0FBQzlCO0FBQ0EsU0FBUztBQUFBLG9HQUFDO0FBQ1Y7QUFDQSxDQUFDIiwiZmlsZSI6Ii4vbm9kZV9tb2R1bGVzL2V4aWYtanMvZXhpZi5qcy5qcyIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbigpIHtcblxuICAgIHZhciBkZWJ1ZyA9IGZhbHNlO1xuXG4gICAgdmFyIHJvb3QgPSB0aGlzO1xuXG4gICAgdmFyIEVYSUYgPSBmdW5jdGlvbihvYmopIHtcbiAgICAgICAgaWYgKG9iaiBpbnN0YW5jZW9mIEVYSUYpIHJldHVybiBvYmo7XG4gICAgICAgIGlmICghKHRoaXMgaW5zdGFuY2VvZiBFWElGKSkgcmV0dXJuIG5ldyBFWElGKG9iaik7XG4gICAgICAgIHRoaXMuRVhJRndyYXBwZWQgPSBvYmo7XG4gICAgfTtcblxuICAgIGlmICh0eXBlb2YgZXhwb3J0cyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnICYmIG1vZHVsZS5leHBvcnRzKSB7XG4gICAgICAgICAgICBleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSBFWElGO1xuICAgICAgICB9XG4gICAgICAgIGV4cG9ydHMuRVhJRiA9IEVYSUY7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcm9vdC5FWElGID0gRVhJRjtcbiAgICB9XG5cbiAgICB2YXIgRXhpZlRhZ3MgPSBFWElGLlRhZ3MgPSB7XG5cbiAgICAgICAgLy8gdmVyc2lvbiB0YWdzXG4gICAgICAgIDB4OTAwMCA6IFwiRXhpZlZlcnNpb25cIiwgICAgICAgICAgICAgLy8gRVhJRiB2ZXJzaW9uXG4gICAgICAgIDB4QTAwMCA6IFwiRmxhc2hwaXhWZXJzaW9uXCIsICAgICAgICAgLy8gRmxhc2hwaXggZm9ybWF0IHZlcnNpb25cblxuICAgICAgICAvLyBjb2xvcnNwYWNlIHRhZ3NcbiAgICAgICAgMHhBMDAxIDogXCJDb2xvclNwYWNlXCIsICAgICAgICAgICAgICAvLyBDb2xvciBzcGFjZSBpbmZvcm1hdGlvbiB0YWdcblxuICAgICAgICAvLyBpbWFnZSBjb25maWd1cmF0aW9uXG4gICAgICAgIDB4QTAwMiA6IFwiUGl4ZWxYRGltZW5zaW9uXCIsICAgICAgICAgLy8gVmFsaWQgd2lkdGggb2YgbWVhbmluZ2Z1bCBpbWFnZVxuICAgICAgICAweEEwMDMgOiBcIlBpeGVsWURpbWVuc2lvblwiLCAgICAgICAgIC8vIFZhbGlkIGhlaWdodCBvZiBtZWFuaW5nZnVsIGltYWdlXG4gICAgICAgIDB4OTEwMSA6IFwiQ29tcG9uZW50c0NvbmZpZ3VyYXRpb25cIiwgLy8gSW5mb3JtYXRpb24gYWJvdXQgY2hhbm5lbHNcbiAgICAgICAgMHg5MTAyIDogXCJDb21wcmVzc2VkQml0c1BlclBpeGVsXCIsICAvLyBDb21wcmVzc2VkIGJpdHMgcGVyIHBpeGVsXG5cbiAgICAgICAgLy8gdXNlciBpbmZvcm1hdGlvblxuICAgICAgICAweDkyN0MgOiBcIk1ha2VyTm90ZVwiLCAgICAgICAgICAgICAgIC8vIEFueSBkZXNpcmVkIGluZm9ybWF0aW9uIHdyaXR0ZW4gYnkgdGhlIG1hbnVmYWN0dXJlclxuICAgICAgICAweDkyODYgOiBcIlVzZXJDb21tZW50XCIsICAgICAgICAgICAgIC8vIENvbW1lbnRzIGJ5IHVzZXJcblxuICAgICAgICAvLyByZWxhdGVkIGZpbGVcbiAgICAgICAgMHhBMDA0IDogXCJSZWxhdGVkU291bmRGaWxlXCIsICAgICAgICAvLyBOYW1lIG9mIHJlbGF0ZWQgc291bmQgZmlsZVxuXG4gICAgICAgIC8vIGRhdGUgYW5kIHRpbWVcbiAgICAgICAgMHg5MDAzIDogXCJEYXRlVGltZU9yaWdpbmFsXCIsICAgICAgICAvLyBEYXRlIGFuZCB0aW1lIHdoZW4gdGhlIG9yaWdpbmFsIGltYWdlIHdhcyBnZW5lcmF0ZWRcbiAgICAgICAgMHg5MDA0IDogXCJEYXRlVGltZURpZ2l0aXplZFwiLCAgICAgICAvLyBEYXRlIGFuZCB0aW1lIHdoZW4gdGhlIGltYWdlIHdhcyBzdG9yZWQgZGlnaXRhbGx5XG4gICAgICAgIDB4OTI5MCA6IFwiU3Vic2VjVGltZVwiLCAgICAgICAgICAgICAgLy8gRnJhY3Rpb25zIG9mIHNlY29uZHMgZm9yIERhdGVUaW1lXG4gICAgICAgIDB4OTI5MSA6IFwiU3Vic2VjVGltZU9yaWdpbmFsXCIsICAgICAgLy8gRnJhY3Rpb25zIG9mIHNlY29uZHMgZm9yIERhdGVUaW1lT3JpZ2luYWxcbiAgICAgICAgMHg5MjkyIDogXCJTdWJzZWNUaW1lRGlnaXRpemVkXCIsICAgICAvLyBGcmFjdGlvbnMgb2Ygc2Vjb25kcyBmb3IgRGF0ZVRpbWVEaWdpdGl6ZWRcblxuICAgICAgICAvLyBwaWN0dXJlLXRha2luZyBjb25kaXRpb25zXG4gICAgICAgIDB4ODI5QSA6IFwiRXhwb3N1cmVUaW1lXCIsICAgICAgICAgICAgLy8gRXhwb3N1cmUgdGltZSAoaW4gc2Vjb25kcylcbiAgICAgICAgMHg4MjlEIDogXCJGTnVtYmVyXCIsICAgICAgICAgICAgICAgICAvLyBGIG51bWJlclxuICAgICAgICAweDg4MjIgOiBcIkV4cG9zdXJlUHJvZ3JhbVwiLCAgICAgICAgIC8vIEV4cG9zdXJlIHByb2dyYW1cbiAgICAgICAgMHg4ODI0IDogXCJTcGVjdHJhbFNlbnNpdGl2aXR5XCIsICAgICAvLyBTcGVjdHJhbCBzZW5zaXRpdml0eVxuICAgICAgICAweDg4MjcgOiBcIklTT1NwZWVkUmF0aW5nc1wiLCAgICAgICAgIC8vIElTTyBzcGVlZCByYXRpbmdcbiAgICAgICAgMHg4ODI4IDogXCJPRUNGXCIsICAgICAgICAgICAgICAgICAgICAvLyBPcHRvZWxlY3RyaWMgY29udmVyc2lvbiBmYWN0b3JcbiAgICAgICAgMHg5MjAxIDogXCJTaHV0dGVyU3BlZWRWYWx1ZVwiLCAgICAgICAvLyBTaHV0dGVyIHNwZWVkXG4gICAgICAgIDB4OTIwMiA6IFwiQXBlcnR1cmVWYWx1ZVwiLCAgICAgICAgICAgLy8gTGVucyBhcGVydHVyZVxuICAgICAgICAweDkyMDMgOiBcIkJyaWdodG5lc3NWYWx1ZVwiLCAgICAgICAgIC8vIFZhbHVlIG9mIGJyaWdodG5lc3NcbiAgICAgICAgMHg5MjA0IDogXCJFeHBvc3VyZUJpYXNcIiwgICAgICAgICAgICAvLyBFeHBvc3VyZSBiaWFzXG4gICAgICAgIDB4OTIwNSA6IFwiTWF4QXBlcnR1cmVWYWx1ZVwiLCAgICAgICAgLy8gU21hbGxlc3QgRiBudW1iZXIgb2YgbGVuc1xuICAgICAgICAweDkyMDYgOiBcIlN1YmplY3REaXN0YW5jZVwiLCAgICAgICAgIC8vIERpc3RhbmNlIHRvIHN1YmplY3QgaW4gbWV0ZXJzXG4gICAgICAgIDB4OTIwNyA6IFwiTWV0ZXJpbmdNb2RlXCIsICAgICAgICAgICAgLy8gTWV0ZXJpbmcgbW9kZVxuICAgICAgICAweDkyMDggOiBcIkxpZ2h0U291cmNlXCIsICAgICAgICAgICAgIC8vIEtpbmQgb2YgbGlnaHQgc291cmNlXG4gICAgICAgIDB4OTIwOSA6IFwiRmxhc2hcIiwgICAgICAgICAgICAgICAgICAgLy8gRmxhc2ggc3RhdHVzXG4gICAgICAgIDB4OTIxNCA6IFwiU3ViamVjdEFyZWFcIiwgICAgICAgICAgICAgLy8gTG9jYXRpb24gYW5kIGFyZWEgb2YgbWFpbiBzdWJqZWN0XG4gICAgICAgIDB4OTIwQSA6IFwiRm9jYWxMZW5ndGhcIiwgICAgICAgICAgICAgLy8gRm9jYWwgbGVuZ3RoIG9mIHRoZSBsZW5zIGluIG1tXG4gICAgICAgIDB4QTIwQiA6IFwiRmxhc2hFbmVyZ3lcIiwgICAgICAgICAgICAgLy8gU3Ryb2JlIGVuZXJneSBpbiBCQ1BTXG4gICAgICAgIDB4QTIwQyA6IFwiU3BhdGlhbEZyZXF1ZW5jeVJlc3BvbnNlXCIsICAgIC8vXG4gICAgICAgIDB4QTIwRSA6IFwiRm9jYWxQbGFuZVhSZXNvbHV0aW9uXCIsICAgLy8gTnVtYmVyIG9mIHBpeGVscyBpbiB3aWR0aCBkaXJlY3Rpb24gcGVyIEZvY2FsUGxhbmVSZXNvbHV0aW9uVW5pdFxuICAgICAgICAweEEyMEYgOiBcIkZvY2FsUGxhbmVZUmVzb2x1dGlvblwiLCAgIC8vIE51bWJlciBvZiBwaXhlbHMgaW4gaGVpZ2h0IGRpcmVjdGlvbiBwZXIgRm9jYWxQbGFuZVJlc29sdXRpb25Vbml0XG4gICAgICAgIDB4QTIxMCA6IFwiRm9jYWxQbGFuZVJlc29sdXRpb25Vbml0XCIsICAgIC8vIFVuaXQgZm9yIG1lYXN1cmluZyBGb2NhbFBsYW5lWFJlc29sdXRpb24gYW5kIEZvY2FsUGxhbmVZUmVzb2x1dGlvblxuICAgICAgICAweEEyMTQgOiBcIlN1YmplY3RMb2NhdGlvblwiLCAgICAgICAgIC8vIExvY2F0aW9uIG9mIHN1YmplY3QgaW4gaW1hZ2VcbiAgICAgICAgMHhBMjE1IDogXCJFeHBvc3VyZUluZGV4XCIsICAgICAgICAgICAvLyBFeHBvc3VyZSBpbmRleCBzZWxlY3RlZCBvbiBjYW1lcmFcbiAgICAgICAgMHhBMjE3IDogXCJTZW5zaW5nTWV0aG9kXCIsICAgICAgICAgICAvLyBJbWFnZSBzZW5zb3IgdHlwZVxuICAgICAgICAweEEzMDAgOiBcIkZpbGVTb3VyY2VcIiwgICAgICAgICAgICAgIC8vIEltYWdlIHNvdXJjZSAoMyA9PSBEU0MpXG4gICAgICAgIDB4QTMwMSA6IFwiU2NlbmVUeXBlXCIsICAgICAgICAgICAgICAgLy8gU2NlbmUgdHlwZSAoMSA9PSBkaXJlY3RseSBwaG90b2dyYXBoZWQpXG4gICAgICAgIDB4QTMwMiA6IFwiQ0ZBUGF0dGVyblwiLCAgICAgICAgICAgICAgLy8gQ29sb3IgZmlsdGVyIGFycmF5IGdlb21ldHJpYyBwYXR0ZXJuXG4gICAgICAgIDB4QTQwMSA6IFwiQ3VzdG9tUmVuZGVyZWRcIiwgICAgICAgICAgLy8gU3BlY2lhbCBwcm9jZXNzaW5nXG4gICAgICAgIDB4QTQwMiA6IFwiRXhwb3N1cmVNb2RlXCIsICAgICAgICAgICAgLy8gRXhwb3N1cmUgbW9kZVxuICAgICAgICAweEE0MDMgOiBcIldoaXRlQmFsYW5jZVwiLCAgICAgICAgICAgIC8vIDEgPSBhdXRvIHdoaXRlIGJhbGFuY2UsIDIgPSBtYW51YWxcbiAgICAgICAgMHhBNDA0IDogXCJEaWdpdGFsWm9vbVJhdGlvblwiLCAgICAgICAvLyBEaWdpdGFsIHpvb20gcmF0aW9cbiAgICAgICAgMHhBNDA1IDogXCJGb2NhbExlbmd0aEluMzVtbUZpbG1cIiwgICAvLyBFcXVpdmFsZW50IGZvYWNsIGxlbmd0aCBhc3N1bWluZyAzNW1tIGZpbG0gY2FtZXJhIChpbiBtbSlcbiAgICAgICAgMHhBNDA2IDogXCJTY2VuZUNhcHR1cmVUeXBlXCIsICAgICAgICAvLyBUeXBlIG9mIHNjZW5lXG4gICAgICAgIDB4QTQwNyA6IFwiR2FpbkNvbnRyb2xcIiwgICAgICAgICAgICAgLy8gRGVncmVlIG9mIG92ZXJhbGwgaW1hZ2UgZ2FpbiBhZGp1c3RtZW50XG4gICAgICAgIDB4QTQwOCA6IFwiQ29udHJhc3RcIiwgICAgICAgICAgICAgICAgLy8gRGlyZWN0aW9uIG9mIGNvbnRyYXN0IHByb2Nlc3NpbmcgYXBwbGllZCBieSBjYW1lcmFcbiAgICAgICAgMHhBNDA5IDogXCJTYXR1cmF0aW9uXCIsICAgICAgICAgICAgICAvLyBEaXJlY3Rpb24gb2Ygc2F0dXJhdGlvbiBwcm9jZXNzaW5nIGFwcGxpZWQgYnkgY2FtZXJhXG4gICAgICAgIDB4QTQwQSA6IFwiU2hhcnBuZXNzXCIsICAgICAgICAgICAgICAgLy8gRGlyZWN0aW9uIG9mIHNoYXJwbmVzcyBwcm9jZXNzaW5nIGFwcGxpZWQgYnkgY2FtZXJhXG4gICAgICAgIDB4QTQwQiA6IFwiRGV2aWNlU2V0dGluZ0Rlc2NyaXB0aW9uXCIsICAgIC8vXG4gICAgICAgIDB4QTQwQyA6IFwiU3ViamVjdERpc3RhbmNlUmFuZ2VcIiwgICAgLy8gRGlzdGFuY2UgdG8gc3ViamVjdFxuXG4gICAgICAgIC8vIG90aGVyIHRhZ3NcbiAgICAgICAgMHhBMDA1IDogXCJJbnRlcm9wZXJhYmlsaXR5SUZEUG9pbnRlclwiLFxuICAgICAgICAweEE0MjAgOiBcIkltYWdlVW5pcXVlSURcIiAgICAgICAgICAgIC8vIElkZW50aWZpZXIgYXNzaWduZWQgdW5pcXVlbHkgdG8gZWFjaCBpbWFnZVxuICAgIH07XG5cbiAgICB2YXIgVGlmZlRhZ3MgPSBFWElGLlRpZmZUYWdzID0ge1xuICAgICAgICAweDAxMDAgOiBcIkltYWdlV2lkdGhcIixcbiAgICAgICAgMHgwMTAxIDogXCJJbWFnZUhlaWdodFwiLFxuICAgICAgICAweDg3NjkgOiBcIkV4aWZJRkRQb2ludGVyXCIsXG4gICAgICAgIDB4ODgyNSA6IFwiR1BTSW5mb0lGRFBvaW50ZXJcIixcbiAgICAgICAgMHhBMDA1IDogXCJJbnRlcm9wZXJhYmlsaXR5SUZEUG9pbnRlclwiLFxuICAgICAgICAweDAxMDIgOiBcIkJpdHNQZXJTYW1wbGVcIixcbiAgICAgICAgMHgwMTAzIDogXCJDb21wcmVzc2lvblwiLFxuICAgICAgICAweDAxMDYgOiBcIlBob3RvbWV0cmljSW50ZXJwcmV0YXRpb25cIixcbiAgICAgICAgMHgwMTEyIDogXCJPcmllbnRhdGlvblwiLFxuICAgICAgICAweDAxMTUgOiBcIlNhbXBsZXNQZXJQaXhlbFwiLFxuICAgICAgICAweDAxMUMgOiBcIlBsYW5hckNvbmZpZ3VyYXRpb25cIixcbiAgICAgICAgMHgwMjEyIDogXCJZQ2JDclN1YlNhbXBsaW5nXCIsXG4gICAgICAgIDB4MDIxMyA6IFwiWUNiQ3JQb3NpdGlvbmluZ1wiLFxuICAgICAgICAweDAxMUEgOiBcIlhSZXNvbHV0aW9uXCIsXG4gICAgICAgIDB4MDExQiA6IFwiWVJlc29sdXRpb25cIixcbiAgICAgICAgMHgwMTI4IDogXCJSZXNvbHV0aW9uVW5pdFwiLFxuICAgICAgICAweDAxMTEgOiBcIlN0cmlwT2Zmc2V0c1wiLFxuICAgICAgICAweDAxMTYgOiBcIlJvd3NQZXJTdHJpcFwiLFxuICAgICAgICAweDAxMTcgOiBcIlN0cmlwQnl0ZUNvdW50c1wiLFxuICAgICAgICAweDAyMDEgOiBcIkpQRUdJbnRlcmNoYW5nZUZvcm1hdFwiLFxuICAgICAgICAweDAyMDIgOiBcIkpQRUdJbnRlcmNoYW5nZUZvcm1hdExlbmd0aFwiLFxuICAgICAgICAweDAxMkQgOiBcIlRyYW5zZmVyRnVuY3Rpb25cIixcbiAgICAgICAgMHgwMTNFIDogXCJXaGl0ZVBvaW50XCIsXG4gICAgICAgIDB4MDEzRiA6IFwiUHJpbWFyeUNocm9tYXRpY2l0aWVzXCIsXG4gICAgICAgIDB4MDIxMSA6IFwiWUNiQ3JDb2VmZmljaWVudHNcIixcbiAgICAgICAgMHgwMjE0IDogXCJSZWZlcmVuY2VCbGFja1doaXRlXCIsXG4gICAgICAgIDB4MDEzMiA6IFwiRGF0ZVRpbWVcIixcbiAgICAgICAgMHgwMTBFIDogXCJJbWFnZURlc2NyaXB0aW9uXCIsXG4gICAgICAgIDB4MDEwRiA6IFwiTWFrZVwiLFxuICAgICAgICAweDAxMTAgOiBcIk1vZGVsXCIsXG4gICAgICAgIDB4MDEzMSA6IFwiU29mdHdhcmVcIixcbiAgICAgICAgMHgwMTNCIDogXCJBcnRpc3RcIixcbiAgICAgICAgMHg4Mjk4IDogXCJDb3B5cmlnaHRcIlxuICAgIH07XG5cbiAgICB2YXIgR1BTVGFncyA9IEVYSUYuR1BTVGFncyA9IHtcbiAgICAgICAgMHgwMDAwIDogXCJHUFNWZXJzaW9uSURcIixcbiAgICAgICAgMHgwMDAxIDogXCJHUFNMYXRpdHVkZVJlZlwiLFxuICAgICAgICAweDAwMDIgOiBcIkdQU0xhdGl0dWRlXCIsXG4gICAgICAgIDB4MDAwMyA6IFwiR1BTTG9uZ2l0dWRlUmVmXCIsXG4gICAgICAgIDB4MDAwNCA6IFwiR1BTTG9uZ2l0dWRlXCIsXG4gICAgICAgIDB4MDAwNSA6IFwiR1BTQWx0aXR1ZGVSZWZcIixcbiAgICAgICAgMHgwMDA2IDogXCJHUFNBbHRpdHVkZVwiLFxuICAgICAgICAweDAwMDcgOiBcIkdQU1RpbWVTdGFtcFwiLFxuICAgICAgICAweDAwMDggOiBcIkdQU1NhdGVsbGl0ZXNcIixcbiAgICAgICAgMHgwMDA5IDogXCJHUFNTdGF0dXNcIixcbiAgICAgICAgMHgwMDBBIDogXCJHUFNNZWFzdXJlTW9kZVwiLFxuICAgICAgICAweDAwMEIgOiBcIkdQU0RPUFwiLFxuICAgICAgICAweDAwMEMgOiBcIkdQU1NwZWVkUmVmXCIsXG4gICAgICAgIDB4MDAwRCA6IFwiR1BTU3BlZWRcIixcbiAgICAgICAgMHgwMDBFIDogXCJHUFNUcmFja1JlZlwiLFxuICAgICAgICAweDAwMEYgOiBcIkdQU1RyYWNrXCIsXG4gICAgICAgIDB4MDAxMCA6IFwiR1BTSW1nRGlyZWN0aW9uUmVmXCIsXG4gICAgICAgIDB4MDAxMSA6IFwiR1BTSW1nRGlyZWN0aW9uXCIsXG4gICAgICAgIDB4MDAxMiA6IFwiR1BTTWFwRGF0dW1cIixcbiAgICAgICAgMHgwMDEzIDogXCJHUFNEZXN0TGF0aXR1ZGVSZWZcIixcbiAgICAgICAgMHgwMDE0IDogXCJHUFNEZXN0TGF0aXR1ZGVcIixcbiAgICAgICAgMHgwMDE1IDogXCJHUFNEZXN0TG9uZ2l0dWRlUmVmXCIsXG4gICAgICAgIDB4MDAxNiA6IFwiR1BTRGVzdExvbmdpdHVkZVwiLFxuICAgICAgICAweDAwMTcgOiBcIkdQU0Rlc3RCZWFyaW5nUmVmXCIsXG4gICAgICAgIDB4MDAxOCA6IFwiR1BTRGVzdEJlYXJpbmdcIixcbiAgICAgICAgMHgwMDE5IDogXCJHUFNEZXN0RGlzdGFuY2VSZWZcIixcbiAgICAgICAgMHgwMDFBIDogXCJHUFNEZXN0RGlzdGFuY2VcIixcbiAgICAgICAgMHgwMDFCIDogXCJHUFNQcm9jZXNzaW5nTWV0aG9kXCIsXG4gICAgICAgIDB4MDAxQyA6IFwiR1BTQXJlYUluZm9ybWF0aW9uXCIsXG4gICAgICAgIDB4MDAxRCA6IFwiR1BTRGF0ZVN0YW1wXCIsXG4gICAgICAgIDB4MDAxRSA6IFwiR1BTRGlmZmVyZW50aWFsXCJcbiAgICB9O1xuXG4gICAgIC8vIEVYSUYgMi4zIFNwZWNcbiAgICB2YXIgSUZEMVRhZ3MgPSBFWElGLklGRDFUYWdzID0ge1xuICAgICAgICAweDAxMDA6IFwiSW1hZ2VXaWR0aFwiLFxuICAgICAgICAweDAxMDE6IFwiSW1hZ2VIZWlnaHRcIixcbiAgICAgICAgMHgwMTAyOiBcIkJpdHNQZXJTYW1wbGVcIixcbiAgICAgICAgMHgwMTAzOiBcIkNvbXByZXNzaW9uXCIsXG4gICAgICAgIDB4MDEwNjogXCJQaG90b21ldHJpY0ludGVycHJldGF0aW9uXCIsXG4gICAgICAgIDB4MDExMTogXCJTdHJpcE9mZnNldHNcIixcbiAgICAgICAgMHgwMTEyOiBcIk9yaWVudGF0aW9uXCIsXG4gICAgICAgIDB4MDExNTogXCJTYW1wbGVzUGVyUGl4ZWxcIixcbiAgICAgICAgMHgwMTE2OiBcIlJvd3NQZXJTdHJpcFwiLFxuICAgICAgICAweDAxMTc6IFwiU3RyaXBCeXRlQ291bnRzXCIsXG4gICAgICAgIDB4MDExQTogXCJYUmVzb2x1dGlvblwiLFxuICAgICAgICAweDAxMUI6IFwiWVJlc29sdXRpb25cIixcbiAgICAgICAgMHgwMTFDOiBcIlBsYW5hckNvbmZpZ3VyYXRpb25cIixcbiAgICAgICAgMHgwMTI4OiBcIlJlc29sdXRpb25Vbml0XCIsXG4gICAgICAgIDB4MDIwMTogXCJKcGVnSUZPZmZzZXRcIiwgICAgLy8gV2hlbiBpbWFnZSBmb3JtYXQgaXMgSlBFRywgdGhpcyB2YWx1ZSBzaG93IG9mZnNldCB0byBKUEVHIGRhdGEgc3RvcmVkLihha2EgXCJUaHVtYm5haWxPZmZzZXRcIiBvciBcIkpQRUdJbnRlcmNoYW5nZUZvcm1hdFwiKVxuICAgICAgICAweDAyMDI6IFwiSnBlZ0lGQnl0ZUNvdW50XCIsIC8vIFdoZW4gaW1hZ2UgZm9ybWF0IGlzIEpQRUcsIHRoaXMgdmFsdWUgc2hvd3MgZGF0YSBzaXplIG9mIEpQRUcgaW1hZ2UgKGFrYSBcIlRodW1ibmFpbExlbmd0aFwiIG9yIFwiSlBFR0ludGVyY2hhbmdlRm9ybWF0TGVuZ3RoXCIpXG4gICAgICAgIDB4MDIxMTogXCJZQ2JDckNvZWZmaWNpZW50c1wiLFxuICAgICAgICAweDAyMTI6IFwiWUNiQ3JTdWJTYW1wbGluZ1wiLFxuICAgICAgICAweDAyMTM6IFwiWUNiQ3JQb3NpdGlvbmluZ1wiLFxuICAgICAgICAweDAyMTQ6IFwiUmVmZXJlbmNlQmxhY2tXaGl0ZVwiXG4gICAgfTtcblxuICAgIHZhciBTdHJpbmdWYWx1ZXMgPSBFWElGLlN0cmluZ1ZhbHVlcyA9IHtcbiAgICAgICAgRXhwb3N1cmVQcm9ncmFtIDoge1xuICAgICAgICAgICAgMCA6IFwiTm90IGRlZmluZWRcIixcbiAgICAgICAgICAgIDEgOiBcIk1hbnVhbFwiLFxuICAgICAgICAgICAgMiA6IFwiTm9ybWFsIHByb2dyYW1cIixcbiAgICAgICAgICAgIDMgOiBcIkFwZXJ0dXJlIHByaW9yaXR5XCIsXG4gICAgICAgICAgICA0IDogXCJTaHV0dGVyIHByaW9yaXR5XCIsXG4gICAgICAgICAgICA1IDogXCJDcmVhdGl2ZSBwcm9ncmFtXCIsXG4gICAgICAgICAgICA2IDogXCJBY3Rpb24gcHJvZ3JhbVwiLFxuICAgICAgICAgICAgNyA6IFwiUG9ydHJhaXQgbW9kZVwiLFxuICAgICAgICAgICAgOCA6IFwiTGFuZHNjYXBlIG1vZGVcIlxuICAgICAgICB9LFxuICAgICAgICBNZXRlcmluZ01vZGUgOiB7XG4gICAgICAgICAgICAwIDogXCJVbmtub3duXCIsXG4gICAgICAgICAgICAxIDogXCJBdmVyYWdlXCIsXG4gICAgICAgICAgICAyIDogXCJDZW50ZXJXZWlnaHRlZEF2ZXJhZ2VcIixcbiAgICAgICAgICAgIDMgOiBcIlNwb3RcIixcbiAgICAgICAgICAgIDQgOiBcIk11bHRpU3BvdFwiLFxuICAgICAgICAgICAgNSA6IFwiUGF0dGVyblwiLFxuICAgICAgICAgICAgNiA6IFwiUGFydGlhbFwiLFxuICAgICAgICAgICAgMjU1IDogXCJPdGhlclwiXG4gICAgICAgIH0sXG4gICAgICAgIExpZ2h0U291cmNlIDoge1xuICAgICAgICAgICAgMCA6IFwiVW5rbm93blwiLFxuICAgICAgICAgICAgMSA6IFwiRGF5bGlnaHRcIixcbiAgICAgICAgICAgIDIgOiBcIkZsdW9yZXNjZW50XCIsXG4gICAgICAgICAgICAzIDogXCJUdW5nc3RlbiAoaW5jYW5kZXNjZW50IGxpZ2h0KVwiLFxuICAgICAgICAgICAgNCA6IFwiRmxhc2hcIixcbiAgICAgICAgICAgIDkgOiBcIkZpbmUgd2VhdGhlclwiLFxuICAgICAgICAgICAgMTAgOiBcIkNsb3VkeSB3ZWF0aGVyXCIsXG4gICAgICAgICAgICAxMSA6IFwiU2hhZGVcIixcbiAgICAgICAgICAgIDEyIDogXCJEYXlsaWdodCBmbHVvcmVzY2VudCAoRCA1NzAwIC0gNzEwMEspXCIsXG4gICAgICAgICAgICAxMyA6IFwiRGF5IHdoaXRlIGZsdW9yZXNjZW50IChOIDQ2MDAgLSA1NDAwSylcIixcbiAgICAgICAgICAgIDE0IDogXCJDb29sIHdoaXRlIGZsdW9yZXNjZW50IChXIDM5MDAgLSA0NTAwSylcIixcbiAgICAgICAgICAgIDE1IDogXCJXaGl0ZSBmbHVvcmVzY2VudCAoV1cgMzIwMCAtIDM3MDBLKVwiLFxuICAgICAgICAgICAgMTcgOiBcIlN0YW5kYXJkIGxpZ2h0IEFcIixcbiAgICAgICAgICAgIDE4IDogXCJTdGFuZGFyZCBsaWdodCBCXCIsXG4gICAgICAgICAgICAxOSA6IFwiU3RhbmRhcmQgbGlnaHQgQ1wiLFxuICAgICAgICAgICAgMjAgOiBcIkQ1NVwiLFxuICAgICAgICAgICAgMjEgOiBcIkQ2NVwiLFxuICAgICAgICAgICAgMjIgOiBcIkQ3NVwiLFxuICAgICAgICAgICAgMjMgOiBcIkQ1MFwiLFxuICAgICAgICAgICAgMjQgOiBcIklTTyBzdHVkaW8gdHVuZ3N0ZW5cIixcbiAgICAgICAgICAgIDI1NSA6IFwiT3RoZXJcIlxuICAgICAgICB9LFxuICAgICAgICBGbGFzaCA6IHtcbiAgICAgICAgICAgIDB4MDAwMCA6IFwiRmxhc2ggZGlkIG5vdCBmaXJlXCIsXG4gICAgICAgICAgICAweDAwMDEgOiBcIkZsYXNoIGZpcmVkXCIsXG4gICAgICAgICAgICAweDAwMDUgOiBcIlN0cm9iZSByZXR1cm4gbGlnaHQgbm90IGRldGVjdGVkXCIsXG4gICAgICAgICAgICAweDAwMDcgOiBcIlN0cm9iZSByZXR1cm4gbGlnaHQgZGV0ZWN0ZWRcIixcbiAgICAgICAgICAgIDB4MDAwOSA6IFwiRmxhc2ggZmlyZWQsIGNvbXB1bHNvcnkgZmxhc2ggbW9kZVwiLFxuICAgICAgICAgICAgMHgwMDBEIDogXCJGbGFzaCBmaXJlZCwgY29tcHVsc29yeSBmbGFzaCBtb2RlLCByZXR1cm4gbGlnaHQgbm90IGRldGVjdGVkXCIsXG4gICAgICAgICAgICAweDAwMEYgOiBcIkZsYXNoIGZpcmVkLCBjb21wdWxzb3J5IGZsYXNoIG1vZGUsIHJldHVybiBsaWdodCBkZXRlY3RlZFwiLFxuICAgICAgICAgICAgMHgwMDEwIDogXCJGbGFzaCBkaWQgbm90IGZpcmUsIGNvbXB1bHNvcnkgZmxhc2ggbW9kZVwiLFxuICAgICAgICAgICAgMHgwMDE4IDogXCJGbGFzaCBkaWQgbm90IGZpcmUsIGF1dG8gbW9kZVwiLFxuICAgICAgICAgICAgMHgwMDE5IDogXCJGbGFzaCBmaXJlZCwgYXV0byBtb2RlXCIsXG4gICAgICAgICAgICAweDAwMUQgOiBcIkZsYXNoIGZpcmVkLCBhdXRvIG1vZGUsIHJldHVybiBsaWdodCBub3QgZGV0ZWN0ZWRcIixcbiAgICAgICAgICAgIDB4MDAxRiA6IFwiRmxhc2ggZmlyZWQsIGF1dG8gbW9kZSwgcmV0dXJuIGxpZ2h0IGRldGVjdGVkXCIsXG4gICAgICAgICAgICAweDAwMjAgOiBcIk5vIGZsYXNoIGZ1bmN0aW9uXCIsXG4gICAgICAgICAgICAweDAwNDEgOiBcIkZsYXNoIGZpcmVkLCByZWQtZXllIHJlZHVjdGlvbiBtb2RlXCIsXG4gICAgICAgICAgICAweDAwNDUgOiBcIkZsYXNoIGZpcmVkLCByZWQtZXllIHJlZHVjdGlvbiBtb2RlLCByZXR1cm4gbGlnaHQgbm90IGRldGVjdGVkXCIsXG4gICAgICAgICAgICAweDAwNDcgOiBcIkZsYXNoIGZpcmVkLCByZWQtZXllIHJlZHVjdGlvbiBtb2RlLCByZXR1cm4gbGlnaHQgZGV0ZWN0ZWRcIixcbiAgICAgICAgICAgIDB4MDA0OSA6IFwiRmxhc2ggZmlyZWQsIGNvbXB1bHNvcnkgZmxhc2ggbW9kZSwgcmVkLWV5ZSByZWR1Y3Rpb24gbW9kZVwiLFxuICAgICAgICAgICAgMHgwMDREIDogXCJGbGFzaCBmaXJlZCwgY29tcHVsc29yeSBmbGFzaCBtb2RlLCByZWQtZXllIHJlZHVjdGlvbiBtb2RlLCByZXR1cm4gbGlnaHQgbm90IGRldGVjdGVkXCIsXG4gICAgICAgICAgICAweDAwNEYgOiBcIkZsYXNoIGZpcmVkLCBjb21wdWxzb3J5IGZsYXNoIG1vZGUsIHJlZC1leWUgcmVkdWN0aW9uIG1vZGUsIHJldHVybiBsaWdodCBkZXRlY3RlZFwiLFxuICAgICAgICAgICAgMHgwMDU5IDogXCJGbGFzaCBmaXJlZCwgYXV0byBtb2RlLCByZWQtZXllIHJlZHVjdGlvbiBtb2RlXCIsXG4gICAgICAgICAgICAweDAwNUQgOiBcIkZsYXNoIGZpcmVkLCBhdXRvIG1vZGUsIHJldHVybiBsaWdodCBub3QgZGV0ZWN0ZWQsIHJlZC1leWUgcmVkdWN0aW9uIG1vZGVcIixcbiAgICAgICAgICAgIDB4MDA1RiA6IFwiRmxhc2ggZmlyZWQsIGF1dG8gbW9kZSwgcmV0dXJuIGxpZ2h0IGRldGVjdGVkLCByZWQtZXllIHJlZHVjdGlvbiBtb2RlXCJcbiAgICAgICAgfSxcbiAgICAgICAgU2Vuc2luZ01ldGhvZCA6IHtcbiAgICAgICAgICAgIDEgOiBcIk5vdCBkZWZpbmVkXCIsXG4gICAgICAgICAgICAyIDogXCJPbmUtY2hpcCBjb2xvciBhcmVhIHNlbnNvclwiLFxuICAgICAgICAgICAgMyA6IFwiVHdvLWNoaXAgY29sb3IgYXJlYSBzZW5zb3JcIixcbiAgICAgICAgICAgIDQgOiBcIlRocmVlLWNoaXAgY29sb3IgYXJlYSBzZW5zb3JcIixcbiAgICAgICAgICAgIDUgOiBcIkNvbG9yIHNlcXVlbnRpYWwgYXJlYSBzZW5zb3JcIixcbiAgICAgICAgICAgIDcgOiBcIlRyaWxpbmVhciBzZW5zb3JcIixcbiAgICAgICAgICAgIDggOiBcIkNvbG9yIHNlcXVlbnRpYWwgbGluZWFyIHNlbnNvclwiXG4gICAgICAgIH0sXG4gICAgICAgIFNjZW5lQ2FwdHVyZVR5cGUgOiB7XG4gICAgICAgICAgICAwIDogXCJTdGFuZGFyZFwiLFxuICAgICAgICAgICAgMSA6IFwiTGFuZHNjYXBlXCIsXG4gICAgICAgICAgICAyIDogXCJQb3J0cmFpdFwiLFxuICAgICAgICAgICAgMyA6IFwiTmlnaHQgc2NlbmVcIlxuICAgICAgICB9LFxuICAgICAgICBTY2VuZVR5cGUgOiB7XG4gICAgICAgICAgICAxIDogXCJEaXJlY3RseSBwaG90b2dyYXBoZWRcIlxuICAgICAgICB9LFxuICAgICAgICBDdXN0b21SZW5kZXJlZCA6IHtcbiAgICAgICAgICAgIDAgOiBcIk5vcm1hbCBwcm9jZXNzXCIsXG4gICAgICAgICAgICAxIDogXCJDdXN0b20gcHJvY2Vzc1wiXG4gICAgICAgIH0sXG4gICAgICAgIFdoaXRlQmFsYW5jZSA6IHtcbiAgICAgICAgICAgIDAgOiBcIkF1dG8gd2hpdGUgYmFsYW5jZVwiLFxuICAgICAgICAgICAgMSA6IFwiTWFudWFsIHdoaXRlIGJhbGFuY2VcIlxuICAgICAgICB9LFxuICAgICAgICBHYWluQ29udHJvbCA6IHtcbiAgICAgICAgICAgIDAgOiBcIk5vbmVcIixcbiAgICAgICAgICAgIDEgOiBcIkxvdyBnYWluIHVwXCIsXG4gICAgICAgICAgICAyIDogXCJIaWdoIGdhaW4gdXBcIixcbiAgICAgICAgICAgIDMgOiBcIkxvdyBnYWluIGRvd25cIixcbiAgICAgICAgICAgIDQgOiBcIkhpZ2ggZ2FpbiBkb3duXCJcbiAgICAgICAgfSxcbiAgICAgICAgQ29udHJhc3QgOiB7XG4gICAgICAgICAgICAwIDogXCJOb3JtYWxcIixcbiAgICAgICAgICAgIDEgOiBcIlNvZnRcIixcbiAgICAgICAgICAgIDIgOiBcIkhhcmRcIlxuICAgICAgICB9LFxuICAgICAgICBTYXR1cmF0aW9uIDoge1xuICAgICAgICAgICAgMCA6IFwiTm9ybWFsXCIsXG4gICAgICAgICAgICAxIDogXCJMb3cgc2F0dXJhdGlvblwiLFxuICAgICAgICAgICAgMiA6IFwiSGlnaCBzYXR1cmF0aW9uXCJcbiAgICAgICAgfSxcbiAgICAgICAgU2hhcnBuZXNzIDoge1xuICAgICAgICAgICAgMCA6IFwiTm9ybWFsXCIsXG4gICAgICAgICAgICAxIDogXCJTb2Z0XCIsXG4gICAgICAgICAgICAyIDogXCJIYXJkXCJcbiAgICAgICAgfSxcbiAgICAgICAgU3ViamVjdERpc3RhbmNlUmFuZ2UgOiB7XG4gICAgICAgICAgICAwIDogXCJVbmtub3duXCIsXG4gICAgICAgICAgICAxIDogXCJNYWNyb1wiLFxuICAgICAgICAgICAgMiA6IFwiQ2xvc2Ugdmlld1wiLFxuICAgICAgICAgICAgMyA6IFwiRGlzdGFudCB2aWV3XCJcbiAgICAgICAgfSxcbiAgICAgICAgRmlsZVNvdXJjZSA6IHtcbiAgICAgICAgICAgIDMgOiBcIkRTQ1wiXG4gICAgICAgIH0sXG5cbiAgICAgICAgQ29tcG9uZW50cyA6IHtcbiAgICAgICAgICAgIDAgOiBcIlwiLFxuICAgICAgICAgICAgMSA6IFwiWVwiLFxuICAgICAgICAgICAgMiA6IFwiQ2JcIixcbiAgICAgICAgICAgIDMgOiBcIkNyXCIsXG4gICAgICAgICAgICA0IDogXCJSXCIsXG4gICAgICAgICAgICA1IDogXCJHXCIsXG4gICAgICAgICAgICA2IDogXCJCXCJcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBmdW5jdGlvbiBhZGRFdmVudChlbGVtZW50LCBldmVudCwgaGFuZGxlcikge1xuICAgICAgICBpZiAoZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKSB7XG4gICAgICAgICAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoZXZlbnQsIGhhbmRsZXIsIGZhbHNlKTtcbiAgICAgICAgfSBlbHNlIGlmIChlbGVtZW50LmF0dGFjaEV2ZW50KSB7XG4gICAgICAgICAgICBlbGVtZW50LmF0dGFjaEV2ZW50KFwib25cIiArIGV2ZW50LCBoYW5kbGVyKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGltYWdlSGFzRGF0YShpbWcpIHtcbiAgICAgICAgcmV0dXJuICEhKGltZy5leGlmZGF0YSk7XG4gICAgfVxuXG5cbiAgICBmdW5jdGlvbiBiYXNlNjRUb0FycmF5QnVmZmVyKGJhc2U2NCwgY29udGVudFR5cGUpIHtcbiAgICAgICAgY29udGVudFR5cGUgPSBjb250ZW50VHlwZSB8fCBiYXNlNjQubWF0Y2goL15kYXRhXFw6KFteXFw7XSspXFw7YmFzZTY0LC9taSlbMV0gfHwgJyc7IC8vIGUuZy4gJ2RhdGE6aW1hZ2UvanBlZztiYXNlNjQsLi4uJyA9PiAnaW1hZ2UvanBlZydcbiAgICAgICAgYmFzZTY0ID0gYmFzZTY0LnJlcGxhY2UoL15kYXRhXFw6KFteXFw7XSspXFw7YmFzZTY0LC9nbWksICcnKTtcbiAgICAgICAgdmFyIGJpbmFyeSA9IGF0b2IoYmFzZTY0KTtcbiAgICAgICAgdmFyIGxlbiA9IGJpbmFyeS5sZW5ndGg7XG4gICAgICAgIHZhciBidWZmZXIgPSBuZXcgQXJyYXlCdWZmZXIobGVuKTtcbiAgICAgICAgdmFyIHZpZXcgPSBuZXcgVWludDhBcnJheShidWZmZXIpO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICB2aWV3W2ldID0gYmluYXJ5LmNoYXJDb2RlQXQoaSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGJ1ZmZlcjtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBvYmplY3RVUkxUb0Jsb2IodXJsLCBjYWxsYmFjaykge1xuICAgICAgICB2YXIgaHR0cCA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xuICAgICAgICBodHRwLm9wZW4oXCJHRVRcIiwgdXJsLCB0cnVlKTtcbiAgICAgICAgaHR0cC5yZXNwb25zZVR5cGUgPSBcImJsb2JcIjtcbiAgICAgICAgaHR0cC5vbmxvYWQgPSBmdW5jdGlvbihlKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5zdGF0dXMgPT0gMjAwIHx8IHRoaXMuc3RhdHVzID09PSAwKSB7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2sodGhpcy5yZXNwb25zZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIGh0dHAuc2VuZCgpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGdldEltYWdlRGF0YShpbWcsIGNhbGxiYWNrKSB7XG4gICAgICAgIGZ1bmN0aW9uIGhhbmRsZUJpbmFyeUZpbGUoYmluRmlsZSkge1xuICAgICAgICAgICAgdmFyIGRhdGEgPSBmaW5kRVhJRmluSlBFRyhiaW5GaWxlKTtcbiAgICAgICAgICAgIGltZy5leGlmZGF0YSA9IGRhdGEgfHwge307XG4gICAgICAgICAgICB2YXIgaXB0Y2RhdGEgPSBmaW5kSVBUQ2luSlBFRyhiaW5GaWxlKTtcbiAgICAgICAgICAgIGltZy5pcHRjZGF0YSA9IGlwdGNkYXRhIHx8IHt9O1xuICAgICAgICAgICAgaWYgKEVYSUYuaXNYbXBFbmFibGVkKSB7XG4gICAgICAgICAgICAgICB2YXIgeG1wZGF0YT0gZmluZFhNUGluSlBFRyhiaW5GaWxlKTtcbiAgICAgICAgICAgICAgIGltZy54bXBkYXRhID0geG1wZGF0YSB8fCB7fTsgICAgICAgICAgICAgICBcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChjYWxsYmFjaykge1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrLmNhbGwoaW1nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpbWcuc3JjKSB7XG4gICAgICAgICAgICBpZiAoL15kYXRhXFw6L2kudGVzdChpbWcuc3JjKSkgeyAvLyBEYXRhIFVSSVxuICAgICAgICAgICAgICAgIHZhciBhcnJheUJ1ZmZlciA9IGJhc2U2NFRvQXJyYXlCdWZmZXIoaW1nLnNyYyk7XG4gICAgICAgICAgICAgICAgaGFuZGxlQmluYXJ5RmlsZShhcnJheUJ1ZmZlcik7XG5cbiAgICAgICAgICAgIH0gZWxzZSBpZiAoL15ibG9iXFw6L2kudGVzdChpbWcuc3JjKSkgeyAvLyBPYmplY3QgVVJMXG4gICAgICAgICAgICAgICAgdmFyIGZpbGVSZWFkZXIgPSBuZXcgRmlsZVJlYWRlcigpO1xuICAgICAgICAgICAgICAgIGZpbGVSZWFkZXIub25sb2FkID0gZnVuY3Rpb24oZSkge1xuICAgICAgICAgICAgICAgICAgICBoYW5kbGVCaW5hcnlGaWxlKGUudGFyZ2V0LnJlc3VsdCk7XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBvYmplY3RVUkxUb0Jsb2IoaW1nLnNyYywgZnVuY3Rpb24gKGJsb2IpIHtcbiAgICAgICAgICAgICAgICAgICAgZmlsZVJlYWRlci5yZWFkQXNBcnJheUJ1ZmZlcihibG9iKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdmFyIGh0dHAgPSBuZXcgWE1MSHR0cFJlcXVlc3QoKTtcbiAgICAgICAgICAgICAgICBodHRwLm9ubG9hZCA9IGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zdGF0dXMgPT0gMjAwIHx8IHRoaXMuc3RhdHVzID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBoYW5kbGVCaW5hcnlGaWxlKGh0dHAucmVzcG9uc2UpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgXCJDb3VsZCBub3QgbG9hZCBpbWFnZVwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGh0dHAgPSBudWxsO1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgaHR0cC5vcGVuKFwiR0VUXCIsIGltZy5zcmMsIHRydWUpO1xuICAgICAgICAgICAgICAgIGh0dHAucmVzcG9uc2VUeXBlID0gXCJhcnJheWJ1ZmZlclwiO1xuICAgICAgICAgICAgICAgIGh0dHAuc2VuZChudWxsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChzZWxmLkZpbGVSZWFkZXIgJiYgKGltZyBpbnN0YW5jZW9mIHNlbGYuQmxvYiB8fCBpbWcgaW5zdGFuY2VvZiBzZWxmLkZpbGUpKSB7XG4gICAgICAgICAgICB2YXIgZmlsZVJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7XG4gICAgICAgICAgICBmaWxlUmVhZGVyLm9ubG9hZCA9IGZ1bmN0aW9uKGUpIHtcbiAgICAgICAgICAgICAgICBpZiAoZGVidWcpIGNvbnNvbGUubG9nKFwiR290IGZpbGUgb2YgbGVuZ3RoIFwiICsgZS50YXJnZXQucmVzdWx0LmJ5dGVMZW5ndGgpO1xuICAgICAgICAgICAgICAgIGhhbmRsZUJpbmFyeUZpbGUoZS50YXJnZXQucmVzdWx0KTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGZpbGVSZWFkZXIucmVhZEFzQXJyYXlCdWZmZXIoaW1nKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGZpbmRFWElGaW5KUEVHKGZpbGUpIHtcbiAgICAgICAgdmFyIGRhdGFWaWV3ID0gbmV3IERhdGFWaWV3KGZpbGUpO1xuXG4gICAgICAgIGlmIChkZWJ1ZykgY29uc29sZS5sb2coXCJHb3QgZmlsZSBvZiBsZW5ndGggXCIgKyBmaWxlLmJ5dGVMZW5ndGgpO1xuICAgICAgICBpZiAoKGRhdGFWaWV3LmdldFVpbnQ4KDApICE9IDB4RkYpIHx8IChkYXRhVmlldy5nZXRVaW50OCgxKSAhPSAweEQ4KSkge1xuICAgICAgICAgICAgaWYgKGRlYnVnKSBjb25zb2xlLmxvZyhcIk5vdCBhIHZhbGlkIEpQRUdcIik7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7IC8vIG5vdCBhIHZhbGlkIGpwZWdcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBvZmZzZXQgPSAyLFxuICAgICAgICAgICAgbGVuZ3RoID0gZmlsZS5ieXRlTGVuZ3RoLFxuICAgICAgICAgICAgbWFya2VyO1xuXG4gICAgICAgIHdoaWxlIChvZmZzZXQgPCBsZW5ndGgpIHtcbiAgICAgICAgICAgIGlmIChkYXRhVmlldy5nZXRVaW50OChvZmZzZXQpICE9IDB4RkYpIHtcbiAgICAgICAgICAgICAgICBpZiAoZGVidWcpIGNvbnNvbGUubG9nKFwiTm90IGEgdmFsaWQgbWFya2VyIGF0IG9mZnNldCBcIiArIG9mZnNldCArIFwiLCBmb3VuZDogXCIgKyBkYXRhVmlldy5nZXRVaW50OChvZmZzZXQpKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7IC8vIG5vdCBhIHZhbGlkIG1hcmtlciwgc29tZXRoaW5nIGlzIHdyb25nXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIG1hcmtlciA9IGRhdGFWaWV3LmdldFVpbnQ4KG9mZnNldCArIDEpO1xuICAgICAgICAgICAgaWYgKGRlYnVnKSBjb25zb2xlLmxvZyhtYXJrZXIpO1xuXG4gICAgICAgICAgICAvLyB3ZSBjb3VsZCBpbXBsZW1lbnQgaGFuZGxpbmcgZm9yIG90aGVyIG1hcmtlcnMgaGVyZSxcbiAgICAgICAgICAgIC8vIGJ1dCB3ZSdyZSBvbmx5IGxvb2tpbmcgZm9yIDB4RkZFMSBmb3IgRVhJRiBkYXRhXG5cbiAgICAgICAgICAgIGlmIChtYXJrZXIgPT0gMjI1KSB7XG4gICAgICAgICAgICAgICAgaWYgKGRlYnVnKSBjb25zb2xlLmxvZyhcIkZvdW5kIDB4RkZFMSBtYXJrZXJcIik7XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gcmVhZEVYSUZEYXRhKGRhdGFWaWV3LCBvZmZzZXQgKyA0LCBkYXRhVmlldy5nZXRVaW50MTYob2Zmc2V0ICsgMikgLSAyKTtcblxuICAgICAgICAgICAgICAgIC8vIG9mZnNldCArPSAyICsgZmlsZS5nZXRTaG9ydEF0KG9mZnNldCsyLCB0cnVlKTtcblxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBvZmZzZXQgKz0gMiArIGRhdGFWaWV3LmdldFVpbnQxNihvZmZzZXQrMik7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgfVxuXG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZmluZElQVENpbkpQRUcoZmlsZSkge1xuICAgICAgICB2YXIgZGF0YVZpZXcgPSBuZXcgRGF0YVZpZXcoZmlsZSk7XG5cbiAgICAgICAgaWYgKGRlYnVnKSBjb25zb2xlLmxvZyhcIkdvdCBmaWxlIG9mIGxlbmd0aCBcIiArIGZpbGUuYnl0ZUxlbmd0aCk7XG4gICAgICAgIGlmICgoZGF0YVZpZXcuZ2V0VWludDgoMCkgIT0gMHhGRikgfHwgKGRhdGFWaWV3LmdldFVpbnQ4KDEpICE9IDB4RDgpKSB7XG4gICAgICAgICAgICBpZiAoZGVidWcpIGNvbnNvbGUubG9nKFwiTm90IGEgdmFsaWQgSlBFR1wiKTtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTsgLy8gbm90IGEgdmFsaWQganBlZ1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIG9mZnNldCA9IDIsXG4gICAgICAgICAgICBsZW5ndGggPSBmaWxlLmJ5dGVMZW5ndGg7XG5cblxuICAgICAgICB2YXIgaXNGaWVsZFNlZ21lbnRTdGFydCA9IGZ1bmN0aW9uKGRhdGFWaWV3LCBvZmZzZXQpe1xuICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICAgICBkYXRhVmlldy5nZXRVaW50OChvZmZzZXQpID09PSAweDM4ICYmXG4gICAgICAgICAgICAgICAgZGF0YVZpZXcuZ2V0VWludDgob2Zmc2V0KzEpID09PSAweDQyICYmXG4gICAgICAgICAgICAgICAgZGF0YVZpZXcuZ2V0VWludDgob2Zmc2V0KzIpID09PSAweDQ5ICYmXG4gICAgICAgICAgICAgICAgZGF0YVZpZXcuZ2V0VWludDgob2Zmc2V0KzMpID09PSAweDREICYmXG4gICAgICAgICAgICAgICAgZGF0YVZpZXcuZ2V0VWludDgob2Zmc2V0KzQpID09PSAweDA0ICYmXG4gICAgICAgICAgICAgICAgZGF0YVZpZXcuZ2V0VWludDgob2Zmc2V0KzUpID09PSAweDA0XG4gICAgICAgICAgICApO1xuICAgICAgICB9O1xuXG4gICAgICAgIHdoaWxlIChvZmZzZXQgPCBsZW5ndGgpIHtcblxuICAgICAgICAgICAgaWYgKCBpc0ZpZWxkU2VnbWVudFN0YXJ0KGRhdGFWaWV3LCBvZmZzZXQgKSl7XG5cbiAgICAgICAgICAgICAgICAvLyBHZXQgdGhlIGxlbmd0aCBvZiB0aGUgbmFtZSBoZWFkZXIgKHdoaWNoIGlzIHBhZGRlZCB0byBhbiBldmVuIG51bWJlciBvZiBieXRlcylcbiAgICAgICAgICAgICAgICB2YXIgbmFtZUhlYWRlckxlbmd0aCA9IGRhdGFWaWV3LmdldFVpbnQ4KG9mZnNldCs3KTtcbiAgICAgICAgICAgICAgICBpZihuYW1lSGVhZGVyTGVuZ3RoICUgMiAhPT0gMCkgbmFtZUhlYWRlckxlbmd0aCArPSAxO1xuICAgICAgICAgICAgICAgIC8vIENoZWNrIGZvciBwcmUgcGhvdG9zaG9wIDYgZm9ybWF0XG4gICAgICAgICAgICAgICAgaWYobmFtZUhlYWRlckxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAvLyBBbHdheXMgNFxuICAgICAgICAgICAgICAgICAgICBuYW1lSGVhZGVyTGVuZ3RoID0gNDtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB2YXIgc3RhcnRPZmZzZXQgPSBvZmZzZXQgKyA4ICsgbmFtZUhlYWRlckxlbmd0aDtcbiAgICAgICAgICAgICAgICB2YXIgc2VjdGlvbkxlbmd0aCA9IGRhdGFWaWV3LmdldFVpbnQxNihvZmZzZXQgKyA2ICsgbmFtZUhlYWRlckxlbmd0aCk7XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gcmVhZElQVENEYXRhKGZpbGUsIHN0YXJ0T2Zmc2V0LCBzZWN0aW9uTGVuZ3RoKTtcblxuICAgICAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgICB9XG5cblxuICAgICAgICAgICAgLy8gTm90IHRoZSBtYXJrZXIsIGNvbnRpbnVlIHNlYXJjaGluZ1xuICAgICAgICAgICAgb2Zmc2V0Kys7XG5cbiAgICAgICAgfVxuXG4gICAgfVxuICAgIHZhciBJcHRjRmllbGRNYXAgPSB7XG4gICAgICAgIDB4NzggOiAnY2FwdGlvbicsXG4gICAgICAgIDB4NkUgOiAnY3JlZGl0JyxcbiAgICAgICAgMHgxOSA6ICdrZXl3b3JkcycsXG4gICAgICAgIDB4MzcgOiAnZGF0ZUNyZWF0ZWQnLFxuICAgICAgICAweDUwIDogJ2J5bGluZScsXG4gICAgICAgIDB4NTUgOiAnYnlsaW5lVGl0bGUnLFxuICAgICAgICAweDdBIDogJ2NhcHRpb25Xcml0ZXInLFxuICAgICAgICAweDY5IDogJ2hlYWRsaW5lJyxcbiAgICAgICAgMHg3NCA6ICdjb3B5cmlnaHQnLFxuICAgICAgICAweDBGIDogJ2NhdGVnb3J5J1xuICAgIH07XG4gICAgZnVuY3Rpb24gcmVhZElQVENEYXRhKGZpbGUsIHN0YXJ0T2Zmc2V0LCBzZWN0aW9uTGVuZ3RoKXtcbiAgICAgICAgdmFyIGRhdGFWaWV3ID0gbmV3IERhdGFWaWV3KGZpbGUpO1xuICAgICAgICB2YXIgZGF0YSA9IHt9O1xuICAgICAgICB2YXIgZmllbGRWYWx1ZSwgZmllbGROYW1lLCBkYXRhU2l6ZSwgc2VnbWVudFR5cGUsIHNlZ21lbnRTaXplO1xuICAgICAgICB2YXIgc2VnbWVudFN0YXJ0UG9zID0gc3RhcnRPZmZzZXQ7XG4gICAgICAgIHdoaWxlKHNlZ21lbnRTdGFydFBvcyA8IHN0YXJ0T2Zmc2V0K3NlY3Rpb25MZW5ndGgpIHtcbiAgICAgICAgICAgIGlmKGRhdGFWaWV3LmdldFVpbnQ4KHNlZ21lbnRTdGFydFBvcykgPT09IDB4MUMgJiYgZGF0YVZpZXcuZ2V0VWludDgoc2VnbWVudFN0YXJ0UG9zKzEpID09PSAweDAyKXtcbiAgICAgICAgICAgICAgICBzZWdtZW50VHlwZSA9IGRhdGFWaWV3LmdldFVpbnQ4KHNlZ21lbnRTdGFydFBvcysyKTtcbiAgICAgICAgICAgICAgICBpZihzZWdtZW50VHlwZSBpbiBJcHRjRmllbGRNYXApIHtcbiAgICAgICAgICAgICAgICAgICAgZGF0YVNpemUgPSBkYXRhVmlldy5nZXRJbnQxNihzZWdtZW50U3RhcnRQb3MrMyk7XG4gICAgICAgICAgICAgICAgICAgIHNlZ21lbnRTaXplID0gZGF0YVNpemUgKyA1O1xuICAgICAgICAgICAgICAgICAgICBmaWVsZE5hbWUgPSBJcHRjRmllbGRNYXBbc2VnbWVudFR5cGVdO1xuICAgICAgICAgICAgICAgICAgICBmaWVsZFZhbHVlID0gZ2V0U3RyaW5nRnJvbURCKGRhdGFWaWV3LCBzZWdtZW50U3RhcnRQb3MrNSwgZGF0YVNpemUpO1xuICAgICAgICAgICAgICAgICAgICAvLyBDaGVjayBpZiB3ZSBhbHJlYWR5IHN0b3JlZCBhIHZhbHVlIHdpdGggdGhpcyBuYW1lXG4gICAgICAgICAgICAgICAgICAgIGlmKGRhdGEuaGFzT3duUHJvcGVydHkoZmllbGROYW1lKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gVmFsdWUgYWxyZWFkeSBzdG9yZWQgd2l0aCB0aGlzIG5hbWUsIGNyZWF0ZSBtdWx0aXZhbHVlIGZpZWxkXG4gICAgICAgICAgICAgICAgICAgICAgICBpZihkYXRhW2ZpZWxkTmFtZV0gaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFbZmllbGROYW1lXS5wdXNoKGZpZWxkVmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVtmaWVsZE5hbWVdID0gW2RhdGFbZmllbGROYW1lXSwgZmllbGRWYWx1ZV07XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkYXRhW2ZpZWxkTmFtZV0gPSBmaWVsZFZhbHVlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzZWdtZW50U3RhcnRQb3MrKztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZGF0YTtcbiAgICB9XG5cblxuXG4gICAgZnVuY3Rpb24gcmVhZFRhZ3MoZmlsZSwgdGlmZlN0YXJ0LCBkaXJTdGFydCwgc3RyaW5ncywgYmlnRW5kKSB7XG4gICAgICAgIHZhciBlbnRyaWVzID0gZmlsZS5nZXRVaW50MTYoZGlyU3RhcnQsICFiaWdFbmQpLFxuICAgICAgICAgICAgdGFncyA9IHt9LFxuICAgICAgICAgICAgZW50cnlPZmZzZXQsIHRhZyxcbiAgICAgICAgICAgIGk7XG5cbiAgICAgICAgZm9yIChpPTA7aTxlbnRyaWVzO2krKykge1xuICAgICAgICAgICAgZW50cnlPZmZzZXQgPSBkaXJTdGFydCArIGkqMTIgKyAyO1xuICAgICAgICAgICAgdGFnID0gc3RyaW5nc1tmaWxlLmdldFVpbnQxNihlbnRyeU9mZnNldCwgIWJpZ0VuZCldO1xuICAgICAgICAgICAgaWYgKCF0YWcgJiYgZGVidWcpIGNvbnNvbGUubG9nKFwiVW5rbm93biB0YWc6IFwiICsgZmlsZS5nZXRVaW50MTYoZW50cnlPZmZzZXQsICFiaWdFbmQpKTtcbiAgICAgICAgICAgIHRhZ3NbdGFnXSA9IHJlYWRUYWdWYWx1ZShmaWxlLCBlbnRyeU9mZnNldCwgdGlmZlN0YXJ0LCBkaXJTdGFydCwgYmlnRW5kKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGFncztcbiAgICB9XG5cblxuICAgIGZ1bmN0aW9uIHJlYWRUYWdWYWx1ZShmaWxlLCBlbnRyeU9mZnNldCwgdGlmZlN0YXJ0LCBkaXJTdGFydCwgYmlnRW5kKSB7XG4gICAgICAgIHZhciB0eXBlID0gZmlsZS5nZXRVaW50MTYoZW50cnlPZmZzZXQrMiwgIWJpZ0VuZCksXG4gICAgICAgICAgICBudW1WYWx1ZXMgPSBmaWxlLmdldFVpbnQzMihlbnRyeU9mZnNldCs0LCAhYmlnRW5kKSxcbiAgICAgICAgICAgIHZhbHVlT2Zmc2V0ID0gZmlsZS5nZXRVaW50MzIoZW50cnlPZmZzZXQrOCwgIWJpZ0VuZCkgKyB0aWZmU3RhcnQsXG4gICAgICAgICAgICBvZmZzZXQsXG4gICAgICAgICAgICB2YWxzLCB2YWwsIG4sXG4gICAgICAgICAgICBudW1lcmF0b3IsIGRlbm9taW5hdG9yO1xuXG4gICAgICAgIHN3aXRjaCAodHlwZSkge1xuICAgICAgICAgICAgY2FzZSAxOiAvLyBieXRlLCA4LWJpdCB1bnNpZ25lZCBpbnRcbiAgICAgICAgICAgIGNhc2UgNzogLy8gdW5kZWZpbmVkLCA4LWJpdCBieXRlLCB2YWx1ZSBkZXBlbmRpbmcgb24gZmllbGRcbiAgICAgICAgICAgICAgICBpZiAobnVtVmFsdWVzID09IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZpbGUuZ2V0VWludDgoZW50cnlPZmZzZXQgKyA4LCAhYmlnRW5kKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBvZmZzZXQgPSBudW1WYWx1ZXMgPiA0ID8gdmFsdWVPZmZzZXQgOiAoZW50cnlPZmZzZXQgKyA4KTtcbiAgICAgICAgICAgICAgICAgICAgdmFscyA9IFtdO1xuICAgICAgICAgICAgICAgICAgICBmb3IgKG49MDtuPG51bVZhbHVlcztuKyspIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHNbbl0gPSBmaWxlLmdldFVpbnQ4KG9mZnNldCArIG4pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB2YWxzO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY2FzZSAyOiAvLyBhc2NpaSwgOC1iaXQgYnl0ZVxuICAgICAgICAgICAgICAgIG9mZnNldCA9IG51bVZhbHVlcyA+IDQgPyB2YWx1ZU9mZnNldCA6IChlbnRyeU9mZnNldCArIDgpO1xuICAgICAgICAgICAgICAgIHJldHVybiBnZXRTdHJpbmdGcm9tREIoZmlsZSwgb2Zmc2V0LCBudW1WYWx1ZXMtMSk7XG5cbiAgICAgICAgICAgIGNhc2UgMzogLy8gc2hvcnQsIDE2IGJpdCBpbnRcbiAgICAgICAgICAgICAgICBpZiAobnVtVmFsdWVzID09IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZpbGUuZ2V0VWludDE2KGVudHJ5T2Zmc2V0ICsgOCwgIWJpZ0VuZCk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgb2Zmc2V0ID0gbnVtVmFsdWVzID4gMiA/IHZhbHVlT2Zmc2V0IDogKGVudHJ5T2Zmc2V0ICsgOCk7XG4gICAgICAgICAgICAgICAgICAgIHZhbHMgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChuPTA7bjxudW1WYWx1ZXM7bisrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YWxzW25dID0gZmlsZS5nZXRVaW50MTYob2Zmc2V0ICsgMipuLCAhYmlnRW5kKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdmFscztcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNhc2UgNDogLy8gbG9uZywgMzIgYml0IGludFxuICAgICAgICAgICAgICAgIGlmIChudW1WYWx1ZXMgPT0gMSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmlsZS5nZXRVaW50MzIoZW50cnlPZmZzZXQgKyA4LCAhYmlnRW5kKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB2YWxzID0gW107XG4gICAgICAgICAgICAgICAgICAgIGZvciAobj0wO248bnVtVmFsdWVzO24rKykge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFsc1tuXSA9IGZpbGUuZ2V0VWludDMyKHZhbHVlT2Zmc2V0ICsgNCpuLCAhYmlnRW5kKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdmFscztcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNhc2UgNTogICAgLy8gcmF0aW9uYWwgPSB0d28gbG9uZyB2YWx1ZXMsIGZpcnN0IGlzIG51bWVyYXRvciwgc2Vjb25kIGlzIGRlbm9taW5hdG9yXG4gICAgICAgICAgICAgICAgaWYgKG51bVZhbHVlcyA9PSAxKSB7XG4gICAgICAgICAgICAgICAgICAgIG51bWVyYXRvciA9IGZpbGUuZ2V0VWludDMyKHZhbHVlT2Zmc2V0LCAhYmlnRW5kKTtcbiAgICAgICAgICAgICAgICAgICAgZGVub21pbmF0b3IgPSBmaWxlLmdldFVpbnQzMih2YWx1ZU9mZnNldCs0LCAhYmlnRW5kKTtcbiAgICAgICAgICAgICAgICAgICAgdmFsID0gbmV3IE51bWJlcihudW1lcmF0b3IgLyBkZW5vbWluYXRvcik7XG4gICAgICAgICAgICAgICAgICAgIHZhbC5udW1lcmF0b3IgPSBudW1lcmF0b3I7XG4gICAgICAgICAgICAgICAgICAgIHZhbC5kZW5vbWluYXRvciA9IGRlbm9taW5hdG9yO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdmFsO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHZhbHMgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChuPTA7bjxudW1WYWx1ZXM7bisrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBudW1lcmF0b3IgPSBmaWxlLmdldFVpbnQzMih2YWx1ZU9mZnNldCArIDgqbiwgIWJpZ0VuZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBkZW5vbWluYXRvciA9IGZpbGUuZ2V0VWludDMyKHZhbHVlT2Zmc2V0KzQgKyA4Km4sICFiaWdFbmQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFsc1tuXSA9IG5ldyBOdW1iZXIobnVtZXJhdG9yIC8gZGVub21pbmF0b3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFsc1tuXS5udW1lcmF0b3IgPSBudW1lcmF0b3I7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YWxzW25dLmRlbm9taW5hdG9yID0gZGVub21pbmF0b3I7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHM7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjYXNlIDk6IC8vIHNsb25nLCAzMiBiaXQgc2lnbmVkIGludFxuICAgICAgICAgICAgICAgIGlmIChudW1WYWx1ZXMgPT0gMSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmlsZS5nZXRJbnQzMihlbnRyeU9mZnNldCArIDgsICFiaWdFbmQpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHZhbHMgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChuPTA7bjxudW1WYWx1ZXM7bisrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YWxzW25dID0gZmlsZS5nZXRJbnQzMih2YWx1ZU9mZnNldCArIDQqbiwgIWJpZ0VuZCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHM7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjYXNlIDEwOiAvLyBzaWduZWQgcmF0aW9uYWwsIHR3byBzbG9uZ3MsIGZpcnN0IGlzIG51bWVyYXRvciwgc2Vjb25kIGlzIGRlbm9taW5hdG9yXG4gICAgICAgICAgICAgICAgaWYgKG51bVZhbHVlcyA9PSAxKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmaWxlLmdldEludDMyKHZhbHVlT2Zmc2V0LCAhYmlnRW5kKSAvIGZpbGUuZ2V0SW50MzIodmFsdWVPZmZzZXQrNCwgIWJpZ0VuZCk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdmFscyA9IFtdO1xuICAgICAgICAgICAgICAgICAgICBmb3IgKG49MDtuPG51bVZhbHVlcztuKyspIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHNbbl0gPSBmaWxlLmdldEludDMyKHZhbHVlT2Zmc2V0ICsgOCpuLCAhYmlnRW5kKSAvIGZpbGUuZ2V0SW50MzIodmFsdWVPZmZzZXQrNCArIDgqbiwgIWJpZ0VuZCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHM7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBHaXZlbiBhbiBJRkQgKEltYWdlIEZpbGUgRGlyZWN0b3J5KSBzdGFydCBvZmZzZXRcbiAgICAqIHJldHVybnMgYW4gb2Zmc2V0IHRvIG5leHQgSUZEIG9yIDAgaWYgaXQncyB0aGUgbGFzdCBJRkQuXG4gICAgKi9cbiAgICBmdW5jdGlvbiBnZXROZXh0SUZET2Zmc2V0KGRhdGFWaWV3LCBkaXJTdGFydCwgYmlnRW5kKXtcbiAgICAgICAgLy90aGUgZmlyc3QgMmJ5dGVzIG1lYW5zIHRoZSBudW1iZXIgb2YgZGlyZWN0b3J5IGVudHJpZXMgY29udGFpbnMgaW4gdGhpcyBJRkRcbiAgICAgICAgdmFyIGVudHJpZXMgPSBkYXRhVmlldy5nZXRVaW50MTYoZGlyU3RhcnQsICFiaWdFbmQpO1xuXG4gICAgICAgIC8vIEFmdGVyIGxhc3QgZGlyZWN0b3J5IGVudHJ5LCB0aGVyZSBpcyBhIDRieXRlcyBvZiBkYXRhLFxuICAgICAgICAvLyBpdCBtZWFucyBhbiBvZmZzZXQgdG8gbmV4dCBJRkQuXG4gICAgICAgIC8vIElmIGl0cyB2YWx1ZSBpcyAnMHgwMDAwMDAwMCcsIGl0IG1lYW5zIHRoaXMgaXMgdGhlIGxhc3QgSUZEIGFuZCB0aGVyZSBpcyBubyBsaW5rZWQgSUZELlxuXG4gICAgICAgIHJldHVybiBkYXRhVmlldy5nZXRVaW50MzIoZGlyU3RhcnQgKyAyICsgZW50cmllcyAqIDEyLCAhYmlnRW5kKTsgLy8gZWFjaCBlbnRyeSBpcyAxMiBieXRlcyBsb25nXG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcmVhZFRodW1ibmFpbEltYWdlKGRhdGFWaWV3LCB0aWZmU3RhcnQsIGZpcnN0SUZET2Zmc2V0LCBiaWdFbmQpe1xuICAgICAgICAvLyBnZXQgdGhlIElGRDEgb2Zmc2V0XG4gICAgICAgIHZhciBJRkQxT2Zmc2V0UG9pbnRlciA9IGdldE5leHRJRkRPZmZzZXQoZGF0YVZpZXcsIHRpZmZTdGFydCtmaXJzdElGRE9mZnNldCwgYmlnRW5kKTtcblxuICAgICAgICBpZiAoIUlGRDFPZmZzZXRQb2ludGVyKSB7XG4gICAgICAgICAgICAvLyBjb25zb2xlLmxvZygnKioqKioqKiogSUZEMU9mZnNldCBpcyBlbXB0eSwgaW1hZ2UgdGh1bWIgbm90IGZvdW5kICoqKioqKioqJyk7XG4gICAgICAgICAgICByZXR1cm4ge307XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoSUZEMU9mZnNldFBvaW50ZXIgPiBkYXRhVmlldy5ieXRlTGVuZ3RoKSB7IC8vIHRoaXMgc2hvdWxkIG5vdCBoYXBwZW5cbiAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKCcqKioqKioqKiBJRkQxT2Zmc2V0IGlzIG91dHNpZGUgdGhlIGJvdW5kcyBvZiB0aGUgRGF0YVZpZXcgKioqKioqKionKTtcbiAgICAgICAgICAgIHJldHVybiB7fTtcbiAgICAgICAgfVxuICAgICAgICAvLyBjb25zb2xlLmxvZygnKioqKioqKiAgdGh1bWJuYWlsIElGRCBvZmZzZXQgKElGRDEpIGlzOiAlcycsIElGRDFPZmZzZXRQb2ludGVyKTtcblxuICAgICAgICB2YXIgdGh1bWJUYWdzID0gcmVhZFRhZ3MoZGF0YVZpZXcsIHRpZmZTdGFydCwgdGlmZlN0YXJ0ICsgSUZEMU9mZnNldFBvaW50ZXIsIElGRDFUYWdzLCBiaWdFbmQpXG5cbiAgICAgICAgLy8gRVhJRiAyLjMgc3BlY2lmaWNhdGlvbiBmb3IgSlBFRyBmb3JtYXQgdGh1bWJuYWlsXG5cbiAgICAgICAgLy8gSWYgdGhlIHZhbHVlIG9mIENvbXByZXNzaW9uKDB4MDEwMykgVGFnIGluIElGRDEgaXMgJzYnLCB0aHVtYm5haWwgaW1hZ2UgZm9ybWF0IGlzIEpQRUcuXG4gICAgICAgIC8vIE1vc3Qgb2YgRXhpZiBpbWFnZSB1c2VzIEpQRUcgZm9ybWF0IGZvciB0aHVtYm5haWwuIEluIHRoYXQgY2FzZSwgeW91IGNhbiBnZXQgb2Zmc2V0IG9mIHRodW1ibmFpbFxuICAgICAgICAvLyBieSBKcGVnSUZPZmZzZXQoMHgwMjAxKSBUYWcgaW4gSUZEMSwgc2l6ZSBvZiB0aHVtYm5haWwgYnkgSnBlZ0lGQnl0ZUNvdW50KDB4MDIwMikgVGFnLlxuICAgICAgICAvLyBEYXRhIGZvcm1hdCBpcyBvcmRpbmFyeSBKUEVHIGZvcm1hdCwgc3RhcnRzIGZyb20gMHhGRkQ4IGFuZCBlbmRzIGJ5IDB4RkZEOS4gSXQgc2VlbXMgdGhhdFxuICAgICAgICAvLyBKUEVHIGZvcm1hdCBhbmQgMTYweDEyMHBpeGVscyBvZiBzaXplIGFyZSByZWNvbW1lbmRlZCB0aHVtYm5haWwgZm9ybWF0IGZvciBFeGlmMi4xIG9yIGxhdGVyLlxuXG4gICAgICAgIGlmICh0aHVtYlRhZ3NbJ0NvbXByZXNzaW9uJ10pIHtcbiAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKCdUaHVtYm5haWwgaW1hZ2UgZm91bmQhJyk7XG5cbiAgICAgICAgICAgIHN3aXRjaCAodGh1bWJUYWdzWydDb21wcmVzc2lvbiddKSB7XG4gICAgICAgICAgICAgICAgY2FzZSA2OlxuICAgICAgICAgICAgICAgICAgICAvLyBjb25zb2xlLmxvZygnVGh1bWJuYWlsIGltYWdlIGZvcm1hdCBpcyBKUEVHJyk7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aHVtYlRhZ3MuSnBlZ0lGT2Zmc2V0ICYmIHRodW1iVGFncy5KcGVnSUZCeXRlQ291bnQpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gZXh0cmFjdCB0aGUgdGh1bWJuYWlsXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgdE9mZnNldCA9IHRpZmZTdGFydCArIHRodW1iVGFncy5KcGVnSUZPZmZzZXQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgdExlbmd0aCA9IHRodW1iVGFncy5KcGVnSUZCeXRlQ291bnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aHVtYlRhZ3NbJ2Jsb2InXSA9IG5ldyBCbG9iKFtuZXcgVWludDhBcnJheShkYXRhVmlldy5idWZmZXIsIHRPZmZzZXQsIHRMZW5ndGgpXSwge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6ICdpbWFnZS9qcGVnJ1xuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgY2FzZSAxOlxuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKFwiVGh1bWJuYWlsIGltYWdlIGZvcm1hdCBpcyBUSUZGLCB3aGljaCBpcyBub3QgaW1wbGVtZW50ZWQuXCIpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhcIlVua25vd24gdGh1bWJuYWlsIGltYWdlIGZvcm1hdCAnJXMnXCIsIHRodW1iVGFnc1snQ29tcHJlc3Npb24nXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodGh1bWJUYWdzWydQaG90b21ldHJpY0ludGVycHJldGF0aW9uJ10gPT0gMikge1xuICAgICAgICAgICAgY29uc29sZS5sb2coXCJUaHVtYm5haWwgaW1hZ2UgZm9ybWF0IGlzIFJHQiwgd2hpY2ggaXMgbm90IGltcGxlbWVudGVkLlwiKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGh1bWJUYWdzO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGdldFN0cmluZ0Zyb21EQihidWZmZXIsIHN0YXJ0LCBsZW5ndGgpIHtcbiAgICAgICAgdmFyIG91dHN0ciA9IFwiXCI7XG4gICAgICAgIGZvciAobiA9IHN0YXJ0OyBuIDwgc3RhcnQrbGVuZ3RoOyBuKyspIHtcbiAgICAgICAgICAgIG91dHN0ciArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGJ1ZmZlci5nZXRVaW50OChuKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG91dHN0cjtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiByZWFkRVhJRkRhdGEoZmlsZSwgc3RhcnQpIHtcbiAgICAgICAgaWYgKGdldFN0cmluZ0Zyb21EQihmaWxlLCBzdGFydCwgNCkgIT0gXCJFeGlmXCIpIHtcbiAgICAgICAgICAgIGlmIChkZWJ1ZykgY29uc29sZS5sb2coXCJOb3QgdmFsaWQgRVhJRiBkYXRhISBcIiArIGdldFN0cmluZ0Zyb21EQihmaWxlLCBzdGFydCwgNCkpO1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGJpZ0VuZCxcbiAgICAgICAgICAgIHRhZ3MsIHRhZyxcbiAgICAgICAgICAgIGV4aWZEYXRhLCBncHNEYXRhLFxuICAgICAgICAgICAgdGlmZk9mZnNldCA9IHN0YXJ0ICsgNjtcblxuICAgICAgICAvLyB0ZXN0IGZvciBUSUZGIHZhbGlkaXR5IGFuZCBlbmRpYW5uZXNzXG4gICAgICAgIGlmIChmaWxlLmdldFVpbnQxNih0aWZmT2Zmc2V0KSA9PSAweDQ5NDkpIHtcbiAgICAgICAgICAgIGJpZ0VuZCA9IGZhbHNlO1xuICAgICAgICB9IGVsc2UgaWYgKGZpbGUuZ2V0VWludDE2KHRpZmZPZmZzZXQpID09IDB4NEQ0RCkge1xuICAgICAgICAgICAgYmlnRW5kID0gdHJ1ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmIChkZWJ1ZykgY29uc29sZS5sb2coXCJOb3QgdmFsaWQgVElGRiBkYXRhISAobm8gMHg0OTQ5IG9yIDB4NEQ0RClcIik7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZmlsZS5nZXRVaW50MTYodGlmZk9mZnNldCsyLCAhYmlnRW5kKSAhPSAweDAwMkEpIHtcbiAgICAgICAgICAgIGlmIChkZWJ1ZykgY29uc29sZS5sb2coXCJOb3QgdmFsaWQgVElGRiBkYXRhISAobm8gMHgwMDJBKVwiKTtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBmaXJzdElGRE9mZnNldCA9IGZpbGUuZ2V0VWludDMyKHRpZmZPZmZzZXQrNCwgIWJpZ0VuZCk7XG5cbiAgICAgICAgaWYgKGZpcnN0SUZET2Zmc2V0IDwgMHgwMDAwMDAwOCkge1xuICAgICAgICAgICAgaWYgKGRlYnVnKSBjb25zb2xlLmxvZyhcIk5vdCB2YWxpZCBUSUZGIGRhdGEhIChGaXJzdCBvZmZzZXQgbGVzcyB0aGFuIDgpXCIsIGZpbGUuZ2V0VWludDMyKHRpZmZPZmZzZXQrNCwgIWJpZ0VuZCkpO1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgdGFncyA9IHJlYWRUYWdzKGZpbGUsIHRpZmZPZmZzZXQsIHRpZmZPZmZzZXQgKyBmaXJzdElGRE9mZnNldCwgVGlmZlRhZ3MsIGJpZ0VuZCk7XG5cbiAgICAgICAgaWYgKHRhZ3MuRXhpZklGRFBvaW50ZXIpIHtcbiAgICAgICAgICAgIGV4aWZEYXRhID0gcmVhZFRhZ3MoZmlsZSwgdGlmZk9mZnNldCwgdGlmZk9mZnNldCArIHRhZ3MuRXhpZklGRFBvaW50ZXIsIEV4aWZUYWdzLCBiaWdFbmQpO1xuICAgICAgICAgICAgZm9yICh0YWcgaW4gZXhpZkRhdGEpIHtcbiAgICAgICAgICAgICAgICBzd2l0Y2ggKHRhZykge1xuICAgICAgICAgICAgICAgICAgICBjYXNlIFwiTGlnaHRTb3VyY2VcIiA6XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJGbGFzaFwiIDpcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcIk1ldGVyaW5nTW9kZVwiIDpcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcIkV4cG9zdXJlUHJvZ3JhbVwiIDpcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcIlNlbnNpbmdNZXRob2RcIiA6XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJTY2VuZUNhcHR1cmVUeXBlXCIgOlxuICAgICAgICAgICAgICAgICAgICBjYXNlIFwiU2NlbmVUeXBlXCIgOlxuICAgICAgICAgICAgICAgICAgICBjYXNlIFwiQ3VzdG9tUmVuZGVyZWRcIiA6XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJXaGl0ZUJhbGFuY2VcIiA6XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJHYWluQ29udHJvbFwiIDpcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcIkNvbnRyYXN0XCIgOlxuICAgICAgICAgICAgICAgICAgICBjYXNlIFwiU2F0dXJhdGlvblwiIDpcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcIlNoYXJwbmVzc1wiIDpcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcIlN1YmplY3REaXN0YW5jZVJhbmdlXCIgOlxuICAgICAgICAgICAgICAgICAgICBjYXNlIFwiRmlsZVNvdXJjZVwiIDpcbiAgICAgICAgICAgICAgICAgICAgICAgIGV4aWZEYXRhW3RhZ10gPSBTdHJpbmdWYWx1ZXNbdGFnXVtleGlmRGF0YVt0YWddXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJFeGlmVmVyc2lvblwiIDpcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcIkZsYXNocGl4VmVyc2lvblwiIDpcbiAgICAgICAgICAgICAgICAgICAgICAgIGV4aWZEYXRhW3RhZ10gPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGV4aWZEYXRhW3RhZ11bMF0sIGV4aWZEYXRhW3RhZ11bMV0sIGV4aWZEYXRhW3RhZ11bMl0sIGV4aWZEYXRhW3RhZ11bM10pO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcIkNvbXBvbmVudHNDb25maWd1cmF0aW9uXCIgOlxuICAgICAgICAgICAgICAgICAgICAgICAgZXhpZkRhdGFbdGFnXSA9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nVmFsdWVzLkNvbXBvbmVudHNbZXhpZkRhdGFbdGFnXVswXV0gK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZ1ZhbHVlcy5Db21wb25lbnRzW2V4aWZEYXRhW3RhZ11bMV1dICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmdWYWx1ZXMuQ29tcG9uZW50c1tleGlmRGF0YVt0YWddWzJdXSArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nVmFsdWVzLkNvbXBvbmVudHNbZXhpZkRhdGFbdGFnXVszXV07XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGFnc1t0YWddID0gZXhpZkRhdGFbdGFnXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0YWdzLkdQU0luZm9JRkRQb2ludGVyKSB7XG4gICAgICAgICAgICBncHNEYXRhID0gcmVhZFRhZ3MoZmlsZSwgdGlmZk9mZnNldCwgdGlmZk9mZnNldCArIHRhZ3MuR1BTSW5mb0lGRFBvaW50ZXIsIEdQU1RhZ3MsIGJpZ0VuZCk7XG4gICAgICAgICAgICBmb3IgKHRhZyBpbiBncHNEYXRhKSB7XG4gICAgICAgICAgICAgICAgc3dpdGNoICh0YWcpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcIkdQU1ZlcnNpb25JRFwiIDpcbiAgICAgICAgICAgICAgICAgICAgICAgIGdwc0RhdGFbdGFnXSA9IGdwc0RhdGFbdGFnXVswXSArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXCIuXCIgKyBncHNEYXRhW3RhZ11bMV0gK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiLlwiICsgZ3BzRGF0YVt0YWddWzJdICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIi5cIiArIGdwc0RhdGFbdGFnXVszXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0YWdzW3RhZ10gPSBncHNEYXRhW3RhZ107XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBleHRyYWN0IHRodW1ibmFpbFxuICAgICAgICB0YWdzWyd0aHVtYm5haWwnXSA9IHJlYWRUaHVtYm5haWxJbWFnZShmaWxlLCB0aWZmT2Zmc2V0LCBmaXJzdElGRE9mZnNldCwgYmlnRW5kKTtcblxuICAgICAgICByZXR1cm4gdGFncztcbiAgICB9XG5cbiAgIGZ1bmN0aW9uIGZpbmRYTVBpbkpQRUcoZmlsZSkge1xuXG4gICAgICAgIGlmICghKCdET01QYXJzZXInIGluIHNlbGYpKSB7XG4gICAgICAgICAgICAvLyBjb25zb2xlLndhcm4oJ1hNTCBwYXJzaW5nIG5vdCBzdXBwb3J0ZWQgd2l0aG91dCBET01QYXJzZXInKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB2YXIgZGF0YVZpZXcgPSBuZXcgRGF0YVZpZXcoZmlsZSk7XG5cbiAgICAgICAgaWYgKGRlYnVnKSBjb25zb2xlLmxvZyhcIkdvdCBmaWxlIG9mIGxlbmd0aCBcIiArIGZpbGUuYnl0ZUxlbmd0aCk7XG4gICAgICAgIGlmICgoZGF0YVZpZXcuZ2V0VWludDgoMCkgIT0gMHhGRikgfHwgKGRhdGFWaWV3LmdldFVpbnQ4KDEpICE9IDB4RDgpKSB7XG4gICAgICAgICAgIGlmIChkZWJ1ZykgY29uc29sZS5sb2coXCJOb3QgYSB2YWxpZCBKUEVHXCIpO1xuICAgICAgICAgICByZXR1cm4gZmFsc2U7IC8vIG5vdCBhIHZhbGlkIGpwZWdcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBvZmZzZXQgPSAyLFxuICAgICAgICAgICAgbGVuZ3RoID0gZmlsZS5ieXRlTGVuZ3RoLFxuICAgICAgICAgICAgZG9tID0gbmV3IERPTVBhcnNlcigpO1xuXG4gICAgICAgIHdoaWxlIChvZmZzZXQgPCAobGVuZ3RoLTQpKSB7XG4gICAgICAgICAgICBpZiAoZ2V0U3RyaW5nRnJvbURCKGRhdGFWaWV3LCBvZmZzZXQsIDQpID09IFwiaHR0cFwiKSB7XG4gICAgICAgICAgICAgICAgdmFyIHN0YXJ0T2Zmc2V0ID0gb2Zmc2V0IC0gMTtcbiAgICAgICAgICAgICAgICB2YXIgc2VjdGlvbkxlbmd0aCA9IGRhdGFWaWV3LmdldFVpbnQxNihvZmZzZXQgLSAyKSAtIDE7XG4gICAgICAgICAgICAgICAgdmFyIHhtcFN0cmluZyA9IGdldFN0cmluZ0Zyb21EQihkYXRhVmlldywgc3RhcnRPZmZzZXQsIHNlY3Rpb25MZW5ndGgpXG4gICAgICAgICAgICAgICAgdmFyIHhtcEVuZEluZGV4ID0geG1wU3RyaW5nLmluZGV4T2YoJ3htcG1ldGE+JykgKyA4O1xuICAgICAgICAgICAgICAgIHhtcFN0cmluZyA9IHhtcFN0cmluZy5zdWJzdHJpbmcoIHhtcFN0cmluZy5pbmRleE9mKCAnPHg6eG1wbWV0YScgKSwgeG1wRW5kSW5kZXggKTtcblxuICAgICAgICAgICAgICAgIHZhciBpbmRleE9mWG1wID0geG1wU3RyaW5nLmluZGV4T2YoJ3g6eG1wbWV0YScpICsgMTBcbiAgICAgICAgICAgICAgICAvL01hbnkgY3VzdG9tIHdyaXR0ZW4gcHJvZ3JhbXMgZW1iZWQgeG1wL3htbCB3aXRob3V0IGFueSBuYW1lc3BhY2UuIEZvbGxvd2luZyBhcmUgc29tZSBvZiB0aGVtLlxuICAgICAgICAgICAgICAgIC8vV2l0aG91dCB0aGVzZSBuYW1lc3BhY2VzLCBYTUwgaXMgdGhvdWdodCB0byBiZSBpbnZhbGlkIGJ5IHBhcnNlcnNcbiAgICAgICAgICAgICAgICB4bXBTdHJpbmcgPSB4bXBTdHJpbmcuc2xpY2UoMCwgaW5kZXhPZlhtcClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICArICd4bWxuczpJcHRjNHhtcENvcmU9XCJodHRwOi8vaXB0Yy5vcmcvc3RkL0lwdGM0eG1wQ29yZS8xLjAveG1sbnMvXCIgJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgJ3htbG5zOnhzaT1cImh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlXCIgJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgJ3htbG5zOnRpZmY9XCJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wL1wiICdcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICArICd4bWxuczpwbHVzPVwiaHR0cDovL3NjaGVtYXMuYW5kcm9pZC5jb20vYXBrL2xpYi9jb20uZ29vZ2xlLmFuZHJvaWQuZ21zLnBsdXNcIiAnXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAneG1sbnM6ZXh0PVwiaHR0cDovL3d3dy5nZXR0eWltYWdlcy5jb20veHNsdEV4dGVuc2lvbi8xLjBcIiAnXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAneG1sbnM6ZXhpZj1cImh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvXCIgJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgJ3htbG5zOnN0RXZ0PVwiaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlRXZlbnQjXCIgJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgJ3htbG5zOnN0UmVmPVwiaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmI1wiICdcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICArICd4bWxuczpjcnM9XCJodHRwOi8vbnMuYWRvYmUuY29tL2NhbWVyYS1yYXctc2V0dGluZ3MvMS4wL1wiICdcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICArICd4bWxuczp4YXBHSW1nPVwiaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL2cvaW1nL1wiICdcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICArICd4bWxuczpJcHRjNHhtcEV4dD1cImh0dHA6Ly9pcHRjLm9yZy9zdGQvSXB0YzR4bXBFeHQvMjAwOC0wMi0yOS9cIiAnXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKyB4bXBTdHJpbmcuc2xpY2UoaW5kZXhPZlhtcClcblxuICAgICAgICAgICAgICAgIHZhciBkb21Eb2N1bWVudCA9IGRvbS5wYXJzZUZyb21TdHJpbmcoIHhtcFN0cmluZywgJ3RleHQveG1sJyApO1xuICAgICAgICAgICAgICAgIHJldHVybiB4bWwyT2JqZWN0KGRvbURvY3VtZW50KTtcbiAgICAgICAgICAgIH0gZWxzZXtcbiAgICAgICAgICAgICBvZmZzZXQrKztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIHhtbDJqc29uKHhtbCkge1xuICAgICAgICB2YXIganNvbiA9IHt9O1xuICAgICAgXG4gICAgICAgIGlmICh4bWwubm9kZVR5cGUgPT0gMSkgeyAvLyBlbGVtZW50IG5vZGVcbiAgICAgICAgICBpZiAoeG1sLmF0dHJpYnV0ZXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAganNvblsnQGF0dHJpYnV0ZXMnXSA9IHt9O1xuICAgICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCB4bWwuYXR0cmlidXRlcy5sZW5ndGg7IGorKykge1xuICAgICAgICAgICAgICB2YXIgYXR0cmlidXRlID0geG1sLmF0dHJpYnV0ZXMuaXRlbShqKTtcbiAgICAgICAgICAgICAganNvblsnQGF0dHJpYnV0ZXMnXVthdHRyaWJ1dGUubm9kZU5hbWVdID0gYXR0cmlidXRlLm5vZGVWYWx1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoeG1sLm5vZGVUeXBlID09IDMpIHsgLy8gdGV4dCBub2RlXG4gICAgICAgICAgcmV0dXJuIHhtbC5ub2RlVmFsdWU7XG4gICAgICAgIH1cbiAgICAgIFxuICAgICAgICAvLyBkZWFsIHdpdGggY2hpbGRyZW5cbiAgICAgICAgaWYgKHhtbC5oYXNDaGlsZE5vZGVzKCkpIHtcbiAgICAgICAgICBmb3IodmFyIGkgPSAwOyBpIDwgeG1sLmNoaWxkTm9kZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHZhciBjaGlsZCA9IHhtbC5jaGlsZE5vZGVzLml0ZW0oaSk7XG4gICAgICAgICAgICB2YXIgbm9kZU5hbWUgPSBjaGlsZC5ub2RlTmFtZTtcbiAgICAgICAgICAgIGlmIChqc29uW25vZGVOYW1lXSA9PSBudWxsKSB7XG4gICAgICAgICAgICAgIGpzb25bbm9kZU5hbWVdID0geG1sMmpzb24oY2hpbGQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgaWYgKGpzb25bbm9kZU5hbWVdLnB1c2ggPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHZhciBvbGQgPSBqc29uW25vZGVOYW1lXTtcbiAgICAgICAgICAgICAgICBqc29uW25vZGVOYW1lXSA9IFtdO1xuICAgICAgICAgICAgICAgIGpzb25bbm9kZU5hbWVdLnB1c2gob2xkKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBqc29uW25vZGVOYW1lXS5wdXNoKHhtbDJqc29uKGNoaWxkKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIFxuICAgICAgICByZXR1cm4ganNvbjtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB4bWwyT2JqZWN0KHhtbCkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgdmFyIG9iaiA9IHt9O1xuICAgICAgICAgICAgaWYgKHhtbC5jaGlsZHJlbi5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgeG1sLmNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgdmFyIGl0ZW0gPSB4bWwuY2hpbGRyZW4uaXRlbShpKTtcbiAgICAgICAgICAgICAgICB2YXIgYXR0cmlidXRlcyA9IGl0ZW0uYXR0cmlidXRlcztcbiAgICAgICAgICAgICAgICBmb3IodmFyIGlkeCBpbiBhdHRyaWJ1dGVzKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBpdGVtQXR0ID0gYXR0cmlidXRlc1tpZHhdO1xuICAgICAgICAgICAgICAgICAgICB2YXIgZGF0YUtleSA9IGl0ZW1BdHQubm9kZU5hbWU7XG4gICAgICAgICAgICAgICAgICAgIHZhciBkYXRhVmFsdWUgPSBpdGVtQXR0Lm5vZGVWYWx1ZTtcblxuICAgICAgICAgICAgICAgICAgICBpZihkYXRhS2V5ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9ialtkYXRhS2V5XSA9IGRhdGFWYWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB2YXIgbm9kZU5hbWUgPSBpdGVtLm5vZGVOYW1lO1xuXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiAob2JqW25vZGVOYW1lXSkgPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgICAgICAgICAgb2JqW25vZGVOYW1lXSA9IHhtbDJqc29uKGl0ZW0pO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIChvYmpbbm9kZU5hbWVdLnB1c2gpID09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIG9sZCA9IG9ialtub2RlTmFtZV07XG5cbiAgICAgICAgICAgICAgICAgICAgb2JqW25vZGVOYW1lXSA9IFtdO1xuICAgICAgICAgICAgICAgICAgICBvYmpbbm9kZU5hbWVdLnB1c2gob2xkKTtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIG9ialtub2RlTmFtZV0ucHVzaCh4bWwyanNvbihpdGVtKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBvYmogPSB4bWwudGV4dENvbnRlbnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gb2JqO1xuICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgY29uc29sZS5sb2coZS5tZXNzYWdlKTtcbiAgICAgICAgICB9XG4gICAgfVxuXG4gICAgRVhJRi5lbmFibGVYbXAgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgRVhJRi5pc1htcEVuYWJsZWQgPSB0cnVlO1xuICAgIH1cblxuICAgIEVYSUYuZGlzYWJsZVhtcCA9IGZ1bmN0aW9uKCkge1xuICAgICAgICBFWElGLmlzWG1wRW5hYmxlZCA9IGZhbHNlO1xuICAgIH1cblxuICAgIEVYSUYuZ2V0RGF0YSA9IGZ1bmN0aW9uKGltZywgY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKCgoc2VsZi5JbWFnZSAmJiBpbWcgaW5zdGFuY2VvZiBzZWxmLkltYWdlKVxuICAgICAgICAgICAgfHwgKHNlbGYuSFRNTEltYWdlRWxlbWVudCAmJiBpbWcgaW5zdGFuY2VvZiBzZWxmLkhUTUxJbWFnZUVsZW1lbnQpKVxuICAgICAgICAgICAgJiYgIWltZy5jb21wbGV0ZSlcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcblxuICAgICAgICBpZiAoIWltYWdlSGFzRGF0YShpbWcpKSB7XG4gICAgICAgICAgICBnZXRJbWFnZURhdGEoaW1nLCBjYWxsYmFjayk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAoY2FsbGJhY2spIHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjay5jYWxsKGltZyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgRVhJRi5nZXRUYWcgPSBmdW5jdGlvbihpbWcsIHRhZykge1xuICAgICAgICBpZiAoIWltYWdlSGFzRGF0YShpbWcpKSByZXR1cm47XG4gICAgICAgIHJldHVybiBpbWcuZXhpZmRhdGFbdGFnXTtcbiAgICB9XG4gICAgXG4gICAgRVhJRi5nZXRJcHRjVGFnID0gZnVuY3Rpb24oaW1nLCB0YWcpIHtcbiAgICAgICAgaWYgKCFpbWFnZUhhc0RhdGEoaW1nKSkgcmV0dXJuO1xuICAgICAgICByZXR1cm4gaW1nLmlwdGNkYXRhW3RhZ107XG4gICAgfVxuXG4gICAgRVhJRi5nZXRBbGxUYWdzID0gZnVuY3Rpb24oaW1nKSB7XG4gICAgICAgIGlmICghaW1hZ2VIYXNEYXRhKGltZykpIHJldHVybiB7fTtcbiAgICAgICAgdmFyIGEsXG4gICAgICAgICAgICBkYXRhID0gaW1nLmV4aWZkYXRhLFxuICAgICAgICAgICAgdGFncyA9IHt9O1xuICAgICAgICBmb3IgKGEgaW4gZGF0YSkge1xuICAgICAgICAgICAgaWYgKGRhdGEuaGFzT3duUHJvcGVydHkoYSkpIHtcbiAgICAgICAgICAgICAgICB0YWdzW2FdID0gZGF0YVthXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGFncztcbiAgICB9XG4gICAgXG4gICAgRVhJRi5nZXRBbGxJcHRjVGFncyA9IGZ1bmN0aW9uKGltZykge1xuICAgICAgICBpZiAoIWltYWdlSGFzRGF0YShpbWcpKSByZXR1cm4ge307XG4gICAgICAgIHZhciBhLFxuICAgICAgICAgICAgZGF0YSA9IGltZy5pcHRjZGF0YSxcbiAgICAgICAgICAgIHRhZ3MgPSB7fTtcbiAgICAgICAgZm9yIChhIGluIGRhdGEpIHtcbiAgICAgICAgICAgIGlmIChkYXRhLmhhc093blByb3BlcnR5KGEpKSB7XG4gICAgICAgICAgICAgICAgdGFnc1thXSA9IGRhdGFbYV07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRhZ3M7XG4gICAgfVxuXG4gICAgRVhJRi5wcmV0dHkgPSBmdW5jdGlvbihpbWcpIHtcbiAgICAgICAgaWYgKCFpbWFnZUhhc0RhdGEoaW1nKSkgcmV0dXJuIFwiXCI7XG4gICAgICAgIHZhciBhLFxuICAgICAgICAgICAgZGF0YSA9IGltZy5leGlmZGF0YSxcbiAgICAgICAgICAgIHN0clByZXR0eSA9IFwiXCI7XG4gICAgICAgIGZvciAoYSBpbiBkYXRhKSB7XG4gICAgICAgICAgICBpZiAoZGF0YS5oYXNPd25Qcm9wZXJ0eShhKSkge1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgZGF0YVthXSA9PSBcIm9iamVjdFwiKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChkYXRhW2FdIGluc3RhbmNlb2YgTnVtYmVyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJQcmV0dHkgKz0gYSArIFwiIDogXCIgKyBkYXRhW2FdICsgXCIgW1wiICsgZGF0YVthXS5udW1lcmF0b3IgKyBcIi9cIiArIGRhdGFbYV0uZGVub21pbmF0b3IgKyBcIl1cXHJcXG5cIjtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0clByZXR0eSArPSBhICsgXCIgOiBbXCIgKyBkYXRhW2FdLmxlbmd0aCArIFwiIHZhbHVlc11cXHJcXG5cIjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHN0clByZXR0eSArPSBhICsgXCIgOiBcIiArIGRhdGFbYV0gKyBcIlxcclxcblwiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc3RyUHJldHR5O1xuICAgIH1cblxuICAgIEVYSUYucmVhZEZyb21CaW5hcnlGaWxlID0gZnVuY3Rpb24oZmlsZSkge1xuICAgICAgICByZXR1cm4gZmluZEVYSUZpbkpQRUcoZmlsZSk7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZCkge1xuICAgICAgICBkZWZpbmUoJ2V4aWYtanMnLCBbXSwgZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICByZXR1cm4gRVhJRjtcbiAgICAgICAgfSk7XG4gICAgfVxufS5jYWxsKHRoaXMpKTtcblxuIl0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/exif-js/exif.js\n");
-
-/***/ }),
-
-/***/ "./node_modules/sortablejs/modular/sortable.esm.js":
+/*! no static exports found */function(e,t,n){"use strict";(function(e){function n(e){return(n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function a(e,t){return!t||"object"!==n(t)&&"function"!=typeof t?s(e):t}function l(e){return(l=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}function s(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function i(e,t){return(i=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}function u(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(e,t){for(var n=0;n
- {% set use_keys = field.use is defined and field.use == 'keys' %}
- {% for key,value in form.value(scope ~ field.name) %}
- {% set index = (use_keys ? key : value) %}
-
+ {% set use_keys = field.use is defined and field.use == 'keys' %}
+ {% for key,value in form.value(scope ~ field.name) %}
+ {% set index = (use_keys ? key : value) %}
+