decidim-core 0.10.1 → 0.11.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (269) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +5 -11
  3. data/app/assets/images/decidim/icons.svg +25 -6
  4. data/app/assets/javascripts/decidim/account_form.js.es6 +8 -8
  5. data/app/assets/javascripts/decidim/append_elements.js.es6 +1 -1
  6. data/app/assets/javascripts/decidim/append_redirect_url_to_modals.js.es6 +5 -5
  7. data/app/assets/javascripts/decidim/data_picker.js.es6 +10 -10
  8. data/app/assets/javascripts/decidim/editor.js.es6 +37 -22
  9. data/app/assets/javascripts/decidim/filters.js.es6 +1 -1
  10. data/app/assets/javascripts/decidim/form_filter.component.js.es6 +15 -15
  11. data/app/assets/javascripts/decidim/form_filter.component.test.js +29 -29
  12. data/app/assets/javascripts/decidim/impersonation.js.es6 +3 -3
  13. data/app/assets/javascripts/decidim/input_mentions.js.es6 +100 -0
  14. data/app/assets/javascripts/decidim/input_tags.js.es6 +12 -0
  15. data/app/assets/javascripts/decidim/{map.js.es6.erb → map.js.es6} +9 -9
  16. data/app/assets/javascripts/decidim/notifications.js.es6 +10 -10
  17. data/app/assets/javascripts/decidim/orders.js.es6 +5 -5
  18. data/app/assets/javascripts/decidim/user_registrations.js.es6 +4 -4
  19. data/app/assets/javascripts/decidim/widget.js.es6 +1 -1
  20. data/app/assets/javascripts/decidim.js.es6 +10 -0
  21. data/app/assets/stylesheets/decidim/application.scss.erb +1 -1
  22. data/app/assets/stylesheets/decidim/modules/_author-avatar.scss +39 -0
  23. data/app/assets/stylesheets/decidim/modules/_cards.scss +158 -3
  24. data/app/assets/stylesheets/decidim/modules/_definition-data.scss +6 -0
  25. data/app/assets/stylesheets/decidim/modules/_extra.scss +1 -3
  26. data/app/assets/stylesheets/decidim/modules/_icons.scss +14 -6
  27. data/app/assets/stylesheets/decidim/modules/_inline-filters.scss +61 -0
  28. data/app/assets/stylesheets/decidim/modules/_input-mentions.scss +124 -0
  29. data/app/assets/stylesheets/decidim/modules/_input-tags.scss +55 -0
  30. data/app/assets/stylesheets/decidim/modules/_modules.scss +3 -0
  31. data/app/assets/stylesheets/decidim/modules/_status-labels.scss +4 -0
  32. data/app/assets/stylesheets/decidim/modules/_typography.scss +16 -0
  33. data/app/assets/stylesheets/decidim/utils/_helpers.scss +29 -0
  34. data/app/assets/stylesheets/decidim/utils/_mixins.scss +6 -0
  35. data/app/cells/decidim/author_box/show.erb +10 -0
  36. data/app/cells/decidim/author_box_cell.rb +21 -0
  37. data/app/cells/decidim/card/show.erb +17 -0
  38. data/app/cells/decidim/card_cell.rb +29 -0
  39. data/app/cells/decidim/profile/profile_inline.erb +21 -0
  40. data/app/cells/decidim/profile/show.erb +13 -0
  41. data/app/cells/decidim/profile_cell.rb +17 -0
  42. data/app/commands/decidim/create_omniauth_registration.rb +3 -2
  43. data/app/commands/decidim/create_report.rb +1 -1
  44. data/app/commands/decidim/invite_user.rb +2 -0
  45. data/app/constraints/decidim/current_component.rb +41 -0
  46. data/app/controllers/concerns/decidim/action_authorization.rb +3 -3
  47. data/app/controllers/concerns/decidim/devise_controllers.rb +2 -1
  48. data/app/controllers/concerns/decidim/filter_resource.rb +1 -1
  49. data/app/controllers/concerns/decidim/form_factory.rb +1 -1
  50. data/app/controllers/concerns/decidim/impersonate_users.rb +6 -2
  51. data/app/controllers/concerns/decidim/needs_authorization.rb +2 -2
  52. data/app/controllers/concerns/decidim/participatory_space_context.rb +15 -0
  53. data/app/controllers/concerns/decidim/settings.rb +5 -5
  54. data/app/controllers/decidim/application_controller.rb +2 -1
  55. data/app/controllers/decidim/{features → components}/base_controller.rb +16 -8
  56. data/app/controllers/decidim/devise/omniauth_registrations_controller.rb +3 -1
  57. data/app/controllers/decidim/devise/registrations_controller.rb +1 -3
  58. data/app/controllers/decidim/doorkeeper/authorizations_controller.rb +16 -0
  59. data/app/controllers/decidim/doorkeeper/credentials_controller.rb +46 -0
  60. data/app/controllers/decidim/doorkeeper/token_info_controller.rb +9 -0
  61. data/app/controllers/decidim/doorkeeper/tokens_controller.rb +9 -0
  62. data/app/controllers/decidim/widgets_controller.rb +1 -1
  63. data/app/forms/decidim/follow_form.rb +1 -1
  64. data/app/forms/decidim/form.rb +1 -1
  65. data/app/forms/decidim/omniauth_registration_form.rb +1 -0
  66. data/app/forms/decidim/registration_form.rb +5 -5
  67. data/app/helpers/decidim/card_helper.rb +16 -0
  68. data/app/helpers/decidim/component_path_helper.rb +36 -0
  69. data/app/helpers/decidim/icon_helper.rb +7 -7
  70. data/app/helpers/decidim/messaging/conversation_helper.rb +4 -3
  71. data/app/helpers/decidim/paginate_helper.rb +1 -1
  72. data/app/helpers/decidim/resource_helper.rb +2 -2
  73. data/app/jobs/decidim/export_job.rb +3 -3
  74. data/app/mailers/decidim/messaging/conversation_mailer.rb +0 -2
  75. data/app/middleware/decidim/current_organization.rb +2 -2
  76. data/app/models/decidim/abilities/admin_ability.rb +1 -1
  77. data/app/models/decidim/abilities/everyone_ability.rb +1 -1
  78. data/app/models/decidim/abilities/participatory_process_admin_ability.rb +2 -2
  79. data/app/models/decidim/abilities/participatory_process_collaborator_ability.rb +2 -2
  80. data/app/models/decidim/action_log.rb +7 -5
  81. data/app/models/decidim/area.rb +7 -0
  82. data/app/models/decidim/authorization.rb +14 -0
  83. data/app/models/decidim/{feature.rb → component.rb} +15 -15
  84. data/app/models/decidim/moderation.rb +1 -1
  85. data/app/models/decidim/oauth_application.rb +24 -0
  86. data/app/models/decidim/organization.rb +5 -0
  87. data/app/models/decidim/participatory_space_link.rb +20 -0
  88. data/app/models/decidim/participatory_space_private_user.rb +19 -0
  89. data/app/models/decidim/user.rb +7 -0
  90. data/app/presenters/decidim/admin_log/area_presenter.rb +38 -0
  91. data/app/presenters/decidim/admin_log/{feature_presenter.rb → component_presenter.rb} +5 -5
  92. data/app/presenters/decidim/admin_log/newsletter_resource_presenter.rb +1 -1
  93. data/app/presenters/decidim/admin_log/oauth_application_presenter.rb +50 -0
  94. data/app/presenters/decidim/admin_log/oauth_application_resource_presenter.rb +18 -0
  95. data/app/presenters/decidim/home_stats_presenter.rb +7 -7
  96. data/app/presenters/decidim/log/value_types/area_presenter.rb +1 -1
  97. data/app/presenters/decidim/log/value_types/area_type_presenter.rb +28 -0
  98. data/app/presenters/decidim/log/value_types/currency_presenter.rb +20 -0
  99. data/app/presenters/decidim/log/value_types/scope_presenter.rb +1 -1
  100. data/app/presenters/decidim/log/value_types/scope_type_presenter.rb +1 -1
  101. data/app/presenters/decidim/resource_locator_presenter.rb +3 -3
  102. data/app/services/decidim/action_authorizer.rb +9 -9
  103. data/app/services/decidim/action_logger.rb +9 -7
  104. data/app/services/decidim/email_notification_generator.rb +1 -1
  105. data/app/services/decidim/notification_generator_for_recipient.rb +1 -1
  106. data/app/services/decidim/resource_search.rb +8 -8
  107. data/app/services/decidim/settings_change.rb +5 -5
  108. data/app/services/decidim/static_map_generator.rb +1 -1
  109. data/app/types/decidim/core/attachment_type.rb +14 -0
  110. data/app/types/decidim/core/category_type.rb +16 -0
  111. data/app/types/decidim/core/coordinates_type.rb +19 -0
  112. data/app/types/decidim/core/scope_api_type.rb +16 -0
  113. data/app/uploaders/decidim/oauth_application_logo_uploader.rb +9 -0
  114. data/app/validators/geocoding_validator.rb +2 -2
  115. data/app/views/decidim/account/delete.html.erb +7 -7
  116. data/app/views/decidim/application/_collection.html.erb +1 -1
  117. data/app/views/decidim/application/_document.html.erb +1 -1
  118. data/app/views/decidim/application/_photos.html.erb +1 -1
  119. data/app/views/decidim/devise/invitations/edit.html.erb +1 -1
  120. data/app/views/decidim/devise/omniauth_registrations/new.html.erb +1 -1
  121. data/app/views/decidim/devise/registrations/new.html.erb +1 -1
  122. data/app/views/decidim/devise/sessions/new.html.erb +2 -2
  123. data/app/views/decidim/devise/shared/_omniauth_buttons.html.erb +1 -1
  124. data/app/views/decidim/devise/shared/_omniauth_buttons_mini.html.erb +1 -1
  125. data/app/views/decidim/doorkeeper/authorizations/new.html.erb +58 -0
  126. data/app/views/decidim/messaging/conversations/_show.html.erb +1 -1
  127. data/app/views/decidim/messaging/conversations/index.html.erb +1 -1
  128. data/app/views/decidim/notifications/index.html.erb +1 -1
  129. data/app/views/decidim/notifications_settings/show.html.erb +2 -2
  130. data/app/views/decidim/own_user_groups/index.html.erb +3 -3
  131. data/app/views/decidim/scopes/_scopes_picker_input.html.erb +4 -4
  132. data/app/views/decidim/scopes/picker.html.erb +3 -3
  133. data/app/views/decidim/shared/_action_authorization_modal.html.erb +1 -1
  134. data/app/views/decidim/shared/_author.html.erb +1 -1
  135. data/app/views/decidim/shared/_author_reference.html.erb +1 -12
  136. data/app/views/decidim/shared/{_feature_announcement.html.erb → _component_announcement.html.erb} +2 -2
  137. data/app/views/decidim/shared/_embed_modal.html.erb +1 -1
  138. data/app/views/decidim/shared/_flag_modal.html.erb +5 -5
  139. data/app/views/decidim/shared/_login_modal.html.erb +3 -3
  140. data/app/views/decidim/shared/_private_participatory_space.html.erb +5 -0
  141. data/app/views/decidim/shared/_share_modal.html.erb +1 -1
  142. data/app/views/decidim/shared/_tags.html.erb +1 -1
  143. data/app/views/decidim/shared/_version_author.html.erb +1 -1
  144. data/app/views/decidim/widgets/_data_picker.html.erb +4 -4
  145. data/app/views/devise/mailer/confirmation_instructions.html.erb +3 -3
  146. data/app/views/devise/mailer/invite_private_user.html.erb +17 -0
  147. data/app/views/devise/mailer/invite_private_user.text.erb +15 -0
  148. data/app/views/devise/mailer/password_change.html.erb +2 -2
  149. data/app/views/devise/mailer/reset_password_instructions.html.erb +5 -5
  150. data/app/views/kaminari/decidim/_first_page.html.erb +2 -3
  151. data/app/views/kaminari/decidim/_gap.html.erb +2 -3
  152. data/app/views/kaminari/decidim/_last_page.html.erb +2 -3
  153. data/app/views/kaminari/decidim/_next_page.html.erb +2 -3
  154. data/app/views/kaminari/decidim/_page.html.erb +2 -3
  155. data/app/views/kaminari/decidim/_paginator.html.erb +1 -2
  156. data/app/views/kaminari/decidim/_prev_page.html.erb +2 -3
  157. data/app/views/layouts/decidim/_application.html.erb +4 -4
  158. data/app/views/layouts/decidim/_component_authorization_modals.html.erb +5 -0
  159. data/app/views/layouts/decidim/_cookie_warning.html.erb +2 -2
  160. data/app/views/layouts/decidim/_head.html.erb +4 -4
  161. data/app/views/layouts/decidim/_impersonation_warning.html.erb +4 -4
  162. data/app/views/layouts/decidim/_language_chooser.html.erb +1 -1
  163. data/app/views/layouts/decidim/_social_media_links.html.erb +5 -5
  164. data/app/views/layouts/decidim/_wrapper.html.erb +5 -5
  165. data/app/views/layouts/decidim/mailer.html.erb +1 -1
  166. data/app/views/layouts/decidim/widget.html.erb +5 -5
  167. data/app/views/pages/home/_hero.html.erb +1 -1
  168. data/app/views/pages/home.html.erb +6 -6
  169. data/config/locales/ca.yml +66 -27
  170. data/config/locales/en.yml +69 -30
  171. data/config/locales/es.yml +66 -27
  172. data/config/locales/eu.yml +69 -30
  173. data/config/locales/fi.yml +69 -30
  174. data/config/locales/fr.yml +85 -46
  175. data/config/locales/gl.yml +69 -30
  176. data/config/locales/it.yml +69 -30
  177. data/config/locales/nl.yml +122 -83
  178. data/config/locales/pl.yml +69 -30
  179. data/config/locales/pt-BR.yml +69 -30
  180. data/config/locales/pt.yml +69 -30
  181. data/config/locales/ru.yml +0 -7
  182. data/config/locales/sv.yml +69 -30
  183. data/config/locales/uk.yml +0 -13
  184. data/config/routes.rb +8 -0
  185. data/db/migrate/20180206183235_create_participatory_space_private_users.rb +15 -0
  186. data/db/migrate/20180221101934_fix_nickname_index.rb +5 -6
  187. data/db/migrate/20180226140756_add_version_to_action_logs.rb +5 -1
  188. data/db/migrate/20180227131727_create_participatory_space_links.rb +12 -0
  189. data/db/migrate/20180305132906_rename_features_to_components.rb +13 -0
  190. data/db/migrate/20180308113207_doorkeeper_models.rb +85 -0
  191. data/db/migrate/20180314085339_rename_maximum_votes_per_proposal_to_threshold_per_proposal.rb +2 -2
  192. data/db/migrate/{20180326075746_change_event_name_and_class_to_rename_to_publish_proposal_event.rb → 20180323102631_change_event_name_and_class_to_rename_to_publish_proposal_event.rb} +0 -0
  193. data/db/seeds.rb +12 -2
  194. data/lib/decidim/api/attachable_interface.rb +13 -0
  195. data/lib/decidim/api/authorable_interface.rb +13 -0
  196. data/lib/decidim/api/categorizable_interface.rb +13 -0
  197. data/lib/decidim/api/participatory_space_interface.rb +4 -4
  198. data/lib/decidim/api/scopable_interface.rb +13 -0
  199. data/lib/decidim/authorable.rb +8 -0
  200. data/lib/decidim/{feature_manifest.rb → component_manifest.rb} +24 -21
  201. data/lib/decidim/{feature_validator.rb → component_validator.rb} +6 -6
  202. data/lib/decidim/{features → components}/export_manifest.rb +4 -4
  203. data/lib/decidim/components/namer.rb +35 -0
  204. data/lib/decidim/components.rb +9 -0
  205. data/lib/decidim/content_parsers/user_parser.rb +1 -1
  206. data/lib/decidim/core/api.rb +13 -0
  207. data/lib/decidim/core/engine.rb +76 -3
  208. data/lib/decidim/core/test/factories.rb +43 -10
  209. data/lib/decidim/core/test/shared_examples/announcements_examples.rb +9 -9
  210. data/lib/decidim/core/test/shared_examples/attachable_interface_examples.rb +16 -0
  211. data/lib/decidim/core/test/shared_examples/authorable_interface_examples.rb +33 -0
  212. data/lib/decidim/core/test/shared_examples/categorizable_interface_examples.rb +19 -0
  213. data/lib/decidim/core/test/shared_examples/comments_examples.rb +3 -3
  214. data/lib/decidim/core/test/shared_examples/follows_examples.rb +1 -1
  215. data/lib/decidim/core/test/shared_examples/has_component.rb +21 -0
  216. data/lib/decidim/core/test/shared_examples/has_reference.rb +2 -2
  217. data/lib/decidim/core/test/shared_examples/localised_email.rb +1 -1
  218. data/lib/decidim/core/test/shared_examples/paginated_resource_examples.rb +1 -1
  219. data/lib/decidim/core/test/shared_examples/reportable.rb +8 -6
  220. data/lib/decidim/core/test/shared_examples/reports_examples.rb +1 -1
  221. data/lib/decidim/core/test/shared_examples/scopable_interface_examples.rb +19 -0
  222. data/lib/decidim/core/test/shared_examples/scope_helper_examples.rb +8 -3
  223. data/lib/decidim/core/test/shared_examples/simple_event.rb +1 -1
  224. data/lib/decidim/core/test/shared_examples/user_localised_email_examples.rb +1 -1
  225. data/lib/decidim/core/test.rb +1 -1
  226. data/lib/decidim/core/version.rb +1 -1
  227. data/lib/decidim/core.rb +35 -37
  228. data/lib/decidim/events/base_event.rb +5 -5
  229. data/lib/decidim/events/simple_event.rb +8 -8
  230. data/lib/decidim/form_builder.rb +48 -3
  231. data/lib/decidim/has_attachment_collections.rb +1 -1
  232. data/lib/decidim/has_attachments.rb +1 -1
  233. data/lib/decidim/has_category.rb +2 -2
  234. data/lib/decidim/has_component.rb +23 -0
  235. data/lib/decidim/has_private_users.rb +26 -0
  236. data/lib/decidim/has_reference.rb +3 -3
  237. data/lib/decidim/page_finder.rb +1 -1
  238. data/lib/decidim/participatory_space_manifest.rb +3 -3
  239. data/lib/decidim/participatory_space_resourceable.rb +80 -0
  240. data/lib/decidim/publicable.rb +2 -2
  241. data/lib/decidim/query_extensions.rb +2 -2
  242. data/lib/decidim/rectify_ext.rb +32 -0
  243. data/lib/decidim/reportable.rb +1 -1
  244. data/lib/decidim/resource_manifest.rb +13 -13
  245. data/lib/decidim/resourceable.rb +8 -8
  246. data/lib/decidim/scopable.rb +1 -1
  247. data/lib/decidim/{scopable_feature.rb → scopable_component.rb} +1 -1
  248. data/lib/decidim/settings_manifest.rb +1 -1
  249. data/lib/decidim/stats_registry.rb +1 -1
  250. data/lib/decidim/view_model.rb +9 -0
  251. data/vendor/assets/javascripts/datepicker-locales/foundation-datepicker.fr.js +4 -1
  252. data/vendor/assets/javascripts/form_datepicker.js.es6 +10 -10
  253. data/vendor/assets/javascripts/quill.min.js +2 -2
  254. data/vendor/assets/javascripts/quill.min.js.map +1 -1
  255. data/vendor/assets/javascripts/tagsinput.js +683 -0
  256. data/vendor/assets/javascripts/tribute.js +1607 -0
  257. data/vendor/assets/stylesheets/quill.bubble.css +30 -16
  258. data/vendor/assets/stylesheets/quill.core.css +19 -9
  259. data/vendor/assets/stylesheets/quill.snow.css +30 -16
  260. data/vendor/assets/stylesheets/tagsinput.css +55 -0
  261. data/vendor/assets/stylesheets/tribute.css +27 -0
  262. metadata +164 -27
  263. data/app/constraints/decidim/current_feature.rb +0 -41
  264. data/app/helpers/decidim/feature_path_helper.rb +0 -36
  265. data/app/views/layouts/decidim/_feature_authorization_modals.html.erb +0 -5
  266. data/lib/decidim/core/test/shared_examples/has_feature.rb +0 -21
  267. data/lib/decidim/features/namer.rb +0 -35
  268. data/lib/decidim/features.rb +0 -9
  269. data/lib/decidim/has_feature.rb +0 -23
@@ -0,0 +1,1607 @@
1
+ (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Tribute = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
2
+ "use strict";
3
+
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+
8
+ var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
9
+
10
+ var _utils = require("./utils");
11
+
12
+ var _utils2 = _interopRequireDefault(_utils);
13
+
14
+ var _TributeEvents = require("./TributeEvents");
15
+
16
+ var _TributeEvents2 = _interopRequireDefault(_TributeEvents);
17
+
18
+ var _TributeMenuEvents = require("./TributeMenuEvents");
19
+
20
+ var _TributeMenuEvents2 = _interopRequireDefault(_TributeMenuEvents);
21
+
22
+ var _TributeRange = require("./TributeRange");
23
+
24
+ var _TributeRange2 = _interopRequireDefault(_TributeRange);
25
+
26
+ var _TributeSearch = require("./TributeSearch");
27
+
28
+ var _TributeSearch2 = _interopRequireDefault(_TributeSearch);
29
+
30
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
31
+
32
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
33
+
34
+ var Tribute = function () {
35
+ function Tribute(_ref) {
36
+ var _this = this;
37
+
38
+ var _ref$values = _ref.values,
39
+ values = _ref$values === undefined ? null : _ref$values,
40
+ _ref$iframe = _ref.iframe,
41
+ iframe = _ref$iframe === undefined ? null : _ref$iframe,
42
+ _ref$selectClass = _ref.selectClass,
43
+ selectClass = _ref$selectClass === undefined ? 'highlight' : _ref$selectClass,
44
+ _ref$trigger = _ref.trigger,
45
+ trigger = _ref$trigger === undefined ? '@' : _ref$trigger,
46
+ _ref$selectTemplate = _ref.selectTemplate,
47
+ selectTemplate = _ref$selectTemplate === undefined ? null : _ref$selectTemplate,
48
+ _ref$menuItemTemplate = _ref.menuItemTemplate,
49
+ menuItemTemplate = _ref$menuItemTemplate === undefined ? null : _ref$menuItemTemplate,
50
+ _ref$lookup = _ref.lookup,
51
+ lookup = _ref$lookup === undefined ? 'key' : _ref$lookup,
52
+ _ref$fillAttr = _ref.fillAttr,
53
+ fillAttr = _ref$fillAttr === undefined ? 'value' : _ref$fillAttr,
54
+ _ref$collection = _ref.collection,
55
+ collection = _ref$collection === undefined ? null : _ref$collection,
56
+ _ref$menuContainer = _ref.menuContainer,
57
+ menuContainer = _ref$menuContainer === undefined ? null : _ref$menuContainer,
58
+ _ref$noMatchTemplate = _ref.noMatchTemplate,
59
+ noMatchTemplate = _ref$noMatchTemplate === undefined ? null : _ref$noMatchTemplate,
60
+ _ref$requireLeadingSp = _ref.requireLeadingSpace,
61
+ requireLeadingSpace = _ref$requireLeadingSp === undefined ? true : _ref$requireLeadingSp,
62
+ _ref$allowSpaces = _ref.allowSpaces,
63
+ allowSpaces = _ref$allowSpaces === undefined ? false : _ref$allowSpaces,
64
+ _ref$replaceTextSuffi = _ref.replaceTextSuffix,
65
+ replaceTextSuffix = _ref$replaceTextSuffi === undefined ? null : _ref$replaceTextSuffi;
66
+
67
+ _classCallCheck(this, Tribute);
68
+
69
+ this.menuSelected = 0;
70
+ this.current = {};
71
+ this.inputEvent = false;
72
+ this.isActive = false;
73
+ this.menuContainer = menuContainer;
74
+ this.allowSpaces = allowSpaces;
75
+ this.replaceTextSuffix = replaceTextSuffix;
76
+
77
+ if (values) {
78
+ this.collection = [{
79
+ // symbol that starts the lookup
80
+ trigger: trigger,
81
+
82
+ iframe: iframe,
83
+
84
+ selectClass: selectClass,
85
+
86
+ // function called on select that retuns the content to insert
87
+ selectTemplate: (selectTemplate || Tribute.defaultSelectTemplate).bind(this),
88
+
89
+ // function called that returns content for an item
90
+ menuItemTemplate: (menuItemTemplate || Tribute.defaultMenuItemTemplate).bind(this),
91
+
92
+ // function called when menu is empty, disables hiding of menu.
93
+ noMatchTemplate: function (t) {
94
+ if (typeof t === 'function') {
95
+ return t.bind(_this);
96
+ }
97
+
98
+ return function () {
99
+ return '<li class="no-match">No match!</li>';
100
+ }.bind(_this);
101
+ }(noMatchTemplate),
102
+
103
+ // column to search against in the object
104
+ lookup: lookup,
105
+
106
+ // column that contains the content to insert by default
107
+ fillAttr: fillAttr,
108
+
109
+ // array of objects or a function returning an array of objects
110
+ values: values,
111
+
112
+ requireLeadingSpace: requireLeadingSpace
113
+ }];
114
+ } else if (collection) {
115
+ this.collection = collection.map(function (item) {
116
+ return {
117
+ trigger: item.trigger || trigger,
118
+ iframe: item.iframe || iframe,
119
+ selectClass: item.selectClass || selectClass,
120
+ selectTemplate: (item.selectTemplate || Tribute.defaultSelectTemplate).bind(_this),
121
+ menuItemTemplate: (item.menuItemTemplate || Tribute.defaultMenuItemTemplate).bind(_this),
122
+ // function called when menu is empty, disables hiding of menu.
123
+ noMatchTemplate: function (t) {
124
+ if (typeof t === 'function') {
125
+ return t.bind(_this);
126
+ }
127
+
128
+ return null;
129
+ }(noMatchTemplate),
130
+ lookup: item.lookup || lookup,
131
+ fillAttr: item.fillAttr || fillAttr,
132
+ values: item.values,
133
+ requireLeadingSpace: item.requireLeadingSpace
134
+ };
135
+ });
136
+ } else {
137
+ throw new Error('[Tribute] No collection specified.');
138
+ }
139
+
140
+ new _TributeRange2.default(this);
141
+ new _TributeEvents2.default(this);
142
+ new _TributeMenuEvents2.default(this);
143
+ new _TributeSearch2.default(this);
144
+ }
145
+
146
+ _createClass(Tribute, [{
147
+ key: "triggers",
148
+ value: function triggers() {
149
+ return this.collection.map(function (config) {
150
+ return config.trigger;
151
+ });
152
+ }
153
+ }, {
154
+ key: "attach",
155
+ value: function attach(el) {
156
+ if (!el) {
157
+ throw new Error('[Tribute] Must pass in a DOM node or NodeList.');
158
+ }
159
+
160
+ // Check if it is a jQuery collection
161
+ if (typeof jQuery !== 'undefined' && el instanceof jQuery) {
162
+ el = el.get();
163
+ }
164
+
165
+ // Is el an Array/Array-like object?
166
+ if (el.constructor === NodeList || el.constructor === HTMLCollection || el.constructor === Array) {
167
+ var length = el.length;
168
+ for (var i = 0; i < length; ++i) {
169
+ this._attach(el[i]);
170
+ }
171
+ } else {
172
+ this._attach(el);
173
+ }
174
+ }
175
+ }, {
176
+ key: "_attach",
177
+ value: function _attach(el) {
178
+ if (el.hasAttribute('data-tribute')) {
179
+ console.warn('Tribute was already bound to ' + el.nodeName);
180
+ }
181
+
182
+ this.ensureEditable(el);
183
+ this.events.bind(el);
184
+ el.setAttribute('data-tribute', true);
185
+ }
186
+ }, {
187
+ key: "ensureEditable",
188
+ value: function ensureEditable(element) {
189
+ if (Tribute.inputTypes().indexOf(element.nodeName) === -1) {
190
+ if (element.contentEditable) {
191
+ element.contentEditable = true;
192
+ } else {
193
+ throw new Error('[Tribute] Cannot bind to ' + element.nodeName);
194
+ }
195
+ }
196
+ }
197
+ }, {
198
+ key: "createMenu",
199
+ value: function createMenu() {
200
+ var wrapper = this.range.getDocument().createElement('div'),
201
+ ul = this.range.getDocument().createElement('ul');
202
+
203
+ wrapper.className = 'tribute-container';
204
+ wrapper.appendChild(ul);
205
+
206
+ if (this.menuContainer) {
207
+ return this.menuContainer.appendChild(wrapper);
208
+ }
209
+
210
+ return this.range.getDocument().body.appendChild(wrapper);
211
+ }
212
+ }, {
213
+ key: "showMenuFor",
214
+ value: function showMenuFor(element, scrollTo) {
215
+ var _this2 = this;
216
+
217
+ // Only proceed if menu isn't already shown for the current element & mentionText
218
+ if (this.isActive && this.current.element === element && this.current.mentionText === this.currentMentionTextSnapshot) {
219
+ return;
220
+ }
221
+ this.currentMentionTextSnapshot = this.current.mentionText;
222
+
223
+ // create the menu if it doesn't exist.
224
+ if (!this.menu) {
225
+ this.menu = this.createMenu();
226
+ this.menuEvents.bind(this.menu);
227
+ }
228
+
229
+ this.isActive = true;
230
+ this.menuSelected = 0;
231
+
232
+ if (!this.current.mentionText) {
233
+ this.current.mentionText = '';
234
+ }
235
+
236
+ var processValues = function processValues(values) {
237
+ // Tribute may not be active any more by the time the value callback returns
238
+ if (!_this2.isActive) {
239
+ return;
240
+ }
241
+
242
+ var items = _this2.search.filter(_this2.current.mentionText, values, {
243
+ pre: '<span>',
244
+ post: '</span>',
245
+ extract: function extract(el) {
246
+ if (typeof _this2.current.collection.lookup === 'string') {
247
+ return el[_this2.current.collection.lookup];
248
+ } else if (typeof _this2.current.collection.lookup === 'function') {
249
+ return _this2.current.collection.lookup(el);
250
+ } else {
251
+ throw new Error('Invalid lookup attribute, lookup must be string or function.');
252
+ }
253
+ }
254
+ });
255
+
256
+ _this2.current.filteredItems = items;
257
+
258
+ var ul = _this2.menu.querySelector('ul');
259
+
260
+ _this2.range.positionMenuAtCaret(scrollTo);
261
+
262
+ if (!items.length) {
263
+ var noMatchEvent = new CustomEvent('tribute-no-match', { detail: _this2.menu });
264
+ _this2.current.element.dispatchEvent(noMatchEvent);
265
+ if (!_this2.current.collection.noMatchTemplate) {
266
+ _this2.hideMenu();
267
+ } else {
268
+ ul.innerHTML = _this2.current.collection.noMatchTemplate();
269
+ }
270
+
271
+ return;
272
+ }
273
+
274
+ ul.innerHTML = '';
275
+
276
+ items.forEach(function (item, index) {
277
+ var li = _this2.range.getDocument().createElement('li');
278
+ li.setAttribute('data-index', index);
279
+ li.addEventListener('mouseenter', function (e) {
280
+ var li = e.target;
281
+ var index = li.getAttribute('data-index');
282
+ _this2.events.setActiveLi(index);
283
+ });
284
+ if (_this2.menuSelected === index) {
285
+ li.className = _this2.current.collection.selectClass;
286
+ }
287
+ li.innerHTML = _this2.current.collection.menuItemTemplate(item);
288
+ ul.appendChild(li);
289
+ });
290
+ };
291
+
292
+ if (typeof this.current.collection.values === 'function') {
293
+ this.current.collection.values(this.current.mentionText, processValues);
294
+ } else {
295
+ processValues(this.current.collection.values);
296
+ }
297
+ }
298
+ }, {
299
+ key: "showMenuForCollection",
300
+ value: function showMenuForCollection(element, collectionIndex) {
301
+ if (element !== document.activeElement) {
302
+ this.placeCaretAtEnd(element);
303
+ }
304
+
305
+ this.current.collection = this.collection[collectionIndex || 0];
306
+ this.current.externalTrigger = true;
307
+ this.current.element = element;
308
+
309
+ if (element.isContentEditable) this.insertTextAtCursor(this.current.collection.trigger);else this.insertAtCaret(element, this.current.collection.trigger);
310
+
311
+ this.showMenuFor(element);
312
+ }
313
+
314
+ // TODO: make sure this works for inputs/textareas
315
+
316
+ }, {
317
+ key: "placeCaretAtEnd",
318
+ value: function placeCaretAtEnd(el) {
319
+ el.focus();
320
+ if (typeof window.getSelection != "undefined" && typeof document.createRange != "undefined") {
321
+ var range = document.createRange();
322
+ range.selectNodeContents(el);
323
+ range.collapse(false);
324
+ var sel = window.getSelection();
325
+ sel.removeAllRanges();
326
+ sel.addRange(range);
327
+ } else if (typeof document.body.createTextRange != "undefined") {
328
+ var textRange = document.body.createTextRange();
329
+ textRange.moveToElementText(el);
330
+ textRange.collapse(false);
331
+ textRange.select();
332
+ }
333
+ }
334
+
335
+ // for contenteditable
336
+
337
+ }, {
338
+ key: "insertTextAtCursor",
339
+ value: function insertTextAtCursor(text) {
340
+ var sel, range, html;
341
+ sel = window.getSelection();
342
+ range = sel.getRangeAt(0);
343
+ range.deleteContents();
344
+ var textNode = document.createTextNode(text);
345
+ range.insertNode(textNode);
346
+ range.selectNodeContents(textNode);
347
+ range.collapse(false);
348
+ sel.removeAllRanges();
349
+ sel.addRange(range);
350
+ }
351
+
352
+ // for regular inputs
353
+
354
+ }, {
355
+ key: "insertAtCaret",
356
+ value: function insertAtCaret(textarea, text) {
357
+ var scrollPos = textarea.scrollTop;
358
+ var caretPos = textarea.selectionStart;
359
+
360
+ var front = textarea.value.substring(0, caretPos);
361
+ var back = textarea.value.substring(textarea.selectionEnd, textarea.value.length);
362
+ textarea.value = front + text + back;
363
+ caretPos = caretPos + text.length;
364
+ textarea.selectionStart = caretPos;
365
+ textarea.selectionEnd = caretPos;
366
+ textarea.focus();
367
+ textarea.scrollTop = scrollPos;
368
+ }
369
+ }, {
370
+ key: "hideMenu",
371
+ value: function hideMenu() {
372
+ if (this.menu) {
373
+ this.menu.style.cssText = 'display: none;';
374
+ this.isActive = false;
375
+ this.menuSelected = 0;
376
+ this.current = {};
377
+ }
378
+ }
379
+ }, {
380
+ key: "selectItemAtIndex",
381
+ value: function selectItemAtIndex(index, originalEvent) {
382
+ index = parseInt(index);
383
+ if (typeof index !== 'number') return;
384
+ var item = this.current.filteredItems[index];
385
+ var content = this.current.collection.selectTemplate(item);
386
+ if (content !== null) this.replaceText(content, originalEvent, item);
387
+ }
388
+ }, {
389
+ key: "replaceText",
390
+ value: function replaceText(content, originalEvent, item) {
391
+ this.range.replaceTriggerText(content, true, true, originalEvent, item);
392
+ }
393
+ }, {
394
+ key: "_append",
395
+ value: function _append(collection, newValues, replace) {
396
+ if (typeof collection.values === 'function') {
397
+ throw new Error('Unable to append to values, as it is a function.');
398
+ } else if (!replace) {
399
+ collection.values = collection.values.concat(newValues);
400
+ } else {
401
+ collection.values = newValues;
402
+ }
403
+ }
404
+ }, {
405
+ key: "append",
406
+ value: function append(collectionIndex, newValues, replace) {
407
+ var index = parseInt(collectionIndex);
408
+ if (typeof index !== 'number') throw new Error('please provide an index for the collection to update.');
409
+
410
+ var collection = this.collection[index];
411
+
412
+ this._append(collection, newValues, replace);
413
+ }
414
+ }, {
415
+ key: "appendCurrent",
416
+ value: function appendCurrent(newValues, replace) {
417
+ if (this.isActive) {
418
+ this._append(this.current.collection, newValues, replace);
419
+ } else {
420
+ throw new Error('No active state. Please use append instead and pass an index.');
421
+ }
422
+ }
423
+ }], [{
424
+ key: "defaultSelectTemplate",
425
+ value: function defaultSelectTemplate(item) {
426
+ if (typeof item === 'undefined') return null;
427
+ if (this.range.isContentEditable(this.current.element)) {
428
+ return '<span class="tribute-mention">' + (this.current.collection.trigger + item.original[this.current.collection.fillAttr]) + '</span>';
429
+ }
430
+
431
+ return this.current.collection.trigger + item.original[this.current.collection.fillAttr];
432
+ }
433
+ }, {
434
+ key: "defaultMenuItemTemplate",
435
+ value: function defaultMenuItemTemplate(matchItem) {
436
+ return matchItem.string;
437
+ }
438
+ }, {
439
+ key: "inputTypes",
440
+ value: function inputTypes() {
441
+ return ['TEXTAREA', 'INPUT'];
442
+ }
443
+ }]);
444
+
445
+ return Tribute;
446
+ }();
447
+
448
+ exports.default = Tribute;
449
+ module.exports = exports["default"];
450
+
451
+ },{"./TributeEvents":2,"./TributeMenuEvents":3,"./TributeRange":4,"./TributeSearch":5,"./utils":7}],2:[function(require,module,exports){
452
+ 'use strict';
453
+
454
+ Object.defineProperty(exports, "__esModule", {
455
+ value: true
456
+ });
457
+
458
+ var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
459
+
460
+ var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
461
+
462
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
463
+
464
+ var TributeEvents = function () {
465
+ function TributeEvents(tribute) {
466
+ _classCallCheck(this, TributeEvents);
467
+
468
+ this.tribute = tribute;
469
+ this.tribute.events = this;
470
+ }
471
+
472
+ _createClass(TributeEvents, [{
473
+ key: 'bind',
474
+ value: function bind(element) {
475
+ element.addEventListener('keydown', this.keydown.bind(element, this), false);
476
+ element.addEventListener('keyup', this.keyup.bind(element, this), false);
477
+ element.addEventListener('input', this.input.bind(element, this), false);
478
+ }
479
+ }, {
480
+ key: 'keydown',
481
+ value: function keydown(instance, event) {
482
+ if (instance.shouldDeactivate(event)) {
483
+ instance.tribute.isActive = false;
484
+ instance.tribute.hideMenu();
485
+ }
486
+
487
+ var element = this;
488
+ instance.commandEvent = false;
489
+
490
+ TributeEvents.keys().forEach(function (o) {
491
+ if (o.key === event.keyCode) {
492
+ instance.commandEvent = true;
493
+ instance.callbacks()[o.value.toLowerCase()](event, element);
494
+ }
495
+ });
496
+ }
497
+ }, {
498
+ key: 'input',
499
+ value: function input(instance, event) {
500
+ instance.inputEvent = true;
501
+ instance.keyup.call(this, instance, event);
502
+ }
503
+ }, {
504
+ key: 'click',
505
+ value: function click(instance, event) {
506
+ var tribute = instance.tribute;
507
+ if (tribute.menu && tribute.menu.contains(event.target)) {
508
+ var li = event.target;
509
+ event.preventDefault();
510
+ event.stopPropagation();
511
+ while (li.nodeName.toLowerCase() !== 'li') {
512
+ li = li.parentNode;
513
+ if (!li || li === tribute.menu) {
514
+ throw new Error('cannot find the <li> container for the click');
515
+ }
516
+ }
517
+ tribute.selectItemAtIndex(li.getAttribute('data-index'), event);
518
+ tribute.hideMenu();
519
+
520
+ // TODO: should fire with externalTrigger and target is outside of menu
521
+ } else if (tribute.current.element && !tribute.current.externalTrigger) {
522
+ tribute.current.externalTrigger = false;
523
+ setTimeout(function () {
524
+ return tribute.hideMenu();
525
+ });
526
+ }
527
+ }
528
+ }, {
529
+ key: 'keyup',
530
+ value: function keyup(instance, event) {
531
+ var _this = this;
532
+
533
+ if (instance.inputEvent) {
534
+ instance.inputEvent = false;
535
+ }
536
+ instance.updateSelection(this);
537
+
538
+ if (event.keyCode === 27) return;
539
+
540
+ if (!instance.tribute.isActive) {
541
+ var _ret = function () {
542
+ var keyCode = instance.getKeyCode(instance, _this, event);
543
+
544
+ if (isNaN(keyCode) || !keyCode) return {
545
+ v: void 0
546
+ };
547
+
548
+ var trigger = instance.tribute.triggers().find(function (trigger) {
549
+ return trigger.charCodeAt(0) === keyCode;
550
+ });
551
+
552
+ if (typeof trigger !== 'undefined') {
553
+ instance.callbacks().triggerChar(event, _this, trigger);
554
+ }
555
+ }();
556
+
557
+ if ((typeof _ret === 'undefined' ? 'undefined' : _typeof(_ret)) === "object") return _ret.v;
558
+ }
559
+
560
+ if (instance.tribute.current.trigger && instance.commandEvent === false || instance.tribute.isActive && event.keyCode === 8) {
561
+ instance.tribute.showMenuFor(this, true);
562
+ }
563
+ }
564
+ }, {
565
+ key: 'shouldDeactivate',
566
+ value: function shouldDeactivate(event) {
567
+ if (!this.tribute.isActive) return false;
568
+
569
+ if (this.tribute.current.mentionText.length === 0) {
570
+ var eventKeyPressed = false;
571
+ TributeEvents.keys().forEach(function (o) {
572
+ if (event.keyCode === o.key) eventKeyPressed = true;
573
+ });
574
+
575
+ return !eventKeyPressed;
576
+ }
577
+
578
+ return false;
579
+ }
580
+ }, {
581
+ key: 'getKeyCode',
582
+ value: function getKeyCode(instance, el, event) {
583
+ var char = void 0;
584
+ var tribute = instance.tribute;
585
+ var info = tribute.range.getTriggerInfo(false, false, true, tribute.allowSpaces);
586
+
587
+ if (info) {
588
+ return info.mentionTriggerChar.charCodeAt(0);
589
+ } else {
590
+ return false;
591
+ }
592
+ }
593
+ }, {
594
+ key: 'updateSelection',
595
+ value: function updateSelection(el) {
596
+ this.tribute.current.element = el;
597
+ var info = this.tribute.range.getTriggerInfo(false, false, true, this.tribute.allowSpaces);
598
+
599
+ if (info) {
600
+ this.tribute.current.selectedPath = info.mentionSelectedPath;
601
+ this.tribute.current.mentionText = info.mentionText;
602
+ this.tribute.current.selectedOffset = info.mentionSelectedOffset;
603
+ }
604
+ }
605
+ }, {
606
+ key: 'callbacks',
607
+ value: function callbacks() {
608
+ var _this2 = this;
609
+
610
+ return {
611
+ triggerChar: function triggerChar(e, el, trigger) {
612
+ var tribute = _this2.tribute;
613
+ tribute.current.trigger = trigger;
614
+
615
+ var collectionItem = tribute.collection.find(function (item) {
616
+ return item.trigger === trigger;
617
+ });
618
+
619
+ tribute.current.collection = collectionItem;
620
+ if (tribute.inputEvent) tribute.showMenuFor(el, true);
621
+ },
622
+ enter: function enter(e, el) {
623
+ // choose selection
624
+ if (_this2.tribute.isActive) {
625
+ e.preventDefault();
626
+ e.stopPropagation();
627
+ setTimeout(function () {
628
+ _this2.tribute.selectItemAtIndex(_this2.tribute.menuSelected, e);
629
+ _this2.tribute.hideMenu();
630
+ }, 0);
631
+ }
632
+ },
633
+ escape: function escape(e, el) {
634
+ if (_this2.tribute.isActive) {
635
+ e.preventDefault();
636
+ e.stopPropagation();
637
+ _this2.tribute.isActive = false;
638
+ _this2.tribute.hideMenu();
639
+ }
640
+ },
641
+ tab: function tab(e, el) {
642
+ // choose first match
643
+ _this2.callbacks().enter(e, el);
644
+ },
645
+ up: function up(e, el) {
646
+ // navigate up ul
647
+ if (_this2.tribute.isActive) {
648
+ e.preventDefault();
649
+ e.stopPropagation();
650
+ var count = _this2.tribute.current.filteredItems.length,
651
+ selected = _this2.tribute.menuSelected;
652
+
653
+ if (count > selected && selected > 0) {
654
+ _this2.tribute.menuSelected--;
655
+ _this2.setActiveLi();
656
+ } else if (selected === 0) {
657
+ _this2.tribute.menuSelected = count - 1;
658
+ _this2.setActiveLi();
659
+ _this2.tribute.menu.scrollTop = _this2.tribute.menu.scrollHeight;
660
+ }
661
+ }
662
+ },
663
+ down: function down(e, el) {
664
+ // navigate down ul
665
+ if (_this2.tribute.isActive) {
666
+ e.preventDefault();
667
+ e.stopPropagation();
668
+ var count = _this2.tribute.current.filteredItems.length - 1,
669
+ selected = _this2.tribute.menuSelected;
670
+
671
+ if (count > selected) {
672
+ _this2.tribute.menuSelected++;
673
+ _this2.setActiveLi();
674
+ } else if (count === selected) {
675
+ _this2.tribute.menuSelected = 0;
676
+ _this2.setActiveLi();
677
+ _this2.tribute.menu.scrollTop = 0;
678
+ }
679
+ }
680
+ },
681
+ delete: function _delete(e, el) {
682
+ if (_this2.tribute.isActive && _this2.tribute.current.mentionText.length < 1) {
683
+ _this2.tribute.hideMenu();
684
+ } else if (_this2.tribute.isActive) {
685
+ _this2.tribute.showMenuFor(el);
686
+ }
687
+ }
688
+ };
689
+ }
690
+ }, {
691
+ key: 'setActiveLi',
692
+ value: function setActiveLi(index) {
693
+ var lis = this.tribute.menu.querySelectorAll('li'),
694
+ length = lis.length >>> 0;
695
+
696
+ // get heights
697
+ var menuFullHeight = this.getFullHeight(this.tribute.menu),
698
+ liHeight = this.getFullHeight(lis[0]);
699
+
700
+ if (index) this.tribute.menuSelected = index;
701
+
702
+ for (var i = 0; i < length; i++) {
703
+ var li = lis[i];
704
+ if (i === this.tribute.menuSelected) {
705
+ var offset = liHeight * (i + 1);
706
+ var scrollTop = this.tribute.menu.scrollTop;
707
+ var totalScroll = scrollTop + menuFullHeight;
708
+
709
+ if (offset > totalScroll) {
710
+ this.tribute.menu.scrollTop += liHeight;
711
+ } else if (offset < totalScroll) {
712
+ this.tribute.menu.scrollTop -= liHeight;
713
+ }
714
+
715
+ li.className = this.tribute.current.collection.selectClass;
716
+ } else {
717
+ li.className = '';
718
+ }
719
+ }
720
+ }
721
+ }, {
722
+ key: 'getFullHeight',
723
+ value: function getFullHeight(elem, includeMargin) {
724
+ var height = elem.getBoundingClientRect().height;
725
+
726
+ if (includeMargin) {
727
+ var style = elem.currentStyle || window.getComputedStyle(elem);
728
+ return height + parseFloat(style.marginTop) + parseFloat(style.marginBottom);
729
+ }
730
+
731
+ return height;
732
+ }
733
+ }], [{
734
+ key: 'keys',
735
+ value: function keys() {
736
+ return [{
737
+ key: 9,
738
+ value: 'TAB'
739
+ }, {
740
+ key: 8,
741
+ value: 'DELETE'
742
+ }, {
743
+ key: 13,
744
+ value: 'ENTER'
745
+ }, {
746
+ key: 27,
747
+ value: 'ESCAPE'
748
+ }, {
749
+ key: 38,
750
+ value: 'UP'
751
+ }, {
752
+ key: 40,
753
+ value: 'DOWN'
754
+ }];
755
+ }
756
+ }]);
757
+
758
+ return TributeEvents;
759
+ }();
760
+
761
+ exports.default = TributeEvents;
762
+ module.exports = exports['default'];
763
+
764
+ },{}],3:[function(require,module,exports){
765
+ 'use strict';
766
+
767
+ Object.defineProperty(exports, "__esModule", {
768
+ value: true
769
+ });
770
+
771
+ var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
772
+
773
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
774
+
775
+ var TributeMenuEvents = function () {
776
+ function TributeMenuEvents(tribute) {
777
+ _classCallCheck(this, TributeMenuEvents);
778
+
779
+ this.tribute = tribute;
780
+ this.tribute.menuEvents = this;
781
+ this.menu = this.tribute.menu;
782
+ }
783
+
784
+ _createClass(TributeMenuEvents, [{
785
+ key: 'bind',
786
+ value: function bind(menu) {
787
+ var _this = this;
788
+
789
+ menu.addEventListener('keydown', this.tribute.events.keydown.bind(this.menu, this), false);
790
+ this.tribute.range.getDocument().addEventListener('mousedown', this.tribute.events.click.bind(null, this), false);
791
+
792
+ // fixes IE11 issues with mousedown
793
+ this.tribute.range.getDocument().addEventListener('MSPointerDown', this.tribute.events.click.bind(null, this), false);
794
+
795
+ window.addEventListener('resize', this.debounce(function () {
796
+ if (_this.tribute.isActive) {
797
+ _this.tribute.range.positionMenuAtCaret(true);
798
+ }
799
+ }, 300, false));
800
+
801
+ if (this.menuContainer) {
802
+ this.menuContainer.addEventListener('scroll', this.debounce(function () {
803
+ if (_this.tribute.isActive) {
804
+ _this.tribute.showMenuFor(_this.tribute.current.element, false);
805
+ }
806
+ }, 300, false), false);
807
+ } else {
808
+ window.onscroll = this.debounce(function () {
809
+ if (_this.tribute.isActive) {
810
+ _this.tribute.showMenuFor(_this.tribute.current.element, false);
811
+ }
812
+ }, 300, false);
813
+ }
814
+ }
815
+ }, {
816
+ key: 'debounce',
817
+ value: function debounce(func, wait, immediate) {
818
+ var _this2 = this,
819
+ _arguments = arguments;
820
+
821
+ var timeout;
822
+ return function () {
823
+ var context = _this2,
824
+ args = _arguments;
825
+ var later = function later() {
826
+ timeout = null;
827
+ if (!immediate) func.apply(context, args);
828
+ };
829
+ var callNow = immediate && !timeout;
830
+ clearTimeout(timeout);
831
+ timeout = setTimeout(later, wait);
832
+ if (callNow) func.apply(context, args);
833
+ };
834
+ }
835
+ }]);
836
+
837
+ return TributeMenuEvents;
838
+ }();
839
+
840
+ exports.default = TributeMenuEvents;
841
+ module.exports = exports['default'];
842
+
843
+ },{}],4:[function(require,module,exports){
844
+ 'use strict';
845
+
846
+ Object.defineProperty(exports, "__esModule", {
847
+ value: true
848
+ });
849
+
850
+ var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
851
+
852
+ var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
853
+
854
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
855
+
856
+ // Thanks to https://github.com/jeff-collins/ment.io
857
+ var TributeRange = function () {
858
+ function TributeRange(tribute) {
859
+ _classCallCheck(this, TributeRange);
860
+
861
+ this.tribute = tribute;
862
+ this.tribute.range = this;
863
+ }
864
+
865
+ _createClass(TributeRange, [{
866
+ key: 'getDocument',
867
+ value: function getDocument() {
868
+ var iframe = void 0;
869
+ if (this.tribute.current.collection) {
870
+ iframe = this.tribute.current.collection.iframe;
871
+ }
872
+
873
+ if (!iframe) {
874
+ return document;
875
+ }
876
+
877
+ return iframe.contentWindow.document;
878
+ }
879
+ }, {
880
+ key: 'positionMenuAtCaret',
881
+ value: function positionMenuAtCaret(scrollTo) {
882
+ var context = this.tribute.current,
883
+ coordinates = void 0;
884
+
885
+ var info = this.getTriggerInfo(false, false, true, this.tribute.allowSpaces);
886
+
887
+ if (typeof info !== 'undefined') {
888
+ if (!this.isContentEditable(context.element)) {
889
+ coordinates = this.getTextAreaOrInputUnderlinePosition(this.getDocument().activeElement, info.mentionPosition);
890
+ } else {
891
+ coordinates = this.getContentEditableCaretPosition(info.mentionPosition);
892
+ }
893
+
894
+ // TODO: flip the dropdown if rendered off of screen edge.
895
+ // let contentWidth = this.tribute.menu.offsetWidth + coordinates.left
896
+ // let parentWidth;
897
+
898
+ // if (this.tribute.menuContainer) {
899
+ // parentWidth = this.tribute.menuContainer.offsetWidth
900
+ // } else {
901
+ // parentWidth = this.getDocument().body.offsetWidth
902
+ // }
903
+
904
+ // if (contentWidth > parentWidth) {
905
+ // let diff = contentWidth - parentWidth
906
+ // let removeFromLeft = this.tribute.menu.offsetWidth - diff
907
+ // let newLeft = coordinates.left - removeFromLeft
908
+
909
+ // if (newLeft > 0) {
910
+ // coordinates.left = newLeft
911
+ // } else {
912
+ // coordinates.left = 0
913
+ // }
914
+ // }
915
+
916
+ this.tribute.menu.style.cssText = 'top: ' + coordinates.top + 'px;\n left: ' + coordinates.left + 'px;\n position: absolute;\n zIndex: 10000;\n display: block;';
917
+
918
+ if (scrollTo) this.scrollIntoView();
919
+ } else {
920
+ this.tribute.menu.style.cssText = 'display: none';
921
+ }
922
+ }
923
+ }, {
924
+ key: 'selectElement',
925
+ value: function selectElement(targetElement, path, offset) {
926
+ var range = void 0;
927
+ var elem = targetElement;
928
+
929
+ if (path) {
930
+ for (var i = 0; i < path.length; i++) {
931
+ elem = elem.childNodes[path[i]];
932
+ if (elem === undefined) {
933
+ return;
934
+ }
935
+ while (elem.length < offset) {
936
+ offset -= elem.length;
937
+ elem = elem.nextSibling;
938
+ }
939
+ if (elem.childNodes.length === 0 && !elem.length) {
940
+ elem = elem.previousSibling;
941
+ }
942
+ }
943
+ }
944
+ var sel = this.getWindowSelection();
945
+
946
+ range = this.getDocument().createRange();
947
+ range.setStart(elem, offset);
948
+ range.setEnd(elem, offset);
949
+ range.collapse(true);
950
+
951
+ try {
952
+ sel.removeAllRanges();
953
+ } catch (error) {}
954
+
955
+ sel.addRange(range);
956
+ targetElement.focus();
957
+ }
958
+
959
+ // TODO: this may not be necessary anymore as we are using mouseup instead of click
960
+
961
+ }, {
962
+ key: 'resetSelection',
963
+ value: function resetSelection(targetElement, path, offset) {
964
+ if (!this.isContentEditable(targetElement)) {
965
+ if (targetElement !== this.getDocument().activeElement) {
966
+ targetElement.focus();
967
+ }
968
+ } else {
969
+ this.selectElement(targetElement, path, offset);
970
+ }
971
+ }
972
+ }, {
973
+ key: 'replaceTriggerText',
974
+ value: function replaceTriggerText(text, requireLeadingSpace, hasTrailingSpace, originalEvent, item) {
975
+ var context = this.tribute.current;
976
+ // TODO: this may not be necessary anymore as we are using mouseup instead of click
977
+ // this.resetSelection(context.element, context.selectedPath, context.selectedOffset)
978
+
979
+ var info = this.getTriggerInfo(true, hasTrailingSpace, requireLeadingSpace, this.tribute.allowSpaces);
980
+
981
+ // Create the event
982
+ var replaceEvent = new CustomEvent('tribute-replaced', {
983
+ detail: {
984
+ item: item,
985
+ event: originalEvent
986
+ }
987
+ });
988
+
989
+ if (info !== undefined) {
990
+ if (!this.isContentEditable(context.element)) {
991
+ var myField = this.getDocument().activeElement;
992
+ var textSuffix = typeof this.tribute.replaceTextSuffix == 'string' ? this.tribute.replaceTextSuffix : ' ';
993
+ text += textSuffix;
994
+ var startPos = info.mentionPosition;
995
+ var endPos = info.mentionPosition + info.mentionText.length + textSuffix.length;
996
+ myField.value = myField.value.substring(0, startPos) + text + myField.value.substring(endPos, myField.value.length);
997
+ myField.selectionStart = startPos + text.length;
998
+ myField.selectionEnd = startPos + text.length;
999
+ } else {
1000
+ // add a space to the end of the pasted text
1001
+ var _textSuffix = typeof this.tribute.replaceTextSuffix == 'string' ? this.tribute.replaceTextSuffix : '\xA0';
1002
+ text += _textSuffix;
1003
+ this.pasteHtml(text, info.mentionPosition, info.mentionPosition + info.mentionText.length + 1);
1004
+ }
1005
+
1006
+ context.element.dispatchEvent(replaceEvent);
1007
+ }
1008
+ }
1009
+ }, {
1010
+ key: 'pasteHtml',
1011
+ value: function pasteHtml(html, startPos, endPos) {
1012
+ var range = void 0,
1013
+ sel = void 0;
1014
+ sel = this.getWindowSelection();
1015
+ range = this.getDocument().createRange();
1016
+ range.setStart(sel.anchorNode, startPos);
1017
+ range.setEnd(sel.anchorNode, endPos);
1018
+ range.deleteContents();
1019
+
1020
+ var el = this.getDocument().createElement('div');
1021
+ el.innerHTML = html;
1022
+ var frag = this.getDocument().createDocumentFragment(),
1023
+ node = void 0,
1024
+ lastNode = void 0;
1025
+ while (node = el.firstChild) {
1026
+ lastNode = frag.appendChild(node);
1027
+ }
1028
+ range.insertNode(frag);
1029
+
1030
+ // Preserve the selection
1031
+ if (lastNode) {
1032
+ range = range.cloneRange();
1033
+ range.setStartAfter(lastNode);
1034
+ range.collapse(true);
1035
+ sel.removeAllRanges();
1036
+ sel.addRange(range);
1037
+ }
1038
+ }
1039
+ }, {
1040
+ key: 'getWindowSelection',
1041
+ value: function getWindowSelection() {
1042
+ if (this.tribute.collection.iframe) {
1043
+ return this.tribute.collection.iframe.contentWindow.getSelection();
1044
+ }
1045
+
1046
+ return window.getSelection();
1047
+ }
1048
+ }, {
1049
+ key: 'getNodePositionInParent',
1050
+ value: function getNodePositionInParent(element) {
1051
+ if (element.parentNode === null) {
1052
+ return 0;
1053
+ }
1054
+
1055
+ for (var i = 0; i < element.parentNode.childNodes.length; i++) {
1056
+ var node = element.parentNode.childNodes[i];
1057
+
1058
+ if (node === element) {
1059
+ return i;
1060
+ }
1061
+ }
1062
+ }
1063
+ }, {
1064
+ key: 'getContentEditableSelectedPath',
1065
+ value: function getContentEditableSelectedPath(ctx) {
1066
+ var sel = this.getWindowSelection();
1067
+ var selected = sel.anchorNode;
1068
+ var path = [];
1069
+ var offset = void 0;
1070
+
1071
+ if (selected != null) {
1072
+ var i = void 0;
1073
+ var ce = selected.contentEditable;
1074
+ while (selected !== null && ce !== 'true') {
1075
+ i = this.getNodePositionInParent(selected);
1076
+ path.push(i);
1077
+ selected = selected.parentNode;
1078
+ if (selected !== null) {
1079
+ ce = selected.contentEditable;
1080
+ }
1081
+ }
1082
+ path.reverse();
1083
+
1084
+ // getRangeAt may not exist, need alternative
1085
+ offset = sel.getRangeAt(0).startOffset;
1086
+
1087
+ return {
1088
+ selected: selected,
1089
+ path: path,
1090
+ offset: offset
1091
+ };
1092
+ }
1093
+ }
1094
+ }, {
1095
+ key: 'getTextPrecedingCurrentSelection',
1096
+ value: function getTextPrecedingCurrentSelection() {
1097
+ var context = this.tribute.current,
1098
+ text = '';
1099
+
1100
+ if (!this.isContentEditable(context.element)) {
1101
+ var textComponent = this.tribute.current.element;
1102
+ if (textComponent) {
1103
+ var startPos = textComponent.selectionStart;
1104
+ if (textComponent.value && startPos >= 0) {
1105
+ text = textComponent.value.substring(0, startPos);
1106
+ }
1107
+ }
1108
+ } else {
1109
+ var selectedElem = this.getWindowSelection().anchorNode;
1110
+
1111
+ if (selectedElem != null) {
1112
+ var workingNodeContent = selectedElem.textContent;
1113
+ var selectStartOffset = this.getWindowSelection().getRangeAt(0).startOffset;
1114
+
1115
+ if (workingNodeContent && selectStartOffset >= 0) {
1116
+ text = workingNodeContent.substring(0, selectStartOffset);
1117
+ }
1118
+ }
1119
+ }
1120
+
1121
+ return text;
1122
+ }
1123
+ }, {
1124
+ key: 'getTriggerInfo',
1125
+ value: function getTriggerInfo(menuAlreadyActive, hasTrailingSpace, requireLeadingSpace, allowSpaces) {
1126
+ var _this = this;
1127
+
1128
+ var ctx = this.tribute.current;
1129
+ var selected = void 0,
1130
+ path = void 0,
1131
+ offset = void 0;
1132
+
1133
+ if (!this.isContentEditable(ctx.element)) {
1134
+ selected = this.getDocument().activeElement;
1135
+ } else {
1136
+ var selectionInfo = this.getContentEditableSelectedPath(ctx);
1137
+
1138
+ if (selectionInfo) {
1139
+ selected = selectionInfo.selected;
1140
+ path = selectionInfo.path;
1141
+ offset = selectionInfo.offset;
1142
+ }
1143
+ }
1144
+
1145
+ var effectiveRange = this.getTextPrecedingCurrentSelection();
1146
+
1147
+ if (effectiveRange !== undefined && effectiveRange !== null) {
1148
+ var _ret = function () {
1149
+ var mostRecentTriggerCharPos = -1;
1150
+ var triggerChar = void 0;
1151
+
1152
+ _this.tribute.collection.forEach(function (config) {
1153
+ var c = config.trigger;
1154
+ var idx = config.requireLeadingSpace ? _this.lastIndexWithLeadingSpace(effectiveRange, c) : effectiveRange.lastIndexOf(c);
1155
+
1156
+ if (idx > mostRecentTriggerCharPos) {
1157
+ mostRecentTriggerCharPos = idx;
1158
+ triggerChar = c;
1159
+ requireLeadingSpace = config.requireLeadingSpace;
1160
+ }
1161
+ });
1162
+
1163
+ if (mostRecentTriggerCharPos >= 0 && (mostRecentTriggerCharPos === 0 || !requireLeadingSpace || /[\xA0\s]/g.test(effectiveRange.substring(mostRecentTriggerCharPos - 1, mostRecentTriggerCharPos)))) {
1164
+ var currentTriggerSnippet = effectiveRange.substring(mostRecentTriggerCharPos + 1, effectiveRange.length);
1165
+
1166
+ triggerChar = effectiveRange.substring(mostRecentTriggerCharPos, mostRecentTriggerCharPos + 1);
1167
+ var firstSnippetChar = currentTriggerSnippet.substring(0, 1);
1168
+ var leadingSpace = currentTriggerSnippet.length > 0 && (firstSnippetChar === ' ' || firstSnippetChar === '\xA0');
1169
+ if (hasTrailingSpace) {
1170
+ currentTriggerSnippet = currentTriggerSnippet.trim();
1171
+ }
1172
+
1173
+ var regex = allowSpaces ? /[^\S ]/g : /[\xA0\s]/g;
1174
+
1175
+ if (!leadingSpace && (menuAlreadyActive || !regex.test(currentTriggerSnippet))) {
1176
+ return {
1177
+ v: {
1178
+ mentionPosition: mostRecentTriggerCharPos,
1179
+ mentionText: currentTriggerSnippet,
1180
+ mentionSelectedElement: selected,
1181
+ mentionSelectedPath: path,
1182
+ mentionSelectedOffset: offset,
1183
+ mentionTriggerChar: triggerChar
1184
+ }
1185
+ };
1186
+ }
1187
+ }
1188
+ }();
1189
+
1190
+ if ((typeof _ret === 'undefined' ? 'undefined' : _typeof(_ret)) === "object") return _ret.v;
1191
+ }
1192
+ }
1193
+ }, {
1194
+ key: 'lastIndexWithLeadingSpace',
1195
+ value: function lastIndexWithLeadingSpace(str, char) {
1196
+ var reversedStr = str.split('').reverse().join('');
1197
+ var index = -1;
1198
+
1199
+ for (var cidx = 0, len = str.length; cidx < len; cidx++) {
1200
+ var firstChar = cidx === str.length - 1;
1201
+ var leadingSpace = /\s/.test(reversedStr[cidx + 1]);
1202
+ var match = char === reversedStr[cidx];
1203
+
1204
+ if (match && (firstChar || leadingSpace)) {
1205
+ index = str.length - 1 - cidx;
1206
+ break;
1207
+ }
1208
+ }
1209
+
1210
+ return index;
1211
+ }
1212
+ }, {
1213
+ key: 'isContentEditable',
1214
+ value: function isContentEditable(element) {
1215
+ return element.nodeName !== 'INPUT' && element.nodeName !== 'TEXTAREA';
1216
+ }
1217
+ }, {
1218
+ key: 'getTextAreaOrInputUnderlinePosition',
1219
+ value: function getTextAreaOrInputUnderlinePosition(element, position) {
1220
+ var properties = ['direction', 'boxSizing', 'width', 'height', 'overflowX', 'overflowY', 'borderTopWidth', 'borderRightWidth', 'borderBottomWidth', 'borderLeftWidth', 'paddingTop', 'paddingRight', 'paddingBottom', 'paddingLeft', 'fontStyle', 'fontVariant', 'fontWeight', 'fontStretch', 'fontSize', 'fontSizeAdjust', 'lineHeight', 'fontFamily', 'textAlign', 'textTransform', 'textIndent', 'textDecoration', 'letterSpacing', 'wordSpacing'];
1221
+
1222
+ var isFirefox = window.mozInnerScreenX !== null;
1223
+
1224
+ var div = this.getDocument().createElement('div');
1225
+ div.id = 'input-textarea-caret-position-mirror-div';
1226
+ this.getDocument().body.appendChild(div);
1227
+
1228
+ var style = div.style;
1229
+ var computed = window.getComputedStyle ? getComputedStyle(element) : element.currentStyle;
1230
+
1231
+ style.whiteSpace = 'pre-wrap';
1232
+ if (element.nodeName !== 'INPUT') {
1233
+ style.wordWrap = 'break-word';
1234
+ }
1235
+
1236
+ // position off-screen
1237
+ style.position = 'absolute';
1238
+ style.visibility = 'hidden';
1239
+
1240
+ // transfer the element's properties to the div
1241
+ properties.forEach(function (prop) {
1242
+ style[prop] = computed[prop];
1243
+ });
1244
+
1245
+ if (isFirefox) {
1246
+ style.width = parseInt(computed.width) - 2 + 'px';
1247
+ if (element.scrollHeight > parseInt(computed.height)) style.overflowY = 'scroll';
1248
+ } else {
1249
+ style.overflow = 'hidden';
1250
+ }
1251
+
1252
+ div.textContent = element.value.substring(0, position);
1253
+
1254
+ if (element.nodeName === 'INPUT') {
1255
+ div.textContent = div.textContent.replace(/\s/g, ' ');
1256
+ }
1257
+
1258
+ var span = this.getDocument().createElement('span');
1259
+ span.textContent = element.value.substring(position) || '.';
1260
+ div.appendChild(span);
1261
+
1262
+ var rect = element.getBoundingClientRect();
1263
+ var doc = document.documentElement;
1264
+ var windowLeft = (window.pageXOffset || doc.scrollLeft) - (doc.clientLeft || 0);
1265
+ var windowTop = (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0);
1266
+
1267
+ var coordinates = {
1268
+ top: rect.top + windowTop + span.offsetTop + parseInt(computed.borderTopWidth) + parseInt(computed.fontSize) - element.scrollTop,
1269
+ left: rect.left + windowLeft + span.offsetLeft + parseInt(computed.borderLeftWidth)
1270
+ };
1271
+
1272
+ this.getDocument().body.removeChild(div);
1273
+
1274
+ return coordinates;
1275
+ }
1276
+ }, {
1277
+ key: 'getContentEditableCaretPosition',
1278
+ value: function getContentEditableCaretPosition(selectedNodePosition) {
1279
+ var markerTextChar = '';
1280
+ var markerEl = void 0,
1281
+ markerId = 'sel_' + new Date().getTime() + '_' + Math.random().toString().substr(2);
1282
+ var range = void 0;
1283
+ var sel = this.getWindowSelection();
1284
+ var prevRange = sel.getRangeAt(0);
1285
+
1286
+ range = this.getDocument().createRange();
1287
+ range.setStart(sel.anchorNode, selectedNodePosition);
1288
+ range.setEnd(sel.anchorNode, selectedNodePosition);
1289
+
1290
+ range.collapse(false);
1291
+
1292
+ // Create the marker element containing a single invisible character using DOM methods and insert it
1293
+ markerEl = this.getDocument().createElement('span');
1294
+ markerEl.id = markerId;
1295
+ markerEl.appendChild(this.getDocument().createTextNode(markerTextChar));
1296
+ range.insertNode(markerEl);
1297
+ sel.removeAllRanges();
1298
+ sel.addRange(prevRange);
1299
+
1300
+ var rect = markerEl.getBoundingClientRect();
1301
+ var doc = document.documentElement;
1302
+ var windowLeft = (window.pageXOffset || doc.scrollLeft) - (doc.clientLeft || 0);
1303
+ var windowTop = (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0);
1304
+ var coordinates = {
1305
+ left: rect.left + windowLeft,
1306
+ top: rect.top + markerEl.offsetHeight + windowTop
1307
+ };
1308
+
1309
+ markerEl.parentNode.removeChild(markerEl);
1310
+ return coordinates;
1311
+ }
1312
+ }, {
1313
+ key: 'scrollIntoView',
1314
+ value: function scrollIntoView(elem) {
1315
+ var reasonableBuffer = 20,
1316
+ clientRect = void 0;
1317
+ var maxScrollDisplacement = 100;
1318
+ var e = this.menu;
1319
+
1320
+ if (typeof e === 'undefined') return;
1321
+
1322
+ while (clientRect === undefined || clientRect.height === 0) {
1323
+ clientRect = e.getBoundingClientRect();
1324
+
1325
+ if (clientRect.height === 0) {
1326
+ e = e.childNodes[0];
1327
+ if (e === undefined || !e.getBoundingClientRect) {
1328
+ return;
1329
+ }
1330
+ }
1331
+ }
1332
+
1333
+ var elemTop = clientRect.top;
1334
+ var elemBottom = elemTop + clientRect.height;
1335
+
1336
+ if (elemTop < 0) {
1337
+ window.scrollTo(0, window.pageYOffset + clientRect.top - reasonableBuffer);
1338
+ } else if (elemBottom > window.innerHeight) {
1339
+ var maxY = window.pageYOffset + clientRect.top - reasonableBuffer;
1340
+
1341
+ if (maxY - window.pageYOffset > maxScrollDisplacement) {
1342
+ maxY = window.pageYOffset + maxScrollDisplacement;
1343
+ }
1344
+
1345
+ var targetY = window.pageYOffset - (window.innerHeight - elemBottom);
1346
+
1347
+ if (targetY > maxY) {
1348
+ targetY = maxY;
1349
+ }
1350
+
1351
+ window.scrollTo(0, targetY);
1352
+ }
1353
+ }
1354
+ }]);
1355
+
1356
+ return TributeRange;
1357
+ }();
1358
+
1359
+ exports.default = TributeRange;
1360
+ module.exports = exports['default'];
1361
+
1362
+ },{}],5:[function(require,module,exports){
1363
+ 'use strict';
1364
+
1365
+ Object.defineProperty(exports, "__esModule", {
1366
+ value: true
1367
+ });
1368
+
1369
+ var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
1370
+
1371
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
1372
+
1373
+ // Thanks to https://github.com/mattyork/fuzzy
1374
+ var TributeSearch = function () {
1375
+ function TributeSearch(tribute) {
1376
+ _classCallCheck(this, TributeSearch);
1377
+
1378
+ this.tribute = tribute;
1379
+ this.tribute.search = this;
1380
+ }
1381
+
1382
+ _createClass(TributeSearch, [{
1383
+ key: 'simpleFilter',
1384
+ value: function simpleFilter(pattern, array) {
1385
+ var _this = this;
1386
+
1387
+ return array.filter(function (string) {
1388
+ return _this.test(pattern, string);
1389
+ });
1390
+ }
1391
+ }, {
1392
+ key: 'test',
1393
+ value: function test(pattern, string) {
1394
+ return this.match(pattern, string) !== null;
1395
+ }
1396
+ }, {
1397
+ key: 'match',
1398
+ value: function match(pattern, string, opts) {
1399
+ opts = opts || {};
1400
+ var patternIdx = 0,
1401
+ result = [],
1402
+ len = string.length,
1403
+ totalScore = 0,
1404
+ currScore = 0,
1405
+ pre = opts.pre || '',
1406
+ post = opts.post || '',
1407
+ compareString = opts.caseSensitive && string || string.toLowerCase(),
1408
+ ch = void 0,
1409
+ compareChar = void 0;
1410
+
1411
+ pattern = opts.caseSensitive && pattern || pattern.toLowerCase();
1412
+
1413
+ var patternCache = this.traverse(compareString, pattern, 0, 0, []);
1414
+ if (!patternCache) {
1415
+ return null;
1416
+ }
1417
+
1418
+ return {
1419
+ rendered: this.render(string, patternCache.cache, pre, post),
1420
+ score: patternCache.score
1421
+ };
1422
+ }
1423
+ }, {
1424
+ key: 'traverse',
1425
+ value: function traverse(string, pattern, stringIndex, patternIndex, patternCache) {
1426
+ // if the pattern search at end
1427
+ if (pattern.length === patternIndex) {
1428
+
1429
+ // calculate socre and copy the cache containing the indices where it's found
1430
+ return {
1431
+ score: this.calculateScore(patternCache),
1432
+ cache: patternCache.slice()
1433
+ };
1434
+ }
1435
+
1436
+ // if string at end or remaining pattern > remaining string
1437
+ if (string.length === stringIndex || pattern.length - patternIndex > string.length - stringIndex) {
1438
+ return undefined;
1439
+ }
1440
+
1441
+ var c = pattern[patternIndex];
1442
+ var index = string.indexOf(c, stringIndex);
1443
+ var best = void 0,
1444
+ temp = void 0;
1445
+
1446
+ while (index > -1) {
1447
+ patternCache.push(index);
1448
+ temp = this.traverse(string, pattern, index + 1, patternIndex + 1, patternCache);
1449
+ patternCache.pop();
1450
+
1451
+ // if downstream traversal failed, return best answer so far
1452
+ if (!temp) {
1453
+ return best;
1454
+ }
1455
+
1456
+ if (!best || best.score < temp.score) {
1457
+ best = temp;
1458
+ }
1459
+
1460
+ index = string.indexOf(c, index + 1);
1461
+ }
1462
+
1463
+ return best;
1464
+ }
1465
+ }, {
1466
+ key: 'calculateScore',
1467
+ value: function calculateScore(patternCache) {
1468
+ var score = 0;
1469
+ var temp = 1;
1470
+
1471
+ patternCache.forEach(function (index, i) {
1472
+ if (i > 0) {
1473
+ if (patternCache[i - 1] + 1 === index) {
1474
+ temp += temp + 1;
1475
+ } else {
1476
+ temp = 1;
1477
+ }
1478
+ }
1479
+
1480
+ score += temp;
1481
+ });
1482
+
1483
+ return score;
1484
+ }
1485
+ }, {
1486
+ key: 'render',
1487
+ value: function render(string, indices, pre, post) {
1488
+ var rendered = string.substring(0, indices[0]);
1489
+
1490
+ indices.forEach(function (index, i) {
1491
+ rendered += pre + string[index] + post + string.substring(index + 1, indices[i + 1] ? indices[i + 1] : string.length);
1492
+ });
1493
+
1494
+ return rendered;
1495
+ }
1496
+ }, {
1497
+ key: 'filter',
1498
+ value: function filter(pattern, arr, opts) {
1499
+ var _this2 = this;
1500
+
1501
+ opts = opts || {};
1502
+ return arr.reduce(function (prev, element, idx, arr) {
1503
+ var str = element;
1504
+
1505
+ if (opts.extract) {
1506
+ str = opts.extract(element);
1507
+
1508
+ if (!str) {
1509
+ // take care of undefineds / nulls / etc.
1510
+ str = '';
1511
+ }
1512
+ }
1513
+
1514
+ var rendered = _this2.match(pattern, str, opts);
1515
+
1516
+ if (rendered != null) {
1517
+ prev[prev.length] = {
1518
+ string: rendered.rendered,
1519
+ score: rendered.score,
1520
+ index: idx,
1521
+ original: element
1522
+ };
1523
+ }
1524
+
1525
+ return prev;
1526
+ }, []).sort(function (a, b) {
1527
+ var compare = b.score - a.score;
1528
+ if (compare) return compare;
1529
+ return a.index - b.index;
1530
+ });
1531
+ }
1532
+ }]);
1533
+
1534
+ return TributeSearch;
1535
+ }();
1536
+
1537
+ exports.default = TributeSearch;
1538
+ module.exports = exports['default'];
1539
+
1540
+ },{}],6:[function(require,module,exports){
1541
+ "use strict";
1542
+
1543
+ Object.defineProperty(exports, "__esModule", {
1544
+ value: true
1545
+ });
1546
+
1547
+ var _Tribute = require("./Tribute");
1548
+
1549
+ var _Tribute2 = _interopRequireDefault(_Tribute);
1550
+
1551
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
1552
+
1553
+ exports.default = _Tribute2.default; /**
1554
+ * Tribute.js
1555
+ * Native ES6 JavaScript @mention Plugin
1556
+ **/
1557
+
1558
+ module.exports = exports["default"];
1559
+
1560
+ },{"./Tribute":1}],7:[function(require,module,exports){
1561
+ 'use strict';
1562
+
1563
+ if (!Array.prototype.find) {
1564
+ Array.prototype.find = function (predicate) {
1565
+ if (this === null) {
1566
+ throw new TypeError('Array.prototype.find called on null or undefined');
1567
+ }
1568
+ if (typeof predicate !== 'function') {
1569
+ throw new TypeError('predicate must be a function');
1570
+ }
1571
+ var list = Object(this);
1572
+ var length = list.length >>> 0;
1573
+ var thisArg = arguments[1];
1574
+ var value;
1575
+
1576
+ for (var i = 0; i < length; i++) {
1577
+ value = list[i];
1578
+ if (predicate.call(thisArg, value, i, list)) {
1579
+ return value;
1580
+ }
1581
+ }
1582
+ return undefined;
1583
+ };
1584
+ }
1585
+
1586
+ if (window && typeof window.CustomEvent !== "function") {
1587
+ var CustomEvent = function CustomEvent(event, params) {
1588
+ params = params || {
1589
+ bubbles: false,
1590
+ cancelable: false,
1591
+ detail: undefined
1592
+ };
1593
+ var evt = document.createEvent('CustomEvent');
1594
+ evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);
1595
+ return evt;
1596
+ };
1597
+
1598
+ if (typeof window.Event !== 'undefined') {
1599
+ CustomEvent.prototype = window.Event.prototype;
1600
+ }
1601
+
1602
+ window.CustomEvent = CustomEvent;
1603
+ }
1604
+
1605
+ },{}]},{},[6])(6)
1606
+ });
1607
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJzcmMvVHJpYnV0ZS5qcyIsInNyYy9UcmlidXRlRXZlbnRzLmpzIiwic3JjL1RyaWJ1dGVNZW51RXZlbnRzLmpzIiwic3JjL1RyaWJ1dGVSYW5nZS5qcyIsInNyYy9UcmlidXRlU2VhcmNoLmpzIiwic3JjL2luZGV4LmpzIiwic3JjL3V0aWxzLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7QUNBQTs7OztBQUNBOzs7O0FBQ0E7Ozs7QUFDQTs7OztBQUNBOzs7Ozs7OztJQUVNLE87QUFDRiwyQkFlRztBQUFBOztBQUFBLCtCQWRDLE1BY0Q7QUFBQSxZQWRDLE1BY0QsK0JBZFUsSUFjVjtBQUFBLCtCQWJDLE1BYUQ7QUFBQSxZQWJDLE1BYUQsK0JBYlUsSUFhVjtBQUFBLG9DQVpDLFdBWUQ7QUFBQSxZQVpDLFdBWUQsb0NBWmUsV0FZZjtBQUFBLGdDQVhDLE9BV0Q7QUFBQSxZQVhDLE9BV0QsZ0NBWFcsR0FXWDtBQUFBLHVDQVZDLGNBVUQ7QUFBQSxZQVZDLGNBVUQsdUNBVmtCLElBVWxCO0FBQUEseUNBVEMsZ0JBU0Q7QUFBQSxZQVRDLGdCQVNELHlDQVRvQixJQVNwQjtBQUFBLCtCQVJDLE1BUUQ7QUFBQSxZQVJDLE1BUUQsK0JBUlUsS0FRVjtBQUFBLGlDQVBDLFFBT0Q7QUFBQSxZQVBDLFFBT0QsaUNBUFksT0FPWjtBQUFBLG1DQU5DLFVBTUQ7QUFBQSxZQU5DLFVBTUQsbUNBTmMsSUFNZDtBQUFBLHNDQUxDLGFBS0Q7QUFBQSxZQUxDLGFBS0Qsc0NBTGlCLElBS2pCO0FBQUEsd0NBSkMsZUFJRDtBQUFBLFlBSkMsZUFJRCx3Q0FKbUIsSUFJbkI7QUFBQSx5Q0FIQyxtQkFHRDtBQUFBLFlBSEMsbUJBR0QseUNBSHVCLElBR3ZCO0FBQUEsb0NBRkMsV0FFRDtBQUFBLFlBRkMsV0FFRCxvQ0FGZSxLQUVmO0FBQUEseUNBREMsaUJBQ0Q7QUFBQSxZQURDLGlC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QUFPLFVBQWxELEVBQThELE9BQU8sTUFBckU7QUFDQSxlQUFPLEdBQVA7QUFDRCxLQVZxRDs7QUFZdkQsUUFBSSxPQUFPLE9BQU8sS0FBZCxLQUF3QixXQUE1QixFQUF5QztBQUN2QyxvQkFBWSxTQUFaLEdBQXdCLE9BQU8sS0FBUCxDQUFhLFNBQXJDO0FBQ0Q7O0FBRUEsV0FBTyxXQUFQLEdBQXFCLFdBQXJCO0FBQ0QiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbiBlKHQsbixyKXtmdW5jdGlvbiBzKG8sdSl7aWYoIW5bb10pe2lmKCF0W29dKXt2YXIgYT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2lmKCF1JiZhKXJldHVybiBhKG8sITApO2lmKGkpcmV0dXJuIGkobywhMCk7dmFyIGY9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitvK1wiJ1wiKTt0aHJvdyBmLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsZn12YXIgbD1uW29dPXtleHBvcnRzOnt9fTt0W29dWzBdLmNhbGwobC5leHBvcnRzLGZ1bmN0aW9uKGUpe3ZhciBuPXRbb11bMV1bZV07cmV0dXJuIHMobj9uOmUpfSxsLGwuZXhwb3J0cyxlLHQsbixyKX1yZXR1cm4gbltvXS5leHBvcnRzfXZhciBpPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7Zm9yKHZhciBvPTA7bzxyLmxlbmd0aDtvKyspcyhyW29dKTtyZXR1cm4gc30pIiwiaW1wb3J0IFRyaWJ1dGVVdGlscyBmcm9tIFwiLi91dGlsc1wiO1xuaW1wb3J0IFRyaWJ1dGVFdmVudHMgZnJvbSBcIi4vVHJpYnV0ZUV2ZW50c1wiO1xuaW1wb3J0IFRyaWJ1dGVNZW51RXZlbnRzIGZyb20gXCIuL1RyaWJ1dGVNZW51RXZlbnRzXCI7XG5pbXBvcnQgVHJpYnV0ZVJhbmdlIGZyb20gXCIuL1RyaWJ1dGVSYW5nZVwiO1xuaW1wb3J0IFRyaWJ1dGVTZWFyY2ggZnJvbSBcIi4vVHJpYnV0ZVNlYXJjaFwiO1xuXG5jbGFzcyBUcmlidXRlIHtcbiAgICBjb25zdHJ1Y3Rvcih7XG4gICAgICAgIHZhbHVlcyA9IG51bGwsXG4gICAgICAgIGlmcmFtZSA9IG51bGwsXG4gICAgICAgIHNlbGVjdENsYXNzID0gJ2hpZ2hsaWdodCcsXG4gICAgICAgIHRyaWdnZXIgPSAnQCcsXG4gICAgICAgIHNlbGVjdFRlbXBsYXRlID0gbnVsbCxcbiAgICAgICAgbWVudUl0ZW1UZW1wbGF0ZSA9IG51bGwsXG4gICAgICAgIGxvb2t1cCA9ICdrZXknLFxuICAgICAgICBmaWxsQXR0ciA9ICd2YWx1ZScsXG4gICAgICAgIGNvbGxlY3Rpb24gPSBudWxsLFxuICAgICAgICBtZW51Q29udGFpbmVyID0gbnVsbCxcbiAgICAgICAgbm9NYXRjaFRlbXBsYXRlID0gbnVsbCxcbiAgICAgICAgcmVxdWlyZUxlYWRpbmdTcGFjZSA9IHRydWUsXG4gICAgICAgIGFsbG93U3BhY2VzID0gZmFsc2UsXG4gICAgICAgIHJlcGxhY2VUZXh0U3VmZml4ID0gbnVsbCxcbiAgICB9KSB7XG5cbiAgICAgICAgdGhpcy5tZW51U2VsZWN0ZWQgPSAwXG4gICAgICAgIHRoaXMuY3VycmVudCA9IHt9XG4gICAgICAgIHRoaXMuaW5wdXRFdmVudCA9IGZhbHNlXG4gICAgICAgIHRoaXMuaXNBY3RpdmUgPSBmYWxzZVxuICAgICAgICB0aGlzLm1lbnVDb250YWluZXIgPSBtZW51Q29udGFpbmVyXG4gICAgICAgIHRoaXMuYWxsb3dTcGFjZXMgPSBhbGxvd1NwYWNlc1xuICAgICAgICB0aGlzLnJlcGxhY2VUZXh0U3VmZml4ID0gcmVwbGFjZVRleHRTdWZmaXhcblxuICAgICAgICBpZiAodmFsdWVzKSB7XG4gICAgICAgICAgICB0aGlzLmNvbGxlY3Rpb24gPSBbe1xuICAgICAgICAgICAgICAgIC8vIHN5bWJvbCB0aGF0IHN0YXJ0cyB0aGUgbG9va3VwXG4gICAgICAgICAgICAgICAgdHJpZ2dlcjogdHJpZ2dlcixcblxuICAgICAgICAgICAgICAgIGlmcmFtZTogaWZyYW1lLFxuXG4gICAgICAgICAgICAgICAgc2VsZWN0Q2xhc3M6IHNlbGVjdENsYXNzLFxuXG4gICAgICAgICAgICAgICAgLy8gZnVuY3Rpb24gY2FsbGVkIG9uIHNlbGVjdCB0aGF0IHJldHVucyB0aGUgY29udGVudCB0byBpbnNlcnRcbiAgICAgICAgICAgICAgICBzZWxlY3RUZW1wbGF0ZTogKHNlbGVjdFRlbXBsYXRlIHx8IFRyaWJ1dGUuZGVmYXVsdFNlbGVjdFRlbXBsYXRlKS5iaW5kKHRoaXMpLFxuXG4gICAgICAgICAgICAgICAgLy8gZnVuY3Rpb24gY2FsbGVkIHRoYXQgcmV0dXJucyBjb250ZW50IGZvciBhbiBpdGVtXG4gICAgICAgICAgICAgICAgbWVudUl0ZW1UZW1wbGF0ZTogKG1lbnVJdGVtVGVtcGxhdGUgfHwgVHJpYnV0ZS5kZWZhdWx0TWVudUl0ZW1UZW1wbGF0ZSkuYmluZCh0aGlzKSxcblxuICAgICAgICAgICAgICAgIC8vIGZ1bmN0aW9uIGNhbGxlZCB3aGVuIG1lbnUgaXMgZW1wdHksIGRpc2FibGVzIGhpZGluZyBvZiBtZW51LlxuICAgICAgICAgICAgICAgIG5vTWF0Y2hUZW1wbGF0ZTogKHQgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0LmJpbmQodGhpcylcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAoKSB7cmV0dXJuICc8bGkgY2xhc3M9XCJuby1tYXRjaFwiPk5vIG1hdGNoITwvbGk+J30uYmluZCh0aGlzKVxuICAgICAgICAgICAgICAgIH0pKG5vTWF0Y2hUZW1wbGF0ZSksXG5cbiAgICAgICAgICAgICAgICAvLyBjb2x1bW4gdG8gc2VhcmNoIGFnYWluc3QgaW4gdGhlIG9iamVjdFxuICAgICAgICAgICAgICAgIGxvb2t1cDogbG9va3VwLFxuXG4gICAgICAgICAgICAgICAgLy8gY29sdW1uIHRoYXQgY29udGFpbnMgdGhlIGNvbnRlbnQgdG8gaW5zZXJ0IGJ5IGRlZmF1bHRcbiAgICAgICAgICAgICAgICBmaWxsQXR0cjogZmlsbEF0dHIsXG5cbiAgICAgICAgICAgICAgICAvLyBhcnJheSBvZiBvYmplY3RzIG9yIGEgZnVuY3Rpb24gcmV0dXJuaW5nIGFuIGFycmF5IG9mIG9iamVjdHNcbiAgICAgICAgICAgICAgICB2YWx1ZXM6IHZhbHVlcyxcblxuICAgICAgICAgICAgICAgIHJlcXVpcmVMZWFkaW5nU3BhY2U6IHJlcXVpcmVMZWFkaW5nU3BhY2UsXG4gICAgICAgICAgICB9XVxuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGNvbGxlY3Rpb24pIHtcbiAgICAgICAgICAgIHRoaXMuY29sbGVjdGlvbiA9IGNvbGxlY3Rpb24ubWFwKGl0ZW0gPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgIHRyaWdnZXI6IGl0ZW0udHJpZ2dlciB8fCB0cmlnZ2VyLFxuICAgICAgICAgICAgICAgICAgICBpZnJhbWU6IGl0ZW0uaWZyYW1lIHx8IGlmcmFtZSxcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0Q2xhc3M6IGl0ZW0uc2VsZWN0Q2xhc3MgfHwgc2VsZWN0Q2xhc3MsXG4gICAgICAgICAgICAgICAgICAgIHNlbGVjdFRlbXBsYXRlOiAoaXRlbS5zZWxlY3RUZW1wbGF0ZSB8fCBUcmlidXRlLmRlZmF1bHRTZWxlY3RUZW1wbGF0ZSkuYmluZCh0aGlzKSxcbiAgICAgICAgICAgICAgICAgICAgbWVudUl0ZW1UZW1wbGF0ZTogKGl0ZW0ubWVudUl0ZW1UZW1wbGF0ZSB8fCBUcmlidXRlLmRlZmF1bHRNZW51SXRlbVRlbXBsYXRlKS5iaW5kKHRoaXMpLFxuICAgICAgICAgICAgICAgICAgICAvLyBmdW5jdGlvbiBjYWxsZWQgd2hlbiBtZW51IGlzIGVtcHR5LCBkaXNhYmxlcyBoaWRpbmcgb2YgbWVudS5cbiAgICAgICAgICAgICAgICAgICAgbm9NYXRjaFRlbXBsYXRlOiAodCA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdC5iaW5kKHRoaXMpXG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsXG4gICAgICAgICAgICAgICAgICAgIH0pKG5vTWF0Y2hUZW1wbGF0ZSksXG4gICAgICAgICAgICAgICAgICAgIGxvb2t1cDogaXRlbS5sb29rdXAgfHwgbG9va3VwLFxuICAgICAgICAgICAgICAgICAgICBmaWxsQXR0cjogaXRlbS5maWxsQXR0ciB8fCBmaWxsQXR0cixcbiAgICAgICAgICAgICAgICAgICAgdmFsdWVzOiBpdGVtLnZhbHVlcyxcbiAgICAgICAgICAgICAgICAgICAgcmVxdWlyZUxlYWRpbmdTcGFjZTogaXRlbS5yZXF1aXJlTGVhZGluZ1NwYWNlXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignW1RyaWJ1dGVdIE5vIGNvbGxlY3Rpb24gc3BlY2lmaWVkLicpXG4gICAgICAgIH1cblxuICAgICAgICBuZXcgVHJpYnV0ZVJhbmdlKHRoaXMpXG4gICAgICAgIG5ldyBUcmlidXRlRXZlbnRzKHRoaXMpXG4gICAgICAgIG5ldyBUcmlidXRlTWVudUV2ZW50cyh0aGlzKVxuICAgICAgICBuZXcgVHJpYnV0ZVNlYXJjaCh0aGlzKVxuICAgIH1cblxuICAgIHN0YXRpYyBkZWZhdWx0U2VsZWN0VGVtcGxhdGUoaXRlbSkge1xuICAgICAgaWYgKHR5cGVvZiBpdGVtID09PSAndW5kZWZpbmVkJykgcmV0dXJuIG51bGw7XG4gICAgICBpZiAodGhpcy5yYW5nZS5pc0NvbnRlbnRFZGl0YWJsZSh0aGlzLmN1cnJlbnQuZWxlbWVudCkpIHtcbiAgICAgICAgICByZXR1cm4gJzxzcGFuIGNsYXNzPVwidHJpYnV0ZS1tZW50aW9uXCI+JyArICh0aGlzLmN1cnJlbnQuY29sbGVjdGlvbi50cmlnZ2VyICsgaXRlbS5vcmlnaW5hbFt0aGlzLmN1cnJlbnQuY29sbGVjdGlvbi5maWxsQXR0cl0pICsgJzwvc3Bhbj4nO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcy5jdXJyZW50LmNvbGxlY3Rpb24udHJpZ2dlciArIGl0ZW0ub3JpZ2luYWxbdGhpcy5jdXJyZW50LmNvbGxlY3Rpb24uZmlsbEF0dHJdO1xuICAgIH1cblxuICAgIHN0YXRpYyBkZWZhdWx0TWVudUl0ZW1UZW1wbGF0ZShtYXRjaEl0ZW0pIHtcbiAgICAgICAgcmV0dXJuIG1hdGNoSXRlbS5zdHJpbmdcbiAgICB9XG5cbiAgICBzdGF0aWMgaW5wdXRUeXBlcygpIHtcbiAgICAgICAgcmV0dXJuIFsnVEVYVEFSRUEnLCAnSU5QVVQnXVxuICAgIH1cblxuICAgIHRyaWdnZXJzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb2xsZWN0aW9uLm1hcChjb25maWcgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIGNvbmZpZy50cmlnZ2VyXG4gICAgICAgIH0pXG4gICAgfVxuXG4gICAgYXR0YWNoKGVsKSB7XG4gICAgICAgIGlmICghZWwpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignW1RyaWJ1dGVdIE11c3QgcGFzcyBpbiBhIERPTSBub2RlIG9yIE5vZGVMaXN0LicpXG4gICAgICAgIH1cblxuICAgICAgICAvLyBDaGVjayBpZiBpdCBpcyBhIGpRdWVyeSBjb2xsZWN0aW9uXG4gICAgICAgIGlmICh0eXBlb2YgalF1ZXJ5ICE9PSAndW5kZWZpbmVkJyAmJiBlbCBpbnN0YW5jZW9mIGpRdWVyeSkge1xuICAgICAgICAgICAgZWwgPSBlbC5nZXQoKVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gSXMgZWwgYW4gQXJyYXkvQXJyYXktbGlrZSBvYmplY3Q/XG4gICAgICAgIGlmIChlbC5jb25zdHJ1Y3RvciA9PT0gTm9kZUxpc3QgfHwgZWwuY29uc3RydWN0b3IgPT09IEhUTUxDb2xsZWN0aW9uIHx8IGVsLmNvbnN0cnVjdG9yID09PSBBcnJheSkge1xuICAgICAgICAgICAgbGV0IGxlbmd0aCA9IGVsLmxlbmd0aFxuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgICAgIHRoaXMuX2F0dGFjaChlbFtpXSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX2F0dGFjaChlbClcbiAgICAgICAgfVxuICAgIH1cblxuICAgIF9hdHRhY2goZWwpIHtcbiAgICAgICAgaWYgKGVsLmhhc0F0dHJpYnV0ZSgnZGF0YS10cmlidXRlJykpIHtcbiAgICAgICAgICAgIGNvbnNvbGUud2FybignVHJpYnV0ZSB3YXMgYWxyZWFkeSBib3VuZCB0byAnICsgZWwubm9kZU5hbWUpXG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmVuc3VyZUVkaXRhYmxlKGVsKVxuICAgICAgICB0aGlzLmV2ZW50cy5iaW5kKGVsKVxuICAgICAgICBlbC5zZXRBdHRyaWJ1dGUoJ2RhdGEtdHJpYnV0ZScsIHRydWUpXG4gICAgfVxuXG4gICAgZW5zdXJlRWRpdGFibGUoZWxlbWVudCkge1xuICAgICAgICBpZiAoVHJpYnV0ZS5pbnB1dFR5cGVzKCkuaW5kZXhPZihlbGVtZW50Lm5vZGVOYW1lKSA9PT0gLTEpIHtcbiAgICAgICAgICAgIGlmIChlbGVtZW50LmNvbnRlbnRFZGl0YWJsZSkge1xuICAgICAgICAgICAgICAgIGVsZW1lbnQuY29udGVudEVkaXRhYmxlID0gdHJ1ZVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1tUcmlidXRlXSBDYW5ub3QgYmluZCB0byAnICsgZWxlbWVudC5ub2RlTmFtZSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGNyZWF0ZU1lbnUoKSB7XG4gICAgICAgIGxldCB3cmFwcGVyID0gdGhpcy5yYW5nZS5nZXREb2N1bWVudCgpLmNyZWF0ZUVsZW1lbnQoJ2RpdicpLFxuICAgICAgICAgICAgdWwgPSB0aGlzLnJhbmdlLmdldERvY3VtZW50KCkuY3JlYXRlRWxlbWVudCgndWwnKVxuXG4gICAgICAgIHdyYXBwZXIuY2xhc3NOYW1lID0gJ3RyaWJ1dGUtY29udGFpbmVyJ1xuICAgICAgICB3cmFwcGVyLmFwcGVuZENoaWxkKHVsKVxuXG4gICAgICAgIGlmICh0aGlzLm1lbnVDb250YWluZXIpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLm1lbnVDb250YWluZXIuYXBwZW5kQ2hpbGQod3JhcHBlcilcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzLnJhbmdlLmdldERvY3VtZW50KCkuYm9keS5hcHBlbmRDaGlsZCh3cmFwcGVyKVxuICAgIH1cblxuICAgIHNob3dNZW51Rm9yKGVsZW1lbnQsIHNjcm9sbFRvKSB7XG4gICAgICAgIC8vIE9ubHkgcHJvY2VlZCBpZiBtZW51IGlzbid0IGFscmVhZHkgc2hvd24gZm9yIHRoZSBjdXJyZW50IGVsZW1lbnQgJiBtZW50aW9uVGV4dFxuICAgICAgICBpZiAodGhpcy5pc0FjdGl2ZSAmJiB0aGlzLmN1cnJlbnQuZWxlbWVudCA9PT0gZWxlbWVudCAmJiB0aGlzLmN1cnJlbnQubWVudGlvblRleHQgPT09IHRoaXMuY3VycmVudE1lbnRpb25UZXh0U25hcHNob3QpIHtcbiAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuICAgICAgICB0aGlzLmN1cnJlbnRNZW50aW9uVGV4dFNuYXBzaG90ID0gdGhpcy5jdXJyZW50Lm1lbnRpb25UZXh0XG5cbiAgICAgICAgLy8gY3JlYXRlIHRoZSBtZW51IGlmIGl0IGRvZXNuJ3QgZXhpc3QuXG4gICAgICAgIGlmICghdGhpcy5tZW51KSB7XG4gICAgICAgICAgICB0aGlzLm1lbnUgPSB0aGlzLmNyZWF0ZU1lbnUoKVxuICAgICAgICAgICAgdGhpcy5tZW51RXZlbnRzLmJpbmQodGhpcy5tZW51KVxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5pc0FjdGl2ZSA9IHRydWVcbiAgICAgICAgdGhpcy5tZW51U2VsZWN0ZWQgPSAwXG5cbiAgICAgICAgaWYgKCF0aGlzLmN1cnJlbnQubWVudGlvblRleHQpIHtcbiAgICAgICAgICAgIHRoaXMuY3VycmVudC5tZW50aW9uVGV4dCA9ICcnXG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBwcm9jZXNzVmFsdWVzID0gKHZhbHVlcykgPT4ge1xuICAgICAgICAgICAgLy8gVHJpYnV0ZSBtYXkgbm90IGJlIGFjdGl2ZSBhbnkgbW9yZSBieSB0aGUgdGltZSB0aGUgdmFsdWUgY2FsbGJhY2sgcmV0dXJuc1xuICAgICAgICAgICAgaWYgKCF0aGlzLmlzQWN0aXZlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGxldCBpdGVtcyA9IHRoaXMuc2VhcmNoLmZpbHRlcih0aGlzLmN1cnJlbnQubWVudGlvblRleHQsIHZhbHVlcywge1xuICAgICAgICAgICAgICAgIHByZTogJzxzcGFuPicsXG4gICAgICAgICAgICAgICAgcG9zdDogJzwvc3Bhbj4nLFxuICAgICAgICAgICAgICAgIGV4dHJhY3Q6IChlbCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHRoaXMuY3VycmVudC5jb2xsZWN0aW9uLmxvb2t1cCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBlbFt0aGlzLmN1cnJlbnQuY29sbGVjdGlvbi5sb29rdXBdXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHRoaXMuY3VycmVudC5jb2xsZWN0aW9uLmxvb2t1cCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuY3VycmVudC5jb2xsZWN0aW9uLmxvb2t1cChlbClcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBsb29rdXAgYXR0cmlidXRlLCBsb29rdXAgbXVzdCBiZSBzdHJpbmcgb3IgZnVuY3Rpb24uJylcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pXG5cbiAgICAgICAgICAgIHRoaXMuY3VycmVudC5maWx0ZXJlZEl0ZW1zID0gaXRlbXNcblxuXG4gICAgICAgICAgICBsZXQgdWwgPSB0aGlzLm1lbnUucXVlcnlTZWxlY3RvcigndWwnKVxuXG4gICAgICAgICAgICB0aGlzLnJhbmdlLnBvc2l0aW9uTWVudUF0Q2FyZXQoc2Nyb2xsVG8pXG5cbiAgICAgICAgICAgIGlmICghaXRlbXMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgbGV0IG5vTWF0Y2hFdmVudCA9IG5ldyBDdXN0b21FdmVudCgndHJpYnV0ZS1uby1tYXRjaCcsIHsgZGV0YWlsOiB0aGlzLm1lbnUgfSlcbiAgICAgICAgICAgICAgICB0aGlzLmN1cnJlbnQuZWxlbWVudC5kaXNwYXRjaEV2ZW50KG5vTWF0Y2hFdmVudClcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuY3VycmVudC5jb2xsZWN0aW9uLm5vTWF0Y2hUZW1wbGF0ZSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmhpZGVNZW51KClcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB1bC5pbm5lckhUTUwgPSB0aGlzLmN1cnJlbnQuY29sbGVjdGlvbi5ub01hdGNoVGVtcGxhdGUoKVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHJldHVyblxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB1bC5pbm5lckhUTUwgPSAnJ1xuXG4gICAgICAgICAgICBpdGVtcy5mb3JFYWNoKChpdGVtLCBpbmRleCkgPT4ge1xuICAgICAgICAgICAgICAgIGxldCBsaSA9IHRoaXMucmFuZ2UuZ2V0RG9jdW1lbnQoKS5jcmVhdGVFbGVtZW50KCdsaScpXG4gICAgICAgICAgICAgICAgbGkuc2V0QXR0cmlidXRlKCdkYXRhLWluZGV4JywgaW5kZXgpXG4gICAgICAgICAgICAgICAgbGkuYWRkRXZlbnRMaXN0ZW5lcignbW91c2VlbnRlcicsIChlKSA9PiB7XG4gICAgICAgICAgICAgICAgICBsZXQgbGkgPSBlLnRhcmdldDtcbiAgICAgICAgICAgICAgICAgIGxldCBpbmRleCA9IGxpLmdldEF0dHJpYnV0ZSgnZGF0YS1pbmRleCcpXG4gICAgICAgICAgICAgICAgICB0aGlzLmV2ZW50cy5zZXRBY3RpdmVMaShpbmRleClcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIGlmICh0aGlzLm1lbnVTZWxlY3RlZCA9PT0gaW5kZXgpIHtcbiAgICAgICAgICAgICAgICAgICAgbGkuY2xhc3NOYW1lID0gdGhpcy5jdXJyZW50LmNvbGxlY3Rpb24uc2VsZWN0Q2xhc3NcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgbGkuaW5uZXJIVE1MID0gdGhpcy5jdXJyZW50LmNvbGxlY3Rpb24ubWVudUl0ZW1UZW1wbGF0ZShpdGVtKVxuICAgICAgICAgICAgICAgIHVsLmFwcGVuZENoaWxkKGxpKVxuICAgICAgICAgICAgfSlcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0eXBlb2YgdGhpcy5jdXJyZW50LmNvbGxlY3Rpb24udmFsdWVzID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnQuY29sbGVjdGlvbi52YWx1ZXModGhpcy5jdXJyZW50Lm1lbnRpb25UZXh0LCBwcm9jZXNzVmFsdWVzKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcHJvY2Vzc1ZhbHVlcyh0aGlzLmN1cnJlbnQuY29sbGVjdGlvbi52YWx1ZXMpXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzaG93TWVudUZvckNvbGxlY3Rpb24oZWxlbWVudCwgY29sbGVjdGlvbkluZGV4KSB7XG4gICAgICAgIGlmIChlbGVtZW50ICE9PSBkb2N1bWVudC5hY3RpdmVFbGVtZW50KSB7XG4gICAgICAgICAgICB0aGlzLnBsYWNlQ2FyZXRBdEVuZChlbGVtZW50KVxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5jdXJyZW50LmNvbGxlY3Rpb24gPSB0aGlzLmNvbGxlY3Rpb25bY29sbGVjdGlvbkluZGV4IHx8IDBdXG4gICAgICAgIHRoaXMuY3VycmVudC5leHRlcm5hbFRyaWdnZXIgPSB0cnVlXG4gICAgICAgIHRoaXMuY3VycmVudC5lbGVtZW50ID0gZWxlbWVudFxuXG4gICAgICAgIGlmIChlbGVtZW50LmlzQ29udGVudEVkaXRhYmxlKVxuICAgICAgICAgICAgdGhpcy5pbnNlcnRUZXh0QXRDdXJzb3IodGhpcy5jdXJyZW50LmNvbGxlY3Rpb24udHJpZ2dlcilcbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgdGhpcy5pbnNlcnRBdENhcmV0KGVsZW1lbnQsIHRoaXMuY3VycmVudC5jb2xsZWN0aW9uLnRyaWdnZXIpXG5cbiAgICAgICAgdGhpcy5zaG93TWVudUZvcihlbGVtZW50KVxuICAgIH1cblxuICAgIC8vIFRPRE86IG1ha2Ugc3VyZSB0aGlzIHdvcmtzIGZvciBpbnB1dHMvdGV4dGFyZWFzXG4gICAgcGxhY2VDYXJldEF0RW5kKGVsKSB7XG4gICAgICAgIGVsLmZvY3VzKCk7XG4gICAgICAgIGlmICh0eXBlb2Ygd2luZG93LmdldFNlbGVjdGlvbiAhPSBcInVuZGVmaW5lZFwiXG4gICAgICAgICAgICAgICAgJiYgdHlwZW9mIGRvY3VtZW50LmNyZWF0ZVJhbmdlICE9IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgICAgIHZhciByYW5nZSA9IGRvY3VtZW50LmNyZWF0ZVJhbmdlKCk7XG4gICAgICAgICAgICByYW5nZS5zZWxlY3ROb2RlQ29udGVudHMoZWwpO1xuICAgICAgICAgICAgcmFuZ2UuY29sbGFwc2UoZmFsc2UpO1xuICAgICAgICAgICAgdmFyIHNlbCA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKTtcbiAgICAgICAgICAgIHNlbC5yZW1vdmVBbGxSYW5nZXMoKTtcbiAgICAgICAgICAgIHNlbC5hZGRSYW5nZShyYW5nZSk7XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGRvY3VtZW50LmJvZHkuY3JlYXRlVGV4dFJhbmdlICE9IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgICAgIHZhciB0ZXh0UmFuZ2UgPSBkb2N1bWVudC5ib2R5LmNyZWF0ZVRleHRSYW5nZSgpO1xuICAgICAgICAgICAgdGV4dFJhbmdlLm1vdmVUb0VsZW1lbnRUZXh0KGVsKTtcbiAgICAgICAgICAgIHRleHRSYW5nZS5jb2xsYXBzZShmYWxzZSk7XG4gICAgICAgICAgICB0ZXh0UmFuZ2Uuc2VsZWN0KCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBmb3IgY29udGVudGVkaXRhYmxlXG4gICAgaW5zZXJ0VGV4dEF0Q3Vyc29yKHRleHQpIHtcbiAgICAgICAgdmFyIHNlbCwgcmFuZ2UsIGh0bWw7XG4gICAgICAgIHNlbCA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKTtcbiAgICAgICAgcmFuZ2UgPSBzZWwuZ2V0UmFuZ2VBdCgwKTtcbiAgICAgICAgcmFuZ2UuZGVsZXRlQ29udGVudHMoKTtcbiAgICAgICAgdmFyIHRleHROb2RlID0gZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUodGV4dCk7XG4gICAgICAgIHJhbmdlLmluc2VydE5vZGUodGV4dE5vZGUpO1xuICAgICAgICByYW5nZS5zZWxlY3ROb2RlQ29udGVudHModGV4dE5vZGUpXG4gICAgICAgIHJhbmdlLmNvbGxhcHNlKGZhbHNlKVxuICAgICAgICBzZWwucmVtb3ZlQWxsUmFuZ2VzKClcbiAgICAgICAgc2VsLmFkZFJhbmdlKHJhbmdlKVxuICAgIH1cblxuICAgIC8vIGZvciByZWd1bGFyIGlucHV0c1xuICAgIGluc2VydEF0Q2FyZXQodGV4dGFyZWEsIHRleHQpIHtcbiAgICAgICAgdmFyIHNjcm9sbFBvcyA9IHRleHRhcmVhLnNjcm9sbFRvcDtcbiAgICAgICAgdmFyIGNhcmV0UG9zID0gdGV4dGFyZWEuc2VsZWN0aW9uU3RhcnQ7XG5cbiAgICAgICAgdmFyIGZyb250ID0gKHRleHRhcmVhLnZhbHVlKS5zdWJzdHJpbmcoMCwgY2FyZXRQb3MpO1xuICAgICAgICB2YXIgYmFjayA9ICh0ZXh0YXJlYS52YWx1ZSkuc3Vic3RyaW5nKHRleHRhcmVhLnNlbGVjdGlvbkVuZCwgdGV4dGFyZWEudmFsdWUubGVuZ3RoKTtcbiAgICAgICAgdGV4dGFyZWEudmFsdWUgPSBmcm9udCArIHRleHQgKyBiYWNrO1xuICAgICAgICBjYXJldFBvcyA9IGNhcmV0UG9zICsgdGV4dC5sZW5ndGg7XG4gICAgICAgIHRleHRhcmVhLnNlbGVjdGlvblN0YXJ0ID0gY2FyZXRQb3M7XG4gICAgICAgIHRleHRhcmVhLnNlbGVjdGlvbkVuZCA9IGNhcmV0UG9zO1xuICAgICAgICB0ZXh0YXJlYS5mb2N1cygpO1xuICAgICAgICB0ZXh0YXJlYS5zY3JvbGxUb3AgPSBzY3JvbGxQb3M7XG4gICAgfVxuXG4gICAgaGlkZU1lbnUoKSB7XG4gICAgICAgIGlmICh0aGlzLm1lbnUpIHtcbiAgICAgICAgICAgIHRoaXMubWVudS5zdHlsZS5jc3NUZXh0ID0gJ2Rpc3BsYXk6IG5vbmU7J1xuICAgICAgICAgICAgdGhpcy5pc0FjdGl2ZSA9IGZhbHNlXG4gICAgICAgICAgICB0aGlzLm1lbnVTZWxlY3RlZCA9IDBcbiAgICAgICAgICAgIHRoaXMuY3VycmVudCA9IHt9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzZWxlY3RJdGVtQXRJbmRleChpbmRleCwgb3JpZ2luYWxFdmVudCkge1xuICAgICAgICBpbmRleCA9IHBhcnNlSW50KGluZGV4KVxuICAgICAgICBpZiAodHlwZW9mIGluZGV4ICE9PSAnbnVtYmVyJykgcmV0dXJuXG4gICAgICAgIGxldCBpdGVtID0gdGhpcy5jdXJyZW50LmZpbHRlcmVkSXRlbXNbaW5kZXhdXG4gICAgICAgIGxldCBjb250ZW50ID0gdGhpcy5jdXJyZW50LmNvbGxlY3Rpb24uc2VsZWN0VGVtcGxhdGUoaXRlbSlcbiAgICAgICAgaWYgKGNvbnRlbnQgIT09IG51bGwpIHRoaXMucmVwbGFjZVRleHQoY29udGVudCwgb3JpZ2luYWxFdmVudCwgaXRlbSlcbiAgICB9XG5cbiAgICByZXBsYWNlVGV4dChjb250ZW50LCBvcmlnaW5hbEV2ZW50LCBpdGVtKSB7XG4gICAgICAgIHRoaXMucmFuZ2UucmVwbGFjZVRyaWdnZXJUZXh0KGNvbnRlbnQsIHRydWUsIHRydWUsIG9yaWdpbmFsRXZlbnQsIGl0ZW0pXG4gICAgfVxuXG4gICAgX2FwcGVuZChjb2xsZWN0aW9uLCBuZXdWYWx1ZXMsIHJlcGxhY2UpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjb2xsZWN0aW9uLnZhbHVlcyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbmFibGUgdG8gYXBwZW5kIHRvIHZhbHVlcywgYXMgaXQgaXMgYSBmdW5jdGlvbi4nKVxuICAgICAgICB9IGVsc2UgaWYgKCFyZXBsYWNlKSB7XG4gICAgICAgICAgICBjb2xsZWN0aW9uLnZhbHVlcyA9IGNvbGxlY3Rpb24udmFsdWVzLmNvbmNhdChuZXdWYWx1ZXMpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb2xsZWN0aW9uLnZhbHVlcyA9IG5ld1ZhbHVlc1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgYXBwZW5kKGNvbGxlY3Rpb25JbmRleCwgbmV3VmFsdWVzLCByZXBsYWNlKSB7XG4gICAgICAgIGxldCBpbmRleCA9IHBhcnNlSW50KGNvbGxlY3Rpb25JbmRleClcbiAgICAgICAgaWYgKHR5cGVvZiBpbmRleCAhPT0gJ251bWJlcicpIHRocm93IG5ldyBFcnJvcigncGxlYXNlIHByb3ZpZGUgYW4gaW5kZXggZm9yIHRoZSBjb2xsZWN0aW9uIHRvIHVwZGF0ZS4nKVxuXG4gICAgICAgIGxldCBjb2xsZWN0aW9uID0gdGhpcy5jb2xsZWN0aW9uW2luZGV4XVxuXG4gICAgICAgIHRoaXMuX2FwcGVuZChjb2xsZWN0aW9uLCBuZXdWYWx1ZXMsIHJlcGxhY2UpXG4gICAgfVxuXG4gICAgYXBwZW5kQ3VycmVudChuZXdWYWx1ZXMsIHJlcGxhY2UpIHtcbiAgICAgICAgaWYgKHRoaXMuaXNBY3RpdmUpIHtcbiAgICAgICAgICAgIHRoaXMuX2FwcGVuZCh0aGlzLmN1cnJlbnQuY29sbGVjdGlvbiwgbmV3VmFsdWVzLCByZXBsYWNlKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdObyBhY3RpdmUgc3RhdGUuIFBsZWFzZSB1c2UgYXBwZW5kIGluc3RlYWQgYW5kIHBhc3MgYW4gaW5kZXguJylcbiAgICAgICAgfVxuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgVHJpYnV0ZTtcbiIsImNsYXNzIFRyaWJ1dGVFdmVudHMge1xuICAgIGNvbnN0cnVjdG9yKHRyaWJ1dGUpIHtcbiAgICAgICAgdGhpcy50cmlidXRlID0gdHJpYnV0ZVxuICAgICAgICB0aGlzLnRyaWJ1dGUuZXZlbnRzID0gdGhpc1xuICAgIH1cblxuICAgIHN0YXRpYyBrZXlzKCkge1xuICAgICAgICByZXR1cm4gW3tcbiAgICAgICAgICAgIGtleTogOSxcbiAgICAgICAgICAgIHZhbHVlOiAnVEFCJ1xuICAgICAgICB9LCB7XG4gICAgICAgICAgICBrZXk6IDgsXG4gICAgICAgICAgICB2YWx1ZTogJ0RFTEVURSdcbiAgICAgICAgfSwge1xuICAgICAgICAgICAga2V5OiAxMyxcbiAgICAgICAgICAgIHZhbHVlOiAnRU5URVInXG4gICAgICAgIH0sIHtcbiAgICAgICAgICAgIGtleTogMjcsXG4gICAgICAgICAgICB2YWx1ZTogJ0VTQ0FQRSdcbiAgICAgICAgfSwge1xuICAgICAgICAgICAga2V5OiAzOCxcbiAgICAgICAgICAgIHZhbHVlOiAnVVAnXG4gICAgICAgIH0sIHtcbiAgICAgICAgICAgIGtleTogNDAsXG4gICAgICAgICAgICB2YWx1ZTogJ0RPV04nXG4gICAgICAgIH1dXG4gICAgfVxuXG4gICAgYmluZChlbGVtZW50KSB7XG4gICAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsXG4gICAgICAgICAgICB0aGlzLmtleWRvd24uYmluZChlbGVtZW50LCB0aGlzKSwgZmFsc2UpXG4gICAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigna2V5dXAnLFxuICAgICAgICAgICAgdGhpcy5rZXl1cC5iaW5kKGVsZW1lbnQsIHRoaXMpLCBmYWxzZSlcbiAgICAgICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCdpbnB1dCcsXG4gICAgICAgICAgICB0aGlzLmlucHV0LmJpbmQoZWxlbWVudCwgdGhpcyksIGZhbHNlKVxuICAgIH1cblxuICAgIGtleWRvd24oaW5zdGFuY2UsIGV2ZW50KSB7XG4gICAgICAgIGlmIChpbnN0YW5jZS5zaG91bGREZWFjdGl2YXRlKGV2ZW50KSkge1xuICAgICAgICAgICAgaW5zdGFuY2UudHJpYnV0ZS5pc0FjdGl2ZSA9IGZhbHNlXG4gICAgICAgICAgICBpbnN0YW5jZS50cmlidXRlLmhpZGVNZW51KClcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBlbGVtZW50ID0gdGhpc1xuICAgICAgICBpbnN0YW5jZS5jb21tYW5kRXZlbnQgPSBmYWxzZVxuXG4gICAgICAgIFRyaWJ1dGVFdmVudHMua2V5cygpLmZvckVhY2gobyA9PiB7XG4gICAgICAgICAgICBpZiAoby5rZXkgPT09IGV2ZW50LmtleUNvZGUpIHtcbiAgICAgICAgICAgICAgICBpbnN0YW5jZS5jb21tYW5kRXZlbnQgPSB0cnVlXG4gICAgICAgICAgICAgICAgaW5zdGFuY2UuY2FsbGJhY2tzKClbby52YWx1ZS50b0xvd2VyQ2FzZSgpXShldmVudCwgZWxlbWVudClcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICB9XG5cbiAgICBpbnB1dChpbnN0YW5jZSwgZXZlbnQpIHtcbiAgICAgICAgaW5zdGFuY2UuaW5wdXRFdmVudCA9IHRydWVcbiAgICAgICAgaW5zdGFuY2Uua2V5dXAuY2FsbCh0aGlzLCBpbnN0YW5jZSwgZXZlbnQpXG4gICAgfVxuXG4gICAgY2xpY2soaW5zdGFuY2UsIGV2ZW50KSB7XG4gICAgICAgIGxldCB0cmlidXRlID0gaW5zdGFuY2UudHJpYnV0ZVxuICAgICAgICBpZiAodHJpYnV0ZS5tZW51ICYmIHRyaWJ1dGUubWVudS5jb250YWlucyhldmVudC50YXJnZXQpKSB7XG4gICAgICAgICAgICBsZXQgbGkgPSBldmVudC50YXJnZXRcbiAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KClcbiAgICAgICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXG4gICAgICAgICAgICB3aGlsZSAobGkubm9kZU5hbWUudG9Mb3dlckNhc2UoKSAhPT0gJ2xpJykge1xuICAgICAgICAgICAgICAgIGxpID0gbGkucGFyZW50Tm9kZVxuICAgICAgICAgICAgICAgIGlmICghbGkgfHwgbGkgPT09IHRyaWJ1dGUubWVudSkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2Nhbm5vdCBmaW5kIHRoZSA8bGk+IGNvbnRhaW5lciBmb3IgdGhlIGNsaWNrJylcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0cmlidXRlLnNlbGVjdEl0ZW1BdEluZGV4KGxpLmdldEF0dHJpYnV0ZSgnZGF0YS1pbmRleCcpLCBldmVudClcbiAgICAgICAgICAgIHRyaWJ1dGUuaGlkZU1lbnUoKVxuXG4gICAgICAgIC8vIFRPRE86IHNob3VsZCBmaXJlIHdpdGggZXh0ZXJuYWxUcmlnZ2VyIGFuZCB0YXJnZXQgaXMgb3V0c2lkZSBvZiBtZW51XG4gICAgICAgIH0gZWxzZSBpZiAodHJpYnV0ZS5jdXJyZW50LmVsZW1lbnQgJiYgIXRyaWJ1dGUuY3VycmVudC5leHRlcm5hbFRyaWdnZXIpIHtcbiAgICAgICAgICAgIHRyaWJ1dGUuY3VycmVudC5leHRlcm5hbFRyaWdnZXIgPSBmYWxzZVxuICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB0cmlidXRlLmhpZGVNZW51KCkpXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBrZXl1cChpbnN0YW5jZSwgZXZlbnQpIHtcbiAgICAgICAgaWYgKGluc3RhbmNlLmlucHV0RXZlbnQpIHtcbiAgICAgICAgICAgIGluc3RhbmNlLmlucHV0RXZlbnQgPSBmYWxzZVxuICAgICAgICB9XG4gICAgICAgIGluc3RhbmNlLnVwZGF0ZVNlbGVjdGlvbih0aGlzKVxuXG4gICAgICAgIGlmIChldmVudC5rZXlDb2RlID09PSAyNykgcmV0dXJuXG5cbiAgICAgICAgaWYgKCFpbnN0YW5jZS50cmlidXRlLmlzQWN0aXZlKSB7XG4gICAgICAgICAgICBsZXQga2V5Q29kZSA9IGluc3RhbmNlLmdldEtleUNvZGUoaW5zdGFuY2UsIHRoaXMsIGV2ZW50KVxuXG4gICAgICAgICAgICBpZiAoaXNOYU4oa2V5Q29kZSkgfHwgIWtleUNvZGUpIHJldHVyblxuXG4gICAgICAgICAgICBsZXQgdHJpZ2dlciA9IGluc3RhbmNlLnRyaWJ1dGUudHJpZ2dlcnMoKS5maW5kKHRyaWdnZXIgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiB0cmlnZ2VyLmNoYXJDb2RlQXQoMCkgPT09IGtleUNvZGVcbiAgICAgICAgICAgIH0pXG5cbiAgICAgICAgICAgIGlmICh0eXBlb2YgdHJpZ2dlciAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgICAgICBpbnN0YW5jZS5jYWxsYmFja3MoKS50cmlnZ2VyQ2hhcihldmVudCwgdGhpcywgdHJpZ2dlcilcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpbnN0YW5jZS50cmlidXRlLmN1cnJlbnQudHJpZ2dlciAmJiBpbnN0YW5jZS5jb21tYW5kRXZlbnQgPT09IGZhbHNlXG4gICAgICAgICAgICB8fCBpbnN0YW5jZS50cmlidXRlLmlzQWN0aXZlICYmIGV2ZW50LmtleUNvZGUgPT09IDgpIHtcbiAgICAgICAgICBpbnN0YW5jZS50cmlidXRlLnNob3dNZW51Rm9yKHRoaXMsIHRydWUpXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzaG91bGREZWFjdGl2YXRlKGV2ZW50KSB7XG4gICAgICAgIGlmICghdGhpcy50cmlidXRlLmlzQWN0aXZlKSByZXR1cm4gZmFsc2VcblxuICAgICAgICBpZiAodGhpcy50cmlidXRlLmN1cnJlbnQubWVudGlvblRleHQubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICBsZXQgZXZlbnRLZXlQcmVzc2VkID0gZmFsc2VcbiAgICAgICAgICAgIFRyaWJ1dGVFdmVudHMua2V5cygpLmZvckVhY2gobyA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGV2ZW50LmtleUNvZGUgPT09IG8ua2V5KSBldmVudEtleVByZXNzZWQgPSB0cnVlXG4gICAgICAgICAgICB9KVxuXG4gICAgICAgICAgICByZXR1cm4gIWV2ZW50S2V5UHJlc3NlZFxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgZ2V0S2V5Q29kZShpbnN0YW5jZSwgZWwsIGV2ZW50KSB7XG4gICAgICAgIGxldCBjaGFyXG4gICAgICAgIGxldCB0cmlidXRlID0gaW5zdGFuY2UudHJpYnV0ZVxuICAgICAgICBsZXQgaW5mbyA9IHRyaWJ1dGUucmFuZ2UuZ2V0VHJpZ2dlckluZm8oZmFsc2UsIGZhbHNlLCB0cnVlLCB0cmlidXRlLmFsbG93U3BhY2VzKVxuXG4gICAgICAgIGlmIChpbmZvKSB7XG4gICAgICAgICAgICByZXR1cm4gaW5mby5tZW50aW9uVHJpZ2dlckNoYXIuY2hhckNvZGVBdCgwKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB1cGRhdGVTZWxlY3Rpb24oZWwpIHtcbiAgICAgICAgdGhpcy50cmlidXRlLmN1cnJlbnQuZWxlbWVudCA9IGVsXG4gICAgICAgIGxldCBpbmZvID0gdGhpcy50cmlidXRlLnJhbmdlLmdldFRyaWdnZXJJbmZvKGZhbHNlLCBmYWxzZSwgdHJ1ZSwgdGhpcy50cmlidXRlLmFsbG93U3BhY2VzKVxuXG4gICAgICAgIGlmIChpbmZvKSB7XG4gICAgICAgICAgICB0aGlzLnRyaWJ1dGUuY3VycmVudC5zZWxlY3RlZFBhdGggPSBpbmZvLm1lbnRpb25TZWxlY3RlZFBhdGhcbiAgICAgICAgICAgIHRoaXMudHJpYnV0ZS5jdXJyZW50Lm1lbnRpb25UZXh0ID0gaW5mby5tZW50aW9uVGV4dFxuICAgICAgICAgICAgdGhpcy50cmlidXRlLmN1cnJlbnQuc2VsZWN0ZWRPZmZzZXQgPSBpbmZvLm1lbnRpb25TZWxlY3RlZE9mZnNldFxuICAgICAgICB9XG4gICAgfVxuXG4gICAgY2FsbGJhY2tzKCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHJpZ2dlckNoYXI6IChlLCBlbCwgdHJpZ2dlcikgPT4ge1xuICAgICAgICAgICAgICAgIGxldCB0cmlidXRlID0gdGhpcy50cmlidXRlXG4gICAgICAgICAgICAgICAgdHJpYnV0ZS5jdXJyZW50LnRyaWdnZXIgPSB0cmlnZ2VyXG5cbiAgICAgICAgICAgICAgICBsZXQgY29sbGVjdGlvbkl0ZW0gPSB0cmlidXRlLmNvbGxlY3Rpb24uZmluZChpdGVtID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGl0ZW0udHJpZ2dlciA9PT0gdHJpZ2dlclxuICAgICAgICAgICAgICAgIH0pXG5cbiAgICAgICAgICAgICAgICB0cmlidXRlLmN1cnJlbnQuY29sbGVjdGlvbiA9IGNvbGxlY3Rpb25JdGVtXG4gICAgICAgICAgICAgICAgaWYgKHRyaWJ1dGUuaW5wdXRFdmVudCkgdHJpYnV0ZS5zaG93TWVudUZvcihlbCwgdHJ1ZSlcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBlbnRlcjogKGUsIGVsKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gY2hvb3NlIHNlbGVjdGlvblxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnRyaWJ1dGUuaXNBY3RpdmUpIHtcbiAgICAgICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpXG4gICAgICAgICAgICAgICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKClcbiAgICAgICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnRyaWJ1dGUuc2VsZWN0SXRlbUF0SW5kZXgodGhpcy50cmlidXRlLm1lbnVTZWxlY3RlZCwgZSlcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudHJpYnV0ZS5oaWRlTWVudSgpXG4gICAgICAgICAgICAgICAgICAgIH0sIDApXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGVzY2FwZTogKGUsIGVsKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMudHJpYnV0ZS5pc0FjdGl2ZSkge1xuICAgICAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KClcbiAgICAgICAgICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKVxuICAgICAgICAgICAgICAgICAgICB0aGlzLnRyaWJ1dGUuaXNBY3RpdmUgPSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICB0aGlzLnRyaWJ1dGUuaGlkZU1lbnUoKVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB0YWI6IChlLCBlbCkgPT4ge1xuICAgICAgICAgICAgICAgIC8vIGNob29zZSBmaXJzdCBtYXRjaFxuICAgICAgICAgICAgICAgIHRoaXMuY2FsbGJhY2tzKCkuZW50ZXIoZSwgZWwpXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdXA6IChlLCBlbCkgPT4ge1xuICAgICAgICAgICAgICAgIC8vIG5hdmlnYXRlIHVwIHVsXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMudHJpYnV0ZS5pc0FjdGl2ZSkge1xuICAgICAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KClcbiAgICAgICAgICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKVxuICAgICAgICAgICAgICAgICAgICBsZXQgY291bnQgPSB0aGlzLnRyaWJ1dGUuY3VycmVudC5maWx0ZXJlZEl0ZW1zLmxlbmd0aCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdGVkID0gdGhpcy50cmlidXRlLm1lbnVTZWxlY3RlZFxuXG4gICAgICAgICAgICAgICAgICAgIGlmIChjb3VudCA+IHNlbGVjdGVkICYmIHNlbGVjdGVkID4gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy50cmlidXRlLm1lbnVTZWxlY3RlZC0tXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNldEFjdGl2ZUxpKClcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChzZWxlY3RlZCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgIHRoaXMudHJpYnV0ZS5tZW51U2VsZWN0ZWQgPSBjb3VudCAtIDFcbiAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNldEFjdGl2ZUxpKClcbiAgICAgICAgICAgICAgICAgICAgICB0aGlzLnRyaWJ1dGUubWVudS5zY3JvbGxUb3AgPSB0aGlzLnRyaWJ1dGUubWVudS5zY3JvbGxIZWlnaHRcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBkb3duOiAoZSwgZWwpID0+IHtcbiAgICAgICAgICAgICAgICAvLyBuYXZpZ2F0ZSBkb3duIHVsXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMudHJpYnV0ZS5pc0FjdGl2ZSkge1xuICAgICAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KClcbiAgICAgICAgICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKVxuICAgICAgICAgICAgICAgICAgICBsZXQgY291bnQgPSB0aGlzLnRyaWJ1dGUuY3VycmVudC5maWx0ZXJlZEl0ZW1zLmxlbmd0aCAtIDEsXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZCA9IHRoaXMudHJpYnV0ZS5tZW51U2VsZWN0ZWRcblxuICAgICAgICAgICAgICAgICAgICBpZiAoY291bnQgPiBzZWxlY3RlZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy50cmlidXRlLm1lbnVTZWxlY3RlZCsrXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNldEFjdGl2ZUxpKClcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjb3VudCA9PT0gc2VsZWN0ZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudHJpYnV0ZS5tZW51U2VsZWN0ZWQgPSAwXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNldEFjdGl2ZUxpKClcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudHJpYnV0ZS5tZW51LnNjcm9sbFRvcCA9IDBcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBkZWxldGU6IChlLCBlbCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnRyaWJ1dGUuaXNBY3RpdmUgJiYgdGhpcy50cmlidXRlLmN1cnJlbnQubWVudGlvblRleHQubGVuZ3RoIDwgMSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnRyaWJ1dGUuaGlkZU1lbnUoKVxuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy50cmlidXRlLmlzQWN0aXZlKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudHJpYnV0ZS5zaG93TWVudUZvcihlbClcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzZXRBY3RpdmVMaShpbmRleCkge1xuICAgICAgICBsZXQgbGlzID0gdGhpcy50cmlidXRlLm1lbnUucXVlcnlTZWxlY3RvckFsbCgnbGknKSxcbiAgICAgICAgICAgIGxlbmd0aCA9IGxpcy5sZW5ndGggPj4+IDBcblxuICAgICAgICAvLyBnZXQgaGVpZ2h0c1xuICAgICAgICBsZXQgbWVudUZ1bGxIZWlnaHQgPSB0aGlzLmdldEZ1bGxIZWlnaHQodGhpcy50cmlidXRlLm1lbnUpLFxuICAgICAgICAgICAgbGlIZWlnaHQgPSB0aGlzLmdldEZ1bGxIZWlnaHQobGlzWzBdKVxuXG4gICAgICAgIGlmIChpbmRleCkgdGhpcy50cmlidXRlLm1lbnVTZWxlY3RlZCA9IGluZGV4O1xuXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGxldCBsaSA9IGxpc1tpXVxuICAgICAgICAgICAgaWYgKGkgPT09IHRoaXMudHJpYnV0ZS5tZW51U2VsZWN0ZWQpIHtcbiAgICAgICAgICAgICAgICBsZXQgb2Zmc2V0ID0gbGlIZWlnaHQgKiAoaSsxKVxuICAgICAgICAgICAgICAgIGxldCBzY3JvbGxUb3AgPSB0aGlzLnRyaWJ1dGUubWVudS5zY3JvbGxUb3BcbiAgICAgICAgICAgICAgICBsZXQgdG90YWxTY3JvbGwgPSBzY3JvbGxUb3AgKyBtZW51RnVsbEhlaWdodFxuXG4gICAgICAgICAgICAgICAgaWYgKG9mZnNldCA+IHRvdGFsU2Nyb2xsKSB7XG4gICAgICAgICAgICAgICAgICB0aGlzLnRyaWJ1dGUubWVudS5zY3JvbGxUb3AgKz0gbGlIZWlnaHRcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKG9mZnNldCA8IHRvdGFsU2Nyb2xsKSB7XG4gICAgICAgICAgICAgICAgICB0aGlzLnRyaWJ1dGUubWVudS5zY3JvbGxUb3AgLT0gbGlIZWlnaHRcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBsaS5jbGFzc05hbWUgPSB0aGlzLnRyaWJ1dGUuY3VycmVudC5jb2xsZWN0aW9uLnNlbGVjdENsYXNzXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGxpLmNsYXNzTmFtZSA9ICcnXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBnZXRGdWxsSGVpZ2h0KGVsZW0sIGluY2x1ZGVNYXJnaW4pIHtcbiAgICAgIGxldCBoZWlnaHQgPSBlbGVtLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLmhlaWdodFxuXG4gICAgICBpZiAoaW5jbHVkZU1hcmdpbikge1xuICAgICAgICBsZXQgc3R5bGUgPSBlbGVtLmN1cnJlbnRTdHlsZSB8fCB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShlbGVtKVxuICAgICAgICByZXR1cm4gaGVpZ2h0ICsgcGFyc2VGbG9hdChzdHlsZS5tYXJnaW5Ub3ApICsgcGFyc2VGbG9hdChzdHlsZS5tYXJnaW5Cb3R0b20pXG4gICAgICB9XG5cbiAgICAgIHJldHVybiBoZWlnaHRcbiAgICB9XG5cbn1cblxuZXhwb3J0IGRlZmF1bHQgVHJpYnV0ZUV2ZW50cztcbiIsImNsYXNzIFRyaWJ1dGVNZW51RXZlbnRzIHtcbiAgICBjb25zdHJ1Y3Rvcih0cmlidXRlKSB7XG4gICAgICAgIHRoaXMudHJpYnV0ZSA9IHRyaWJ1dGVcbiAgICAgICAgdGhpcy50cmlidXRlLm1lbnVFdmVudHMgPSB0aGlzXG4gICAgICAgIHRoaXMubWVudSA9IHRoaXMudHJpYnV0ZS5tZW51XG4gICAgfVxuXG4gICAgYmluZChtZW51KSB7XG4gICAgICAgIG1lbnUuYWRkRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsXG4gICAgICAgICAgICB0aGlzLnRyaWJ1dGUuZXZlbnRzLmtleWRvd24uYmluZCh0aGlzLm1lbnUsIHRoaXMpLCBmYWxzZSlcbiAgICAgICAgdGhpcy50cmlidXRlLnJhbmdlLmdldERvY3VtZW50KCkuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vkb3duJyxcbiAgICAgICAgICAgIHRoaXMudHJpYnV0ZS5ldmVudHMuY2xpY2suYmluZChudWxsLCB0aGlzKSwgZmFsc2UpXG5cbiAgICAgICAgLy8gZml4ZXMgSUUxMSBpc3N1ZXMgd2l0aCBtb3VzZWRvd25cbiAgICAgICAgdGhpcy50cmlidXRlLnJhbmdlLmdldERvY3VtZW50KCkuYWRkRXZlbnRMaXN0ZW5lcignTVNQb2ludGVyRG93bicsXG4gICAgICAgICAgICB0aGlzLnRyaWJ1dGUuZXZlbnRzLmNsaWNrLmJpbmQobnVsbCwgdGhpcyksIGZhbHNlKVxuXG4gICAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdyZXNpemUnLCB0aGlzLmRlYm91bmNlKCgpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLnRyaWJ1dGUuaXNBY3RpdmUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnRyaWJ1dGUucmFuZ2UucG9zaXRpb25NZW51QXRDYXJldCh0cnVlKVxuICAgICAgICAgICAgfVxuICAgICAgICB9LCAzMDAsIGZhbHNlKSlcblxuICAgICAgICBpZiAodGhpcy5tZW51Q29udGFpbmVyKSB7XG4gICAgICAgICAgICB0aGlzLm1lbnVDb250YWluZXIuYWRkRXZlbnRMaXN0ZW5lcignc2Nyb2xsJywgdGhpcy5kZWJvdW5jZSgoKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMudHJpYnV0ZS5pc0FjdGl2ZSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnRyaWJ1dGUuc2hvd01lbnVGb3IodGhpcy50cmlidXRlLmN1cnJlbnQuZWxlbWVudCwgZmFsc2UpXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSwgMzAwLCBmYWxzZSksIGZhbHNlKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgd2luZG93Lm9uc2Nyb2xsID0gdGhpcy5kZWJvdW5jZSgoKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMudHJpYnV0ZS5pc0FjdGl2ZSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnRyaWJ1dGUuc2hvd01lbnVGb3IodGhpcy50cmlidXRlLmN1cnJlbnQuZWxlbWVudCwgZmFsc2UpXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSwgMzAwLCBmYWxzZSlcbiAgICAgICAgfVxuXG4gICAgfVxuXG4gICAgZGVib3VuY2UoZnVuYywgd2FpdCwgaW1tZWRpYXRlKSB7XG4gICAgICAgIHZhciB0aW1lb3V0XG4gICAgICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgICAgICB2YXIgY29udGV4dCA9IHRoaXMsXG4gICAgICAgICAgICAgICAgYXJncyA9IGFyZ3VtZW50c1xuICAgICAgICAgICAgdmFyIGxhdGVyID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRpbWVvdXQgPSBudWxsXG4gICAgICAgICAgICAgICAgaWYgKCFpbW1lZGlhdGUpIGZ1bmMuYXBwbHkoY29udGV4dCwgYXJncylcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBjYWxsTm93ID0gaW1tZWRpYXRlICYmICF0aW1lb3V0XG4gICAgICAgICAgICBjbGVhclRpbWVvdXQodGltZW91dClcbiAgICAgICAgICAgIHRpbWVvdXQgPSBzZXRUaW1lb3V0KGxhdGVyLCB3YWl0KVxuICAgICAgICAgICAgaWYgKGNhbGxOb3cpIGZ1bmMuYXBwbHkoY29udGV4dCwgYXJncylcbiAgICAgICAgfVxuICAgIH1cbn1cblxuXG5leHBvcnQgZGVmYXVsdCBUcmlidXRlTWVudUV2ZW50cztcbiIsIi8vIFRoYW5rcyB0byBodHRwczovL2dpdGh1Yi5jb20vamVmZi1jb2xsaW5zL21lbnQuaW9cbmNsYXNzIFRyaWJ1dGVSYW5nZSB7XG4gICAgY29uc3RydWN0b3IodHJpYnV0ZSkge1xuICAgICAgICB0aGlzLnRyaWJ1dGUgPSB0cmlidXRlXG4gICAgICAgIHRoaXMudHJpYnV0ZS5yYW5nZSA9IHRoaXNcbiAgICB9XG5cbiAgICBnZXREb2N1bWVudCgpIHtcbiAgICAgICAgbGV0IGlmcmFtZVxuICAgICAgICBpZiAodGhpcy50cmlidXRlLmN1cnJlbnQuY29sbGVjdGlvbikge1xuICAgICAgICAgICAgaWZyYW1lID0gdGhpcy50cmlidXRlLmN1cnJlbnQuY29sbGVjdGlvbi5pZnJhbWVcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghaWZyYW1lKSB7XG4gICAgICAgICAgICByZXR1cm4gZG9jdW1lbnRcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBpZnJhbWUuY29udGVudFdpbmRvdy5kb2N1bWVudFxuICAgIH1cblxuICAgIHBvc2l0aW9uTWVudUF0Q2FyZXQoc2Nyb2xsVG8pIHtcbiAgICAgICAgbGV0IGNvbnRleHQgPSB0aGlzLnRyaWJ1dGUuY3VycmVudCxcbiAgICAgICAgICAgIGNvb3JkaW5hdGVzXG5cbiAgICAgICAgbGV0IGluZm8gPSB0aGlzLmdldFRyaWdnZXJJbmZvKGZhbHNlLCBmYWxzZSwgdHJ1ZSwgdGhpcy50cmlidXRlLmFsbG93U3BhY2VzKVxuXG4gICAgICAgIGlmICh0eXBlb2YgaW5mbyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5pc0NvbnRlbnRFZGl0YWJsZShjb250ZXh0LmVsZW1lbnQpKSB7XG4gICAgICAgICAgICAgICAgY29vcmRpbmF0ZXMgPSB0aGlzLmdldFRleHRBcmVhT3JJbnB1dFVuZGVybGluZVBvc2l0aW9uKHRoaXMuZ2V0RG9jdW1lbnQoKS5hY3RpdmVFbGVtZW50LFxuICAgICAgICAgICAgICAgICAgICBpbmZvLm1lbnRpb25Qb3NpdGlvbilcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvb3JkaW5hdGVzID0gdGhpcy5nZXRDb250ZW50RWRpdGFibGVDYXJldFBvc2l0aW9uKGluZm8ubWVudGlvblBvc2l0aW9uKVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBUT0RPOiBmbGlwIHRoZSBkcm9wZG93biBpZiByZW5kZXJlZCBvZmYgb2Ygc2NyZWVuIGVkZ2UuXG4gICAgICAgICAgICAvLyBsZXQgY29udGVudFdpZHRoID0gdGhpcy50cmlidXRlLm1lbnUub2Zmc2V0V2lkdGggKyBjb29yZGluYXRlcy5sZWZ0XG4gICAgICAgICAgICAvLyBsZXQgcGFyZW50V2lkdGg7XG5cbiAgICAgICAgICAgIC8vIGlmICh0aGlzLnRyaWJ1dGUubWVudUNvbnRhaW5lcikge1xuICAgICAgICAgICAgLy8gICAgIHBhcmVudFdpZHRoID0gdGhpcy50cmlidXRlLm1lbnVDb250YWluZXIub2Zmc2V0V2lkdGhcbiAgICAgICAgICAgIC8vIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyAgICAgcGFyZW50V2lkdGggPSB0aGlzLmdldERvY3VtZW50KCkuYm9keS5vZmZzZXRXaWR0aFxuICAgICAgICAgICAgLy8gfVxuXG4gICAgICAgICAgICAvLyBpZiAoY29udGVudFdpZHRoID4gcGFyZW50V2lkdGgpIHtcbiAgICAgICAgICAgIC8vICAgICBsZXQgZGlmZiA9IGNvbnRlbnRXaWR0aCAtIHBhcmVudFdpZHRoXG4gICAgICAgICAgICAvLyAgICAgbGV0IHJlbW92ZUZyb21MZWZ0ID0gdGhpcy50cmlidXRlLm1lbnUub2Zmc2V0V2lkdGggLSBkaWZmXG4gICAgICAgICAgICAvLyAgICAgbGV0IG5ld0xlZnQgPSBjb29yZGluYXRlcy5sZWZ0IC0gcmVtb3ZlRnJvbUxlZnRcblxuICAgICAgICAgICAgLy8gICAgIGlmIChuZXdMZWZ0ID4gMCkge1xuICAgICAgICAgICAgLy8gICAgICAgICBjb29yZGluYXRlcy5sZWZ0ID0gbmV3TGVmdFxuICAgICAgICAgICAgLy8gICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyAgICAgICAgIGNvb3JkaW5hdGVzLmxlZnQgPSAwXG4gICAgICAgICAgICAvLyAgICAgfVxuICAgICAgICAgICAgLy8gfVxuXG4gICAgICAgICAgICB0aGlzLnRyaWJ1dGUubWVudS5zdHlsZS5jc3NUZXh0ID0gYHRvcDogJHtjb29yZGluYXRlcy50b3B9cHg7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVmdDogJHtjb29yZGluYXRlcy5sZWZ0fXB4O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB6SW5kZXg6IDEwMDAwO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpc3BsYXk6IGJsb2NrO2BcblxuICAgICAgICAgICAgaWYgKHNjcm9sbFRvKSB0aGlzLnNjcm9sbEludG9WaWV3KClcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMudHJpYnV0ZS5tZW51LnN0eWxlLmNzc1RleHQgPSAnZGlzcGxheTogbm9uZSdcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHNlbGVjdEVsZW1lbnQodGFyZ2V0RWxlbWVudCwgcGF0aCwgb2Zmc2V0KSB7XG4gICAgICAgIGxldCByYW5nZVxuICAgICAgICBsZXQgZWxlbSA9IHRhcmdldEVsZW1lbnRcblxuICAgICAgICBpZiAocGF0aCkge1xuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBwYXRoLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgZWxlbSA9IGVsZW0uY2hpbGROb2Rlc1twYXRoW2ldXVxuICAgICAgICAgICAgICAgIGlmIChlbGVtID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHdoaWxlIChlbGVtLmxlbmd0aCA8IG9mZnNldCkge1xuICAgICAgICAgICAgICAgICAgICBvZmZzZXQgLT0gZWxlbS5sZW5ndGhcbiAgICAgICAgICAgICAgICAgICAgZWxlbSA9IGVsZW0ubmV4dFNpYmxpbmdcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGVsZW0uY2hpbGROb2Rlcy5sZW5ndGggPT09IDAgJiYgIWVsZW0ubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgIGVsZW0gPSBlbGVtLnByZXZpb3VzU2libGluZ1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBsZXQgc2VsID0gdGhpcy5nZXRXaW5kb3dTZWxlY3Rpb24oKVxuXG4gICAgICAgIHJhbmdlID0gdGhpcy5nZXREb2N1bWVudCgpLmNyZWF0ZVJhbmdlKClcbiAgICAgICAgcmFuZ2Uuc2V0U3RhcnQoZWxlbSwgb2Zmc2V0KVxuICAgICAgICByYW5nZS5zZXRFbmQoZWxlbSwgb2Zmc2V0KVxuICAgICAgICByYW5nZS5jb2xsYXBzZSh0cnVlKVxuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBzZWwucmVtb3ZlQWxsUmFuZ2VzKClcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHt9XG5cbiAgICAgICAgc2VsLmFkZFJhbmdlKHJhbmdlKVxuICAgICAgICB0YXJnZXRFbGVtZW50LmZvY3VzKClcbiAgICB9XG5cbiAgICAvLyBUT0RPOiB0aGlzIG1heSBub3QgYmUgbmVjZXNzYXJ5IGFueW1vcmUgYXMgd2UgYXJlIHVzaW5nIG1vdXNldXAgaW5zdGVhZCBvZiBjbGlja1xuICAgIHJlc2V0U2VsZWN0aW9uKHRhcmdldEVsZW1lbnQsIHBhdGgsIG9mZnNldCkge1xuICAgICAgICBpZiAoIXRoaXMuaXNDb250ZW50RWRpdGFibGUodGFyZ2V0RWxlbWVudCkpIHtcbiAgICAgICAgICAgIGlmICh0YXJnZXRFbGVtZW50ICE9PSB0aGlzLmdldERvY3VtZW50KCkuYWN0aXZlRWxlbWVudCkge1xuICAgICAgICAgICAgICAgIHRhcmdldEVsZW1lbnQuZm9jdXMoKVxuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5zZWxlY3RFbGVtZW50KHRhcmdldEVsZW1lbnQsIHBhdGgsIG9mZnNldClcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJlcGxhY2VUcmlnZ2VyVGV4dCh0ZXh0LCByZXF1aXJlTGVhZGluZ1NwYWNlLCBoYXNUcmFpbGluZ1NwYWNlLCBvcmlnaW5hbEV2ZW50LCBpdGVtKSB7XG4gICAgICAgIGxldCBjb250ZXh0ID0gdGhpcy50cmlidXRlLmN1cnJlbnRcbiAgICAgICAgLy8gVE9ETzogdGhpcyBtYXkgbm90IGJlIG5lY2Vzc2FyeSBhbnltb3JlIGFzIHdlIGFyZSB1c2luZyBtb3VzZXVwIGluc3RlYWQgb2YgY2xpY2tcbiAgICAgICAgLy8gdGhpcy5yZXNldFNlbGVjdGlvbihjb250ZXh0LmVsZW1lbnQsIGNvbnRleHQuc2VsZWN0ZWRQYXRoLCBjb250ZXh0LnNlbGVjdGVkT2Zmc2V0KVxuXG4gICAgICAgIGxldCBpbmZvID0gdGhpcy5nZXRUcmlnZ2VySW5mbyh0cnVlLCBoYXNUcmFpbGluZ1NwYWNlLCByZXF1aXJlTGVhZGluZ1NwYWNlLCB0aGlzLnRyaWJ1dGUuYWxsb3dTcGFjZXMpXG5cbiAgICAgICAgLy8gQ3JlYXRlIHRoZSBldmVudFxuICAgICAgICBsZXQgcmVwbGFjZUV2ZW50ID0gbmV3IEN1c3RvbUV2ZW50KCd0cmlidXRlLXJlcGxhY2VkJywge1xuICAgICAgICAgICAgZGV0YWlsOiB7XG4gICAgICAgICAgICAgICAgaXRlbTogaXRlbSxcbiAgICAgICAgICAgICAgICBldmVudDogb3JpZ2luYWxFdmVudFxuICAgICAgICAgICAgfVxuICAgICAgICB9KVxuXG4gICAgICAgIGlmIChpbmZvICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5pc0NvbnRlbnRFZGl0YWJsZShjb250ZXh0LmVsZW1lbnQpKSB7XG4gICAgICAgICAgICAgICAgbGV0IG15RmllbGQgPSB0aGlzLmdldERvY3VtZW50KCkuYWN0aXZlRWxlbWVudFxuICAgICAgICAgICAgICAgIGxldCB0ZXh0U3VmZml4ID0gdHlwZW9mIHRoaXMudHJpYnV0ZS5yZXBsYWNlVGV4dFN1ZmZpeCA9PSAnc3RyaW5nJ1xuICAgICAgICAgICAgICAgICAgICA/IHRoaXMudHJpYnV0ZS5yZXBsYWNlVGV4dFN1ZmZpeFxuICAgICAgICAgICAgICAgICAgICA6ICcgJ1xuICAgICAgICAgICAgICAgIHRleHQgKz0gdGV4dFN1ZmZpeFxuICAgICAgICAgICAgICAgIGxldCBzdGFydFBvcyA9IGluZm8ubWVudGlvblBvc2l0aW9uXG4gICAgICAgICAgICAgICAgbGV0IGVuZFBvcyA9IGluZm8ubWVudGlvblBvc2l0aW9uICsgaW5mby5tZW50aW9uVGV4dC5sZW5ndGggKyB0ZXh0U3VmZml4Lmxlbmd0aFxuICAgICAgICAgICAgICAgIG15RmllbGQudmFsdWUgPSBteUZpZWxkLnZhbHVlLnN1YnN0cmluZygwLCBzdGFydFBvcykgKyB0ZXh0ICtcbiAgICAgICAgICAgICAgICAgICAgbXlGaWVsZC52YWx1ZS5zdWJzdHJpbmcoZW5kUG9zLCBteUZpZWxkLnZhbHVlLmxlbmd0aClcbiAgICAgICAgICAgICAgICBteUZpZWxkLnNlbGVjdGlvblN0YXJ0ID0gc3RhcnRQb3MgKyB0ZXh0Lmxlbmd0aFxuICAgICAgICAgICAgICAgIG15RmllbGQuc2VsZWN0aW9uRW5kID0gc3RhcnRQb3MgKyB0ZXh0Lmxlbmd0aFxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBhZGQgYSBzcGFjZSB0byB0aGUgZW5kIG9mIHRoZSBwYXN0ZWQgdGV4dFxuICAgICAgICAgICAgICAgIGxldCB0ZXh0U3VmZml4ID0gdHlwZW9mIHRoaXMudHJpYnV0ZS5yZXBsYWNlVGV4dFN1ZmZpeCA9PSAnc3RyaW5nJ1xuICAgICAgICAgICAgICAgICAgICA/IHRoaXMudHJpYnV0ZS5yZXBsYWNlVGV4dFN1ZmZpeFxuICAgICAgICAgICAgICAgICAgICA6ICdcXHhBMCdcbiAgICAgICAgICAgICAgICB0ZXh0ICs9IHRleHRTdWZmaXhcbiAgICAgICAgICAgICAgICB0aGlzLnBhc3RlSHRtbCh0ZXh0LCBpbmZvLm1lbnRpb25Qb3NpdGlvbixcbiAgICAgICAgICAgICAgICAgICAgaW5mby5tZW50aW9uUG9zaXRpb24gKyBpbmZvLm1lbnRpb25UZXh0Lmxlbmd0aCArIDEpXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnRleHQuZWxlbWVudC5kaXNwYXRjaEV2ZW50KHJlcGxhY2VFdmVudClcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHBhc3RlSHRtbChodG1sLCBzdGFydFBvcywgZW5kUG9zKSB7XG4gICAgICAgIGxldCByYW5nZSwgc2VsXG4gICAgICAgIHNlbCA9IHRoaXMuZ2V0V2luZG93U2VsZWN0aW9uKClcbiAgICAgICAgcmFuZ2UgPSB0aGlzLmdldERvY3VtZW50KCkuY3JlYXRlUmFuZ2UoKVxuICAgICAgICByYW5nZS5zZXRTdGFydChzZWwuYW5jaG9yTm9kZSwgc3RhcnRQb3MpXG4gICAgICAgIHJhbmdlLnNldEVuZChzZWwuYW5jaG9yTm9kZSwgZW5kUG9zKVxuICAgICAgICByYW5nZS5kZWxldGVDb250ZW50cygpXG5cbiAgICAgICAgbGV0IGVsID0gdGhpcy5nZXREb2N1bWVudCgpLmNyZWF0ZUVsZW1lbnQoJ2RpdicpXG4gICAgICAgIGVsLmlubmVySFRNTCA9IGh0bWxcbiAgICAgICAgbGV0IGZyYWcgPSB0aGlzLmdldERvY3VtZW50KCkuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpLFxuICAgICAgICAgICAgbm9kZSwgbGFzdE5vZGVcbiAgICAgICAgd2hpbGUgKChub2RlID0gZWwuZmlyc3RDaGlsZCkpIHtcbiAgICAgICAgICAgIGxhc3ROb2RlID0gZnJhZy5hcHBlbmRDaGlsZChub2RlKVxuICAgICAgICB9XG4gICAgICAgIHJhbmdlLmluc2VydE5vZGUoZnJhZylcblxuICAgICAgICAvLyBQcmVzZXJ2ZSB0aGUgc2VsZWN0aW9uXG4gICAgICAgIGlmIChsYXN0Tm9kZSkge1xuICAgICAgICAgICAgcmFuZ2UgPSByYW5nZS5jbG9uZVJhbmdlKClcbiAgICAgICAgICAgIHJhbmdlLnNldFN0YXJ0QWZ0ZXIobGFzdE5vZGUpXG4gICAgICAgICAgICByYW5nZS5jb2xsYXBzZSh0cnVlKVxuICAgICAgICAgICAgc2VsLnJlbW92ZUFsbFJhbmdlcygpXG4gICAgICAgICAgICBzZWwuYWRkUmFuZ2UocmFuZ2UpXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBnZXRXaW5kb3dTZWxlY3Rpb24oKSB7XG4gICAgICAgIGlmICh0aGlzLnRyaWJ1dGUuY29sbGVjdGlvbi5pZnJhbWUpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnRyaWJ1dGUuY29sbGVjdGlvbi5pZnJhbWUuY29udGVudFdpbmRvdy5nZXRTZWxlY3Rpb24oKVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHdpbmRvdy5nZXRTZWxlY3Rpb24oKVxuICAgIH1cblxuICAgIGdldE5vZGVQb3NpdGlvbkluUGFyZW50KGVsZW1lbnQpIHtcbiAgICAgICAgaWYgKGVsZW1lbnQucGFyZW50Tm9kZSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIDBcbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZWxlbWVudC5wYXJlbnROb2RlLmNoaWxkTm9kZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGxldCBub2RlID0gZWxlbWVudC5wYXJlbnROb2RlLmNoaWxkTm9kZXNbaV1cblxuICAgICAgICAgICAgaWYgKG5vZGUgPT09IGVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgZ2V0Q29udGVudEVkaXRhYmxlU2VsZWN0ZWRQYXRoKGN0eCkge1xuICAgICAgICBsZXQgc2VsID0gdGhpcy5nZXRXaW5kb3dTZWxlY3Rpb24oKVxuICAgICAgICBsZXQgc2VsZWN0ZWQgPSBzZWwuYW5jaG9yTm9kZVxuICAgICAgICBsZXQgcGF0aCA9IFtdXG4gICAgICAgIGxldCBvZmZzZXRcblxuICAgICAgICBpZiAoc2VsZWN0ZWQgIT0gbnVsbCkge1xuICAgICAgICAgICAgbGV0IGlcbiAgICAgICAgICAgIGxldCBjZSA9IHNlbGVjdGVkLmNvbnRlbnRFZGl0YWJsZVxuICAgICAgICAgICAgd2hpbGUgKHNlbGVjdGVkICE9PSBudWxsICYmIGNlICE9PSAndHJ1ZScpIHtcbiAgICAgICAgICAgICAgICBpID0gdGhpcy5nZXROb2RlUG9zaXRpb25JblBhcmVudChzZWxlY3RlZClcbiAgICAgICAgICAgICAgICBwYXRoLnB1c2goaSlcbiAgICAgICAgICAgICAgICBzZWxlY3RlZCA9IHNlbGVjdGVkLnBhcmVudE5vZGVcbiAgICAgICAgICAgICAgICBpZiAoc2VsZWN0ZWQgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgY2UgPSBzZWxlY3RlZC5jb250ZW50RWRpdGFibGVcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBwYXRoLnJldmVyc2UoKVxuXG4gICAgICAgICAgICAvLyBnZXRSYW5nZUF0IG1heSBub3QgZXhpc3QsIG5lZWQgYWx0ZXJuYXRpdmVcbiAgICAgICAgICAgIG9mZnNldCA9IHNlbC5nZXRSYW5nZUF0KDApLnN0YXJ0T2Zmc2V0XG5cbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgc2VsZWN0ZWQ6IHNlbGVjdGVkLFxuICAgICAgICAgICAgICAgIHBhdGg6IHBhdGgsXG4gICAgICAgICAgICAgICAgb2Zmc2V0OiBvZmZzZXRcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGdldFRleHRQcmVjZWRpbmdDdXJyZW50U2VsZWN0aW9uKCkge1xuICAgICAgICBsZXQgY29udGV4dCA9IHRoaXMudHJpYnV0ZS5jdXJyZW50LFxuICAgICAgICAgICAgdGV4dCA9ICcnXG5cbiAgICAgICAgaWYgKCF0aGlzLmlzQ29udGVudEVkaXRhYmxlKGNvbnRleHQuZWxlbWVudCkpIHtcbiAgICAgICAgICAgIGxldCB0ZXh0Q29tcG9uZW50ID0gdGhpcy50cmlidXRlLmN1cnJlbnQuZWxlbWVudDtcbiAgICAgICAgICAgIGlmICh0ZXh0Q29tcG9uZW50KSB7XG4gICAgICAgICAgICAgICAgbGV0IHN0YXJ0UG9zID0gdGV4dENvbXBvbmVudC5zZWxlY3Rpb25TdGFydFxuICAgICAgICAgICAgICAgIGlmICh0ZXh0Q29tcG9uZW50LnZhbHVlICYmIHN0YXJ0UG9zID49IDApIHtcbiAgICAgICAgICAgICAgICAgICAgdGV4dCA9IHRleHRDb21wb25lbnQudmFsdWUuc3Vic3RyaW5nKDAsIHN0YXJ0UG9zKVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbGV0IHNlbGVjdGVkRWxlbSA9IHRoaXMuZ2V0V2luZG93U2VsZWN0aW9uKCkuYW5jaG9yTm9kZVxuXG4gICAgICAgICAgICBpZiAoc2VsZWN0ZWRFbGVtICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICBsZXQgd29ya2luZ05vZGVDb250ZW50ID0gc2VsZWN0ZWRFbGVtLnRleHRDb250ZW50XG4gICAgICAgICAgICAgICAgbGV0IHNlbGVjdFN0YXJ0T2Zmc2V0ID0gdGhpcy5nZXRXaW5kb3dTZWxlY3Rpb24oKS5nZXRSYW5nZUF0KDApLnN0YXJ0T2Zmc2V0XG5cbiAgICAgICAgICAgICAgICBpZiAod29ya2luZ05vZGVDb250ZW50ICYmIHNlbGVjdFN0YXJ0T2Zmc2V0ID49IDApIHtcbiAgICAgICAgICAgICAgICAgICAgdGV4dCA9IHdvcmtpbmdOb2RlQ29udGVudC5zdWJzdHJpbmcoMCwgc2VsZWN0U3RhcnRPZmZzZXQpXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRleHRcbiAgICB9XG5cbiAgICBnZXRUcmlnZ2VySW5mbyhtZW51QWxyZWFkeUFjdGl2ZSwgaGFzVHJhaWxpbmdTcGFjZSwgcmVxdWlyZUxlYWRpbmdTcGFjZSwgYWxsb3dTcGFjZXMpIHtcbiAgICAgICAgbGV0IGN0eCA9IHRoaXMudHJpYnV0ZS5jdXJyZW50XG4gICAgICAgIGxldCBzZWxlY3RlZCwgcGF0aCwgb2Zmc2V0XG5cbiAgICAgICAgaWYgKCF0aGlzLmlzQ29udGVudEVkaXRhYmxlKGN0eC5lbGVtZW50KSkge1xuICAgICAgICAgICAgc2VsZWN0ZWQgPSB0aGlzLmdldERvY3VtZW50KCkuYWN0aXZlRWxlbWVudFxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbGV0IHNlbGVjdGlvbkluZm8gPSB0aGlzLmdldENvbnRlbnRFZGl0YWJsZVNlbGVjdGVkUGF0aChjdHgpXG5cbiAgICAgICAgICAgIGlmIChzZWxlY3Rpb25JbmZvKSB7XG4gICAgICAgICAgICAgICAgc2VsZWN0ZWQgPSBzZWxlY3Rpb25JbmZvLnNlbGVjdGVkXG4gICAgICAgICAgICAgICAgcGF0aCA9IHNlbGVjdGlvbkluZm8ucGF0aFxuICAgICAgICAgICAgICAgIG9mZnNldCA9IHNlbGVjdGlvbkluZm8ub2Zmc2V0XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgZWZmZWN0aXZlUmFuZ2UgPSB0aGlzLmdldFRleHRQcmVjZWRpbmdDdXJyZW50U2VsZWN0aW9uKClcblxuICAgICAgICBpZiAoZWZmZWN0aXZlUmFuZ2UgIT09IHVuZGVmaW5lZCAmJiBlZmZlY3RpdmVSYW5nZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgbGV0IG1vc3RSZWNlbnRUcmlnZ2VyQ2hhclBvcyA9IC0xXG4gICAgICAgICAgICBsZXQgdHJpZ2dlckNoYXJcblxuICAgICAgICAgICAgdGhpcy50cmlidXRlLmNvbGxlY3Rpb24uZm9yRWFjaChjb25maWcgPT4ge1xuICAgICAgICAgICAgICAgIGxldCBjID0gY29uZmlnLnRyaWdnZXJcbiAgICAgICAgICAgICAgICBsZXQgaWR4ID0gY29uZmlnLnJlcXVpcmVMZWFkaW5nU3BhY2UgP1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmxhc3RJbmRleFdpdGhMZWFkaW5nU3BhY2UoZWZmZWN0aXZlUmFuZ2UsIGMpIDpcbiAgICAgICAgICAgICAgICAgICAgZWZmZWN0aXZlUmFuZ2UubGFzdEluZGV4T2YoYylcblxuICAgICAgICAgICAgICAgIGlmIChpZHggPiBtb3N0UmVjZW50VHJpZ2dlckNoYXJQb3MpIHtcbiAgICAgICAgICAgICAgICAgICAgbW9zdFJlY2VudFRyaWdnZXJDaGFyUG9zID0gaWR4XG4gICAgICAgICAgICAgICAgICAgIHRyaWdnZXJDaGFyID0gY1xuICAgICAgICAgICAgICAgICAgICByZXF1aXJlTGVhZGluZ1NwYWNlID0gY29uZmlnLnJlcXVpcmVMZWFkaW5nU3BhY2VcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KVxuXG4gICAgICAgICAgICBpZiAobW9zdFJlY2VudFRyaWdnZXJDaGFyUG9zID49IDAgJiZcbiAgICAgICAgICAgICAgICAoXG4gICAgICAgICAgICAgICAgICAgIG1vc3RSZWNlbnRUcmlnZ2VyQ2hhclBvcyA9PT0gMCB8fFxuICAgICAgICAgICAgICAgICAgICAhcmVxdWlyZUxlYWRpbmdTcGFjZSB8fFxuICAgICAgICAgICAgICAgICAgICAvW1xceEEwXFxzXS9nLnRlc3QoXG4gICAgICAgICAgICAgICAgICAgICAgICBlZmZlY3RpdmVSYW5nZS5zdWJzdHJpbmcoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9zdFJlY2VudFRyaWdnZXJDaGFyUG9zIC0gMSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb3N0UmVjZW50VHJpZ2dlckNoYXJQb3MpXG4gICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICBsZXQgY3VycmVudFRyaWdnZXJTbmlwcGV0ID0gZWZmZWN0aXZlUmFuZ2Uuc3Vic3RyaW5nKG1vc3RSZWNlbnRUcmlnZ2VyQ2hhclBvcyArIDEsXG4gICAgICAgICAgICAgICAgICAgIGVmZmVjdGl2ZVJhbmdlLmxlbmd0aClcblxuICAgICAgICAgICAgICAgIHRyaWdnZXJDaGFyID0gZWZmZWN0aXZlUmFuZ2Uuc3Vic3RyaW5nKG1vc3RSZWNlbnRUcmlnZ2VyQ2hhclBvcywgbW9zdFJlY2VudFRyaWdnZXJDaGFyUG9zICsgMSlcbiAgICAgICAgICAgICAgICBsZXQgZmlyc3RTbmlwcGV0Q2hhciA9IGN1cnJlbnRUcmlnZ2VyU25pcHBldC5zdWJzdHJpbmcoMCwgMSlcbiAgICAgICAgICAgICAgICBsZXQgbGVhZGluZ1NwYWNlID0gY3VycmVudFRyaWdnZXJTbmlwcGV0Lmxlbmd0aCA+IDAgJiZcbiAgICAgICAgICAgICAgICAgICAgKFxuICAgICAgICAgICAgICAgICAgICAgICAgZmlyc3RTbmlwcGV0Q2hhciA9PT0gJyAnIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICBmaXJzdFNuaXBwZXRDaGFyID09PSAnXFx4QTAnXG4gICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICBpZiAoaGFzVHJhaWxpbmdTcGFjZSkge1xuICAgICAgICAgICAgICAgICAgICBjdXJyZW50VHJpZ2dlclNuaXBwZXQgPSBjdXJyZW50VHJpZ2dlclNuaXBwZXQudHJpbSgpXG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgbGV0IHJlZ2V4ID0gYWxsb3dTcGFjZXMgPyAvW15cXFMgXS9nIDogL1tcXHhBMFxcc10vZztcblxuICAgICAgICAgICAgICAgIGlmICghbGVhZGluZ1NwYWNlICYmIChtZW51QWxyZWFkeUFjdGl2ZSB8fCAhKHJlZ2V4LnRlc3QoY3VycmVudFRyaWdnZXJTbmlwcGV0KSkpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtZW50aW9uUG9zaXRpb246IG1vc3RSZWNlbnRUcmlnZ2VyQ2hhclBvcyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lbnRpb25UZXh0OiBjdXJyZW50VHJpZ2dlclNuaXBwZXQsXG4gICAgICAgICAgICAgICAgICAgICAgICBtZW50aW9uU2VsZWN0ZWRFbGVtZW50OiBzZWxlY3RlZCxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lbnRpb25TZWxlY3RlZFBhdGg6IHBhdGgsXG4gICAgICAgICAgICAgICAgICAgICAgICBtZW50aW9uU2VsZWN0ZWRPZmZzZXQ6IG9mZnNldCxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lbnRpb25UcmlnZ2VyQ2hhcjogdHJpZ2dlckNoYXJcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGxhc3RJbmRleFdpdGhMZWFkaW5nU3BhY2UgKHN0ciwgY2hhcikge1xuICAgICAgICBsZXQgcmV2ZXJzZWRTdHIgPSBzdHIuc3BsaXQoJycpLnJldmVyc2UoKS5qb2luKCcnKVxuICAgICAgICBsZXQgaW5kZXggPSAtMVxuXG4gICAgICAgIGZvciAobGV0IGNpZHggPSAwLCBsZW4gPSBzdHIubGVuZ3RoOyBjaWR4IDwgbGVuOyBjaWR4KyspIHtcbiAgICAgICAgICAgIGxldCBmaXJzdENoYXIgPSBjaWR4ID09PSBzdHIubGVuZ3RoIC0gMVxuICAgICAgICAgICAgbGV0IGxlYWRpbmdTcGFjZSA9IC9cXHMvLnRlc3QocmV2ZXJzZWRTdHJbY2lkeCArIDFdKVxuICAgICAgICAgICAgbGV0IG1hdGNoID0gY2hhciA9PT0gcmV2ZXJzZWRTdHJbY2lkeF1cblxuICAgICAgICAgICAgaWYgKG1hdGNoICYmIChmaXJzdENoYXIgfHwgbGVhZGluZ1NwYWNlKSkge1xuICAgICAgICAgICAgICAgIGluZGV4ID0gc3RyLmxlbmd0aCAtIDEgLSBjaWR4XG4gICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBpbmRleFxuICAgIH1cblxuICAgIGlzQ29udGVudEVkaXRhYmxlKGVsZW1lbnQpIHtcbiAgICAgICAgcmV0dXJuIGVsZW1lbnQubm9kZU5hbWUgIT09ICdJTlBVVCcgJiYgZWxlbWVudC5ub2RlTmFtZSAhPT0gJ1RFWFRBUkVBJ1xuICAgIH1cblxuICAgIGdldFRleHRBcmVhT3JJbnB1dFVuZGVybGluZVBvc2l0aW9uKGVsZW1lbnQsIHBvc2l0aW9uKSB7XG4gICAgICAgIGxldCBwcm9wZXJ0aWVzID0gWydkaXJlY3Rpb24nLCAnYm94U2l6aW5nJywgJ3dpZHRoJywgJ2hlaWdodCcsICdvdmVyZmxvd1gnLFxuICAgICAgICAgICAgJ292ZXJmbG93WScsICdib3JkZXJUb3BXaWR0aCcsICdib3JkZXJSaWdodFdpZHRoJyxcbiAgICAgICAgICAgICdib3JkZXJCb3R0b21XaWR0aCcsICdib3JkZXJMZWZ0V2lkdGgnLCAncGFkZGluZ1RvcCcsXG4gICAgICAgICAgICAncGFkZGluZ1JpZ2h0JywgJ3BhZGRpbmdCb3R0b20nLCAncGFkZGluZ0xlZnQnLFxuICAgICAgICAgICAgJ2ZvbnRTdHlsZScsICdmb250VmFyaWFudCcsICdmb250V2VpZ2h0JywgJ2ZvbnRTdHJldGNoJyxcbiAgICAgICAgICAgICdmb250U2l6ZScsICdmb250U2l6ZUFkanVzdCcsICdsaW5lSGVpZ2h0JywgJ2ZvbnRGYW1pbHknLFxuICAgICAgICAgICAgJ3RleHRBbGlnbicsICd0ZXh0VHJhbnNmb3JtJywgJ3RleHRJbmRlbnQnLFxuICAgICAgICAgICAgJ3RleHREZWNvcmF0aW9uJywgJ2xldHRlclNwYWNpbmcnLCAnd29yZFNwYWNpbmcnXG4gICAgICAgIF1cblxuICAgICAgICBsZXQgaXNGaXJlZm94ID0gKHdpbmRvdy5tb3pJbm5lclNjcmVlblggIT09IG51bGwpXG5cbiAgICAgICAgbGV0IGRpdiA9IHRoaXMuZ2V0RG9jdW1lbnQoKS5jcmVhdGVFbGVtZW50KCdkaXYnKVxuICAgICAgICBkaXYuaWQgPSAnaW5wdXQtdGV4dGFyZWEtY2FyZXQtcG9zaXRpb24tbWlycm9yLWRpdidcbiAgICAgICAgdGhpcy5nZXREb2N1bWVudCgpLmJvZHkuYXBwZW5kQ2hpbGQoZGl2KVxuXG4gICAgICAgIGxldCBzdHlsZSA9IGRpdi5zdHlsZVxuICAgICAgICBsZXQgY29tcHV0ZWQgPSB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZSA/IGdldENvbXB1dGVkU3R5bGUoZWxlbWVudCkgOiBlbGVtZW50LmN1cnJlbnRTdHlsZVxuXG4gICAgICAgIHN0eWxlLndoaXRlU3BhY2UgPSAncHJlLXdyYXAnXG4gICAgICAgIGlmIChlbGVtZW50Lm5vZGVOYW1lICE9PSAnSU5QVVQnKSB7XG4gICAgICAgICAgICBzdHlsZS53b3JkV3JhcCA9ICdicmVhay13b3JkJ1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gcG9zaXRpb24gb2ZmLXNjcmVlblxuICAgICAgICBzdHlsZS5wb3NpdGlvbiA9ICdhYnNvbHV0ZSdcbiAgICAgICAgc3R5bGUudmlzaWJpbGl0eSA9ICdoaWRkZW4nXG5cbiAgICAgICAgLy8gdHJhbnNmZXIgdGhlIGVsZW1lbnQncyBwcm9wZXJ0aWVzIHRvIHRoZSBkaXZcbiAgICAgICAgcHJvcGVydGllcy5mb3JFYWNoKHByb3AgPT4ge1xuICAgICAgICAgICAgc3R5bGVbcHJvcF0gPSBjb21wdXRlZFtwcm9wXVxuICAgICAgICB9KVxuXG4gICAgICAgIGlmIChpc0ZpcmVmb3gpIHtcbiAgICAgICAgICAgIHN0eWxlLndpZHRoID0gYCR7KHBhcnNlSW50KGNvbXB1dGVkLndpZHRoKSAtIDIpfXB4YFxuICAgICAgICAgICAgaWYgKGVsZW1lbnQuc2Nyb2xsSGVpZ2h0ID4gcGFyc2VJbnQoY29tcHV0ZWQuaGVpZ2h0KSlcbiAgICAgICAgICAgICAgICBzdHlsZS5vdmVyZmxvd1kgPSAnc2Nyb2xsJ1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc3R5bGUub3ZlcmZsb3cgPSAnaGlkZGVuJ1xuICAgICAgICB9XG5cbiAgICAgICAgZGl2LnRleHRDb250ZW50ID0gZWxlbWVudC52YWx1ZS5zdWJzdHJpbmcoMCwgcG9zaXRpb24pXG5cbiAgICAgICAgaWYgKGVsZW1lbnQubm9kZU5hbWUgPT09ICdJTlBVVCcpIHtcbiAgICAgICAgICAgIGRpdi50ZXh0Q29udGVudCA9IGRpdi50ZXh0Q29udGVudC5yZXBsYWNlKC9cXHMvZywgJ8KgJylcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBzcGFuID0gdGhpcy5nZXREb2N1bWVudCgpLmNyZWF0ZUVsZW1lbnQoJ3NwYW4nKVxuICAgICAgICBzcGFuLnRleHRDb250ZW50ID0gZWxlbWVudC52YWx1ZS5zdWJzdHJpbmcocG9zaXRpb24pIHx8ICcuJ1xuICAgICAgICBkaXYuYXBwZW5kQ2hpbGQoc3BhbilcblxuICAgICAgICBsZXQgcmVjdCA9IGVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KClcbiAgICAgICAgbGV0IGRvYyA9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudFxuICAgICAgICBsZXQgd2luZG93TGVmdCA9ICh3aW5kb3cucGFnZVhPZmZzZXQgfHwgZG9jLnNjcm9sbExlZnQpIC0gKGRvYy5jbGllbnRMZWZ0IHx8IDApXG4gICAgICAgIGxldCB3aW5kb3dUb3AgPSAod2luZG93LnBhZ2VZT2Zmc2V0IHx8IGRvYy5zY3JvbGxUb3ApIC0gKGRvYy5jbGllbnRUb3AgfHwgMClcblxuICAgICAgICBsZXQgY29vcmRpbmF0ZXMgPSB7XG4gICAgICAgICAgICB0b3A6IHJlY3QudG9wICsgd2luZG93VG9wICsgc3Bhbi5vZmZzZXRUb3AgKyBwYXJzZUludChjb21wdXRlZC5ib3JkZXJUb3BXaWR0aCkgKyBwYXJzZUludChjb21wdXRlZC5mb250U2l6ZSkgLSBlbGVtZW50LnNjcm9sbFRvcCxcbiAgICAgICAgICAgIGxlZnQ6IHJlY3QubGVmdCArIHdpbmRvd0xlZnQgKyBzcGFuLm9mZnNldExlZnQgKyBwYXJzZUludChjb21wdXRlZC5ib3JkZXJMZWZ0V2lkdGgpXG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmdldERvY3VtZW50KCkuYm9keS5yZW1vdmVDaGlsZChkaXYpXG5cbiAgICAgICAgcmV0dXJuIGNvb3JkaW5hdGVzXG4gICAgfVxuXG4gICAgZ2V0Q29udGVudEVkaXRhYmxlQ2FyZXRQb3NpdGlvbihzZWxlY3RlZE5vZGVQb3NpdGlvbikge1xuICAgICAgICBsZXQgbWFya2VyVGV4dENoYXIgPSAn77u/J1xuICAgICAgICBsZXQgbWFya2VyRWwsIG1hcmtlcklkID0gYHNlbF8ke25ldyBEYXRlKCkuZ2V0VGltZSgpfV8ke01hdGgucmFuZG9tKCkudG9TdHJpbmcoKS5zdWJzdHIoMil9YFxuICAgICAgICBsZXQgcmFuZ2VcbiAgICAgICAgbGV0IHNlbCA9IHRoaXMuZ2V0V2luZG93U2VsZWN0aW9uKClcbiAgICAgICAgbGV0IHByZXZSYW5nZSA9IHNlbC5nZXRSYW5nZUF0KDApXG5cbiAgICAgICAgcmFuZ2UgPSB0aGlzLmdldERvY3VtZW50KCkuY3JlYXRlUmFuZ2UoKVxuICAgICAgICByYW5nZS5zZXRTdGFydChzZWwuYW5jaG9yTm9kZSwgc2VsZWN0ZWROb2RlUG9zaXRpb24pXG4gICAgICAgIHJhbmdlLnNldEVuZChzZWwuYW5jaG9yTm9kZSwgc2VsZWN0ZWROb2RlUG9zaXRpb24pXG5cbiAgICAgICAgcmFuZ2UuY29sbGFwc2UoZmFsc2UpXG5cbiAgICAgICAgLy8gQ3JlYXRlIHRoZSBtYXJrZXIgZWxlbWVudCBjb250YWluaW5nIGEgc2luZ2xlIGludmlzaWJsZSBjaGFyYWN0ZXIgdXNpbmcgRE9NIG1ldGhvZHMgYW5kIGluc2VydCBpdFxuICAgICAgICBtYXJrZXJFbCA9IHRoaXMuZ2V0RG9jdW1lbnQoKS5jcmVhdGVFbGVtZW50KCdzcGFuJylcbiAgICAgICAgbWFya2VyRWwuaWQgPSBtYXJrZXJJZFxuICAgICAgICBtYXJrZXJFbC5hcHBlbmRDaGlsZCh0aGlzLmdldERvY3VtZW50KCkuY3JlYXRlVGV4dE5vZGUobWFya2VyVGV4dENoYXIpKVxuICAgICAgICByYW5nZS5pbnNlcnROb2RlKG1hcmtlckVsKVxuICAgICAgICBzZWwucmVtb3ZlQWxsUmFuZ2VzKClcbiAgICAgICAgc2VsLmFkZFJhbmdlKHByZXZSYW5nZSlcblxuICAgICAgICBsZXQgcmVjdCA9IG1hcmtlckVsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpXG4gICAgICAgIGxldCBkb2MgPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnRcbiAgICAgICAgbGV0IHdpbmRvd0xlZnQgPSAod2luZG93LnBhZ2VYT2Zmc2V0IHx8IGRvYy5zY3JvbGxMZWZ0KSAtIChkb2MuY2xpZW50TGVmdCB8fCAwKVxuICAgICAgICBsZXQgd2luZG93VG9wID0gKHdpbmRvdy5wYWdlWU9mZnNldCB8fCBkb2Muc2Nyb2xsVG9wKSAtIChkb2MuY2xpZW50VG9wIHx8IDApXG4gICAgICAgIGxldCBjb29yZGluYXRlcyA9IHtcbiAgICAgICAgICAgIGxlZnQ6IHJlY3QubGVmdCArIHdpbmRvd0xlZnQsXG4gICAgICAgICAgICB0b3A6IHJlY3QudG9wICsgbWFya2VyRWwub2Zmc2V0SGVpZ2h0ICsgd2luZG93VG9wXG4gICAgICAgIH1cblxuICAgICAgICBtYXJrZXJFbC5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKG1hcmtlckVsKVxuICAgICAgICByZXR1cm4gY29vcmRpbmF0ZXNcbiAgICB9XG5cbiAgICBzY3JvbGxJbnRvVmlldyhlbGVtKSB7XG4gICAgICAgIGxldCByZWFzb25hYmxlQnVmZmVyID0gMjAsXG4gICAgICAgICAgICBjbGllbnRSZWN0XG4gICAgICAgIGxldCBtYXhTY3JvbGxEaXNwbGFjZW1lbnQgPSAxMDBcbiAgICAgICAgbGV0IGUgPSB0aGlzLm1lbnVcblxuICAgICAgICBpZiAodHlwZW9mIGUgPT09ICd1bmRlZmluZWQnKSByZXR1cm47XG5cbiAgICAgICAgd2hpbGUgKGNsaWVudFJlY3QgPT09IHVuZGVmaW5lZCB8fCBjbGllbnRSZWN0LmhlaWdodCA9PT0gMCkge1xuICAgICAgICAgICAgY2xpZW50UmVjdCA9IGUuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KClcblxuICAgICAgICAgICAgaWYgKGNsaWVudFJlY3QuaGVpZ2h0ID09PSAwKSB7XG4gICAgICAgICAgICAgICAgZSA9IGUuY2hpbGROb2Rlc1swXVxuICAgICAgICAgICAgICAgIGlmIChlID09PSB1bmRlZmluZWQgfHwgIWUuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVyblxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBlbGVtVG9wID0gY2xpZW50UmVjdC50b3BcbiAgICAgICAgbGV0IGVsZW1Cb3R0b20gPSBlbGVtVG9wICsgY2xpZW50UmVjdC5oZWlnaHRcblxuICAgICAgICBpZiAoZWxlbVRvcCA8IDApIHtcbiAgICAgICAgICAgIHdpbmRvdy5zY3JvbGxUbygwLCB3aW5kb3cucGFnZVlPZmZzZXQgKyBjbGllbnRSZWN0LnRvcCAtIHJlYXNvbmFibGVCdWZmZXIpXG4gICAgICAgIH0gZWxzZSBpZiAoZWxlbUJvdHRvbSA+IHdpbmRvdy5pbm5lckhlaWdodCkge1xuICAgICAgICAgICAgbGV0IG1heFkgPSB3aW5kb3cucGFnZVlPZmZzZXQgKyBjbGllbnRSZWN0LnRvcCAtIHJlYXNvbmFibGVCdWZmZXJcblxuICAgICAgICAgICAgaWYgKG1heFkgLSB3aW5kb3cucGFnZVlPZmZzZXQgPiBtYXhTY3JvbGxEaXNwbGFjZW1lbnQpIHtcbiAgICAgICAgICAgICAgICBtYXhZID0gd2luZG93LnBhZ2VZT2Zmc2V0ICsgbWF4U2Nyb2xsRGlzcGxhY2VtZW50XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGxldCB0YXJnZXRZID0gd2luZG93LnBhZ2VZT2Zmc2V0IC0gKHdpbmRvdy5pbm5lckhlaWdodCAtIGVsZW1Cb3R0b20pXG5cbiAgICAgICAgICAgIGlmICh0YXJnZXRZID4gbWF4WSkge1xuICAgICAgICAgICAgICAgIHRhcmdldFkgPSBtYXhZXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHdpbmRvdy5zY3JvbGxUbygwLCB0YXJnZXRZKVxuICAgICAgICB9XG4gICAgfVxufVxuXG5cbmV4cG9ydCBkZWZhdWx0IFRyaWJ1dGVSYW5nZTtcbiIsIi8vIFRoYW5rcyB0byBodHRwczovL2dpdGh1Yi5jb20vbWF0dHlvcmsvZnV6enlcbmNsYXNzIFRyaWJ1dGVTZWFyY2gge1xuICAgIGNvbnN0cnVjdG9yKHRyaWJ1dGUpIHtcbiAgICAgICAgdGhpcy50cmlidXRlID0gdHJpYnV0ZVxuICAgICAgICB0aGlzLnRyaWJ1dGUuc2VhcmNoID0gdGhpc1xuICAgIH1cblxuICAgIHNpbXBsZUZpbHRlcihwYXR0ZXJuLCBhcnJheSkge1xuICAgICAgICByZXR1cm4gYXJyYXkuZmlsdGVyKHN0cmluZyA9PiB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy50ZXN0KHBhdHRlcm4sIHN0cmluZylcbiAgICAgICAgfSlcbiAgICB9XG5cbiAgICB0ZXN0KHBhdHRlcm4sIHN0cmluZykge1xuICAgICAgICByZXR1cm4gdGhpcy5tYXRjaChwYXR0ZXJuLCBzdHJpbmcpICE9PSBudWxsXG4gICAgfVxuXG4gICAgbWF0Y2gocGF0dGVybiwgc3RyaW5nLCBvcHRzKSB7XG4gICAgICAgIG9wdHMgPSBvcHRzIHx8IHt9XG4gICAgICAgIGxldCBwYXR0ZXJuSWR4ID0gMCxcbiAgICAgICAgICAgIHJlc3VsdCA9IFtdLFxuICAgICAgICAgICAgbGVuID0gc3RyaW5nLmxlbmd0aCxcbiAgICAgICAgICAgIHRvdGFsU2NvcmUgPSAwLFxuICAgICAgICAgICAgY3VyclNjb3JlID0gMCxcbiAgICAgICAgICAgIHByZSA9IG9wdHMucHJlIHx8ICcnLFxuICAgICAgICAgICAgcG9zdCA9IG9wdHMucG9zdCB8fCAnJyxcbiAgICAgICAgICAgIGNvbXBhcmVTdHJpbmcgPSBvcHRzLmNhc2VTZW5zaXRpdmUgJiYgc3RyaW5nIHx8IHN0cmluZy50b0xvd2VyQ2FzZSgpLFxuICAgICAgICAgICAgY2gsIGNvbXBhcmVDaGFyXG5cbiAgICAgICAgcGF0dGVybiA9IG9wdHMuY2FzZVNlbnNpdGl2ZSAmJiBwYXR0ZXJuIHx8IHBhdHRlcm4udG9Mb3dlckNhc2UoKVxuXG4gICAgICAgIGxldCBwYXR0ZXJuQ2FjaGUgPSB0aGlzLnRyYXZlcnNlKGNvbXBhcmVTdHJpbmcsIHBhdHRlcm4sIDAsIDAsIFtdKVxuICAgICAgICBpZiAoIXBhdHRlcm5DYWNoZSkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGxcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICByZW5kZXJlZDogdGhpcy5yZW5kZXIoc3RyaW5nLCBwYXR0ZXJuQ2FjaGUuY2FjaGUsIHByZSwgcG9zdCksXG4gICAgICAgICAgICBzY29yZTogcGF0dGVybkNhY2hlLnNjb3JlXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB0cmF2ZXJzZShzdHJpbmcsIHBhdHRlcm4sIHN0cmluZ0luZGV4LCBwYXR0ZXJuSW5kZXgsIHBhdHRlcm5DYWNoZSkge1xuICAgICAgICAvLyBpZiB0aGUgcGF0dGVybiBzZWFyY2ggYXQgZW5kXG4gICAgICAgIGlmIChwYXR0ZXJuLmxlbmd0aCA9PT0gcGF0dGVybkluZGV4KSB7XG5cbiAgICAgICAgICAgIC8vIGNhbGN1bGF0ZSBzb2NyZSBhbmQgY29weSB0aGUgY2FjaGUgY29udGFpbmluZyB0aGUgaW5kaWNlcyB3aGVyZSBpdCdzIGZvdW5kXG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIHNjb3JlOiB0aGlzLmNhbGN1bGF0ZVNjb3JlKHBhdHRlcm5DYWNoZSksXG4gICAgICAgICAgICAgICAgY2FjaGU6IHBhdHRlcm5DYWNoZS5zbGljZSgpXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBpZiBzdHJpbmcgYXQgZW5kIG9yIHJlbWFpbmluZyBwYXR0ZXJuID4gcmVtYWluaW5nIHN0cmluZ1xuICAgICAgICBpZiAoc3RyaW5nLmxlbmd0aCA9PT0gc3RyaW5nSW5kZXggfHwgcGF0dGVybi5sZW5ndGggLSBwYXR0ZXJuSW5kZXggPiBzdHJpbmcubGVuZ3RoIC0gc3RyaW5nSW5kZXgpIHtcbiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWRcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBjID0gcGF0dGVybltwYXR0ZXJuSW5kZXhdXG4gICAgICAgIGxldCBpbmRleCA9IHN0cmluZy5pbmRleE9mKGMsIHN0cmluZ0luZGV4KVxuICAgICAgICBsZXQgYmVzdCwgdGVtcFxuXG4gICAgICAgIHdoaWxlIChpbmRleCA+IC0xKSB7XG4gICAgICAgICAgICBwYXR0ZXJuQ2FjaGUucHVzaChpbmRleClcbiAgICAgICAgICAgIHRlbXAgPSB0aGlzLnRyYXZlcnNlKHN0cmluZywgcGF0dGVybiwgaW5kZXggKyAxLCBwYXR0ZXJuSW5kZXggKyAxLCBwYXR0ZXJuQ2FjaGUpXG4gICAgICAgICAgICBwYXR0ZXJuQ2FjaGUucG9wKClcblxuICAgICAgICAgICAgLy8gaWYgZG93bnN0cmVhbSB0cmF2ZXJzYWwgZmFpbGVkLCByZXR1cm4gYmVzdCBhbnN3ZXIgc28gZmFyXG4gICAgICAgICAgICBpZiAoIXRlbXApIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYmVzdFxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoIWJlc3QgfHwgYmVzdC5zY29yZSA8IHRlbXAuc2NvcmUpIHtcbiAgICAgICAgICAgICAgICBiZXN0ID0gdGVtcFxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpbmRleCA9IHN0cmluZy5pbmRleE9mKGMsIGluZGV4ICsgMSlcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBiZXN0XG4gICAgfVxuXG4gICAgY2FsY3VsYXRlU2NvcmUocGF0dGVybkNhY2hlKSB7XG4gICAgICAgIGxldCBzY29yZSA9IDBcbiAgICAgICAgbGV0IHRlbXAgPSAxXG5cbiAgICAgICAgcGF0dGVybkNhY2hlLmZvckVhY2goKGluZGV4LCBpKSA9PiB7XG4gICAgICAgICAgICBpZiAoaSA+IDApIHtcbiAgICAgICAgICAgICAgICBpZiAocGF0dGVybkNhY2hlW2kgLSAxXSArIDEgPT09IGluZGV4KSB7XG4gICAgICAgICAgICAgICAgICAgIHRlbXAgKz0gdGVtcCArIDFcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRlbXAgPSAxXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBzY29yZSArPSB0ZW1wXG4gICAgICAgIH0pXG5cbiAgICAgICAgcmV0dXJuIHNjb3JlXG4gICAgfVxuXG4gICAgcmVuZGVyKHN0cmluZywgaW5kaWNlcywgcHJlLCBwb3N0KSB7XG4gICAgICAgIHZhciByZW5kZXJlZCA9IHN0cmluZy5zdWJzdHJpbmcoMCwgaW5kaWNlc1swXSlcblxuICAgICAgICBpbmRpY2VzLmZvckVhY2goKGluZGV4LCBpKSA9PiB7XG4gICAgICAgICAgICByZW5kZXJlZCArPSBwcmUgKyBzdHJpbmdbaW5kZXhdICsgcG9zdCArXG4gICAgICAgICAgICAgICAgc3RyaW5nLnN1YnN0cmluZyhpbmRleCArIDEsIChpbmRpY2VzW2kgKyAxXSkgPyBpbmRpY2VzW2kgKyAxXSA6IHN0cmluZy5sZW5ndGgpXG4gICAgICAgIH0pXG5cbiAgICAgICAgcmV0dXJuIHJlbmRlcmVkXG4gICAgfVxuXG4gICAgZmlsdGVyKHBhdHRlcm4sIGFyciwgb3B0cykge1xuICAgICAgICBvcHRzID0gb3B0cyB8fCB7fVxuICAgICAgICByZXR1cm4gYXJyXG4gICAgICAgICAgICAucmVkdWNlKChwcmV2LCBlbGVtZW50LCBpZHgsIGFycikgPT4ge1xuICAgICAgICAgICAgICAgIGxldCBzdHIgPSBlbGVtZW50XG5cbiAgICAgICAgICAgICAgICBpZiAob3B0cy5leHRyYWN0KSB7XG4gICAgICAgICAgICAgICAgICAgIHN0ciA9IG9wdHMuZXh0cmFjdChlbGVtZW50KVxuXG4gICAgICAgICAgICAgICAgICAgIGlmICghc3RyKSB7IC8vIHRha2UgY2FyZSBvZiB1bmRlZmluZWRzIC8gbnVsbHMgLyBldGMuXG4gICAgICAgICAgICAgICAgICAgICAgICBzdHIgPSAnJ1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgbGV0IHJlbmRlcmVkID0gdGhpcy5tYXRjaChwYXR0ZXJuLCBzdHIsIG9wdHMpXG5cbiAgICAgICAgICAgICAgICBpZiAocmVuZGVyZWQgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBwcmV2W3ByZXYubGVuZ3RoXSA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZzogcmVuZGVyZWQucmVuZGVyZWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBzY29yZTogcmVuZGVyZWQuc2NvcmUsXG4gICAgICAgICAgICAgICAgICAgICAgICBpbmRleDogaWR4LFxuICAgICAgICAgICAgICAgICAgICAgICAgb3JpZ2luYWw6IGVsZW1lbnRcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHJldHVybiBwcmV2XG4gICAgICAgICAgICB9LCBbXSlcblxuICAgICAgICAuc29ydCgoYSwgYikgPT4ge1xuICAgICAgICAgICAgbGV0IGNvbXBhcmUgPSBiLnNjb3JlIC0gYS5zY29yZVxuICAgICAgICAgICAgaWYgKGNvbXBhcmUpIHJldHVybiBjb21wYXJlXG4gICAgICAgICAgICByZXR1cm4gYS5pbmRleCAtIGIuaW5kZXhcbiAgICAgICAgfSlcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFRyaWJ1dGVTZWFyY2g7IiwiLyoqXG4qIFRyaWJ1dGUuanNcbiogTmF0aXZlIEVTNiBKYXZhU2NyaXB0IEBtZW50aW9uIFBsdWdpblxuKiovXG5cbmltcG9ydCBUcmlidXRlIGZyb20gXCIuL1RyaWJ1dGVcIjtcblxuZXhwb3J0IGRlZmF1bHQgVHJpYnV0ZTtcbiIsImlmICghQXJyYXkucHJvdG90eXBlLmZpbmQpIHtcbiAgICBBcnJheS5wcm90b3R5cGUuZmluZCA9IGZ1bmN0aW9uKHByZWRpY2F0ZSkge1xuICAgICAgICBpZiAodGhpcyA9PT0gbnVsbCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQXJyYXkucHJvdG90eXBlLmZpbmQgY2FsbGVkIG9uIG51bGwgb3IgdW5kZWZpbmVkJylcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIHByZWRpY2F0ZSAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigncHJlZGljYXRlIG11c3QgYmUgYSBmdW5jdGlvbicpXG4gICAgICAgIH1cbiAgICAgICAgdmFyIGxpc3QgPSBPYmplY3QodGhpcylcbiAgICAgICAgdmFyIGxlbmd0aCA9IGxpc3QubGVuZ3RoID4+PiAwXG4gICAgICAgIHZhciB0aGlzQXJnID0gYXJndW1lbnRzWzFdXG4gICAgICAgIHZhciB2YWx1ZVxuXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHZhbHVlID0gbGlzdFtpXVxuICAgICAgICAgICAgaWYgKHByZWRpY2F0ZS5jYWxsKHRoaXNBcmcsIHZhbHVlLCBpLCBsaXN0KSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB1bmRlZmluZWRcbiAgICB9XG59XG5cbmlmICh3aW5kb3cgJiYgdHlwZW9mIHdpbmRvdy5DdXN0b21FdmVudCAhPT0gXCJmdW5jdGlvblwiKSB7XG4gIGZ1bmN0aW9uIEN1c3RvbUV2ZW50KGV2ZW50LCBwYXJhbXMpIHtcbiAgICBwYXJhbXMgPSBwYXJhbXMgfHwge1xuICAgICAgYnViYmxlczogZmFsc2UsXG4gICAgICBjYW5jZWxhYmxlOiBmYWxzZSxcbiAgICAgIGRldGFpbDogdW5kZWZpbmVkXG4gICAgfVxuICAgIHZhciBldnQgPSBkb2N1bWVudC5jcmVhdGVFdmVudCgnQ3VzdG9tRXZlbnQnKVxuICAgIGV2dC5pbml0Q3VzdG9tRXZlbnQoZXZlbnQsIHBhcmFtcy5idWJibGVzLCBwYXJhbXMuY2FuY2VsYWJsZSwgcGFyYW1zLmRldGFpbClcbiAgICByZXR1cm4gZXZ0XG4gIH1cblxuIGlmICh0eXBlb2Ygd2luZG93LkV2ZW50ICE9PSAndW5kZWZpbmVkJykge1xuICAgQ3VzdG9tRXZlbnQucHJvdG90eXBlID0gd2luZG93LkV2ZW50LnByb3RvdHlwZVxuIH1cblxuICB3aW5kb3cuQ3VzdG9tRXZlbnQgPSBDdXN0b21FdmVudFxufSJdfQ==