obsidian-dev-utils 85.1.0 → 86.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (273) hide show
  1. package/@types/obsidian-integration-testing/package.json +4 -0
  2. package/CHANGELOG.md +16 -0
  3. package/README.md +1 -0
  4. package/dist/dev/main.js +9138 -4743
  5. package/dist/lib/cjs/@types/obsidian-integration-testing.d.cts +18 -0
  6. package/dist/lib/cjs/__merged.cjs +1291 -0
  7. package/dist/lib/cjs/__merged.d.cts +165 -0
  8. package/dist/lib/cjs/abort-controller.cjs +3 -4
  9. package/dist/lib/cjs/async.cjs +13 -7
  10. package/dist/lib/cjs/async.d.cts +6 -0
  11. package/dist/lib/cjs/disposable.cjs +224 -3
  12. package/dist/lib/cjs/disposable.d.cts +222 -2
  13. package/dist/lib/cjs/error.cjs +41 -3
  14. package/dist/lib/cjs/error.d.cts +50 -1
  15. package/dist/lib/cjs/generated-during-build.cjs +2 -2
  16. package/dist/lib/cjs/index.cjs +4 -1
  17. package/dist/lib/cjs/index.d.cts +1 -0
  18. package/dist/lib/cjs/obsidian/attachment-path.cjs +3 -3
  19. package/dist/lib/cjs/obsidian/command-handlers/command-handler-component.cjs +27 -11
  20. package/dist/lib/cjs/obsidian/command-handlers/command-handler-component.d.cts +14 -9
  21. package/dist/lib/cjs/obsidian/command-handlers/index.cjs +4 -1
  22. package/dist/lib/cjs/obsidian/command-handlers/index.d.cts +1 -0
  23. package/dist/lib/cjs/obsidian/command-handlers/open-demo-vault-command-handler.cjs +195 -0
  24. package/dist/lib/cjs/obsidian/command-handlers/open-demo-vault-command-handler.d.cts +65 -0
  25. package/dist/lib/cjs/obsidian/community-plugins.cjs +156 -0
  26. package/dist/lib/cjs/obsidian/community-plugins.d.cts +22 -0
  27. package/dist/lib/cjs/obsidian/components/disposable-component.cjs +8 -8
  28. package/dist/lib/cjs/obsidian/components/disposable-component.d.cts +9 -3
  29. package/dist/lib/cjs/obsidian/components/monkey-around-component.cjs +17 -2
  30. package/dist/lib/cjs/obsidian/components/monkey-around-component.d.cts +17 -0
  31. package/dist/lib/cjs/obsidian/components/plugin-notice-component.cjs +161 -22
  32. package/dist/lib/cjs/obsidian/components/plugin-notice-component.d.cts +81 -8
  33. package/dist/lib/cjs/obsidian/css-class.cjs +4 -1
  34. package/dist/lib/cjs/obsidian/css-class.d.cts +13 -0
  35. package/dist/lib/cjs/obsidian/desktop-demo-vault-opener.cjs +239 -0
  36. package/dist/lib/cjs/obsidian/desktop-demo-vault-opener.d.cts +45 -0
  37. package/dist/lib/cjs/obsidian/desktop-trusted-input.cjs +215 -0
  38. package/dist/lib/cjs/obsidian/desktop-trusted-input.d.cts +135 -0
  39. package/dist/lib/cjs/obsidian/i18n/locales/en.cjs +3 -1
  40. package/dist/lib/cjs/obsidian/i18n/locales/en.d.cts +2 -0
  41. package/dist/lib/cjs/obsidian/i18n/locales/translations-map.d.cts +2 -0
  42. package/dist/lib/cjs/obsidian/index.cjs +10 -1
  43. package/dist/lib/cjs/obsidian/index.d.cts +3 -0
  44. package/dist/lib/cjs/obsidian/link.cjs +2 -2
  45. package/dist/lib/cjs/obsidian/modals/index.cjs +4 -1
  46. package/dist/lib/cjs/obsidian/modals/index.d.cts +1 -0
  47. package/dist/lib/cjs/obsidian/modals/minimizable-modal.cjs +15 -2
  48. package/dist/lib/cjs/obsidian/modals/minimizable-modal.d.cts +18 -3
  49. package/dist/lib/cjs/obsidian/modals/select-option.cjs +182 -0
  50. package/dist/lib/cjs/obsidian/modals/select-option.d.cts +65 -0
  51. package/dist/lib/cjs/obsidian/plugin/obsidian-plugin-repo-paths.cjs +4 -1
  52. package/dist/lib/cjs/obsidian/plugin/obsidian-plugin-repo-paths.d.cts +6 -0
  53. package/dist/lib/cjs/obsidian/plugin/plugin.cjs +50 -3
  54. package/dist/lib/cjs/obsidian/plugin/plugin.d.cts +17 -0
  55. package/dist/lib/cjs/obsidian/workspace.cjs +8 -1
  56. package/dist/lib/cjs/obsidian/workspace.d.cts +10 -0
  57. package/dist/lib/cjs/path.cjs +4 -4
  58. package/dist/lib/cjs/path.d.cts +1 -1
  59. package/dist/lib/cjs/script-utils/demo-vault.cjs +177 -0
  60. package/dist/lib/cjs/script-utils/demo-vault.d.cts +23 -0
  61. package/dist/lib/cjs/script-utils/exec.cjs +27 -5
  62. package/dist/lib/cjs/script-utils/exec.d.cts +20 -0
  63. package/dist/lib/cjs/script-utils/index.cjs +9 -3
  64. package/dist/lib/cjs/script-utils/index.d.cts +2 -0
  65. package/dist/lib/cjs/script-utils/linters/eslint-no-restricted-syntax.cjs +1 -5
  66. package/dist/lib/cjs/script-utils/obsidian-dev-utils-repo-paths.cjs +2 -1
  67. package/dist/lib/cjs/script-utils/obsidian-dev-utils-repo-paths.d.cts +2 -0
  68. package/dist/lib/cjs/script-utils/version.cjs +8 -1
  69. package/dist/lib/cjs/script-utils/version.d.cts +8 -0
  70. package/dist/lib/cjs/script-utils/warnings-as-errors.cjs +157 -0
  71. package/dist/lib/cjs/script-utils/warnings-as-errors.d.cts +27 -0
  72. package/dist/lib/cjs/setup.cjs +75 -4
  73. package/dist/lib/cjs/setup.d.cts +29 -7
  74. package/dist/lib/cjs/string.cjs +7 -4
  75. package/dist/lib/cjs/string.d.cts +11 -1
  76. package/dist/lib/esm/@types/obsidian-integration-testing.d.mts +18 -0
  77. package/dist/lib/esm/__merged.d.mts +165 -0
  78. package/dist/lib/esm/__merged.mjs +1134 -0
  79. package/dist/lib/esm/abort-controller.mjs +7 -5
  80. package/dist/lib/esm/async.d.mts +6 -0
  81. package/dist/lib/esm/async.mjs +13 -7
  82. package/dist/lib/esm/disposable.d.mts +222 -2
  83. package/dist/lib/esm/disposable.mjs +215 -2
  84. package/dist/lib/esm/error.d.mts +50 -1
  85. package/dist/lib/esm/error.mjs +41 -4
  86. package/dist/lib/esm/generated-during-build.mjs +2 -2
  87. package/dist/lib/esm/index.d.mts +1 -0
  88. package/dist/lib/esm/index.mjs +3 -1
  89. package/dist/lib/esm/obsidian/attachment-path.mjs +4 -4
  90. package/dist/lib/esm/obsidian/command-handlers/command-handler-component.d.mts +14 -9
  91. package/dist/lib/esm/obsidian/command-handlers/command-handler-component.mjs +31 -11
  92. package/dist/lib/esm/obsidian/command-handlers/index.d.mts +1 -0
  93. package/dist/lib/esm/obsidian/command-handlers/index.mjs +3 -1
  94. package/dist/lib/esm/obsidian/command-handlers/open-demo-vault-command-handler.d.mts +65 -0
  95. package/dist/lib/esm/obsidian/command-handlers/open-demo-vault-command-handler.mjs +77 -0
  96. package/dist/lib/esm/obsidian/community-plugins.d.mts +22 -0
  97. package/dist/lib/esm/obsidian/community-plugins.mjs +48 -0
  98. package/dist/lib/esm/obsidian/components/disposable-component.d.mts +9 -3
  99. package/dist/lib/esm/obsidian/components/disposable-component.mjs +8 -8
  100. package/dist/lib/esm/obsidian/components/monkey-around-component.d.mts +17 -0
  101. package/dist/lib/esm/obsidian/components/monkey-around-component.mjs +17 -2
  102. package/dist/lib/esm/obsidian/components/plugin-notice-component.d.mts +81 -8
  103. package/dist/lib/esm/obsidian/components/plugin-notice-component.mjs +163 -23
  104. package/dist/lib/esm/obsidian/css-class.d.mts +13 -0
  105. package/dist/lib/esm/obsidian/css-class.mjs +4 -1
  106. package/dist/lib/esm/obsidian/desktop-demo-vault-opener.d.mts +45 -0
  107. package/dist/lib/esm/obsidian/desktop-demo-vault-opener.mjs +121 -0
  108. package/dist/lib/esm/obsidian/desktop-trusted-input.d.mts +135 -0
  109. package/dist/lib/esm/obsidian/desktop-trusted-input.mjs +103 -0
  110. package/dist/lib/esm/obsidian/i18n/locales/en.d.mts +2 -0
  111. package/dist/lib/esm/obsidian/i18n/locales/en.mjs +3 -1
  112. package/dist/lib/esm/obsidian/i18n/locales/translations-map.d.mts +2 -0
  113. package/dist/lib/esm/obsidian/index.d.mts +3 -0
  114. package/dist/lib/esm/obsidian/index.mjs +7 -1
  115. package/dist/lib/esm/obsidian/link.mjs +3 -3
  116. package/dist/lib/esm/obsidian/modals/index.d.mts +1 -0
  117. package/dist/lib/esm/obsidian/modals/index.mjs +3 -1
  118. package/dist/lib/esm/obsidian/modals/minimizable-modal.d.mts +18 -3
  119. package/dist/lib/esm/obsidian/modals/minimizable-modal.mjs +17 -3
  120. package/dist/lib/esm/obsidian/modals/select-option.d.mts +65 -0
  121. package/dist/lib/esm/obsidian/modals/select-option.mjs +77 -0
  122. package/dist/lib/esm/obsidian/plugin/obsidian-plugin-repo-paths.d.mts +6 -0
  123. package/dist/lib/esm/obsidian/plugin/obsidian-plugin-repo-paths.mjs +4 -1
  124. package/dist/lib/esm/obsidian/plugin/plugin.d.mts +17 -0
  125. package/dist/lib/esm/obsidian/plugin/plugin.mjs +50 -3
  126. package/dist/lib/esm/obsidian/workspace.d.mts +10 -0
  127. package/dist/lib/esm/obsidian/workspace.mjs +7 -1
  128. package/dist/lib/esm/path.d.mts +1 -1
  129. package/dist/lib/esm/path.mjs +3 -3
  130. package/dist/lib/esm/script-utils/demo-vault.d.mts +23 -0
  131. package/dist/lib/esm/script-utils/demo-vault.mjs +63 -0
  132. package/dist/lib/esm/script-utils/exec.d.mts +20 -0
  133. package/dist/lib/esm/script-utils/exec.mjs +25 -5
  134. package/dist/lib/esm/script-utils/index.d.mts +2 -0
  135. package/dist/lib/esm/script-utils/index.mjs +6 -2
  136. package/dist/lib/esm/script-utils/linters/eslint-no-restricted-syntax.mjs +1 -5
  137. package/dist/lib/esm/script-utils/obsidian-dev-utils-repo-paths.d.mts +2 -0
  138. package/dist/lib/esm/script-utils/obsidian-dev-utils-repo-paths.mjs +2 -1
  139. package/dist/lib/esm/script-utils/version.d.mts +8 -0
  140. package/dist/lib/esm/script-utils/version.mjs +8 -1
  141. package/dist/lib/esm/script-utils/warnings-as-errors.d.mts +27 -0
  142. package/dist/lib/esm/script-utils/warnings-as-errors.mjs +38 -0
  143. package/dist/lib/esm/setup.d.mts +29 -7
  144. package/dist/lib/esm/setup.mjs +78 -4
  145. package/dist/lib/esm/string.d.mts +11 -1
  146. package/dist/lib/esm/string.mjs +5 -3
  147. package/dist/styles.css +33 -3
  148. package/obsidian/command-handlers/open-demo-vault-command-handler/package.json +6 -0
  149. package/obsidian/community-plugins/package.json +6 -0
  150. package/obsidian/desktop-demo-vault-opener/package.json +6 -0
  151. package/obsidian/desktop-trusted-input/package.json +6 -0
  152. package/obsidian/modals/select-option/package.json +6 -0
  153. package/package.json +6 -7
  154. package/script-utils/demo-vault/package.json +6 -0
  155. package/script-utils/warnings-as-errors/package.json +6 -0
  156. /package/obsidian/@types/{Dataview → dataview}/api/data-array/package.json +0 -0
  157. /package/obsidian/@types/{Dataview → dataview}/api/extensions/package.json +0 -0
  158. /package/obsidian/@types/{Dataview → dataview}/api/inline-api/package.json +0 -0
  159. /package/obsidian/@types/{Dataview → dataview}/api/plugin-api/package.json +0 -0
  160. /package/obsidian/@types/{Dataview → dataview}/api/result/package.json +0 -0
  161. /package/obsidian/@types/{Dataview → dataview}/data-import/common/package.json +0 -0
  162. /package/obsidian/@types/{Dataview → dataview}/data-import/csv/package.json +0 -0
  163. /package/obsidian/@types/{Dataview → dataview}/data-import/inline-field/package.json +0 -0
  164. /package/obsidian/@types/{Dataview → dataview}/data-import/markdown-file/package.json +0 -0
  165. /package/obsidian/@types/{Dataview → dataview}/data-import/persister/package.json +0 -0
  166. /package/obsidian/@types/{Dataview → dataview}/data-import/web-worker/import-entry/package.json +0 -0
  167. /package/obsidian/@types/{Dataview → dataview}/data-import/web-worker/import-impl/package.json +0 -0
  168. /package/obsidian/@types/{Dataview → dataview}/data-import/web-worker/import-manager/package.json +0 -0
  169. /package/obsidian/@types/{Dataview → dataview}/data-index/index/package.json +0 -0
  170. /package/obsidian/@types/{Dataview → dataview}/data-index/package.json +0 -0
  171. /package/obsidian/@types/{Dataview → dataview}/data-index/resolver/package.json +0 -0
  172. /package/obsidian/@types/{Dataview → dataview}/data-index/source/package.json +0 -0
  173. /package/obsidian/@types/{Dataview → dataview}/data-model/markdown/package.json +0 -0
  174. /package/obsidian/@types/{Dataview → dataview}/data-model/serialized/markdown/package.json +0 -0
  175. /package/obsidian/@types/{Dataview → dataview}/data-model/transferable/package.json +0 -0
  176. /package/obsidian/@types/{Dataview → dataview}/data-model/value/package.json +0 -0
  177. /package/obsidian/@types/{Dataview → dataview}/expression/binaryop/package.json +0 -0
  178. /package/obsidian/@types/{Dataview → dataview}/expression/context/package.json +0 -0
  179. /package/obsidian/@types/{Dataview → dataview}/expression/field/package.json +0 -0
  180. /package/obsidian/@types/{Dataview → dataview}/expression/functions/package.json +0 -0
  181. /package/obsidian/@types/{Dataview → dataview}/expression/parse/package.json +0 -0
  182. /package/obsidian/@types/{Dataview → dataview}/index/package.json +0 -0
  183. /package/obsidian/@types/{Dataview → dataview}/main/package.json +0 -0
  184. /package/obsidian/@types/{Dataview → dataview}/package.json +0 -0
  185. /package/obsidian/@types/{Dataview → dataview}/query/engine/package.json +0 -0
  186. /package/obsidian/@types/{Dataview → dataview}/query/parse/package.json +0 -0
  187. /package/obsidian/@types/{Dataview → dataview}/query/query/package.json +0 -0
  188. /package/obsidian/@types/{Dataview → dataview}/settings/package.json +0 -0
  189. /package/obsidian/@types/{Dataview → dataview}/typings/obsidian-ex/package.json +0 -0
  190. /package/obsidian/@types/{Dataview → dataview}/typings/workers/package.json +0 -0
  191. /package/obsidian/@types/{Dataview → dataview}/ui/export/markdown/package.json +0 -0
  192. /package/obsidian/@types/{Dataview → dataview}/ui/lp-render/package.json +0 -0
  193. /package/obsidian/@types/{Dataview → dataview}/ui/markdown/package.json +0 -0
  194. /package/obsidian/@types/{Dataview → dataview}/ui/refreshable-view/package.json +0 -0
  195. /package/obsidian/@types/{Dataview → dataview}/ui/render/package.json +0 -0
  196. /package/obsidian/@types/{Dataview → dataview}/ui/views/calendar-view/package.json +0 -0
  197. /package/obsidian/@types/{Dataview → dataview}/ui/views/inline-field-live-preview/package.json +0 -0
  198. /package/obsidian/@types/{Dataview → dataview}/ui/views/inline-view/package.json +0 -0
  199. /package/obsidian/@types/{Dataview → dataview}/ui/views/js-view/package.json +0 -0
  200. /package/obsidian/@types/{Dataview → dataview}/ui/views/list-view/package.json +0 -0
  201. /package/obsidian/@types/{Dataview → dataview}/ui/views/table-view/package.json +0 -0
  202. /package/obsidian/@types/{Dataview → dataview}/ui/views/task-view/package.json +0 -0
  203. /package/obsidian/@types/{Dataview → dataview}/util/hash/package.json +0 -0
  204. /package/obsidian/@types/{Dataview → dataview}/util/locale/package.json +0 -0
  205. /package/obsidian/@types/{Dataview → dataview}/util/media/package.json +0 -0
  206. /package/obsidian/@types/{Dataview → dataview}/util/normalize/package.json +0 -0
  207. /package/obsidian/{App → app}/package.json +0 -0
  208. /package/obsidian/{Backlink → backlink}/package.json +0 -0
  209. /package/obsidian/{Callout → callout}/package.json +0 -0
  210. /package/obsidian/{Components → components}/abort-signal-component/package.json +0 -0
  211. /package/obsidian/{Components → components}/all-windows-event-component/package.json +0 -0
  212. /package/obsidian/{Components → components}/async-error-handler-component/package.json +0 -0
  213. /package/obsidian/{Components → components}/async-events-component/package.json +0 -0
  214. /package/obsidian/{Components → components}/case-insensitive-file-index-component/package.json +0 -0
  215. /package/obsidian/{Components → components}/component-ex/package.json +0 -0
  216. /package/obsidian/{Components → components}/console-debug-component/package.json +0 -0
  217. /package/obsidian/{Components → components}/disposable-component/package.json +0 -0
  218. /package/obsidian/{Components → components}/embed-extensions-component/package.json +0 -0
  219. /package/obsidian/{Components → components}/generate-markdown-link-default-params-component/package.json +0 -0
  220. /package/obsidian/{Components → components}/index/package.json +0 -0
  221. /package/obsidian/{Components → components}/layout-ready-component/package.json +0 -0
  222. /package/obsidian/{Components → components}/menu-event-registrar-component/package.json +0 -0
  223. /package/obsidian/{Components → components}/monkey-around-component/package.json +0 -0
  224. /package/obsidian/{Components → components}/package.json +0 -0
  225. /package/obsidian/{Components → components}/plugin-context-component/package.json +0 -0
  226. /package/obsidian/{Components → components}/plugin-notice-component/package.json +0 -0
  227. /package/obsidian/{Components → components}/plugin-settings-component/package.json +0 -0
  228. /package/obsidian/{Components → components}/plugin-settings-tab-component/package.json +0 -0
  229. /package/obsidian/{Components → components}/registry-component/package.json +0 -0
  230. /package/obsidian/{Components → components}/rename-delete-handler-component/package.json +0 -0
  231. /package/obsidian/{Dataview → dataview}/package.json +0 -0
  232. /package/obsidian/{Editor → editor}/package.json +0 -0
  233. /package/obsidian/{Frontmatter → frontmatter}/package.json +0 -0
  234. /package/obsidian/{Link → link}/package.json +0 -0
  235. /package/obsidian/{Logger → logger}/package.json +0 -0
  236. /package/obsidian/{Loop → loop}/package.json +0 -0
  237. /package/obsidian/{Markdown → markdown}/package.json +0 -0
  238. /package/obsidian/{Modals/Alert → modals/alert}/package.json +0 -0
  239. /package/obsidian/{Modals/Confirm → modals/confirm}/package.json +0 -0
  240. /package/obsidian/{Modals → modals}/index/package.json +0 -0
  241. /package/obsidian/{Modals → modals}/minimizable-modal/package.json +0 -0
  242. /package/obsidian/{Modals → modals}/modal/package.json +0 -0
  243. /package/obsidian/{Modals → modals}/package.json +0 -0
  244. /package/obsidian/{Modals/Prompt → modals/prompt}/package.json +0 -0
  245. /package/obsidian/{Modals → modals}/select-item/package.json +0 -0
  246. /package/obsidian/{Modals → modals}/suggest-modal-command-builder/package.json +0 -0
  247. /package/obsidian/{Pdf → pdf}/package.json +0 -0
  248. /package/obsidian/{Plugin → plugin}/index/package.json +0 -0
  249. /package/obsidian/{Plugin → plugin}/obsidian-plugin-repo-paths/package.json +0 -0
  250. /package/obsidian/{Plugin → plugin}/package.json +0 -0
  251. /package/obsidian/{Plugin/Plugin → plugin/plugin}/package.json +0 -0
  252. /package/obsidian/{Plugin → plugin}/plugin-context/package.json +0 -0
  253. /package/obsidian/{Plugin → plugin}/plugin-event-source/package.json +0 -0
  254. /package/obsidian/{Plugin → plugin}/plugin-settings-tab/package.json +0 -0
  255. /package/obsidian/{Queue → queue}/package.json +0 -0
  256. /package/obsidian/{React → react}/app-context/package.json +0 -0
  257. /package/obsidian/{React → react}/index/package.json +0 -0
  258. /package/obsidian/{React → react}/package.json +0 -0
  259. /package/obsidian/{Reference → reference}/package.json +0 -0
  260. /package/obsidian/{Validation → validation}/package.json +0 -0
  261. /package/obsidian/{Vault → vault}/package.json +0 -0
  262. /package/obsidian/{Workspace → workspace}/package.json +0 -0
  263. /package/{Transformers → transformers}/date-transformer/package.json +0 -0
  264. /package/{Transformers → transformers}/duration-transformer/package.json +0 -0
  265. /package/{Transformers → transformers}/group-transformer/package.json +0 -0
  266. /package/{Transformers → transformers}/index/package.json +0 -0
  267. /package/{Transformers → transformers}/map-transformer/package.json +0 -0
  268. /package/{Transformers → transformers}/package.json +0 -0
  269. /package/{Transformers → transformers}/set-transformer/package.json +0 -0
  270. /package/{Transformers → transformers}/skip-private-property-transformer/package.json +0 -0
  271. /package/{Transformers/Transformer → transformers/transformer}/package.json +0 -0
  272. /package/{Transformers → transformers}/two-way-map-transformer/package.json +0 -0
  273. /package/{Transformers → transformers}/typed-transformer/package.json +0 -0
@@ -4,6 +4,8 @@
4
4
  *
5
5
  * Component that manages displaying notices to the user.
6
6
  */
7
+ import type { App } from 'obsidian';
8
+ import type { Promisable } from 'type-fest';
7
9
  import { Notice } from 'obsidian';
8
10
  import type { ValueProvider } from '../../value-provider.mjs';
9
11
  import { ComponentEx } from './component-ex.mjs';
@@ -64,20 +66,64 @@ export interface PluginNoticeComponentShowNoticeOptions {
64
66
  * @default `false`
65
67
  */
66
68
  readonly isPermanent?: boolean;
69
+ /**
70
+ * Whether the notice occupies the single per-plugin reusable slot.
71
+ *
72
+ * A reusable notice takes the shared slot: the next reusable notice hides it, and it is hidden on unload.
73
+ * A non-reusable (standalone) notice is not placed in the slot — it never hides, and is never hidden by, a
74
+ * reusable notice; multiple standalone notices coexist. Standalone notices are still hidden together on unload.
75
+ *
76
+ * A permanent notice must be reusable ({@link PluginNoticeComponentShowNoticeOptions.isPermanent} implies
77
+ * `isReusable`); passing `isReusable: false` together with `isPermanent: true` throws.
78
+ *
79
+ * @default `true`
80
+ */
81
+ readonly isReusable?: boolean;
82
+ /**
83
+ * A callback invoked when the notice is hidden — whether by the user closing it, by a later reusable
84
+ * notice replacing it, by its duration elapsing, or on component unload. It runs at most once per
85
+ * notice. An async callback is run fire-and-forget (its rejection surfaces through the async-error
86
+ * pipeline).
87
+ */
88
+ onHide?(this: void): Promisable<void>;
89
+ /**
90
+ * Whether the notice is hard to close: it does not dismiss on any stray click, and instead shows a
91
+ * close (X) button whose click opens a confirmation modal, dismissing the notice only if confirmed.
92
+ *
93
+ * A hard-to-close notice is shown with an infinite duration and is standalone (implies
94
+ * {@link PluginNoticeComponentShowNoticeOptions.isReusable} `= false`), so a later notice never
95
+ * silently replaces it; passing `isReusable: true` together with `requiresCloseConfirmation: true`
96
+ * throws.
97
+ *
98
+ * @default `false`
99
+ */
100
+ readonly requiresCloseConfirmation?: boolean;
101
+ }
102
+ interface PluginNoticeComponentConstructorParams {
103
+ readonly app: App;
104
+ readonly pluginName: string;
67
105
  }
68
106
  /**
69
107
  * Manages showing plugin notices. Automatically hides the previous notice when a new one is shown.
70
108
  */
71
109
  export declare class PluginNoticeComponent extends ComponentEx {
110
+ /**
111
+ * The Obsidian app instance.
112
+ */
113
+ protected readonly app: App;
114
+ /**
115
+ * The plugin name (shown as prefix in notices).
116
+ */
72
117
  protected readonly pluginName: string;
73
118
  private notice;
74
119
  private readonly pendingTimerCancellations;
120
+ private readonly standaloneNotices;
75
121
  /**
76
122
  * Creates a new plugin notice component.
77
123
  *
78
- * @param pluginName - The plugin name (shown as prefix in notices).
124
+ * @param params - The constructor parameters.
79
125
  */
80
- constructor(pluginName: string);
126
+ constructor(params: PluginNoticeComponentConstructorParams);
81
127
  /**
82
128
  * Dismisses the permanent notice left over from a previous load (e.g. a previous plugin session) on load.
83
129
  */
@@ -116,6 +162,14 @@ export declare class PluginNoticeComponent extends ComponentEx {
116
162
  * timer) when disposed and lets the content be updated while it is shown.
117
163
  */
118
164
  showNoticeAfterDelay(params: PluginNoticeComponentShowNoticeAfterDelayParams): PluginNoticeComponentDelayedNotice;
165
+ /**
166
+ * Appends a close (X) button to the notice content. Clicking it opens a confirmation modal and, only
167
+ * if confirmed, hides the notice and drops it from the standalone-notice tracking set.
168
+ *
169
+ * @param contentEl - The notice content wrapper to append the button to.
170
+ * @param getNotice - Resolves the notice to hide when the close is confirmed.
171
+ */
172
+ private appendCloseButton;
119
173
  /**
120
174
  * Builds the message for a delayed notice: the resolved content, optionally followed by a Cancel
121
175
  * button that aborts the provided controller when clicked.
@@ -130,7 +184,7 @@ export declare class PluginNoticeComponent extends ComponentEx {
130
184
  * element; the container intercepts clicks originating on an interactive element (a link, button,
131
185
  * input, etc.) and stops them there, so the element's own handler still runs but the notice stays.
132
186
  *
133
- * @param message - The message to display after the plugin name prefix.
187
+ * @param params - The parameters.
134
188
  * @returns A {@link DocumentFragment} holding the wrapped, prefixed notice content.
135
189
  */
136
190
  private buildNoticeContent;
@@ -144,15 +198,34 @@ export declare class PluginNoticeComponent extends ComponentEx {
144
198
  private buildPrefixedMessage;
145
199
  private getPermanentNotice;
146
200
  private getPermanentNotices;
201
+ /**
202
+ * Makes a notice hard to close: marks its outer element (so the CSS neutralizes its padding) and
203
+ * installs a capture-phase click guard that stops every click except on the close button from
204
+ * reaching Obsidian's own dismiss handler.
205
+ *
206
+ * @param notice - The notice to guard.
207
+ * @param requiresCloseConfirmation - Whether the notice requires close confirmation; when `false`,
208
+ * nothing is installed.
209
+ */
210
+ private installCloseConfirmationGuards;
147
211
  private setPermanentNotice;
148
212
  /**
149
- * Shows a notice with the given duration, replacing the current notice, and optionally registers it
150
- * as this plugin's permanent notice.
213
+ * Shows a notice with the given duration. A reusable notice replaces the current reusable notice (and
214
+ * is optionally registered as this plugin's permanent notice); a standalone notice is tracked
215
+ * separately, leaving the reusable slot untouched.
151
216
  *
152
- * @param message - The message to display.
153
- * @param durationInMilliseconds - The notice duration; `0` keeps it until it is hidden explicitly.
154
- * @param shouldRegisterAsPermanent - Whether to track the notice as this plugin's permanent notice.
217
+ * @param params - The parameters.
155
218
  * @returns The created notice.
156
219
  */
157
220
  private showNoticeWithDuration;
221
+ /**
222
+ * Wraps a notice's `hide` so the given callback runs the first time the notice is hidden — by the
223
+ * user, by a replacing notice, by its duration elapsing, or on unload. Does nothing when no callback
224
+ * is given.
225
+ *
226
+ * @param notice - The notice whose `hide` to wrap.
227
+ * @param onHide - The callback to invoke on the first hide, or `undefined` to skip wrapping.
228
+ */
229
+ private wireOnHide;
158
230
  }
231
+ export {};
@@ -23,33 +23,46 @@ if you want to view the source, please visit the github repository of this plugi
23
23
 
24
24
  import {
25
25
  ButtonComponent,
26
- Notice
26
+ Notice,
27
+ setIcon
27
28
  } from "obsidian";
28
29
  import { invokeAsyncSafely } from "../../async.mjs";
29
30
  import { normalizeOptionalProperties } from "../../object-utils.mjs";
30
31
  import { getObsidianDevUtilsState } from "../../obsidian-dev-utils-state.mjs";
32
+ import { ensureNonNullable } from "../../type-guards.mjs";
31
33
  import { resolveValue } from "../../value-provider.mjs";
32
34
  import { CssClass } from "../css-class.mjs";
33
35
  import { t } from "../i18n/i18n.mjs";
36
+ import { confirm } from "../modals/confirm.mjs";
34
37
  import { addPluginCssClasses } from "../plugin/plugin-context.mjs";
35
38
  import { ComponentEx } from "./component-ex.mjs";
39
+ import { MonkeyAroundComponent } from "./monkey-around-component.mjs";
36
40
  const PERMANENT_NOTICES_STATE_KEY = "plugin-notice-component:permanent-notices";
37
41
  const PERMANENT_NOTICE_DURATION_IN_MILLISECONDS = 0;
38
42
  const DEFAULT_DELAY_BEFORE_SHOW_IN_MILLISECONDS = 500;
39
43
  const INTERACTIVE_ELEMENT_SELECTOR = 'a, button, input, select, textarea, label, [contenteditable="true"], [role="button"], [role="link"], [role="checkbox"], [role="tab"], [role="menuitem"]';
40
44
  class PluginNoticeComponent extends ComponentEx {
45
+ /**
46
+ * The Obsidian app instance.
47
+ */
48
+ app;
49
+ /**
50
+ * The plugin name (shown as prefix in notices).
51
+ */
52
+ pluginName;
53
+ notice = null;
54
+ pendingTimerCancellations = /* @__PURE__ */ new Set();
55
+ standaloneNotices = /* @__PURE__ */ new Set();
41
56
  /**
42
57
  * Creates a new plugin notice component.
43
58
  *
44
- * @param pluginName - The plugin name (shown as prefix in notices).
59
+ * @param params - The constructor parameters.
45
60
  */
46
- constructor(pluginName) {
61
+ constructor(params) {
47
62
  super();
48
- this.pluginName = pluginName;
63
+ this.app = params.app;
64
+ this.pluginName = params.pluginName;
49
65
  }
50
- pluginName;
51
- notice = null;
52
- pendingTimerCancellations = /* @__PURE__ */ new Set();
53
66
  /**
54
67
  * Dismisses the permanent notice left over from a previous load (e.g. a previous plugin session) on load.
55
68
  */
@@ -69,6 +82,10 @@ class PluginNoticeComponent extends ComponentEx {
69
82
  if (this.getPermanentNotice() !== this.notice) {
70
83
  this.notice?.hide();
71
84
  }
85
+ for (const standaloneNotice of this.standaloneNotices) {
86
+ standaloneNotice.hide();
87
+ }
88
+ this.standaloneNotices.clear();
72
89
  }
73
90
  /**
74
91
  * Displays a notice message to the user.
@@ -79,7 +96,23 @@ class PluginNoticeComponent extends ComponentEx {
79
96
  */
80
97
  showNotice(message, options) {
81
98
  const isPermanent = options?.isPermanent ?? false;
82
- return this.showNoticeWithDuration(message, isPermanent ? PERMANENT_NOTICE_DURATION_IN_MILLISECONDS : void 0, isPermanent);
99
+ const requiresCloseConfirmation = options?.requiresCloseConfirmation ?? false;
100
+ const isReusable = options?.isReusable ?? !requiresCloseConfirmation;
101
+ if (options?.isReusable === true && requiresCloseConfirmation) {
102
+ throw new Error("A notice that requires close confirmation cannot be reusable.");
103
+ }
104
+ if (options?.isReusable === false && isPermanent) {
105
+ throw new Error("A permanent notice must be reusable.");
106
+ }
107
+ const durationInMilliseconds = isPermanent || requiresCloseConfirmation ? PERMANENT_NOTICE_DURATION_IN_MILLISECONDS : null;
108
+ return this.showNoticeWithDuration({
109
+ durationInMilliseconds,
110
+ isReusable,
111
+ message,
112
+ onHide: options?.onHide,
113
+ requiresCloseConfirmation,
114
+ shouldRegisterAsPermanent: isPermanent
115
+ });
83
116
  }
84
117
  /**
85
118
  * Shows a notice describing a long-running operation, but only once the operation has run for longer
@@ -123,14 +156,21 @@ class PluginNoticeComponent extends ComponentEx {
123
156
  if (isDisposed) {
124
157
  return;
125
158
  }
126
- shownNotice = this.showNoticeWithDuration(buildDelayedMessage(resolvedContent), PERMANENT_NOTICE_DURATION_IN_MILLISECONDS, false);
159
+ shownNotice = this.showNoticeWithDuration({
160
+ durationInMilliseconds: PERMANENT_NOTICE_DURATION_IN_MILLISECONDS,
161
+ isReusable: true,
162
+ message: buildDelayedMessage(resolvedContent),
163
+ onHide: void 0,
164
+ requiresCloseConfirmation: false,
165
+ shouldRegisterAsPermanent: false
166
+ });
127
167
  });
128
168
  }, params.delayInMilliseconds ?? DEFAULT_DELAY_BEFORE_SHOW_IN_MILLISECONDS);
129
169
  this.pendingTimerCancellations.add(cancelPendingTimer);
130
170
  return {
131
171
  setContent: (content) => {
132
172
  currentContent = content;
133
- shownNotice?.setMessage(this.buildNoticeContent(buildDelayedMessage(content)));
173
+ shownNotice?.setMessage(this.buildNoticeContent({ message: buildDelayedMessage(content) }));
134
174
  },
135
175
  [Symbol.dispose]: () => {
136
176
  isDisposed = true;
@@ -142,6 +182,35 @@ class PluginNoticeComponent extends ComponentEx {
142
182
  }
143
183
  };
144
184
  }
185
+ /**
186
+ * Appends a close (X) button to the notice content. Clicking it opens a confirmation modal and, only
187
+ * if confirmed, hides the notice and drops it from the standalone-notice tracking set.
188
+ *
189
+ * @param contentEl - The notice content wrapper to append the button to.
190
+ * @param getNotice - Resolves the notice to hide when the close is confirmed.
191
+ */
192
+ appendCloseButton(contentEl, getNotice) {
193
+ const closeButtonEl = contentEl.createEl("button", {
194
+ attr: { "aria-label": t(($) => $.obsidianDevUtils.notices.closeAriaLabel) }
195
+ });
196
+ addPluginCssClasses(closeButtonEl, CssClass.PluginNoticeCloseButton);
197
+ setIcon(closeButtonEl, "x");
198
+ closeButtonEl.addEventListener("click", (evt) => {
199
+ evt.stopPropagation();
200
+ invokeAsyncSafely(async () => {
201
+ const isConfirmed = await confirm({
202
+ app: this.app,
203
+ message: t(($) => $.obsidianDevUtils.notices.closeConfirmMessage)
204
+ });
205
+ if (!isConfirmed) {
206
+ return;
207
+ }
208
+ const notice = ensureNonNullable(getNotice());
209
+ notice.hide();
210
+ this.standaloneNotices.delete(notice);
211
+ });
212
+ });
213
+ }
145
214
  /**
146
215
  * Builds the message for a delayed notice: the resolved content, optionally followed by a Cancel
147
216
  * button that aborts the provided controller when clicked.
@@ -174,19 +243,27 @@ class PluginNoticeComponent extends ComponentEx {
174
243
  * element; the container intercepts clicks originating on an interactive element (a link, button,
175
244
  * input, etc.) and stops them there, so the element's own handler still runs but the notice stays.
176
245
  *
177
- * @param message - The message to display after the plugin name prefix.
246
+ * @param params - The parameters.
178
247
  * @returns A {@link DocumentFragment} holding the wrapped, prefixed notice content.
179
248
  */
180
- buildNoticeContent(message) {
249
+ buildNoticeContent(params) {
250
+ const { getNotice, message, requiresCloseConfirmation = false } = params;
181
251
  const fragment = createFragment();
182
252
  const contentEl = fragment.createDiv();
183
253
  addPluginCssClasses(contentEl, CssClass.PluginNoticeContent);
184
254
  contentEl.appendChild(this.buildPrefixedMessage(message));
185
255
  contentEl.addEventListener("click", (evt) => {
256
+ if (requiresCloseConfirmation) {
257
+ evt.stopPropagation();
258
+ return;
259
+ }
186
260
  if (evt.target instanceof Element && evt.target.closest(INTERACTIVE_ELEMENT_SELECTOR)) {
187
261
  evt.stopPropagation();
188
262
  }
189
263
  });
264
+ if (requiresCloseConfirmation) {
265
+ this.appendCloseButton(contentEl, ensureNonNullable(getNotice));
266
+ }
190
267
  return fragment;
191
268
  }
192
269
  /**
@@ -218,6 +295,27 @@ class PluginNoticeComponent extends ComponentEx {
218
295
  getPermanentNotices() {
219
296
  return getObsidianDevUtilsState(PERMANENT_NOTICES_STATE_KEY, /* @__PURE__ */ new Map()).value;
220
297
  }
298
+ /**
299
+ * Makes a notice hard to close: marks its outer element (so the CSS neutralizes its padding) and
300
+ * installs a capture-phase click guard that stops every click except on the close button from
301
+ * reaching Obsidian's own dismiss handler.
302
+ *
303
+ * @param notice - The notice to guard.
304
+ * @param requiresCloseConfirmation - Whether the notice requires close confirmation; when `false`,
305
+ * nothing is installed.
306
+ */
307
+ installCloseConfirmationGuards(notice, requiresCloseConfirmation) {
308
+ if (!requiresCloseConfirmation) {
309
+ return;
310
+ }
311
+ addPluginCssClasses(notice.containerEl, CssClass.PluginNoticeRequiresConfirmation);
312
+ notice.containerEl.addEventListener("click", (evt) => {
313
+ if (evt.target instanceof Element && evt.target.closest(`.${CssClass.PluginNoticeCloseButton}`)) {
314
+ return;
315
+ }
316
+ evt.stopPropagation();
317
+ }, { capture: true });
318
+ }
221
319
  setPermanentNotice(notice) {
222
320
  const map = this.getPermanentNotices();
223
321
  if (notice) {
@@ -227,27 +325,69 @@ class PluginNoticeComponent extends ComponentEx {
227
325
  }
228
326
  }
229
327
  /**
230
- * Shows a notice with the given duration, replacing the current notice, and optionally registers it
231
- * as this plugin's permanent notice.
328
+ * Shows a notice with the given duration. A reusable notice replaces the current reusable notice (and
329
+ * is optionally registered as this plugin's permanent notice); a standalone notice is tracked
330
+ * separately, leaving the reusable slot untouched.
232
331
  *
233
- * @param message - The message to display.
234
- * @param durationInMilliseconds - The notice duration; `0` keeps it until it is hidden explicitly.
235
- * @param shouldRegisterAsPermanent - Whether to track the notice as this plugin's permanent notice.
332
+ * @param params - The parameters.
236
333
  * @returns The created notice.
237
334
  */
238
- showNoticeWithDuration(message, durationInMilliseconds, shouldRegisterAsPermanent) {
335
+ showNoticeWithDuration(params) {
336
+ const { durationInMilliseconds, isReusable, message, onHide, requiresCloseConfirmation, shouldRegisterAsPermanent } = params;
337
+ const noticeDurationInMilliseconds = durationInMilliseconds ?? void 0;
338
+ let builtNotice = null;
339
+ const content = this.buildNoticeContent(normalizeOptionalProperties({
340
+ getNotice: requiresCloseConfirmation ? () => builtNotice : void 0,
341
+ message,
342
+ requiresCloseConfirmation
343
+ }));
344
+ if (!isReusable) {
345
+ builtNotice = new Notice(content, noticeDurationInMilliseconds);
346
+ this.installCloseConfirmationGuards(builtNotice, requiresCloseConfirmation);
347
+ this.wireOnHide(builtNotice, onHide);
348
+ this.standaloneNotices.add(builtNotice);
349
+ return builtNotice;
350
+ }
239
351
  this.notice?.hide();
240
- const content = this.buildNoticeContent(message);
241
- this.notice = new Notice(content, durationInMilliseconds);
352
+ builtNotice = new Notice(content, noticeDurationInMilliseconds);
353
+ this.notice = builtNotice;
354
+ this.installCloseConfirmationGuards(builtNotice, requiresCloseConfirmation);
355
+ this.wireOnHide(builtNotice, onHide);
242
356
  if (shouldRegisterAsPermanent) {
243
- this.setPermanentNotice(this.notice);
357
+ this.setPermanentNotice(builtNotice);
244
358
  } else {
245
359
  this.setPermanentNotice(null);
246
360
  }
247
- return this.notice;
361
+ return builtNotice;
362
+ }
363
+ /**
364
+ * Wraps a notice's `hide` so the given callback runs the first time the notice is hidden — by the
365
+ * user, by a replacing notice, by its duration elapsing, or on unload. Does nothing when no callback
366
+ * is given.
367
+ *
368
+ * @param notice - The notice whose `hide` to wrap.
369
+ * @param onHide - The callback to invoke on the first hide, or `undefined` to skip wrapping.
370
+ */
371
+ wireOnHide(notice, onHide) {
372
+ if (!onHide) {
373
+ return;
374
+ }
375
+ const patchComponent = new MonkeyAroundComponent();
376
+ patchComponent.load();
377
+ patchComponent.registerMethodPatch({
378
+ methodName: "hide",
379
+ obj: notice,
380
+ once: true,
381
+ patchHandler: ({ fallback }) => {
382
+ fallback();
383
+ invokeAsyncSafely(async () => {
384
+ await onHide();
385
+ });
386
+ }
387
+ });
248
388
  }
249
389
  }
250
390
  export {
251
391
  PluginNoticeComponent
252
392
  };
253
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vLi4vLi4vc3JjL29ic2lkaWFuL2NvbXBvbmVudHMvcGx1Z2luLW5vdGljZS1jb21wb25lbnQudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQGZpbGVcbiAqXG4gKiBDb21wb25lbnQgdGhhdCBtYW5hZ2VzIGRpc3BsYXlpbmcgbm90aWNlcyB0byB0aGUgdXNlci5cbiAqL1xuXG5pbXBvcnQge1xuICBCdXR0b25Db21wb25lbnQsXG4gIE5vdGljZVxufSBmcm9tICdvYnNpZGlhbic7XG5cbmltcG9ydCB0eXBlIHsgVmFsdWVQcm92aWRlciB9IGZyb20gJy4uLy4uL3ZhbHVlLXByb3ZpZGVyLnRzJztcblxuaW1wb3J0IHsgaW52b2tlQXN5bmNTYWZlbHkgfSBmcm9tICcuLi8uLi9hc3luYy50cyc7XG5pbXBvcnQgeyBub3JtYWxpemVPcHRpb25hbFByb3BlcnRpZXMgfSBmcm9tICcuLi8uLi9vYmplY3QtdXRpbHMudHMnO1xuaW1wb3J0IHsgZ2V0T2JzaWRpYW5EZXZVdGlsc1N0YXRlIH0gZnJvbSAnLi4vLi4vb2JzaWRpYW4tZGV2LXV0aWxzLXN0YXRlLnRzJztcbmltcG9ydCB7IHJlc29sdmVWYWx1ZSB9IGZyb20gJy4uLy4uL3ZhbHVlLXByb3ZpZGVyLnRzJztcbmltcG9ydCB7IENzc0NsYXNzIH0gZnJvbSAnLi4vY3NzLWNsYXNzLnRzJztcbmltcG9ydCB7IHQgfSBmcm9tICcuLi9pMThuL2kxOG4udHMnO1xuaW1wb3J0IHsgYWRkUGx1Z2luQ3NzQ2xhc3NlcyB9IGZyb20gJy4uL3BsdWdpbi9wbHVnaW4tY29udGV4dC50cyc7XG5pbXBvcnQgeyBDb21wb25lbnRFeCB9IGZyb20gJy4vY29tcG9uZW50LWV4LnRzJztcblxuY29uc3QgUEVSTUFORU5UX05PVElDRVNfU1RBVEVfS0VZID0gJ3BsdWdpbi1ub3RpY2UtY29tcG9uZW50OnBlcm1hbmVudC1ub3RpY2VzJztcbmNvbnN0IFBFUk1BTkVOVF9OT1RJQ0VfRFVSQVRJT05fSU5fTUlMTElTRUNPTkRTID0gMDtcbmNvbnN0IERFRkFVTFRfREVMQVlfQkVGT1JFX1NIT1dfSU5fTUlMTElTRUNPTkRTID0gNTAwO1xuXG4vLyBFbGVtZW50cyBhIHVzZXIgY2xpY2tzIHRvIGFjdCBvbiB0aGVtIHJhdGhlciB0aGFuIHRvIGRpc21pc3MgdGhlIG5vdGljZS4gQSBjbGljayBsYW5kaW5nIG9uIChvclxuLy8gSW5zaWRlKSBvbmUgb2YgdGhlc2UgaXMga2VwdCBmcm9tIGJ1YmJsaW5nIHRvIHRoZSBub3RpY2UsIHNvIHRoZSBub3RpY2Ugc3RheXMgb3Blbi5cbmNvbnN0IElOVEVSQUNUSVZFX0VMRU1FTlRfU0VMRUNUT1IgPSAnYSwgYnV0dG9uLCBpbnB1dCwgc2VsZWN0LCB0ZXh0YXJlYSwgbGFiZWwsIFtjb250ZW50ZWRpdGFibGU9XCJ0cnVlXCJdLCBbcm9sZT1cImJ1dHRvblwiXSwgW3JvbGU9XCJsaW5rXCJdLCBbcm9sZT1cImNoZWNrYm94XCJdLCBbcm9sZT1cInRhYlwiXSwgW3JvbGU9XCJtZW51aXRlbVwiXSc7XG5cbi8qKlxuICogQSBoYW5kbGUgdG8gYSBkZWxheWVkIG5vdGljZSBjcmVhdGVkIGJ5IHtAbGluayBQbHVnaW5Ob3RpY2VDb21wb25lbnQuc2hvd05vdGljZUFmdGVyRGVsYXl9LiBJdCBpcyBhXG4gKiB7QGxpbmsgRGlzcG9zYWJsZX0gKHNvIGl0IGNhbiBiZSB1c2VkIHdpdGggYHVzaW5nYCkgdGhhdCBhbHNvIGxldHMgdGhlIGNvbnRlbnQgYmUgdXBkYXRlZCB3aGlsZSB0aGVcbiAqIG5vdGljZSBpcyBzaG93bi5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBQbHVnaW5Ob3RpY2VDb21wb25lbnREZWxheWVkTm90aWNlIGV4dGVuZHMgRGlzcG9zYWJsZSB7XG4gIC8qKlxuICAgKiBSZXBsYWNlcyB0aGUgbm90aWNlIGNvbnRlbnQsIHJlLWFwcGx5aW5nIHRoZSBwbHVnaW4tbmFtZSBwcmVmaXgsIHRoZSBpbnRlcmFjdGl2ZS1jbGljayBndWFyZCwgYW5kXG4gICAqIHRoZSBDYW5jZWwgYnV0dG9uLiBVc2VmdWwgZm9yIHJlcG9ydGluZyBwcm9ncmVzcy4gSWYgdGhlIGRlbGF5IGhhcyBub3QgZWxhcHNlZCB5ZXQsIHRoZSBuZXcgY29udGVudFxuICAgKiBiZWNvbWVzIHdoYXQgaXMgc2hvd24gb25jZSBpdCBkb2VzLlxuICAgKlxuICAgKiBAcGFyYW0gY29udGVudCAtIFRoZSBuZXcgbm90aWNlIGNvbnRlbnQuXG4gICAqL1xuICBzZXRDb250ZW50KGNvbnRlbnQ6IERvY3VtZW50RnJhZ21lbnQgfCBzdHJpbmcpOiB2b2lkO1xufVxuXG4vKipcbiAqIFBhcmFtZXRlcnMgZm9yIHtAbGluayBQbHVnaW5Ob3RpY2VDb21wb25lbnQuc2hvd05vdGljZUFmdGVyRGVsYXl9LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFBsdWdpbk5vdGljZUNvbXBvbmVudFNob3dOb3RpY2VBZnRlckRlbGF5UGFyYW1zIHtcbiAgLyoqXG4gICAqIFdoZW4gcHJvdmlkZWQsIGEgQ2FuY2VsIGJ1dHRvbiBpcyBhcHBlbmRlZCB0byB0aGUgbm90aWNlOyBjbGlja2luZyBpdCBhYm9ydHMgdGhpcyBjb250cm9sbGVyLiBXaGVuXG4gICAqIG9taXR0ZWQsIG5vIENhbmNlbCBidXR0b24gaXMgc2hvd24uXG4gICAqL1xuICByZWFkb25seSBhYm9ydENvbnRyb2xsZXI/OiBBYm9ydENvbnRyb2xsZXI7XG5cbiAgLyoqXG4gICAqIFRoZSB0ZXh0IG9mIHRoZSBDYW5jZWwgYnV0dG9uIHNob3duIHdoZW4ge0BsaW5rIFBsdWdpbk5vdGljZUNvbXBvbmVudFNob3dOb3RpY2VBZnRlckRlbGF5UGFyYW1zLmFib3J0Q29udHJvbGxlcn1cbiAgICogaXMgcHJvdmlkZWQuIFdoZW4gb21pdHRlZCwgdGhlIGxvY2FsaXplZCBgQ2FuY2VsYCBsYWJlbCBpcyB1c2VkLlxuICAgKi9cbiAgcmVhZG9ubHkgY2FuY2VsQnV0dG9uVGV4dD86IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIG5vdGljZSBjb250ZW50LCByZXNvbHZlZCBsYXppbHkgb25seSBpZiB0aGUgZGVsYXkgZWxhcHNlcyBcdTIwMTQgc28gYW4gb3BlcmF0aW9uIHRoYXQgZmluaXNoZXNcbiAgICogc29vbmVyIG5ldmVyIGJ1aWxkcyBpdC5cbiAgICovXG4gIHJlYWRvbmx5IGNvbnRlbnQ6IFZhbHVlUHJvdmlkZXI8RG9jdW1lbnRGcmFnbWVudCB8IHN0cmluZz47XG5cbiAgLyoqXG4gICAqIEhvdyBsb25nIHRoZSBvcGVyYXRpb24gbXVzdCBydW4gYmVmb3JlIHRoZSBub3RpY2UgaXMgc2hvd24uIE9wZXJhdGlvbnMgdGhhdCBmaW5pc2ggc29vbmVyIG5ldmVyXG4gICAqIHNob3cgYSBub3RpY2UsIGF2b2lkaW5nIGEgZGlzdHJhY3RpbmcgZmxhc2guXG4gICAqXG4gICAqIEBkZWZhdWx0IGA1MDBgXG4gICAqL1xuICByZWFkb25seSBkZWxheUluTWlsbGlzZWNvbmRzPzogbnVtYmVyO1xufVxuXG4vKipcbiAqIE9wdGlvbnMgZm9yIHtAbGluayBQbHVnaW5Ob3RpY2VDb21wb25lbnQuc2hvd05vdGljZX0uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUGx1Z2luTm90aWNlQ29tcG9uZW50U2hvd05vdGljZU9wdGlvbnMge1xuICAvKipcbiAgICogV2hldGhlciB0aGUgbm90aWNlIHNob3VsZCBzdGF5IHVudGlsIGl0IGlzIHJlcGxhY2VkLCB0aGUgcGx1Z2luIGlzIHJlbG9hZGVkLCBvciB0aGUgdXNlciBkaXNtaXNzZXMgaXQuXG4gICAqXG4gICAqIEEgcGVybWFuZW50IG5vdGljZSBpcyBzaG93biB3aXRoIGFuIGluZmluaXRlIGR1cmF0aW9uIGFuZCBpcyBub3QgaGlkZGVuIHdoZW4gdGhlIGNvbXBvbmVudCB1bmxvYWRzLCBzbyBpdCBjYW5cbiAgICogY29tbXVuaWNhdGUgc3RhdGUgdGhhdCBvdXRsaXZlcyB0aGUgcGx1Z2luIChlLmcuIGEgY2xlYW51cCB0aGF0IHJlcXVpcmVzIGEgcmVsb2FkKS4gVGhlcmUgaXMgYXQgbW9zdCBvbmUgcGVybWFuZW50XG4gICAqIG5vdGljZSBwZXIgcGx1Z2luOiBpdCBpcyBoaWRkZW4gYnkgdGhlIG5leHQge0BsaW5rIFBsdWdpbk5vdGljZUNvbXBvbmVudC5zaG93Tm90aWNlfSBjYWxsIGFuZCBkaXNtaXNzZWRcbiAgICogYXV0b21hdGljYWxseSB0aGUgbmV4dCB0aW1lIHRoZSBjb21wb25lbnQgbG9hZHMgKGkuZS4gd2hlbiB0aGUgcGx1Z2luIGlzIHJlLWVuYWJsZWQpLlxuICAgKlxuICAgKiBAZGVmYXVsdCBgZmFsc2VgXG4gICAqL1xuICByZWFkb25seSBpc1Blcm1hbmVudD86IGJvb2xlYW47XG59XG5cbmludGVyZmFjZSBQbHVnaW5Ob3RpY2VDb21wb25lbnRCdWlsZERlbGF5ZWROb3RpY2VNZXNzYWdlUGFyYW1zIHtcbiAgcmVhZG9ubHkgYWJvcnRDb250cm9sbGVyPzogQWJvcnRDb250cm9sbGVyO1xuICByZWFkb25seSBjYW5jZWxCdXR0b25UZXh0Pzogc3RyaW5nO1xuICByZWFkb25seSBjb250ZW50OiBEb2N1bWVudEZyYWdtZW50IHwgc3RyaW5nO1xufVxuXG4vKipcbiAqIE1hbmFnZXMgc2hvd2luZyBwbHVnaW4gbm90aWNlcy4gQXV0b21hdGljYWxseSBoaWRlcyB0aGUgcHJldmlvdXMgbm90aWNlIHdoZW4gYSBuZXcgb25lIGlzIHNob3duLlxuICovXG5leHBvcnQgY2xhc3MgUGx1Z2luTm90aWNlQ29tcG9uZW50IGV4dGVuZHMgQ29tcG9uZW50RXgge1xuICBwcml2YXRlIG5vdGljZTogTm90aWNlIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgcmVhZG9ubHkgcGVuZGluZ1RpbWVyQ2FuY2VsbGF0aW9ucyA9IG5ldyBTZXQ8KCkgPT4gdm9pZD4oKTtcblxuICAvKipcbiAgICogQ3JlYXRlcyBhIG5ldyBwbHVnaW4gbm90aWNlIGNvbXBvbmVudC5cbiAgICpcbiAgICogQHBhcmFtIHBsdWdpbk5hbWUgLSBUaGUgcGx1Z2luIG5hbWUgKHNob3duIGFzIHByZWZpeCBpbiBub3RpY2VzKS5cbiAgICovXG4gIHB1YmxpYyBjb25zdHJ1Y3Rvcihwcm90ZWN0ZWQgcmVhZG9ubHkgcGx1Z2luTmFtZTogc3RyaW5nKSB7XG4gICAgc3VwZXIoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEaXNtaXNzZXMgdGhlIHBlcm1hbmVudCBub3RpY2UgbGVmdCBvdmVyIGZyb20gYSBwcmV2aW91cyBsb2FkIChlLmcuIGEgcHJldmlvdXMgcGx1Z2luIHNlc3Npb24pIG9uIGxvYWQuXG4gICAqL1xuICBwdWJsaWMgb3ZlcnJpZGUgb25sb2FkKCk6IHZvaWQge1xuICAgIHN1cGVyLm9ubG9hZCgpO1xuICAgIGNvbnN0IHBlcm1hbmVudE5vdGljZSA9IHRoaXMuZ2V0UGVybWFuZW50Tm90aWNlKCk7XG4gICAgcGVybWFuZW50Tm90aWNlPy5oaWRlKCk7XG4gICAgdGhpcy5zZXRQZXJtYW5lbnROb3RpY2UobnVsbCk7XG4gIH1cblxuICAvKipcbiAgICogSGlkZXMgdGhlIGN1cnJlbnQgbm90aWNlIG9uIHVubG9hZCwgdW5sZXNzIGl0IGlzIHRoZSBwZXJtYW5lbnQgbm90aWNlICh3aGljaCBpcyBtZWFudCB0byBvdXRsaXZlIHRoZSBwbHVnaW4pLlxuICAgKi9cbiAgcHVibGljIG92ZXJyaWRlIG9udW5sb2FkKCk6IHZvaWQge1xuICAgIC8vIENhbmNlbCBhbnkgZGVsYXllZCBub3RpY2Ugd2hvc2UgdGltZXIgaGFzIG5vdCBmaXJlZCB5ZXQsIHNvIGl0IG5ldmVyIGFwcGVhcnMgYWZ0ZXIgdW5sb2FkLlxuICAgIGZvciAoY29uc3QgY2FuY2VsUGVuZGluZ1RpbWVyIG9mIFsuLi50aGlzLnBlbmRpbmdUaW1lckNhbmNlbGxhdGlvbnNdKSB7XG4gICAgICBjYW5jZWxQZW5kaW5nVGltZXIoKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuZ2V0UGVybWFuZW50Tm90aWNlKCkgIT09IHRoaXMubm90aWNlKSB7XG4gICAgICB0aGlzLm5vdGljZT8uaGlkZSgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBEaXNwbGF5cyBhIG5vdGljZSBtZXNzYWdlIHRvIHRoZSB1c2VyLlxuICAgKlxuICAgKiBAcGFyYW0gbWVzc2FnZSAtIFRoZSBtZXNzYWdlIHRvIGRpc3BsYXkuXG4gICAqIEBwYXJhbSBvcHRpb25zIC0gVGhlIG9wdGlvbnMgZm9yIGRpc3BsYXlpbmcgdGhlIG5vdGljZS5cbiAgICogQHJldHVybnMgVGhlIG5vdGljZSBvYmplY3QuXG4gICAqL1xuICBwdWJsaWMgc2hvd05vdGljZShtZXNzYWdlOiBEb2N1bWVudEZyYWdtZW50IHwgc3RyaW5nLCBvcHRpb25zPzogUGx1Z2luTm90aWNlQ29tcG9uZW50U2hvd05vdGljZU9wdGlvbnMpOiBOb3RpY2Uge1xuICAgIGNvbnN0IGlzUGVybWFuZW50ID0gb3B0aW9ucz8uaXNQZXJtYW5lbnQgPz8gZmFsc2U7XG4gICAgcmV0dXJuIHRoaXMuc2hvd05vdGljZVdpdGhEdXJhdGlvbihtZXNzYWdlLCBpc1Blcm1hbmVudCA/IFBFUk1BTkVOVF9OT1RJQ0VfRFVSQVRJT05fSU5fTUlMTElTRUNPTkRTIDogdW5kZWZpbmVkLCBpc1Blcm1hbmVudCk7XG4gIH1cblxuICAvKipcbiAgICogU2hvd3MgYSBub3RpY2UgZGVzY3JpYmluZyBhIGxvbmctcnVubmluZyBvcGVyYXRpb24sIGJ1dCBvbmx5IG9uY2UgdGhlIG9wZXJhdGlvbiBoYXMgcnVuIGZvciBsb25nZXJcbiAgICogdGhhbiB7QGxpbmsgUGx1Z2luTm90aWNlQ29tcG9uZW50U2hvd05vdGljZUFmdGVyRGVsYXlQYXJhbXMuZGVsYXlJbk1pbGxpc2Vjb25kc30gXHUyMDE0IHNvIG9wZXJhdGlvbnNcbiAgICogdGhhdCBmaW5pc2ggc29vbmVyIG5ldmVyIGZsYXNoIGEgbm90aWNlLiBUaGUgbm90aWNlIHN0YXlzIHVudGlsIHRoZSByZXR1cm5lZCB7QGxpbmsgRGlzcG9zYWJsZX0gaXNcbiAgICogZGlzcG9zZWQgKHdoaWNoIGFsc28gY2FuY2VscyB0aGUgcGVuZGluZyB0aW1lciBpZiBpdCBoYXMgbm90IGZpcmVkIHlldCksIHNvIGl0IGNhbiBiZSB1c2VkIHdpdGhcbiAgICogYHVzaW5nYC4gV2hlbiBhbiB7QGxpbmsgUGx1Z2luTm90aWNlQ29tcG9uZW50U2hvd05vdGljZUFmdGVyRGVsYXlQYXJhbXMuYWJvcnRDb250cm9sbGVyfSBpcyBnaXZlbiwgYVxuICAgKiBDYW5jZWwgYnV0dG9uIHRoYXQgYWJvcnRzIGl0IGlzIGFwcGVuZGVkIChhbmQsIGJlaW5nIGludGVyYWN0aXZlLCBkb2VzIG5vdCBkaXNtaXNzIHRoZSBub3RpY2UpLlxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiBgYGB0c1xuICAgKiB1c2luZyBfbm90aWNlID0gcGx1Z2luTm90aWNlQ29tcG9uZW50LnNob3dOb3RpY2VBZnRlckRlbGF5KHtcbiAgICogICBhYm9ydENvbnRyb2xsZXIsXG4gICAqICAgY29udGVudDogKCkgPT4gYnVpbGRQcm9ncmVzc0ZyYWdtZW50KClcbiAgICogfSk7XG4gICAqIGF3YWl0IHJ1bk9wZXJhdGlvbihhYm9ydENvbnRyb2xsZXIuc2lnbmFsKTtcbiAgICogYGBgXG4gICAqXG4gICAqIEBwYXJhbSBwYXJhbXMgLSBUaGUgcGFyYW1ldGVycy5cbiAgICogQHJldHVybnMgQSB7QGxpbmsgUGx1Z2luTm90aWNlQ29tcG9uZW50RGVsYXllZE5vdGljZX0gdGhhdCBoaWRlcyB0aGUgbm90aWNlIChvciBjYW5jZWxzIHRoZSBwZW5kaW5nXG4gICAqIHRpbWVyKSB3aGVuIGRpc3Bvc2VkIGFuZCBsZXRzIHRoZSBjb250ZW50IGJlIHVwZGF0ZWQgd2hpbGUgaXQgaXMgc2hvd24uXG4gICAqL1xuICBwdWJsaWMgc2hvd05vdGljZUFmdGVyRGVsYXkocGFyYW1zOiBQbHVnaW5Ob3RpY2VDb21wb25lbnRTaG93Tm90aWNlQWZ0ZXJEZWxheVBhcmFtcyk6IFBsdWdpbk5vdGljZUNvbXBvbmVudERlbGF5ZWROb3RpY2Uge1xuICAgIGxldCBzaG93bk5vdGljZTogTm90aWNlIHwgbnVsbCA9IG51bGw7XG4gICAgbGV0IGlzRGlzcG9zZWQgPSBmYWxzZTtcbiAgICBsZXQgdGltZXJJZCA9IDA7XG4gICAgbGV0IGN1cnJlbnRDb250ZW50OiBWYWx1ZVByb3ZpZGVyPERvY3VtZW50RnJhZ21lbnQgfCBzdHJpbmc+ID0gcGFyYW1zLmNvbnRlbnQ7XG5cbiAgICBjb25zdCBjYW5jZWxQZW5kaW5nVGltZXIgPSAoKTogdm9pZCA9PiB7XG4gICAgICB3aW5kb3cuY2xlYXJUaW1lb3V0KHRpbWVySWQpO1xuICAgICAgdGhpcy5wZW5kaW5nVGltZXJDYW5jZWxsYXRpb25zLmRlbGV0ZShjYW5jZWxQZW5kaW5nVGltZXIpO1xuICAgIH07XG5cbiAgICBjb25zdCBidWlsZERlbGF5ZWRNZXNzYWdlID0gKGNvbnRlbnQ6IERvY3VtZW50RnJhZ21lbnQgfCBzdHJpbmcpOiBEb2N1bWVudEZyYWdtZW50ID0+XG4gICAgICB0aGlzLmJ1aWxkRGVsYXllZE5vdGljZU1lc3NhZ2Uobm9ybWFsaXplT3B0aW9uYWxQcm9wZXJ0aWVzPFBsdWdpbk5vdGljZUNvbXBvbmVudEJ1aWxkRGVsYXllZE5vdGljZU1lc3NhZ2VQYXJhbXM+KHtcbiAgICAgICAgYWJvcnRDb250cm9sbGVyOiBwYXJhbXMuYWJvcnRDb250cm9sbGVyLFxuICAgICAgICBjYW5jZWxCdXR0b25UZXh0OiBwYXJhbXMuY2FuY2VsQnV0dG9uVGV4dCxcbiAgICAgICAgY29udGVudFxuICAgICAgfSkpO1xuXG4gICAgdGltZXJJZCA9IHdpbmRvdy5zZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIGNhbmNlbFBlbmRpbmdUaW1lcigpO1xuICAgICAgaW52b2tlQXN5bmNTYWZlbHkoYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCByZXNvbHZlZENvbnRlbnQgPSBhd2FpdCByZXNvbHZlVmFsdWUoY3VycmVudENvbnRlbnQsIHt9KTtcbiAgICAgICAgLy8gVGhlIGhhbmRsZSBtYXkgaGF2ZSBiZWVuIGRpc3Bvc2VkIHdoaWxlIHRoZSBjb250ZW50IHdhcyBiZWluZyByZXNvbHZlZDsgZG9uJ3Qgc2hvdyBhIHN0YWxlIG5vdGljZS5cbiAgICAgICAgaWYgKGlzRGlzcG9zZWQpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgc2hvd25Ob3RpY2UgPSB0aGlzLnNob3dOb3RpY2VXaXRoRHVyYXRpb24oYnVpbGREZWxheWVkTWVzc2FnZShyZXNvbHZlZENvbnRlbnQpLCBQRVJNQU5FTlRfTk9USUNFX0RVUkFUSU9OX0lOX01JTExJU0VDT05EUywgZmFsc2UpO1xuICAgICAgfSk7XG4gICAgfSwgcGFyYW1zLmRlbGF5SW5NaWxsaXNlY29uZHMgPz8gREVGQVVMVF9ERUxBWV9CRUZPUkVfU0hPV19JTl9NSUxMSVNFQ09ORFMpO1xuXG4gICAgdGhpcy5wZW5kaW5nVGltZXJDYW5jZWxsYXRpb25zLmFkZChjYW5jZWxQZW5kaW5nVGltZXIpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHNldENvbnRlbnQ6IChjb250ZW50OiBEb2N1bWVudEZyYWdtZW50IHwgc3RyaW5nKTogdm9pZCA9PiB7XG4gICAgICAgIGN1cnJlbnRDb250ZW50ID0gY29udGVudDtcbiAgICAgICAgLy8gUmUtd3JhcCBzbyB0aGUgcHJlZml4LCBpbnRlcmFjdGl2ZSBndWFyZCwgYW5kIENhbmNlbCBidXR0b24gc3Vydml2ZSB0aGUgY29udGVudCBzd2FwLlxuICAgICAgICBzaG93bk5vdGljZT8uc2V0TWVzc2FnZSh0aGlzLmJ1aWxkTm90aWNlQ29udGVudChidWlsZERlbGF5ZWRNZXNzYWdlKGNvbnRlbnQpKSk7XG4gICAgICB9LFxuICAgICAgW1N5bWJvbC5kaXNwb3NlXTogKCk6IHZvaWQgPT4ge1xuICAgICAgICBpc0Rpc3Bvc2VkID0gdHJ1ZTtcbiAgICAgICAgY2FuY2VsUGVuZGluZ1RpbWVyKCk7XG4gICAgICAgIHNob3duTm90aWNlPy5oaWRlKCk7XG4gICAgICAgIGlmICh0aGlzLm5vdGljZSA9PT0gc2hvd25Ob3RpY2UpIHtcbiAgICAgICAgICB0aGlzLm5vdGljZSA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkcyB0aGUgbWVzc2FnZSBmb3IgYSBkZWxheWVkIG5vdGljZTogdGhlIHJlc29sdmVkIGNvbnRlbnQsIG9wdGlvbmFsbHkgZm9sbG93ZWQgYnkgYSBDYW5jZWxcbiAgICogYnV0dG9uIHRoYXQgYWJvcnRzIHRoZSBwcm92aWRlZCBjb250cm9sbGVyIHdoZW4gY2xpY2tlZC5cbiAgICpcbiAgICogQHBhcmFtIHBhcmFtcyAtIFRoZSBwYXJhbWV0ZXJzLlxuICAgKiBAcmV0dXJucyBBIHtAbGluayBEb2N1bWVudEZyYWdtZW50fSBob2xkaW5nIHRoZSBjb250ZW50IGFuZCwgaWYgcmVxdWVzdGVkLCBhIENhbmNlbCBidXR0b24uXG4gICAqL1xuICBwcml2YXRlIGJ1aWxkRGVsYXllZE5vdGljZU1lc3NhZ2UocGFyYW1zOiBQbHVnaW5Ob3RpY2VDb21wb25lbnRCdWlsZERlbGF5ZWROb3RpY2VNZXNzYWdlUGFyYW1zKTogRG9jdW1lbnRGcmFnbWVudCB7XG4gICAgY29uc3QgeyBhYm9ydENvbnRyb2xsZXIsIGNhbmNlbEJ1dHRvblRleHQsIGNvbnRlbnQgfSA9IHBhcmFtcztcbiAgICBjb25zdCBmcmFnbWVudCA9IGNyZWF0ZUZyYWdtZW50KCk7XG4gICAgaWYgKHR5cGVvZiBjb250ZW50ID09PSAnc3RyaW5nJykge1xuICAgICAgZnJhZ21lbnQuYXBwZW5kVGV4dChjb250ZW50KTtcbiAgICB9IGVsc2Uge1xuICAgICAgZnJhZ21lbnQuYXBwZW5kQ2hpbGQoY29udGVudCk7XG4gICAgfVxuXG4gICAgaWYgKGFib3J0Q29udHJvbGxlcikge1xuICAgICAgLy8gYEJ1dHRvbkNvbXBvbmVudGAgcmVxdWlyZXMgYW4gYEhUTUxFbGVtZW50YCBwYXJlbnQsIHNvIGJ1aWxkIGl0IG9uIGEgdGhyb3dhd2F5XG4gICAgICAvLyBEZXRhY2hlZCBlbGVtZW50IGFuZCBtb3ZlIGl0cyBgYnV0dG9uRWxgIGludG8gdGhlIGZyYWdtZW50LlxuICAgICAgY29uc3QgY2FuY2VsQnV0dG9uID0gbmV3IEJ1dHRvbkNvbXBvbmVudChjcmVhdGVEaXYoKSk7XG4gICAgICBjYW5jZWxCdXR0b24uc2V0QnV0dG9uVGV4dChjYW5jZWxCdXR0b25UZXh0ID8/IHQoKCQpID0+ICQub2JzaWRpYW5EZXZVdGlscy5idXR0b25zLmNhbmNlbCkpO1xuICAgICAgYWRkUGx1Z2luQ3NzQ2xhc3NlcyhjYW5jZWxCdXR0b24uYnV0dG9uRWwsIENzc0NsYXNzLkNhbmNlbEJ1dHRvbik7XG4gICAgICAvLyBUaGUgY2xpY2sgaXMgd2lyZWQgdmlhIGBhZGRFdmVudExpc3RlbmVyYCByYXRoZXIgdGhhbiBgQnV0dG9uQ29tcG9uZW50Lm9uQ2xpY2tgIHNvIGl0XG4gICAgICAvLyBCdWJibGVzIHRocm91Z2ggdGhlIGludGVyYWN0aXZlLWVsZW1lbnQgZ3VhcmQgKGtlZXBpbmcgdGhlIG5vdGljZSBvcGVuKSBhbmQgc3RheXNcbiAgICAgIC8vIERpcmVjdGx5IGV4ZXJjaXNhYmxlIHZpYSBhIGRpc3BhdGNoZWQgRE9NIGV2ZW50IGluIHVuaXQgdGVzdHMuXG4gICAgICBjYW5jZWxCdXR0b24uYnV0dG9uRWwuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiB7XG4gICAgICAgIGFib3J0Q29udHJvbGxlci5hYm9ydCgpO1xuICAgICAgfSk7XG4gICAgICBmcmFnbWVudC5hcHBlbmRDaGlsZChjYW5jZWxCdXR0b24uYnV0dG9uRWwpO1xuICAgIH1cbiAgICByZXR1cm4gZnJhZ21lbnQ7XG4gIH1cblxuICAvKipcbiAgICogQnVpbGRzIHRoZSBub3RpY2UgY29udGVudCB3cmFwcGVkIGluIGEgY29udGFpbmVyIHRoYXQga2VlcHMgdGhlIG5vdGljZSBvcGVuIHdoZW4gYW4gaW50ZXJhY3RpdmVcbiAgICogZWxlbWVudCBpbnNpZGUgaXQgaXMgY2xpY2tlZC4gT2JzaWRpYW4gZGlzbWlzc2VzIGEgbm90aWNlIG9uIGFueSBjbGljayB0aGF0IGJ1YmJsZXMgdXAgdG8gaXRzXG4gICAqIGVsZW1lbnQ7IHRoZSBjb250YWluZXIgaW50ZXJjZXB0cyBjbGlja3Mgb3JpZ2luYXRpbmcgb24gYW4gaW50ZXJhY3RpdmUgZWxlbWVudCAoYSBsaW5rLCBidXR0b24sXG4gICAqIGlucHV0LCBldGMuKSBhbmQgc3RvcHMgdGhlbSB0aGVyZSwgc28gdGhlIGVsZW1lbnQncyBvd24gaGFuZGxlciBzdGlsbCBydW5zIGJ1dCB0aGUgbm90aWNlIHN0YXlzLlxuICAgKlxuICAgKiBAcGFyYW0gbWVzc2FnZSAtIFRoZSBtZXNzYWdlIHRvIGRpc3BsYXkgYWZ0ZXIgdGhlIHBsdWdpbiBuYW1lIHByZWZpeC5cbiAgICogQHJldHVybnMgQSB7QGxpbmsgRG9jdW1lbnRGcmFnbWVudH0gaG9sZGluZyB0aGUgd3JhcHBlZCwgcHJlZml4ZWQgbm90aWNlIGNvbnRlbnQuXG4gICAqL1xuICBwcml2YXRlIGJ1aWxkTm90aWNlQ29udGVudChtZXNzYWdlOiBEb2N1bWVudEZyYWdtZW50IHwgc3RyaW5nKTogRG9jdW1lbnRGcmFnbWVudCB7XG4gICAgY29uc3QgZnJhZ21lbnQgPSBjcmVhdGVGcmFnbWVudCgpO1xuICAgIGNvbnN0IGNvbnRlbnRFbCA9IGZyYWdtZW50LmNyZWF0ZURpdigpO1xuICAgIGFkZFBsdWdpbkNzc0NsYXNzZXMoY29udGVudEVsLCBDc3NDbGFzcy5QbHVnaW5Ob3RpY2VDb250ZW50KTtcbiAgICBjb250ZW50RWwuYXBwZW5kQ2hpbGQodGhpcy5idWlsZFByZWZpeGVkTWVzc2FnZShtZXNzYWdlKSk7XG4gICAgY29udGVudEVsLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKGV2dCkgPT4ge1xuICAgICAgaWYgKGV2dC50YXJnZXQgaW5zdGFuY2VvZiBFbGVtZW50ICYmIGV2dC50YXJnZXQuY2xvc2VzdChJTlRFUkFDVElWRV9FTEVNRU5UX1NFTEVDVE9SKSkge1xuICAgICAgICBldnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIGZyYWdtZW50O1xuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkcyB0aGUgbm90aWNlIGNvbnRlbnQsIHByZWZpeGluZyB0aGUgbWVzc2FnZSB3aXRoIHRoZSBwbHVnaW4gbmFtZSBpbiBhIHN0eWxlZCBlbGVtZW50IHNvIGl0IGlzXG4gICAqIHZpc3VhbGx5IGRpc3Rpbmd1aXNoZWQgZnJvbSB0aGUgbWVzc2FnZSBib2R5LlxuICAgKlxuICAgKiBAcGFyYW0gbWVzc2FnZSAtIFRoZSBtZXNzYWdlIHRvIGRpc3BsYXkgYWZ0ZXIgdGhlIHBsdWdpbiBuYW1lIHByZWZpeC5cbiAgICogQHJldHVybnMgQSB7QGxpbmsgRG9jdW1lbnRGcmFnbWVudH0gd2l0aCB0aGUgc3R5bGVkIHBsdWdpbiBuYW1lIHByZWZpeCBmb2xsb3dlZCBieSB0aGUgbWVzc2FnZS5cbiAgICovXG4gIHByaXZhdGUgYnVpbGRQcmVmaXhlZE1lc3NhZ2UobWVzc2FnZTogRG9jdW1lbnRGcmFnbWVudCB8IHN0cmluZyk6IERvY3VtZW50RnJhZ21lbnQge1xuICAgIGNvbnN0IGZyYWdtZW50ID0gY3JlYXRlRnJhZ21lbnQoKTtcbiAgICBjb25zdCBuYW1lRWwgPSBjcmVhdGVTcGFuKHsgdGV4dDogdGhpcy5wbHVnaW5OYW1lIH0pO1xuICAgIGFkZFBsdWdpbkNzc0NsYXNzZXMobmFtZUVsLCBDc3NDbGFzcy5QbHVnaW5Ob3RpY2VOYW1lKTtcbiAgICBmcmFnbWVudC5hcHBlbmRDaGlsZChuYW1lRWwpO1xuICAgIGlmICghdGhpcy5fbG9hZGVkKSB7XG4gICAgICBmcmFnbWVudC5hcHBlbmRUZXh0KCcgKHVubG9hZGVkKScpO1xuICAgIH1cbiAgICBmcmFnbWVudC5hcHBlbmRUZXh0KCdcXG4nKTtcbiAgICBpZiAodHlwZW9mIG1lc3NhZ2UgPT09ICdzdHJpbmcnKSB7XG4gICAgICBmcmFnbWVudC5hcHBlbmRUZXh0KG1lc3NhZ2UpO1xuICAgIH0gZWxzZSB7XG4gICAgICBmcmFnbWVudC5hcHBlbmRDaGlsZChtZXNzYWdlKTtcbiAgICB9XG4gICAgcmV0dXJuIGZyYWdtZW50O1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRQZXJtYW5lbnROb3RpY2UoKTogTm90aWNlIHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0UGVybWFuZW50Tm90aWNlcygpLmdldCh0aGlzLnBsdWdpbk5hbWUpID8/IG51bGw7XG4gIH1cblxuICBwcml2YXRlIGdldFBlcm1hbmVudE5vdGljZXMoKTogTWFwPHN0cmluZywgTm90aWNlPiB7XG4gICAgcmV0dXJuIGdldE9ic2lkaWFuRGV2VXRpbHNTdGF0ZTxNYXA8c3RyaW5nLCBOb3RpY2U+PihQRVJNQU5FTlRfTk9USUNFU19TVEFURV9LRVksIG5ldyBNYXA8c3RyaW5nLCBOb3RpY2U+KCkpLnZhbHVlO1xuICB9XG5cbiAgcHJpdmF0ZSBzZXRQZXJtYW5lbnROb3RpY2Uobm90aWNlOiBOb3RpY2UgfCBudWxsKTogdm9pZCB7XG4gICAgY29uc3QgbWFwID0gdGhpcy5nZXRQZXJtYW5lbnROb3RpY2VzKCk7XG4gICAgaWYgKG5vdGljZSkge1xuICAgICAgbWFwLnNldCh0aGlzLnBsdWdpbk5hbWUsIG5vdGljZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG1hcC5kZWxldGUodGhpcy5wbHVnaW5OYW1lKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU2hvd3MgYSBub3RpY2Ugd2l0aCB0aGUgZ2l2ZW4gZHVyYXRpb24sIHJlcGxhY2luZyB0aGUgY3VycmVudCBub3RpY2UsIGFuZCBvcHRpb25hbGx5IHJlZ2lzdGVycyBpdFxuICAgKiBhcyB0aGlzIHBsdWdpbidzIHBlcm1hbmVudCBub3RpY2UuXG4gICAqXG4gICAqIEBwYXJhbSBtZXNzYWdlIC0gVGhlIG1lc3NhZ2UgdG8gZGlzcGxheS5cbiAgICogQHBhcmFtIGR1cmF0aW9uSW5NaWxsaXNlY29uZHMgLSBUaGUgbm90aWNlIGR1cmF0aW9uOyBgMGAga2VlcHMgaXQgdW50aWwgaXQgaXMgaGlkZGVuIGV4cGxpY2l0bHkuXG4gICAqIEBwYXJhbSBzaG91bGRSZWdpc3RlckFzUGVybWFuZW50IC0gV2hldGhlciB0byB0cmFjayB0aGUgbm90aWNlIGFzIHRoaXMgcGx1Z2luJ3MgcGVybWFuZW50IG5vdGljZS5cbiAgICogQHJldHVybnMgVGhlIGNyZWF0ZWQgbm90aWNlLlxuICAgKi9cbiAgcHJpdmF0ZSBzaG93Tm90aWNlV2l0aER1cmF0aW9uKG1lc3NhZ2U6IERvY3VtZW50RnJhZ21lbnQgfCBzdHJpbmcsIGR1cmF0aW9uSW5NaWxsaXNlY29uZHM6IG51bWJlciB8IHVuZGVmaW5lZCwgc2hvdWxkUmVnaXN0ZXJBc1Blcm1hbmVudDogYm9vbGVhbik6IE5vdGljZSB7XG4gICAgdGhpcy5ub3RpY2U/LmhpZGUoKTtcblxuICAgIGNvbnN0IGNvbnRlbnQgPSB0aGlzLmJ1aWxkTm90aWNlQ29udGVudChtZXNzYWdlKTtcbiAgICB0aGlzLm5vdGljZSA9IG5ldyBOb3RpY2UoY29udGVudCwgZHVyYXRpb25Jbk1pbGxpc2Vjb25kcyk7XG5cbiAgICBpZiAoc2hvdWxkUmVnaXN0ZXJBc1Blcm1hbmVudCkge1xuICAgICAgdGhpcy5zZXRQZXJtYW5lbnROb3RpY2UodGhpcy5ub3RpY2UpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnNldFBlcm1hbmVudE5vdGljZShudWxsKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMubm90aWNlO1xuICB9XG59XG4iXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQU1BO0FBQUEsRUFDRTtBQUFBLEVBQ0E7QUFBQSxPQUNLO0FBSVAsU0FBUyx5QkFBeUI7QUFDbEMsU0FBUyxtQ0FBbUM7QUFDNUMsU0FBUyxnQ0FBZ0M7QUFDekMsU0FBUyxvQkFBb0I7QUFDN0IsU0FBUyxnQkFBZ0I7QUFDekIsU0FBUyxTQUFTO0FBQ2xCLFNBQVMsMkJBQTJCO0FBQ3BDLFNBQVMsbUJBQW1CO0FBRTVCLE1BQU0sOEJBQThCO0FBQ3BDLE1BQU0sNENBQTRDO0FBQ2xELE1BQU0sNENBQTRDO0FBSWxELE1BQU0s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
393
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vLi4vLi4vc3JjL29ic2lkaWFuL2NvbXBvbmVudHMvcGx1Z2luLW5vdGljZS1jb21wb25lbnQudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQGZpbGVcbiAqXG4gKiBDb21wb25lbnQgdGhhdCBtYW5hZ2VzIGRpc3BsYXlpbmcgbm90aWNlcyB0byB0aGUgdXNlci5cbiAqL1xuXG5pbXBvcnQgdHlwZSB7IEFwcCB9IGZyb20gJ29ic2lkaWFuJztcbmltcG9ydCB0eXBlIHsgUHJvbWlzYWJsZSB9IGZyb20gJ3R5cGUtZmVzdCc7XG5cbmltcG9ydCB7XG4gIEJ1dHRvbkNvbXBvbmVudCxcbiAgTm90aWNlLFxuICBzZXRJY29uXG59IGZyb20gJ29ic2lkaWFuJztcblxuaW1wb3J0IHR5cGUgeyBWYWx1ZVByb3ZpZGVyIH0gZnJvbSAnLi4vLi4vdmFsdWUtcHJvdmlkZXIudHMnO1xuXG5pbXBvcnQgeyBpbnZva2VBc3luY1NhZmVseSB9IGZyb20gJy4uLy4uL2FzeW5jLnRzJztcbmltcG9ydCB7IG5vcm1hbGl6ZU9wdGlvbmFsUHJvcGVydGllcyB9IGZyb20gJy4uLy4uL29iamVjdC11dGlscy50cyc7XG5pbXBvcnQgeyBnZXRPYnNpZGlhbkRldlV0aWxzU3RhdGUgfSBmcm9tICcuLi8uLi9vYnNpZGlhbi1kZXYtdXRpbHMtc3RhdGUudHMnO1xuaW1wb3J0IHsgZW5zdXJlTm9uTnVsbGFibGUgfSBmcm9tICcuLi8uLi90eXBlLWd1YXJkcy50cyc7XG5pbXBvcnQgeyByZXNvbHZlVmFsdWUgfSBmcm9tICcuLi8uLi92YWx1ZS1wcm92aWRlci50cyc7XG5pbXBvcnQgeyBDc3NDbGFzcyB9IGZyb20gJy4uL2Nzcy1jbGFzcy50cyc7XG5pbXBvcnQgeyB0IH0gZnJvbSAnLi4vaTE4bi9pMThuLnRzJztcbmltcG9ydCB7IGNvbmZpcm0gfSBmcm9tICcuLi9tb2RhbHMvY29uZmlybS50cyc7XG5pbXBvcnQgeyBhZGRQbHVnaW5Dc3NDbGFzc2VzIH0gZnJvbSAnLi4vcGx1Z2luL3BsdWdpbi1jb250ZXh0LnRzJztcbmltcG9ydCB7IENvbXBvbmVudEV4IH0gZnJvbSAnLi9jb21wb25lbnQtZXgudHMnO1xuaW1wb3J0IHsgTW9ua2V5QXJvdW5kQ29tcG9uZW50IH0gZnJvbSAnLi9tb25rZXktYXJvdW5kLWNvbXBvbmVudC50cyc7XG5cbmNvbnN0IFBFUk1BTkVOVF9OT1RJQ0VTX1NUQVRFX0tFWSA9ICdwbHVnaW4tbm90aWNlLWNvbXBvbmVudDpwZXJtYW5lbnQtbm90aWNlcyc7XG5jb25zdCBQRVJNQU5FTlRfTk9USUNFX0RVUkFUSU9OX0lOX01JTExJU0VDT05EUyA9IDA7XG5jb25zdCBERUZBVUxUX0RFTEFZX0JFRk9SRV9TSE9XX0lOX01JTExJU0VDT05EUyA9IDUwMDtcblxuLy8gRWxlbWVudHMgYSB1c2VyIGNsaWNrcyB0byBhY3Qgb24gdGhlbSByYXRoZXIgdGhhbiB0byBkaXNtaXNzIHRoZSBub3RpY2UuIEEgY2xpY2sgbGFuZGluZyBvbiAob3Jcbi8vIEluc2lkZSkgb25lIG9mIHRoZXNlIGlzIGtlcHQgZnJvbSBidWJibGluZyB0byB0aGUgbm90aWNlLCBzbyB0aGUgbm90aWNlIHN0YXlzIG9wZW4uXG5jb25zdCBJTlRFUkFDVElWRV9FTEVNRU5UX1NFTEVDVE9SID0gJ2EsIGJ1dHRvbiwgaW5wdXQsIHNlbGVjdCwgdGV4dGFyZWEsIGxhYmVsLCBbY29udGVudGVkaXRhYmxlPVwidHJ1ZVwiXSwgW3JvbGU9XCJidXR0b25cIl0sIFtyb2xlPVwibGlua1wiXSwgW3JvbGU9XCJjaGVja2JveFwiXSwgW3JvbGU9XCJ0YWJcIl0sIFtyb2xlPVwibWVudWl0ZW1cIl0nO1xuXG4vKipcbiAqIEEgaGFuZGxlIHRvIGEgZGVsYXllZCBub3RpY2UgY3JlYXRlZCBieSB7QGxpbmsgUGx1Z2luTm90aWNlQ29tcG9uZW50LnNob3dOb3RpY2VBZnRlckRlbGF5fS4gSXQgaXMgYVxuICoge0BsaW5rIERpc3Bvc2FibGV9IChzbyBpdCBjYW4gYmUgdXNlZCB3aXRoIGB1c2luZ2ApIHRoYXQgYWxzbyBsZXRzIHRoZSBjb250ZW50IGJlIHVwZGF0ZWQgd2hpbGUgdGhlXG4gKiBub3RpY2UgaXMgc2hvd24uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUGx1Z2luTm90aWNlQ29tcG9uZW50RGVsYXllZE5vdGljZSBleHRlbmRzIERpc3Bvc2FibGUge1xuICAvKipcbiAgICogUmVwbGFjZXMgdGhlIG5vdGljZSBjb250ZW50LCByZS1hcHBseWluZyB0aGUgcGx1Z2luLW5hbWUgcHJlZml4LCB0aGUgaW50ZXJhY3RpdmUtY2xpY2sgZ3VhcmQsIGFuZFxuICAgKiB0aGUgQ2FuY2VsIGJ1dHRvbi4gVXNlZnVsIGZvciByZXBvcnRpbmcgcHJvZ3Jlc3MuIElmIHRoZSBkZWxheSBoYXMgbm90IGVsYXBzZWQgeWV0LCB0aGUgbmV3IGNvbnRlbnRcbiAgICogYmVjb21lcyB3aGF0IGlzIHNob3duIG9uY2UgaXQgZG9lcy5cbiAgICpcbiAgICogQHBhcmFtIGNvbnRlbnQgLSBUaGUgbmV3IG5vdGljZSBjb250ZW50LlxuICAgKi9cbiAgc2V0Q29udGVudChjb250ZW50OiBEb2N1bWVudEZyYWdtZW50IHwgc3RyaW5nKTogdm9pZDtcbn1cblxuLyoqXG4gKiBQYXJhbWV0ZXJzIGZvciB7QGxpbmsgUGx1Z2luTm90aWNlQ29tcG9uZW50LnNob3dOb3RpY2VBZnRlckRlbGF5fS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBQbHVnaW5Ob3RpY2VDb21wb25lbnRTaG93Tm90aWNlQWZ0ZXJEZWxheVBhcmFtcyB7XG4gIC8qKlxuICAgKiBXaGVuIHByb3ZpZGVkLCBhIENhbmNlbCBidXR0b24gaXMgYXBwZW5kZWQgdG8gdGhlIG5vdGljZTsgY2xpY2tpbmcgaXQgYWJvcnRzIHRoaXMgY29udHJvbGxlci4gV2hlblxuICAgKiBvbWl0dGVkLCBubyBDYW5jZWwgYnV0dG9uIGlzIHNob3duLlxuICAgKi9cbiAgcmVhZG9ubHkgYWJvcnRDb250cm9sbGVyPzogQWJvcnRDb250cm9sbGVyO1xuXG4gIC8qKlxuICAgKiBUaGUgdGV4dCBvZiB0aGUgQ2FuY2VsIGJ1dHRvbiBzaG93biB3aGVuIHtAbGluayBQbHVnaW5Ob3RpY2VDb21wb25lbnRTaG93Tm90aWNlQWZ0ZXJEZWxheVBhcmFtcy5hYm9ydENvbnRyb2xsZXJ9XG4gICAqIGlzIHByb3ZpZGVkLiBXaGVuIG9taXR0ZWQsIHRoZSBsb2NhbGl6ZWQgYENhbmNlbGAgbGFiZWwgaXMgdXNlZC5cbiAgICovXG4gIHJlYWRvbmx5IGNhbmNlbEJ1dHRvblRleHQ/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBub3RpY2UgY29udGVudCwgcmVzb2x2ZWQgbGF6aWx5IG9ubHkgaWYgdGhlIGRlbGF5IGVsYXBzZXMgXHUyMDE0IHNvIGFuIG9wZXJhdGlvbiB0aGF0IGZpbmlzaGVzXG4gICAqIHNvb25lciBuZXZlciBidWlsZHMgaXQuXG4gICAqL1xuICByZWFkb25seSBjb250ZW50OiBWYWx1ZVByb3ZpZGVyPERvY3VtZW50RnJhZ21lbnQgfCBzdHJpbmc+O1xuXG4gIC8qKlxuICAgKiBIb3cgbG9uZyB0aGUgb3BlcmF0aW9uIG11c3QgcnVuIGJlZm9yZSB0aGUgbm90aWNlIGlzIHNob3duLiBPcGVyYXRpb25zIHRoYXQgZmluaXNoIHNvb25lciBuZXZlclxuICAgKiBzaG93IGEgbm90aWNlLCBhdm9pZGluZyBhIGRpc3RyYWN0aW5nIGZsYXNoLlxuICAgKlxuICAgKiBAZGVmYXVsdCBgNTAwYFxuICAgKi9cbiAgcmVhZG9ubHkgZGVsYXlJbk1pbGxpc2Vjb25kcz86IG51bWJlcjtcbn1cblxuLyoqXG4gKiBPcHRpb25zIGZvciB7QGxpbmsgUGx1Z2luTm90aWNlQ29tcG9uZW50LnNob3dOb3RpY2V9LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFBsdWdpbk5vdGljZUNvbXBvbmVudFNob3dOb3RpY2VPcHRpb25zIHtcbiAgLyoqXG4gICAqIFdoZXRoZXIgdGhlIG5vdGljZSBzaG91bGQgc3RheSB1bnRpbCBpdCBpcyByZXBsYWNlZCwgdGhlIHBsdWdpbiBpcyByZWxvYWRlZCwgb3IgdGhlIHVzZXIgZGlzbWlzc2VzIGl0LlxuICAgKlxuICAgKiBBIHBlcm1hbmVudCBub3RpY2UgaXMgc2hvd24gd2l0aCBhbiBpbmZpbml0ZSBkdXJhdGlvbiBhbmQgaXMgbm90IGhpZGRlbiB3aGVuIHRoZSBjb21wb25lbnQgdW5sb2Fkcywgc28gaXQgY2FuXG4gICAqIGNvbW11bmljYXRlIHN0YXRlIHRoYXQgb3V0bGl2ZXMgdGhlIHBsdWdpbiAoZS5nLiBhIGNsZWFudXAgdGhhdCByZXF1aXJlcyBhIHJlbG9hZCkuIFRoZXJlIGlzIGF0IG1vc3Qgb25lIHBlcm1hbmVudFxuICAgKiBub3RpY2UgcGVyIHBsdWdpbjogaXQgaXMgaGlkZGVuIGJ5IHRoZSBuZXh0IHtAbGluayBQbHVnaW5Ob3RpY2VDb21wb25lbnQuc2hvd05vdGljZX0gY2FsbCBhbmQgZGlzbWlzc2VkXG4gICAqIGF1dG9tYXRpY2FsbHkgdGhlIG5leHQgdGltZSB0aGUgY29tcG9uZW50IGxvYWRzIChpLmUuIHdoZW4gdGhlIHBsdWdpbiBpcyByZS1lbmFibGVkKS5cbiAgICpcbiAgICogQGRlZmF1bHQgYGZhbHNlYFxuICAgKi9cbiAgcmVhZG9ubHkgaXNQZXJtYW5lbnQ/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoZSBub3RpY2Ugb2NjdXBpZXMgdGhlIHNpbmdsZSBwZXItcGx1Z2luIHJldXNhYmxlIHNsb3QuXG4gICAqXG4gICAqIEEgcmV1c2FibGUgbm90aWNlIHRha2VzIHRoZSBzaGFyZWQgc2xvdDogdGhlIG5leHQgcmV1c2FibGUgbm90aWNlIGhpZGVzIGl0LCBhbmQgaXQgaXMgaGlkZGVuIG9uIHVubG9hZC5cbiAgICogQSBub24tcmV1c2FibGUgKHN0YW5kYWxvbmUpIG5vdGljZSBpcyBub3QgcGxhY2VkIGluIHRoZSBzbG90IFx1MjAxNCBpdCBuZXZlciBoaWRlcywgYW5kIGlzIG5ldmVyIGhpZGRlbiBieSwgYVxuICAgKiByZXVzYWJsZSBub3RpY2U7IG11bHRpcGxlIHN0YW5kYWxvbmUgbm90aWNlcyBjb2V4aXN0LiBTdGFuZGFsb25lIG5vdGljZXMgYXJlIHN0aWxsIGhpZGRlbiB0b2dldGhlciBvbiB1bmxvYWQuXG4gICAqXG4gICAqIEEgcGVybWFuZW50IG5vdGljZSBtdXN0IGJlIHJldXNhYmxlICh7QGxpbmsgUGx1Z2luTm90aWNlQ29tcG9uZW50U2hvd05vdGljZU9wdGlvbnMuaXNQZXJtYW5lbnR9IGltcGxpZXNcbiAgICogYGlzUmV1c2FibGVgKTsgcGFzc2luZyBgaXNSZXVzYWJsZTogZmFsc2VgIHRvZ2V0aGVyIHdpdGggYGlzUGVybWFuZW50OiB0cnVlYCB0aHJvd3MuXG4gICAqXG4gICAqIEBkZWZhdWx0IGB0cnVlYFxuICAgKi9cbiAgcmVhZG9ubHkgaXNSZXVzYWJsZT86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIEEgY2FsbGJhY2sgaW52b2tlZCB3aGVuIHRoZSBub3RpY2UgaXMgaGlkZGVuIFx1MjAxNCB3aGV0aGVyIGJ5IHRoZSB1c2VyIGNsb3NpbmcgaXQsIGJ5IGEgbGF0ZXIgcmV1c2FibGVcbiAgICogbm90aWNlIHJlcGxhY2luZyBpdCwgYnkgaXRzIGR1cmF0aW9uIGVsYXBzaW5nLCBvciBvbiBjb21wb25lbnQgdW5sb2FkLiBJdCBydW5zIGF0IG1vc3Qgb25jZSBwZXJcbiAgICogbm90aWNlLiBBbiBhc3luYyBjYWxsYmFjayBpcyBydW4gZmlyZS1hbmQtZm9yZ2V0IChpdHMgcmVqZWN0aW9uIHN1cmZhY2VzIHRocm91Z2ggdGhlIGFzeW5jLWVycm9yXG4gICAqIHBpcGVsaW5lKS5cbiAgICovXG4gIG9uSGlkZT8odGhpczogdm9pZCk6IFByb21pc2FibGU8dm9pZD47XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdGhlIG5vdGljZSBpcyBoYXJkIHRvIGNsb3NlOiBpdCBkb2VzIG5vdCBkaXNtaXNzIG9uIGFueSBzdHJheSBjbGljaywgYW5kIGluc3RlYWQgc2hvd3MgYVxuICAgKiBjbG9zZSAoWCkgYnV0dG9uIHdob3NlIGNsaWNrIG9wZW5zIGEgY29uZmlybWF0aW9uIG1vZGFsLCBkaXNtaXNzaW5nIHRoZSBub3RpY2Ugb25seSBpZiBjb25maXJtZWQuXG4gICAqXG4gICAqIEEgaGFyZC10by1jbG9zZSBub3RpY2UgaXMgc2hvd24gd2l0aCBhbiBpbmZpbml0ZSBkdXJhdGlvbiBhbmQgaXMgc3RhbmRhbG9uZSAoaW1wbGllc1xuICAgKiB7QGxpbmsgUGx1Z2luTm90aWNlQ29tcG9uZW50U2hvd05vdGljZU9wdGlvbnMuaXNSZXVzYWJsZX0gYD0gZmFsc2VgKSwgc28gYSBsYXRlciBub3RpY2UgbmV2ZXJcbiAgICogc2lsZW50bHkgcmVwbGFjZXMgaXQ7IHBhc3NpbmcgYGlzUmV1c2FibGU6IHRydWVgIHRvZ2V0aGVyIHdpdGggYHJlcXVpcmVzQ2xvc2VDb25maXJtYXRpb246IHRydWVgXG4gICAqIHRocm93cy5cbiAgICpcbiAgICogQGRlZmF1bHQgYGZhbHNlYFxuICAgKi9cbiAgcmVhZG9ubHkgcmVxdWlyZXNDbG9zZUNvbmZpcm1hdGlvbj86IGJvb2xlYW47XG59XG5cbmludGVyZmFjZSBQbHVnaW5Ob3RpY2VDb21wb25lbnRCdWlsZERlbGF5ZWROb3RpY2VNZXNzYWdlUGFyYW1zIHtcbiAgcmVhZG9ubHkgYWJvcnRDb250cm9sbGVyPzogQWJvcnRDb250cm9sbGVyO1xuICByZWFkb25seSBjYW5jZWxCdXR0b25UZXh0Pzogc3RyaW5nO1xuICByZWFkb25seSBjb250ZW50OiBEb2N1bWVudEZyYWdtZW50IHwgc3RyaW5nO1xufVxuXG5pbnRlcmZhY2UgUGx1Z2luTm90aWNlQ29tcG9uZW50QnVpbGROb3RpY2VDb250ZW50UGFyYW1zIHtcbiAgLyoqXG4gICAqIFJlc29sdmVzIHRoZSBub3RpY2UgdGhpcyBjb250ZW50IGJlbG9uZ3MgdG8sIHVzZWQgYnkgdGhlIGNsb3NlIGJ1dHRvbidzIGhhbmRsZXIuIFRoZSBub3RpY2UgZG9lc1xuICAgKiBub3QgZXhpc3QgeWV0IHdoZW4gdGhlIGNvbnRlbnQgaXMgYnVpbHQsIHNvIGl0IGlzIHJlc29sdmVkIGxhemlseSBhdCBjbGljayB0aW1lLiBSZXF1aXJlZCB3aGVuXG4gICAqIHtAbGluayBQbHVnaW5Ob3RpY2VDb21wb25lbnRCdWlsZE5vdGljZUNvbnRlbnRQYXJhbXMucmVxdWlyZXNDbG9zZUNvbmZpcm1hdGlvbn0gaXMgYHRydWVgLlxuICAgKi9cbiAgZ2V0Tm90aWNlPyh0aGlzOiB2b2lkKTogTm90aWNlIHwgbnVsbDtcblxuICAvKipcbiAgICogVGhlIG1lc3NhZ2UgdG8gZGlzcGxheSBhZnRlciB0aGUgcGx1Z2luIG5hbWUgcHJlZml4LlxuICAgKi9cbiAgcmVhZG9ubHkgbWVzc2FnZTogRG9jdW1lbnRGcmFnbWVudCB8IHN0cmluZztcblxuICAvKipcbiAgICogV2hldGhlciB0aGUgbm90aWNlIGlzIGhhcmQgdG8gY2xvc2U6IHN0b3BzIGV2ZXJ5IGNsaWNrIGZyb20gZGlzbWlzc2luZyBpdCBhbmQgYWRkcyBhIGNsb3NlIGJ1dHRvblxuICAgKiBndWFyZGVkIGJ5IGEgY29uZmlybWF0aW9uIG1vZGFsLlxuICAgKlxuICAgKiBAZGVmYXVsdCBgZmFsc2VgXG4gICAqL1xuICByZWFkb25seSByZXF1aXJlc0Nsb3NlQ29uZmlybWF0aW9uPzogYm9vbGVhbjtcbn1cblxuaW50ZXJmYWNlIFBsdWdpbk5vdGljZUNvbXBvbmVudENvbnN0cnVjdG9yUGFyYW1zIHtcbiAgcmVhZG9ubHkgYXBwOiBBcHA7XG4gIHJlYWRvbmx5IHBsdWdpbk5hbWU6IHN0cmluZztcbn1cblxuaW50ZXJmYWNlIFBsdWdpbk5vdGljZUNvbXBvbmVudFNob3dOb3RpY2VXaXRoRHVyYXRpb25QYXJhbXMge1xuICByZWFkb25seSBkdXJhdGlvbkluTWlsbGlzZWNvbmRzOiBudWxsIHwgbnVtYmVyO1xuICByZWFkb25seSBpc1JldXNhYmxlOiBib29sZWFuO1xuICByZWFkb25seSBtZXNzYWdlOiBEb2N1bWVudEZyYWdtZW50IHwgc3RyaW5nO1xuICByZWFkb25seSBvbkhpZGU6ICgoKSA9PiBQcm9taXNhYmxlPHZvaWQ+KSB8IHVuZGVmaW5lZDtcbiAgcmVhZG9ubHkgcmVxdWlyZXNDbG9zZUNvbmZpcm1hdGlvbjogYm9vbGVhbjtcbiAgcmVhZG9ubHkgc2hvdWxkUmVnaXN0ZXJBc1Blcm1hbmVudDogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBNYW5hZ2VzIHNob3dpbmcgcGx1Z2luIG5vdGljZXMuIEF1dG9tYXRpY2FsbHkgaGlkZXMgdGhlIHByZXZpb3VzIG5vdGljZSB3aGVuIGEgbmV3IG9uZSBpcyBzaG93bi5cbiAqL1xuZXhwb3J0IGNsYXNzIFBsdWdpbk5vdGljZUNvbXBvbmVudCBleHRlbmRzIENvbXBvbmVudEV4IHtcbiAgLyoqXG4gICAqIFRoZSBPYnNpZGlhbiBhcHAgaW5zdGFuY2UuXG4gICAqL1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgYXBwOiBBcHA7XG5cbiAgLyoqXG4gICAqIFRoZSBwbHVnaW4gbmFtZSAoc2hvd24gYXMgcHJlZml4IGluIG5vdGljZXMpLlxuICAgKi9cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IHBsdWdpbk5hbWU6IHN0cmluZztcblxuICBwcml2YXRlIG5vdGljZTogTm90aWNlIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgcmVhZG9ubHkgcGVuZGluZ1RpbWVyQ2FuY2VsbGF0aW9ucyA9IG5ldyBTZXQ8KCkgPT4gdm9pZD4oKTtcbiAgcHJpdmF0ZSByZWFkb25seSBzdGFuZGFsb25lTm90aWNlcyA9IG5ldyBTZXQ8Tm90aWNlPigpO1xuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgbmV3IHBsdWdpbiBub3RpY2UgY29tcG9uZW50LlxuICAgKlxuICAgKiBAcGFyYW0gcGFyYW1zIC0gVGhlIGNvbnN0cnVjdG9yIHBhcmFtZXRlcnMuXG4gICAqL1xuICBwdWJsaWMgY29uc3RydWN0b3IocGFyYW1zOiBQbHVnaW5Ob3RpY2VDb21wb25lbnRDb25zdHJ1Y3RvclBhcmFtcykge1xuICAgIHN1cGVyKCk7XG4gICAgdGhpcy5hcHAgPSBwYXJhbXMuYXBwO1xuICAgIHRoaXMucGx1Z2luTmFtZSA9IHBhcmFtcy5wbHVnaW5OYW1lO1xuICB9XG5cbiAgLyoqXG4gICAqIERpc21pc3NlcyB0aGUgcGVybWFuZW50IG5vdGljZSBsZWZ0IG92ZXIgZnJvbSBhIHByZXZpb3VzIGxvYWQgKGUuZy4gYSBwcmV2aW91cyBwbHVnaW4gc2Vzc2lvbikgb24gbG9hZC5cbiAgICovXG4gIHB1YmxpYyBvdmVycmlkZSBvbmxvYWQoKTogdm9pZCB7XG4gICAgc3VwZXIub25sb2FkKCk7XG4gICAgY29uc3QgcGVybWFuZW50Tm90aWNlID0gdGhpcy5nZXRQZXJtYW5lbnROb3RpY2UoKTtcbiAgICBwZXJtYW5lbnROb3RpY2U/LmhpZGUoKTtcbiAgICB0aGlzLnNldFBlcm1hbmVudE5vdGljZShudWxsKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBIaWRlcyB0aGUgY3VycmVudCBub3RpY2Ugb24gdW5sb2FkLCB1bmxlc3MgaXQgaXMgdGhlIHBlcm1hbmVudCBub3RpY2UgKHdoaWNoIGlzIG1lYW50IHRvIG91dGxpdmUgdGhlIHBsdWdpbikuXG4gICAqL1xuICBwdWJsaWMgb3ZlcnJpZGUgb251bmxvYWQoKTogdm9pZCB7XG4gICAgLy8gQ2FuY2VsIGFueSBkZWxheWVkIG5vdGljZSB3aG9zZSB0aW1lciBoYXMgbm90IGZpcmVkIHlldCwgc28gaXQgbmV2ZXIgYXBwZWFycyBhZnRlciB1bmxvYWQuXG4gICAgZm9yIChjb25zdCBjYW5jZWxQZW5kaW5nVGltZXIgb2YgWy4uLnRoaXMucGVuZGluZ1RpbWVyQ2FuY2VsbGF0aW9uc10pIHtcbiAgICAgIGNhbmNlbFBlbmRpbmdUaW1lcigpO1xuICAgIH1cbiAgICBpZiAodGhpcy5nZXRQZXJtYW5lbnROb3RpY2UoKSAhPT0gdGhpcy5ub3RpY2UpIHtcbiAgICAgIHRoaXMubm90aWNlPy5oaWRlKCk7XG4gICAgfVxuICAgIGZvciAoY29uc3Qgc3RhbmRhbG9uZU5vdGljZSBvZiB0aGlzLnN0YW5kYWxvbmVOb3RpY2VzKSB7XG4gICAgICBzdGFuZGFsb25lTm90aWNlLmhpZGUoKTtcbiAgICB9XG4gICAgdGhpcy5zdGFuZGFsb25lTm90aWNlcy5jbGVhcigpO1xuICB9XG5cbiAgLyoqXG4gICAqIERpc3BsYXlzIGEgbm90aWNlIG1lc3NhZ2UgdG8gdGhlIHVzZXIuXG4gICAqXG4gICAqIEBwYXJhbSBtZXNzYWdlIC0gVGhlIG1lc3NhZ2UgdG8gZGlzcGxheS5cbiAgICogQHBhcmFtIG9wdGlvbnMgLSBUaGUgb3B0aW9ucyBmb3IgZGlzcGxheWluZyB0aGUgbm90aWNlLlxuICAgKiBAcmV0dXJucyBUaGUgbm90aWNlIG9iamVjdC5cbiAgICovXG4gIHB1YmxpYyBzaG93Tm90aWNlKG1lc3NhZ2U6IERvY3VtZW50RnJhZ21lbnQgfCBzdHJpbmcsIG9wdGlvbnM/OiBQbHVnaW5Ob3RpY2VDb21wb25lbnRTaG93Tm90aWNlT3B0aW9ucyk6IE5vdGljZSB7XG4gICAgY29uc3QgaXNQZXJtYW5lbnQgPSBvcHRpb25zPy5pc1Blcm1hbmVudCA/PyBmYWxzZTtcbiAgICBjb25zdCByZXF1aXJlc0Nsb3NlQ29uZmlybWF0aW9uID0gb3B0aW9ucz8ucmVxdWlyZXNDbG9zZUNvbmZpcm1hdGlvbiA/PyBmYWxzZTtcbiAgICBjb25zdCBpc1JldXNhYmxlID0gb3B0aW9ucz8uaXNSZXVzYWJsZSA/PyAhcmVxdWlyZXNDbG9zZUNvbmZpcm1hdGlvbjtcblxuICAgIGlmIChvcHRpb25zPy5pc1JldXNhYmxlID09PSB0cnVlICYmIHJlcXVpcmVzQ2xvc2VDb25maXJtYXRpb24pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQSBub3RpY2UgdGhhdCByZXF1aXJlcyBjbG9zZSBjb25maXJtYXRpb24gY2Fubm90IGJlIHJldXNhYmxlLicpO1xuICAgIH1cbiAgICBpZiAob3B0aW9ucz8uaXNSZXVzYWJsZSA9PT0gZmFsc2UgJiYgaXNQZXJtYW5lbnQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQSBwZXJtYW5lbnQgbm90aWNlIG11c3QgYmUgcmV1c2FibGUuJyk7XG4gICAgfVxuXG4gICAgY29uc3QgZHVyYXRpb25Jbk1pbGxpc2Vjb25kcyA9IGlzUGVybWFuZW50IHx8IHJlcXVpcmVzQ2xvc2VDb25maXJtYXRpb24gPyBQRVJNQU5FTlRfTk9USUNFX0RVUkFUSU9OX0lOX01JTExJU0VDT05EUyA6IG51bGw7XG4gICAgcmV0dXJuIHRoaXMuc2hvd05vdGljZVdpdGhEdXJhdGlvbih7XG4gICAgICBkdXJhdGlvbkluTWlsbGlzZWNvbmRzLFxuICAgICAgaXNSZXVzYWJsZSxcbiAgICAgIG1lc3NhZ2UsXG4gICAgICBvbkhpZGU6IG9wdGlvbnM/Lm9uSGlkZSxcbiAgICAgIHJlcXVpcmVzQ2xvc2VDb25maXJtYXRpb24sXG4gICAgICBzaG91bGRSZWdpc3RlckFzUGVybWFuZW50OiBpc1Blcm1hbmVudFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFNob3dzIGEgbm90aWNlIGRlc2NyaWJpbmcgYSBsb25nLXJ1bm5pbmcgb3BlcmF0aW9uLCBidXQgb25seSBvbmNlIHRoZSBvcGVyYXRpb24gaGFzIHJ1biBmb3IgbG9uZ2VyXG4gICAqIHRoYW4ge0BsaW5rIFBsdWdpbk5vdGljZUNvbXBvbmVudFNob3dOb3RpY2VBZnRlckRlbGF5UGFyYW1zLmRlbGF5SW5NaWxsaXNlY29uZHN9IFx1MjAxNCBzbyBvcGVyYXRpb25zXG4gICAqIHRoYXQgZmluaXNoIHNvb25lciBuZXZlciBmbGFzaCBhIG5vdGljZS4gVGhlIG5vdGljZSBzdGF5cyB1bnRpbCB0aGUgcmV0dXJuZWQge0BsaW5rIERpc3Bvc2FibGV9IGlzXG4gICAqIGRpc3Bvc2VkICh3aGljaCBhbHNvIGNhbmNlbHMgdGhlIHBlbmRpbmcgdGltZXIgaWYgaXQgaGFzIG5vdCBmaXJlZCB5ZXQpLCBzbyBpdCBjYW4gYmUgdXNlZCB3aXRoXG4gICAqIGB1c2luZ2AuIFdoZW4gYW4ge0BsaW5rIFBsdWdpbk5vdGljZUNvbXBvbmVudFNob3dOb3RpY2VBZnRlckRlbGF5UGFyYW1zLmFib3J0Q29udHJvbGxlcn0gaXMgZ2l2ZW4sIGFcbiAgICogQ2FuY2VsIGJ1dHRvbiB0aGF0IGFib3J0cyBpdCBpcyBhcHBlbmRlZCAoYW5kLCBiZWluZyBpbnRlcmFjdGl2ZSwgZG9lcyBub3QgZGlzbWlzcyB0aGUgbm90aWNlKS5cbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogYGBgdHNcbiAgICogdXNpbmcgX25vdGljZSA9IHBsdWdpbk5vdGljZUNvbXBvbmVudC5zaG93Tm90aWNlQWZ0ZXJEZWxheSh7XG4gICAqICAgYWJvcnRDb250cm9sbGVyLFxuICAgKiAgIGNvbnRlbnQ6ICgpID0+IGJ1aWxkUHJvZ3Jlc3NGcmFnbWVudCgpXG4gICAqIH0pO1xuICAgKiBhd2FpdCBydW5PcGVyYXRpb24oYWJvcnRDb250cm9sbGVyLnNpZ25hbCk7XG4gICAqIGBgYFxuICAgKlxuICAgKiBAcGFyYW0gcGFyYW1zIC0gVGhlIHBhcmFtZXRlcnMuXG4gICAqIEByZXR1cm5zIEEge0BsaW5rIFBsdWdpbk5vdGljZUNvbXBvbmVudERlbGF5ZWROb3RpY2V9IHRoYXQgaGlkZXMgdGhlIG5vdGljZSAob3IgY2FuY2VscyB0aGUgcGVuZGluZ1xuICAgKiB0aW1lcikgd2hlbiBkaXNwb3NlZCBhbmQgbGV0cyB0aGUgY29udGVudCBiZSB1cGRhdGVkIHdoaWxlIGl0IGlzIHNob3duLlxuICAgKi9cbiAgcHVibGljIHNob3dOb3RpY2VBZnRlckRlbGF5KHBhcmFtczogUGx1Z2luTm90aWNlQ29tcG9uZW50U2hvd05vdGljZUFmdGVyRGVsYXlQYXJhbXMpOiBQbHVnaW5Ob3RpY2VDb21wb25lbnREZWxheWVkTm90aWNlIHtcbiAgICBsZXQgc2hvd25Ob3RpY2U6IE5vdGljZSB8IG51bGwgPSBudWxsO1xuICAgIGxldCBpc0Rpc3Bvc2VkID0gZmFsc2U7XG4gICAgbGV0IHRpbWVySWQgPSAwO1xuICAgIGxldCBjdXJyZW50Q29udGVudDogVmFsdWVQcm92aWRlcjxEb2N1bWVudEZyYWdtZW50IHwgc3RyaW5nPiA9IHBhcmFtcy5jb250ZW50O1xuXG4gICAgY29uc3QgY2FuY2VsUGVuZGluZ1RpbWVyID0gKCk6IHZvaWQgPT4ge1xuICAgICAgd2luZG93LmNsZWFyVGltZW91dCh0aW1lcklkKTtcbiAgICAgIHRoaXMucGVuZGluZ1RpbWVyQ2FuY2VsbGF0aW9ucy5kZWxldGUoY2FuY2VsUGVuZGluZ1RpbWVyKTtcbiAgICB9O1xuXG4gICAgY29uc3QgYnVpbGREZWxheWVkTWVzc2FnZSA9IChjb250ZW50OiBEb2N1bWVudEZyYWdtZW50IHwgc3RyaW5nKTogRG9jdW1lbnRGcmFnbWVudCA9PlxuICAgICAgdGhpcy5idWlsZERlbGF5ZWROb3RpY2VNZXNzYWdlKG5vcm1hbGl6ZU9wdGlvbmFsUHJvcGVydGllczxQbHVnaW5Ob3RpY2VDb21wb25lbnRCdWlsZERlbGF5ZWROb3RpY2VNZXNzYWdlUGFyYW1zPih7XG4gICAgICAgIGFib3J0Q29udHJvbGxlcjogcGFyYW1zLmFib3J0Q29udHJvbGxlcixcbiAgICAgICAgY2FuY2VsQnV0dG9uVGV4dDogcGFyYW1zLmNhbmNlbEJ1dHRvblRleHQsXG4gICAgICAgIGNvbnRlbnRcbiAgICAgIH0pKTtcblxuICAgIHRpbWVySWQgPSB3aW5kb3cuc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICBjYW5jZWxQZW5kaW5nVGltZXIoKTtcbiAgICAgIGludm9rZUFzeW5jU2FmZWx5KGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3QgcmVzb2x2ZWRDb250ZW50ID0gYXdhaXQgcmVzb2x2ZVZhbHVlKGN1cnJlbnRDb250ZW50LCB7fSk7XG4gICAgICAgIC8vIFRoZSBoYW5kbGUgbWF5IGhhdmUgYmVlbiBkaXNwb3NlZCB3aGlsZSB0aGUgY29udGVudCB3YXMgYmVpbmcgcmVzb2x2ZWQ7IGRvbid0IHNob3cgYSBzdGFsZSBub3RpY2UuXG4gICAgICAgIGlmIChpc0Rpc3Bvc2VkKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHNob3duTm90aWNlID0gdGhpcy5zaG93Tm90aWNlV2l0aER1cmF0aW9uKHtcbiAgICAgICAgICBkdXJhdGlvbkluTWlsbGlzZWNvbmRzOiBQRVJNQU5FTlRfTk9USUNFX0RVUkFUSU9OX0lOX01JTExJU0VDT05EUyxcbiAgICAgICAgICBpc1JldXNhYmxlOiB0cnVlLFxuICAgICAgICAgIG1lc3NhZ2U6IGJ1aWxkRGVsYXllZE1lc3NhZ2UocmVzb2x2ZWRDb250ZW50KSxcbiAgICAgICAgICBvbkhpZGU6IHVuZGVmaW5lZCxcbiAgICAgICAgICByZXF1aXJlc0Nsb3NlQ29uZmlybWF0aW9uOiBmYWxzZSxcbiAgICAgICAgICBzaG91bGRSZWdpc3RlckFzUGVybWFuZW50OiBmYWxzZVxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0sIHBhcmFtcy5kZWxheUluTWlsbGlzZWNvbmRzID8/IERFRkFVTFRfREVMQVlfQkVGT1JFX1NIT1dfSU5fTUlMTElTRUNPTkRTKTtcblxuICAgIHRoaXMucGVuZGluZ1RpbWVyQ2FuY2VsbGF0aW9ucy5hZGQoY2FuY2VsUGVuZGluZ1RpbWVyKTtcblxuICAgIHJldHVybiB7XG4gICAgICBzZXRDb250ZW50OiAoY29udGVudDogRG9jdW1lbnRGcmFnbWVudCB8IHN0cmluZyk6IHZvaWQgPT4ge1xuICAgICAgICBjdXJyZW50Q29udGVudCA9IGNvbnRlbnQ7XG4gICAgICAgIC8vIFJlLXdyYXAgc28gdGhlIHByZWZpeCwgaW50ZXJhY3RpdmUgZ3VhcmQsIGFuZCBDYW5jZWwgYnV0dG9uIHN1cnZpdmUgdGhlIGNvbnRlbnQgc3dhcC5cbiAgICAgICAgc2hvd25Ob3RpY2U/LnNldE1lc3NhZ2UodGhpcy5idWlsZE5vdGljZUNvbnRlbnQoeyBtZXNzYWdlOiBidWlsZERlbGF5ZWRNZXNzYWdlKGNvbnRlbnQpIH0pKTtcbiAgICAgIH0sXG4gICAgICBbU3ltYm9sLmRpc3Bvc2VdOiAoKTogdm9pZCA9PiB7XG4gICAgICAgIGlzRGlzcG9zZWQgPSB0cnVlO1xuICAgICAgICBjYW5jZWxQZW5kaW5nVGltZXIoKTtcbiAgICAgICAgc2hvd25Ob3RpY2U/LmhpZGUoKTtcbiAgICAgICAgaWYgKHRoaXMubm90aWNlID09PSBzaG93bk5vdGljZSkge1xuICAgICAgICAgIHRoaXMubm90aWNlID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogQXBwZW5kcyBhIGNsb3NlIChYKSBidXR0b24gdG8gdGhlIG5vdGljZSBjb250ZW50LiBDbGlja2luZyBpdCBvcGVucyBhIGNvbmZpcm1hdGlvbiBtb2RhbCBhbmQsIG9ubHlcbiAgICogaWYgY29uZmlybWVkLCBoaWRlcyB0aGUgbm90aWNlIGFuZCBkcm9wcyBpdCBmcm9tIHRoZSBzdGFuZGFsb25lLW5vdGljZSB0cmFja2luZyBzZXQuXG4gICAqXG4gICAqIEBwYXJhbSBjb250ZW50RWwgLSBUaGUgbm90aWNlIGNvbnRlbnQgd3JhcHBlciB0byBhcHBlbmQgdGhlIGJ1dHRvbiB0by5cbiAgICogQHBhcmFtIGdldE5vdGljZSAtIFJlc29sdmVzIHRoZSBub3RpY2UgdG8gaGlkZSB3aGVuIHRoZSBjbG9zZSBpcyBjb25maXJtZWQuXG4gICAqL1xuICBwcml2YXRlIGFwcGVuZENsb3NlQnV0dG9uKGNvbnRlbnRFbDogSFRNTEVsZW1lbnQsIGdldE5vdGljZTogKCkgPT4gTm90aWNlIHwgbnVsbCk6IHZvaWQge1xuICAgIGNvbnN0IGNsb3NlQnV0dG9uRWwgPSBjb250ZW50RWwuY3JlYXRlRWwoJ2J1dHRvbicsIHtcbiAgICAgIGF0dHI6IHsgJ2FyaWEtbGFiZWwnOiB0KCgkKSA9PiAkLm9ic2lkaWFuRGV2VXRpbHMubm90aWNlcy5jbG9zZUFyaWFMYWJlbCkgfVxuICAgIH0pO1xuICAgIGFkZFBsdWdpbkNzc0NsYXNzZXMoY2xvc2VCdXR0b25FbCwgQ3NzQ2xhc3MuUGx1Z2luTm90aWNlQ2xvc2VCdXR0b24pO1xuICAgIHNldEljb24oY2xvc2VCdXR0b25FbCwgJ3gnKTtcbiAgICBjbG9zZUJ1dHRvbkVsLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKGV2dCkgPT4ge1xuICAgICAgZXZ0LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgaW52b2tlQXN5bmNTYWZlbHkoYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCBpc0NvbmZpcm1lZCA9IGF3YWl0IGNvbmZpcm0oe1xuICAgICAgICAgIGFwcDogdGhpcy5hcHAsXG4gICAgICAgICAgbWVzc2FnZTogdCgoJCkgPT4gJC5vYnNpZGlhbkRldlV0aWxzLm5vdGljZXMuY2xvc2VDb25maXJtTWVzc2FnZSlcbiAgICAgICAgfSk7XG4gICAgICAgIGlmICghaXNDb25maXJtZWQpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgbm90aWNlID0gZW5zdXJlTm9uTnVsbGFibGUoZ2V0Tm90aWNlKCkpO1xuICAgICAgICBub3RpY2UuaGlkZSgpO1xuICAgICAgICB0aGlzLnN0YW5kYWxvbmVOb3RpY2VzLmRlbGV0ZShub3RpY2UpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQnVpbGRzIHRoZSBtZXNzYWdlIGZvciBhIGRlbGF5ZWQgbm90aWNlOiB0aGUgcmVzb2x2ZWQgY29udGVudCwgb3B0aW9uYWxseSBmb2xsb3dlZCBieSBhIENhbmNlbFxuICAgKiBidXR0b24gdGhhdCBhYm9ydHMgdGhlIHByb3ZpZGVkIGNvbnRyb2xsZXIgd2hlbiBjbGlja2VkLlxuICAgKlxuICAgKiBAcGFyYW0gcGFyYW1zIC0gVGhlIHBhcmFtZXRlcnMuXG4gICAqIEByZXR1cm5zIEEge0BsaW5rIERvY3VtZW50RnJhZ21lbnR9IGhvbGRpbmcgdGhlIGNvbnRlbnQgYW5kLCBpZiByZXF1ZXN0ZWQsIGEgQ2FuY2VsIGJ1dHRvbi5cbiAgICovXG4gIHByaXZhdGUgYnVpbGREZWxheWVkTm90aWNlTWVzc2FnZShwYXJhbXM6IFBsdWdpbk5vdGljZUNvbXBvbmVudEJ1aWxkRGVsYXllZE5vdGljZU1lc3NhZ2VQYXJhbXMpOiBEb2N1bWVudEZyYWdtZW50IHtcbiAgICBjb25zdCB7IGFib3J0Q29udHJvbGxlciwgY2FuY2VsQnV0dG9uVGV4dCwgY29udGVudCB9ID0gcGFyYW1zO1xuICAgIGNvbnN0IGZyYWdtZW50ID0gY3JlYXRlRnJhZ21lbnQoKTtcbiAgICBpZiAodHlwZW9mIGNvbnRlbnQgPT09ICdzdHJpbmcnKSB7XG4gICAgICBmcmFnbWVudC5hcHBlbmRUZXh0KGNvbnRlbnQpO1xuICAgIH0gZWxzZSB7XG4gICAgICBmcmFnbWVudC5hcHBlbmRDaGlsZChjb250ZW50KTtcbiAgICB9XG5cbiAgICBpZiAoYWJvcnRDb250cm9sbGVyKSB7XG4gICAgICAvLyBgQnV0dG9uQ29tcG9uZW50YCByZXF1aXJlcyBhbiBgSFRNTEVsZW1lbnRgIHBhcmVudCwgc28gYnVpbGQgaXQgb24gYSB0aHJvd2F3YXlcbiAgICAgIC8vIERldGFjaGVkIGVsZW1lbnQgYW5kIG1vdmUgaXRzIGBidXR0b25FbGAgaW50byB0aGUgZnJhZ21lbnQuXG4gICAgICBjb25zdCBjYW5jZWxCdXR0b24gPSBuZXcgQnV0dG9uQ29tcG9uZW50KGNyZWF0ZURpdigpKTtcbiAgICAgIGNhbmNlbEJ1dHRvbi5zZXRCdXR0b25UZXh0KGNhbmNlbEJ1dHRvblRleHQgPz8gdCgoJCkgPT4gJC5vYnNpZGlhbkRldlV0aWxzLmJ1dHRvbnMuY2FuY2VsKSk7XG4gICAgICBhZGRQbHVnaW5Dc3NDbGFzc2VzKGNhbmNlbEJ1dHRvbi5idXR0b25FbCwgQ3NzQ2xhc3MuQ2FuY2VsQnV0dG9uKTtcbiAgICAgIC8vIFRoZSBjbGljayBpcyB3aXJlZCB2aWEgYGFkZEV2ZW50TGlzdGVuZXJgIHJhdGhlciB0aGFuIGBCdXR0b25Db21wb25lbnQub25DbGlja2Agc28gaXRcbiAgICAgIC8vIEJ1YmJsZXMgdGhyb3VnaCB0aGUgaW50ZXJhY3RpdmUtZWxlbWVudCBndWFyZCAoa2VlcGluZyB0aGUgbm90aWNlIG9wZW4pIGFuZCBzdGF5c1xuICAgICAgLy8gRGlyZWN0bHkgZXhlcmNpc2FibGUgdmlhIGEgZGlzcGF0Y2hlZCBET00gZXZlbnQgaW4gdW5pdCB0ZXN0cy5cbiAgICAgIGNhbmNlbEJ1dHRvbi5idXR0b25FbC5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IHtcbiAgICAgICAgYWJvcnRDb250cm9sbGVyLmFib3J0KCk7XG4gICAgICB9KTtcbiAgICAgIGZyYWdtZW50LmFwcGVuZENoaWxkKGNhbmNlbEJ1dHRvbi5idXR0b25FbCk7XG4gICAgfVxuICAgIHJldHVybiBmcmFnbWVudDtcbiAgfVxuXG4gIC8qKlxuICAgKiBCdWlsZHMgdGhlIG5vdGljZSBjb250ZW50IHdyYXBwZWQgaW4gYSBjb250YWluZXIgdGhhdCBrZWVwcyB0aGUgbm90aWNlIG9wZW4gd2hlbiBhbiBpbnRlcmFjdGl2ZVxuICAgKiBlbGVtZW50IGluc2lkZSBpdCBpcyBjbGlja2VkLiBPYnNpZGlhbiBkaXNtaXNzZXMgYSBub3RpY2Ugb24gYW55IGNsaWNrIHRoYXQgYnViYmxlcyB1cCB0byBpdHNcbiAgICogZWxlbWVudDsgdGhlIGNvbnRhaW5lciBpbnRlcmNlcHRzIGNsaWNrcyBvcmlnaW5hdGluZyBvbiBhbiBpbnRlcmFjdGl2ZSBlbGVtZW50IChhIGxpbmssIGJ1dHRvbixcbiAgICogaW5wdXQsIGV0Yy4pIGFuZCBzdG9wcyB0aGVtIHRoZXJlLCBzbyB0aGUgZWxlbWVudCdzIG93biBoYW5kbGVyIHN0aWxsIHJ1bnMgYnV0IHRoZSBub3RpY2Ugc3RheXMuXG4gICAqXG4gICAqIEBwYXJhbSBwYXJhbXMgLSBUaGUgcGFyYW1ldGVycy5cbiAgICogQHJldHVybnMgQSB7QGxpbmsgRG9jdW1lbnRGcmFnbWVudH0gaG9sZGluZyB0aGUgd3JhcHBlZCwgcHJlZml4ZWQgbm90aWNlIGNvbnRlbnQuXG4gICAqL1xuICBwcml2YXRlIGJ1aWxkTm90aWNlQ29udGVudChwYXJhbXM6IFBsdWdpbk5vdGljZUNvbXBvbmVudEJ1aWxkTm90aWNlQ29udGVudFBhcmFtcyk6IERvY3VtZW50RnJhZ21lbnQge1xuICAgIGNvbnN0IHsgZ2V0Tm90aWNlLCBtZXNzYWdlLCByZXF1aXJlc0Nsb3NlQ29uZmlybWF0aW9uID0gZmFsc2UgfSA9IHBhcmFtcztcbiAgICBjb25zdCBmcmFnbWVudCA9IGNyZWF0ZUZyYWdtZW50KCk7XG4gICAgY29uc3QgY29udGVudEVsID0gZnJhZ21lbnQuY3JlYXRlRGl2KCk7XG4gICAgYWRkUGx1Z2luQ3NzQ2xhc3Nlcyhjb250ZW50RWwsIENzc0NsYXNzLlBsdWdpbk5vdGljZUNvbnRlbnQpO1xuICAgIGNvbnRlbnRFbC5hcHBlbmRDaGlsZCh0aGlzLmJ1aWxkUHJlZml4ZWRNZXNzYWdlKG1lc3NhZ2UpKTtcbiAgICBjb250ZW50RWwuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoZXZ0KSA9PiB7XG4gICAgICAvLyBBIGhhcmQtdG8tY2xvc2Ugbm90aWNlIG11c3Qgbm90IGRpc21pc3Mgb24gYW55IHN0cmF5IGNsaWNrOyBvbmx5IGl0cyBjbG9zZSBidXR0b24gKHZpYSB0aGVcbiAgICAgIC8vIENvbmZpcm1hdGlvbiBtb2RhbCkgbWF5IGRpc21pc3MgaXQuXG4gICAgICBpZiAocmVxdWlyZXNDbG9zZUNvbmZpcm1hdGlvbikge1xuICAgICAgICBldnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmIChldnQudGFyZ2V0IGluc3RhbmNlb2YgRWxlbWVudCAmJiBldnQudGFyZ2V0LmNsb3Nlc3QoSU5URVJBQ1RJVkVfRUxFTUVOVF9TRUxFQ1RPUikpIHtcbiAgICAgICAgZXZ0LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaWYgKHJlcXVpcmVzQ2xvc2VDb25maXJtYXRpb24pIHtcbiAgICAgIHRoaXMuYXBwZW5kQ2xvc2VCdXR0b24oY29udGVudEVsLCBlbnN1cmVOb25OdWxsYWJsZShnZXROb3RpY2UpKTtcbiAgICB9XG4gICAgcmV0dXJuIGZyYWdtZW50O1xuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkcyB0aGUgbm90aWNlIGNvbnRlbnQsIHByZWZpeGluZyB0aGUgbWVzc2FnZSB3aXRoIHRoZSBwbHVnaW4gbmFtZSBpbiBhIHN0eWxlZCBlbGVtZW50IHNvIGl0IGlzXG4gICAqIHZpc3VhbGx5IGRpc3Rpbmd1aXNoZWQgZnJvbSB0aGUgbWVzc2FnZSBib2R5LlxuICAgKlxuICAgKiBAcGFyYW0gbWVzc2FnZSAtIFRoZSBtZXNzYWdlIHRvIGRpc3BsYXkgYWZ0ZXIgdGhlIHBsdWdpbiBuYW1lIHByZWZpeC5cbiAgICogQHJldHVybnMgQSB7QGxpbmsgRG9jdW1lbnRGcmFnbWVudH0gd2l0aCB0aGUgc3R5bGVkIHBsdWdpbiBuYW1lIHByZWZpeCBmb2xsb3dlZCBieSB0aGUgbWVzc2FnZS5cbiAgICovXG4gIHByaXZhdGUgYnVpbGRQcmVmaXhlZE1lc3NhZ2UobWVzc2FnZTogRG9jdW1lbnRGcmFnbWVudCB8IHN0cmluZyk6IERvY3VtZW50RnJhZ21lbnQge1xuICAgIGNvbnN0IGZyYWdtZW50ID0gY3JlYXRlRnJhZ21lbnQoKTtcbiAgICBjb25zdCBuYW1lRWwgPSBjcmVhdGVTcGFuKHsgdGV4dDogdGhpcy5wbHVnaW5OYW1lIH0pO1xuICAgIGFkZFBsdWdpbkNzc0NsYXNzZXMobmFtZUVsLCBDc3NDbGFzcy5QbHVnaW5Ob3RpY2VOYW1lKTtcbiAgICBmcmFnbWVudC5hcHBlbmRDaGlsZChuYW1lRWwpO1xuICAgIGlmICghdGhpcy5fbG9hZGVkKSB7XG4gICAgICBmcmFnbWVudC5hcHBlbmRUZXh0KCcgKHVubG9hZGVkKScpO1xuICAgIH1cbiAgICBmcmFnbWVudC5hcHBlbmRUZXh0KCdcXG4nKTtcbiAgICBpZiAodHlwZW9mIG1lc3NhZ2UgPT09ICdzdHJpbmcnKSB7XG4gICAgICBmcmFnbWVudC5hcHBlbmRUZXh0KG1lc3NhZ2UpO1xuICAgIH0gZWxzZSB7XG4gICAgICBmcmFnbWVudC5hcHBlbmRDaGlsZChtZXNzYWdlKTtcbiAgICB9XG4gICAgcmV0dXJuIGZyYWdtZW50O1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRQZXJtYW5lbnROb3RpY2UoKTogTm90aWNlIHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0UGVybWFuZW50Tm90aWNlcygpLmdldCh0aGlzLnBsdWdpbk5hbWUpID8/IG51bGw7XG4gIH1cblxuICBwcml2YXRlIGdldFBlcm1hbmVudE5vdGljZXMoKTogTWFwPHN0cmluZywgTm90aWNlPiB7XG4gICAgcmV0dXJuIGdldE9ic2lkaWFuRGV2VXRpbHNTdGF0ZTxNYXA8c3RyaW5nLCBOb3RpY2U+PihQRVJNQU5FTlRfTk9USUNFU19TVEFURV9LRVksIG5ldyBNYXA8c3RyaW5nLCBOb3RpY2U+KCkpLnZhbHVlO1xuICB9XG5cbiAgLyoqXG4gICAqIE1ha2VzIGEgbm90aWNlIGhhcmQgdG8gY2xvc2U6IG1hcmtzIGl0cyBvdXRlciBlbGVtZW50IChzbyB0aGUgQ1NTIG5ldXRyYWxpemVzIGl0cyBwYWRkaW5nKSBhbmRcbiAgICogaW5zdGFsbHMgYSBjYXB0dXJlLXBoYXNlIGNsaWNrIGd1YXJkIHRoYXQgc3RvcHMgZXZlcnkgY2xpY2sgZXhjZXB0IG9uIHRoZSBjbG9zZSBidXR0b24gZnJvbVxuICAgKiByZWFjaGluZyBPYnNpZGlhbidzIG93biBkaXNtaXNzIGhhbmRsZXIuXG4gICAqXG4gICAqIEBwYXJhbSBub3RpY2UgLSBUaGUgbm90aWNlIHRvIGd1YXJkLlxuICAgKiBAcGFyYW0gcmVxdWlyZXNDbG9zZUNvbmZpcm1hdGlvbiAtIFdoZXRoZXIgdGhlIG5vdGljZSByZXF1aXJlcyBjbG9zZSBjb25maXJtYXRpb247IHdoZW4gYGZhbHNlYCxcbiAgICogbm90aGluZyBpcyBpbnN0YWxsZWQuXG4gICAqL1xuICBwcml2YXRlIGluc3RhbGxDbG9zZUNvbmZpcm1hdGlvbkd1YXJkcyhub3RpY2U6IE5vdGljZSwgcmVxdWlyZXNDbG9zZUNvbmZpcm1hdGlvbjogYm9vbGVhbik6IHZvaWQge1xuICAgIGlmICghcmVxdWlyZXNDbG9zZUNvbmZpcm1hdGlvbikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICAvLyBUaGUgb3V0ZXIgYC5ub3RpY2VgIGVsZW1lbnQgKGBjb250YWluZXJFbGApIGNhcnJpZXMgT2JzaWRpYW4ncyBkaXNtaXNzLW9uLWNsaWNrIGhhbmRsZXIgYW5kIHRoZVxuICAgIC8vIFBhZGRpbmcgYSBzdHJheSBjbGljayBjb3VsZCBsYW5kIG9uOyBtYXJrIGl0IHNvIHRoZSBzdHlsZXNoZWV0IGRyb3BzIHRoYXQgcGFkZGluZy5cbiAgICBhZGRQbHVnaW5Dc3NDbGFzc2VzKG5vdGljZS5jb250YWluZXJFbCwgQ3NzQ2xhc3MuUGx1Z2luTm90aWNlUmVxdWlyZXNDb25maXJtYXRpb24pO1xuICAgIC8vIFN0b3AgZXZlcnkgY2xpY2sgb24gdGhlIG5vdGljZSBcdTIwMTQgZXhjZXB0IG9uIHRoZSBjbG9zZSBidXR0b24gXHUyMDE0IGZyb20gcmVhY2hpbmcgT2JzaWRpYW4ncyBkaXNtaXNzXG4gICAgLy8gSGFuZGxlci4gUmVnaXN0ZXJlZCBpbiB0aGUgY2FwdHVyZSBwaGFzZSBvbiB0aGUgb3V0ZXJtb3N0IGVsZW1lbnQgc28gaXQgYWx3YXlzIHJ1bnMgZmlyc3QuXG4gICAgbm90aWNlLmNvbnRhaW5lckVsLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKGV2dCkgPT4ge1xuICAgICAgaWYgKGV2dC50YXJnZXQgaW5zdGFuY2VvZiBFbGVtZW50ICYmIGV2dC50YXJnZXQuY2xvc2VzdChgLiR7Q3NzQ2xhc3MuUGx1Z2luTm90aWNlQ2xvc2VCdXR0b259YCkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgZXZ0LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIH0sIHsgY2FwdHVyZTogdHJ1ZSB9KTtcbiAgfVxuXG4gIHByaXZhdGUgc2V0UGVybWFuZW50Tm90aWNlKG5vdGljZTogTm90aWNlIHwgbnVsbCk6IHZvaWQge1xuICAgIGNvbnN0IG1hcCA9IHRoaXMuZ2V0UGVybWFuZW50Tm90aWNlcygpO1xuICAgIGlmIChub3RpY2UpIHtcbiAgICAgIG1hcC5zZXQodGhpcy5wbHVnaW5OYW1lLCBub3RpY2UpO1xuICAgIH0gZWxzZSB7XG4gICAgICBtYXAuZGVsZXRlKHRoaXMucGx1Z2luTmFtZSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFNob3dzIGEgbm90aWNlIHdpdGggdGhlIGdpdmVuIGR1cmF0aW9uLiBBIHJldXNhYmxlIG5vdGljZSByZXBsYWNlcyB0aGUgY3VycmVudCByZXVzYWJsZSBub3RpY2UgKGFuZFxuICAgKiBpcyBvcHRpb25hbGx5IHJlZ2lzdGVyZWQgYXMgdGhpcyBwbHVnaW4ncyBwZXJtYW5lbnQgbm90aWNlKTsgYSBzdGFuZGFsb25lIG5vdGljZSBpcyB0cmFja2VkXG4gICAqIHNlcGFyYXRlbHksIGxlYXZpbmcgdGhlIHJldXNhYmxlIHNsb3QgdW50b3VjaGVkLlxuICAgKlxuICAgKiBAcGFyYW0gcGFyYW1zIC0gVGhlIHBhcmFtZXRlcnMuXG4gICAqIEByZXR1cm5zIFRoZSBjcmVhdGVkIG5vdGljZS5cbiAgICovXG4gIHByaXZhdGUgc2hvd05vdGljZVdpdGhEdXJhdGlvbihwYXJhbXM6IFBsdWdpbk5vdGljZUNvbXBvbmVudFNob3dOb3RpY2VXaXRoRHVyYXRpb25QYXJhbXMpOiBOb3RpY2Uge1xuICAgIGNvbnN0IHsgZHVyYXRpb25Jbk1pbGxpc2Vjb25kcywgaXNSZXVzYWJsZSwgbWVzc2FnZSwgb25IaWRlLCByZXF1aXJlc0Nsb3NlQ29uZmlybWF0aW9uLCBzaG91bGRSZWdpc3RlckFzUGVybWFuZW50IH0gPSBwYXJhbXM7XG4gICAgLy8gT2JzaWRpYW4ncyBgTm90aWNlYCB0cmVhdHMgYW4gb21pdHRlZCBkdXJhdGlvbiBhcyBpdHMgZGVmYXVsdCwgc28gbWFwIHRoZSBgbnVsbGAgXCJubyBleHBsaWNpdFxuICAgIC8vIER1cmF0aW9uXCIgdmFsdWUgdG8gYHVuZGVmaW5lZGAuXG4gICAgY29uc3Qgbm90aWNlRHVyYXRpb25Jbk1pbGxpc2Vjb25kcyA9IGR1cmF0aW9uSW5NaWxsaXNlY29uZHMgPz8gdW5kZWZpbmVkO1xuXG4gICAgLy8gVGhlIGNsb3NlIGJ1dHRvbidzIGNvbmZpcm0gaGFuZGxlciBuZWVkcyB0aGUgYE5vdGljZWAsIHdoaWNoIGRvZXMgbm90IGV4aXN0IHVudGlsIGl0IGlzIGJ1aWx0IGZyb21cbiAgICAvLyBUaGlzIGNvbnRlbnQ7IGNhcHR1cmUgaXQgbGF6aWx5IHZpYSBhIGhvbGRlciByZXNvbHZlZCBhdCBjbGljayB0aW1lLiBUaGUgZ2V0dGVyIGlzIGNyZWF0ZWQgb25seVxuICAgIC8vIEZvciBhIGhhcmQtdG8tY2xvc2Ugbm90aWNlIFx1MjAxNCB0aGUgb25seSBraW5kIHRoYXQgaGFzIGEgY2xvc2UgYnV0dG9uLlxuICAgIGxldCBidWlsdE5vdGljZTogTm90aWNlIHwgbnVsbCA9IG51bGw7XG4gICAgY29uc3QgY29udGVudCA9IHRoaXMuYnVpbGROb3RpY2VDb250ZW50KG5vcm1hbGl6ZU9wdGlvbmFsUHJvcGVydGllczxQbHVnaW5Ob3RpY2VDb21wb25lbnRCdWlsZE5vdGljZUNvbnRlbnRQYXJhbXM+KHtcbiAgICAgIGdldE5vdGljZTogcmVxdWlyZXNDbG9zZUNvbmZpcm1hdGlvbiA/ICgpOiBOb3RpY2UgfCBudWxsID0+IGJ1aWx0Tm90aWNlIDogdW5kZWZpbmVkLFxuICAgICAgbWVzc2FnZSxcbiAgICAgIHJlcXVpcmVzQ2xvc2VDb25maXJtYXRpb25cbiAgICB9KSk7XG5cbiAgICBpZiAoIWlzUmV1c2FibGUpIHtcbiAgICAgIGJ1aWx0Tm90aWNlID0gbmV3IE5vdGljZShjb250ZW50LCBub3RpY2VEdXJhdGlvbkluTWlsbGlzZWNvbmRzKTtcbiAgICAgIHRoaXMuaW5zdGFsbENsb3NlQ29uZmlybWF0aW9uR3VhcmRzKGJ1aWx0Tm90aWNlLCByZXF1aXJlc0Nsb3NlQ29uZmlybWF0aW9uKTtcbiAgICAgIHRoaXMud2lyZU9uSGlkZShidWlsdE5vdGljZSwgb25IaWRlKTtcbiAgICAgIHRoaXMuc3RhbmRhbG9uZU5vdGljZXMuYWRkKGJ1aWx0Tm90aWNlKTtcbiAgICAgIHJldHVybiBidWlsdE5vdGljZTtcbiAgICB9XG5cbiAgICB0aGlzLm5vdGljZT8uaGlkZSgpO1xuICAgIGJ1aWx0Tm90aWNlID0gbmV3IE5vdGljZShjb250ZW50LCBub3RpY2VEdXJhdGlvbkluTWlsbGlzZWNvbmRzKTtcbiAgICB0aGlzLm5vdGljZSA9IGJ1aWx0Tm90aWNlO1xuICAgIHRoaXMuaW5zdGFsbENsb3NlQ29uZmlybWF0aW9uR3VhcmRzKGJ1aWx0Tm90aWNlLCByZXF1aXJlc0Nsb3NlQ29uZmlybWF0aW9uKTtcbiAgICB0aGlzLndpcmVPbkhpZGUoYnVpbHROb3RpY2UsIG9uSGlkZSk7XG5cbiAgICBpZiAoc2hvdWxkUmVnaXN0ZXJBc1Blcm1hbmVudCkge1xuICAgICAgdGhpcy5zZXRQZXJtYW5lbnROb3RpY2UoYnVpbHROb3RpY2UpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnNldFBlcm1hbmVudE5vdGljZShudWxsKTtcbiAgICB9XG4gICAgcmV0dXJuIGJ1aWx0Tm90aWNlO1xuICB9XG5cbiAgLyoqXG4gICAqIFdyYXBzIGEgbm90aWNlJ3MgYGhpZGVgIHNvIHRoZSBnaXZlbiBjYWxsYmFjayBydW5zIHRoZSBmaXJzdCB0aW1lIHRoZSBub3RpY2UgaXMgaGlkZGVuIFx1MjAxNCBieSB0aGVcbiAgICogdXNlciwgYnkgYSByZXBsYWNpbmcgbm90aWNlLCBieSBpdHMgZHVyYXRpb24gZWxhcHNpbmcsIG9yIG9uIHVubG9hZC4gRG9lcyBub3RoaW5nIHdoZW4gbm8gY2FsbGJhY2tcbiAgICogaXMgZ2l2ZW4uXG4gICAqXG4gICAqIEBwYXJhbSBub3RpY2UgLSBUaGUgbm90aWNlIHdob3NlIGBoaWRlYCB0byB3cmFwLlxuICAgKiBAcGFyYW0gb25IaWRlIC0gVGhlIGNhbGxiYWNrIHRvIGludm9rZSBvbiB0aGUgZmlyc3QgaGlkZSwgb3IgYHVuZGVmaW5lZGAgdG8gc2tpcCB3cmFwcGluZy5cbiAgICovXG4gIHByaXZhdGUgd2lyZU9uSGlkZShub3RpY2U6IE5vdGljZSwgb25IaWRlOiAoKCkgPT4gUHJvbWlzYWJsZTx2b2lkPikgfCB1bmRlZmluZWQpOiB2b2lkIHtcbiAgICBpZiAoIW9uSGlkZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICAvLyBSdW4gYG9uSGlkZWAgdGhlIGZpcnN0IHRpbWUgdGhlIG5vdGljZSBpcyBoaWRkZW4uIEEgYG9uY2VgIHBhdGNoIG9uIGBoaWRlYCBpbnRlcmNlcHRzIGV4YWN0bHkgb25lXG4gICAgLy8gQ2FsbCB0aGVuIHVuaW5zdGFsbHMgaXRzZWxmICh1bmxvYWRpbmcgdGhpcyBkZWRpY2F0ZWQgY29tcG9uZW50KSwgc28gdGhlcmUgaXMgbm8gbWFudWFsXG4gICAgLy8gU2luZ2xlLWZpcmUgYm9va2tlZXBpbmcgYW5kIG5vIGxpbmdlcmluZyBwYXRjaCBvbiB0aGUgdHJhbnNpZW50IG5vdGljZS5cbiAgICBjb25zdCBwYXRjaENvbXBvbmVudCA9IG5ldyBNb25rZXlBcm91bmRDb21wb25lbnQoKTtcbiAgICBwYXRjaENvbXBvbmVudC5sb2FkKCk7XG4gICAgcGF0Y2hDb21wb25lbnQucmVnaXN0ZXJNZXRob2RQYXRjaCh7XG4gICAgICBtZXRob2ROYW1lOiAnaGlkZScsXG4gICAgICBvYmo6IG5vdGljZSxcbiAgICAgIG9uY2U6IHRydWUsXG4gICAgICBwYXRjaEhhbmRsZXI6ICh7IGZhbGxiYWNrIH0pID0+IHtcbiAgICAgICAgZmFsbGJhY2soKTtcbiAgICAgICAgaW52b2tlQXN5bmNTYWZlbHkoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIGF3YWl0IG9uSGlkZSgpO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxufVxuIl0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFTQTtBQUFBLEVBQ0U7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLE9BQ0s7QUFJUCxTQUFTLHlCQUF5QjtBQUNsQyxTQUFTLG1DQUFtQztBQUM1QyxTQUFTLGdDQUFnQztBQUN6QyxTQUFTLHlCQUF5QjtBQUNsQyxTQUFTLG9CQUFvQjtBQUM3QixTQUFTLGdCQUFn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
@@ -117,6 +117,10 @@ export declare enum CssClass {
117
117
  * A CSS class for the password component.
118
118
  */
119
119
  PasswordComponent = "password-component",
120
+ /**
121
+ * A CSS class for the close button of a notice that requires close confirmation.
122
+ */
123
+ PluginNoticeCloseButton = "plugin-notice-close-button",
120
124
  /**
121
125
  * A CSS class for the container wrapping a notice's content, used to keep the notice open when an
122
126
  * interactive element inside it is clicked.
@@ -126,6 +130,11 @@ export declare enum CssClass {
126
130
  * A CSS class for the plugin name shown as the prefix of a notice.
127
131
  */
128
132
  PluginNoticeName = "plugin-notice-name",
133
+ /**
134
+ * A CSS class applied to the notice element of a notice that requires close confirmation, used to
135
+ * make its whole area non-dismissible.
136
+ */
137
+ PluginNoticeRequiresConfirmation = "plugin-notice-requires-confirmation",
129
138
  /**
130
139
  * A CSS class for the plugin settings tab.
131
140
  */
@@ -142,6 +151,10 @@ export declare enum CssClass {
142
151
  * A CSS class for the select item modal.
143
152
  */
144
153
  SelectItemModal = "select-item-modal",
154
+ /**
155
+ * A CSS class for the select option modal.
156
+ */
157
+ SelectOptionModal = "select-option-modal",
145
158
  /**
146
159
  * A CSS class for the setting component wrapper.
147
160
  */