@mnaoumov/obsidian-lib 10.9.0 → 10.10.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 (59) hide show
  1. package/codemirror/editor-mode-extension/package.json +6 -0
  2. package/dist/lib/cjs/__merged.cjs +28 -1
  3. package/dist/lib/cjs/__merged.d.cts +4 -1
  4. package/dist/lib/cjs/codemirror/editor-mode-extension.cjs +180 -0
  5. package/dist/lib/cjs/codemirror/editor-mode-extension.d.cts +50 -0
  6. package/dist/lib/cjs/codemirror/index.cjs +4 -1
  7. package/dist/lib/cjs/codemirror/index.d.cts +1 -0
  8. package/dist/lib/cjs/codemirror/inline-token-widgets.cjs +4 -7
  9. package/dist/lib/cjs/components/plugin-settings-component.cjs +4 -3
  10. package/dist/lib/cjs/components/plugin-settings-component.d.cts +2 -1
  11. package/dist/lib/cjs/css-class.cjs +7 -1
  12. package/dist/lib/cjs/css-class.d.cts +24 -0
  13. package/dist/lib/cjs/generated-during-build.cjs +2 -2
  14. package/dist/lib/cjs/i18n/i18n.cjs +38 -10
  15. package/dist/lib/cjs/i18n/i18n.d.cts +29 -2
  16. package/dist/lib/cjs/i18n/locales/en.cjs +13 -1
  17. package/dist/lib/cjs/i18n/locales/en.d.cts +12 -0
  18. package/dist/lib/cjs/i18n/locales/translations-map.d.cts +12 -0
  19. package/dist/lib/cjs/modals/code-block-builder.cjs +486 -0
  20. package/dist/lib/cjs/modals/code-block-builder.d.cts +321 -0
  21. package/dist/lib/cjs/modals/index.cjs +4 -1
  22. package/dist/lib/cjs/modals/index.d.cts +1 -0
  23. package/dist/lib/cjs/plugin/index.cjs +4 -1
  24. package/dist/lib/cjs/plugin/index.d.cts +1 -0
  25. package/dist/lib/cjs/plugin/plugin-async-cleanup.cjs +189 -0
  26. package/dist/lib/cjs/plugin/plugin-async-cleanup.d.cts +111 -0
  27. package/dist/lib/cjs/plugin/plugin.cjs +47 -2
  28. package/dist/lib/cjs/plugin/plugin.d.cts +25 -1
  29. package/dist/lib/esm/__merged.d.mts +4 -1
  30. package/dist/lib/esm/__merged.mjs +31 -1
  31. package/dist/lib/esm/codemirror/editor-mode-extension.d.mts +50 -0
  32. package/dist/lib/esm/codemirror/editor-mode-extension.mjs +93 -0
  33. package/dist/lib/esm/codemirror/index.d.mts +1 -0
  34. package/dist/lib/esm/codemirror/index.mjs +3 -1
  35. package/dist/lib/esm/codemirror/inline-token-widgets.mjs +3 -9
  36. package/dist/lib/esm/components/plugin-settings-component.d.mts +2 -1
  37. package/dist/lib/esm/components/plugin-settings-component.mjs +4 -3
  38. package/dist/lib/esm/css-class.d.mts +24 -0
  39. package/dist/lib/esm/css-class.mjs +7 -1
  40. package/dist/lib/esm/generated-during-build.mjs +2 -2
  41. package/dist/lib/esm/i18n/i18n.d.mts +29 -2
  42. package/dist/lib/esm/i18n/i18n.mjs +40 -10
  43. package/dist/lib/esm/i18n/locales/en.d.mts +12 -0
  44. package/dist/lib/esm/i18n/locales/en.mjs +13 -1
  45. package/dist/lib/esm/i18n/locales/translations-map.d.mts +12 -0
  46. package/dist/lib/esm/modals/code-block-builder.d.mts +321 -0
  47. package/dist/lib/esm/modals/code-block-builder.mjs +408 -0
  48. package/dist/lib/esm/modals/index.d.mts +1 -0
  49. package/dist/lib/esm/modals/index.mjs +3 -1
  50. package/dist/lib/esm/plugin/index.d.mts +1 -0
  51. package/dist/lib/esm/plugin/index.mjs +3 -1
  52. package/dist/lib/esm/plugin/plugin-async-cleanup.d.mts +111 -0
  53. package/dist/lib/esm/plugin/plugin-async-cleanup.mjs +96 -0
  54. package/dist/lib/esm/plugin/plugin.d.mts +25 -1
  55. package/dist/lib/esm/plugin/plugin.mjs +52 -2
  56. package/dist/styles.css +31 -1
  57. package/modals/code-block-builder/package.json +6 -0
  58. package/package.json +1 -1
  59. package/plugin/plugin-async-cleanup/package.json +6 -0
@@ -0,0 +1,111 @@
1
+ /// <reference path="../library-references.d.cts" />
2
+ /**
3
+ * @file
4
+ *
5
+ * Async cleanup that outlives a plugin instance, so the next instance of the same plugin can await it.
6
+ *
7
+ * Obsidian's `onunload` is synchronous and nothing awaits what it starts. Read from Obsidian `1.15.1`:
8
+ * `Plugins.unloadPlugin` calls the old instance's `unload()` and returns, and `enablePlugin` then constructs the new
9
+ * instance and awaits its `load()`. So on a disable / enable, a reload or an update while enabled, work like closing
10
+ * an IndexedDB connection is still in flight when the new instance starts, and the new instance can open a database
11
+ * the old one still holds.
12
+ *
13
+ * The registry here closes that gap without owning the reload lifecycle: a cleanup starts when the component it is
14
+ * registered on unloads, its promise is kept realm-wide under the plugin id, and the next instance awaits it, bounded
15
+ * by a timeout, before it starts. `PluginBase` does both halves itself.
16
+ *
17
+ * The registry lives in the realm-global shared-state bag under the versioned key `pluginAsyncCleanupsV1`, because the
18
+ * old instance and the new one may bundle different copies of this library. It is a wire format between those copies:
19
+ * a plain `Map` from plugin id to a `Promise<void>` that never rejects. A change of meaning moves to a new key.
20
+ */
21
+ import type { Component } from 'obsidian' with { 'resolution-mode': 'import' };
22
+ import type { Promisable } from 'type-fest' with { 'resolution-mode': 'import' };
23
+ /**
24
+ * The shared-state key of the pending cleanups. Versioned, because it is a wire format between copies of this library.
25
+ */
26
+ export declare const PLUGIN_ASYNC_CLEANUPS_STATE_KEY = "pluginAsyncCleanupsV1";
27
+ /**
28
+ * How long a new plugin instance waits for the previous instance's cleanups by default.
29
+ */
30
+ export declare const DEFAULT_PLUGIN_ASYNC_CLEANUP_TIMEOUT_IN_MILLISECONDS = 10000;
31
+ /**
32
+ * Parameters for {@link didPluginAsyncCleanupsSettle}.
33
+ */
34
+ export interface DidPluginAsyncCleanupsSettleParams {
35
+ /**
36
+ * The id of the plugin whose pending cleanups to await.
37
+ */
38
+ readonly pluginId: string;
39
+ /**
40
+ * How long to wait before giving up. Defaults to {@link DEFAULT_PLUGIN_ASYNC_CLEANUP_TIMEOUT_IN_MILLISECONDS}.
41
+ */
42
+ readonly timeoutInMilliseconds?: number;
43
+ }
44
+ /**
45
+ * An async cleanup.
46
+ */
47
+ export type PluginAsyncCleanup = () => Promisable<void>;
48
+ /**
49
+ * Parameters for {@link registerPluginAsyncCleanup}.
50
+ */
51
+ export interface RegisterPluginAsyncCleanupParams {
52
+ /**
53
+ * The cleanup to run.
54
+ */
55
+ readonly cleanup: PluginAsyncCleanup;
56
+ /**
57
+ * The component whose unload starts the cleanup.
58
+ */
59
+ readonly component: Component;
60
+ /**
61
+ * The id of the plugin the cleanup belongs to, which the next instance waits under.
62
+ */
63
+ readonly pluginId: string;
64
+ }
65
+ /**
66
+ * Parameters for {@link trackPluginAsyncCleanup}.
67
+ */
68
+ export interface TrackPluginAsyncCleanupParams {
69
+ /**
70
+ * The cleanup to run now.
71
+ */
72
+ readonly cleanup: PluginAsyncCleanup;
73
+ /**
74
+ * The id of the plugin the cleanup belongs to.
75
+ */
76
+ readonly pluginId: string;
77
+ }
78
+ /**
79
+ * Awaits every cleanup still in flight for the plugin, bounded by a timeout.
80
+ *
81
+ * Resolves at once when nothing is pending. Never rejects.
82
+ *
83
+ * @param params - The parameters.
84
+ * @returns `true` if every pending cleanup settled in time, `false` if the timeout was reached first.
85
+ */
86
+ export declare function didPluginAsyncCleanupsSettle(params: DidPluginAsyncCleanupsSettleParams): Promise<boolean>;
87
+ /**
88
+ * Checks whether a plugin has cleanups still in flight.
89
+ *
90
+ * @param pluginId - The plugin id.
91
+ * @returns Whether any cleanup registered under the id has not settled yet.
92
+ */
93
+ export declare function hasPendingPluginAsyncCleanups(pluginId: string): boolean;
94
+ /**
95
+ * Registers an async cleanup that starts when the component unloads and that the next instance of the plugin awaits.
96
+ *
97
+ * The cleanup runs exactly once, on the component's unload. Register it on the component whose lifetime matches the
98
+ * resource: a `PluginBase` subclass calls `registerAsyncCleanup` instead, which scopes it to the feature surface.
99
+ *
100
+ * @param params - The parameters.
101
+ */
102
+ export declare function registerPluginAsyncCleanup(params: RegisterPluginAsyncCleanupParams): void;
103
+ /**
104
+ * Runs an async cleanup now and tracks it under the plugin id until it settles.
105
+ *
106
+ * A cleanup that throws or rejects is printed and counts as settled, so a failing cleanup never stops the next
107
+ * instance from loading.
108
+ *
109
+ * @param params - The parameters.
110
+ */
111
+ export declare function trackPluginAsyncCleanup(params: TrackPluginAsyncCleanupParams): void;
@@ -144,6 +144,7 @@ var import_i18n = require('../i18n/i18n.cjs');
144
144
  var import_translations_map = require('../i18n/locales/translations-map.cjs');
145
145
  var import_resource_lock = require('../resource-lock.cjs');
146
146
  var import_plugin_api = require('./plugin-api.cjs');
147
+ var import_plugin_async_cleanup = require('./plugin-async-cleanup.cjs');
147
148
  var import_plugin_event_source = require('./plugin-event-source.cjs');
148
149
  var import_plugin_lifecycle_events = require('./plugin-lifecycle-events.cjs');
149
150
  class PluginBase extends (0, import_async_events.mixinAsyncEvents)()(import_obsidian.Plugin) {
@@ -370,6 +371,9 @@ class PluginBase extends (0, import_async_events.mixinAsyncEvents)()(import_obsi
370
371
  */
371
372
  async onload() {
372
373
  try {
374
+ if ((0, import_plugin_async_cleanup.hasPendingPluginAsyncCleanups)(this.manifest.id)) {
375
+ await this.waitForPreviousAsyncCleanups();
376
+ }
373
377
  super.addChild(this.universalWrapperComponent);
374
378
  this.universalWrapperComponent.load();
375
379
  await (0, import_i18n.initI18N)(this.createTranslationsMap());
@@ -470,13 +474,24 @@ class PluginBase extends (0, import_async_events.mixinAsyncEvents)()(import_obsi
470
474
  * Provides the translations map used to initialize i18n during {@link onload}.
471
475
  *
472
476
  * Override in subclass to supply plugin-specific translations. The default returns the built-in
473
- * `@mnaoumov/obsidian-lib` translations.
477
+ * `@mnaoumov/obsidian-lib` translations. A language may map to a `LocaleLoader` instead of its translations, so
478
+ * only the shown language is initialized; see {@link https://mnaoumov.dev/obsidian-lib/guides/translations/}.
474
479
  *
475
480
  * @returns The translations map.
476
481
  */
477
482
  createTranslationsMap() {
478
483
  return import_translations_map.defaultTranslationsMap;
479
484
  }
485
+ /**
486
+ * Provides how long a new instance waits for the previous instance's async cleanups before loading anyway.
487
+ *
488
+ * Override in subclass to change it. The default is 10 seconds.
489
+ *
490
+ * @returns The timeout in milliseconds.
491
+ */
492
+ getAsyncCleanupTimeoutInMilliseconds() {
493
+ return import_plugin_async_cleanup.DEFAULT_PLUGIN_ASYNC_CLEANUP_TIMEOUT_IN_MILLISECONDS;
494
+ }
480
495
  /**
481
496
  * Provides the icon shown on the plugin's parent entry in `Notebook Navigator`'s context menus.
482
497
  *
@@ -562,6 +577,26 @@ class PluginBase extends (0, import_async_events.mixinAsyncEvents)()(import_obsi
562
577
  onloadImpl() {
563
578
  return (0, import_function.noopAsync)();
564
579
  }
580
+ /**
581
+ * Registers an async cleanup that the next instance of this plugin awaits before it starts.
582
+ *
583
+ * Use it for teardown that cannot finish synchronously and must finish before the resource is opened again, such
584
+ * as closing an IndexedDB connection. Obsidian's `onunload` is synchronous and awaits nothing, so without this a
585
+ * reload starts the new instance while the old one still holds the database.
586
+ *
587
+ * Scoped like {@link addChild}: the cleanup starts when the plugin's feature surface unloads, which is on plugin
588
+ * unload and whenever the gate closes. The next load of the plugin, and the next opening of the gate, await it,
589
+ * bounded by {@link getAsyncCleanupTimeoutInMilliseconds}. A cleanup that throws is printed, never rethrown.
590
+ *
591
+ * @param cleanup - The cleanup to run.
592
+ */
593
+ registerAsyncCleanup(cleanup) {
594
+ (0, import_plugin_async_cleanup.registerPluginAsyncCleanup)({
595
+ cleanup,
596
+ component: this.gatedWrapperComponent,
597
+ pluginId: this.manifest.id
598
+ });
599
+ }
565
600
  /**
566
601
  * Stores a universal component, unloading whichever component the key held before.
567
602
  *
@@ -634,6 +669,9 @@ class PluginBase extends (0, import_async_events.mixinAsyncEvents)()(import_obsi
634
669
  const gatedWrapperComponent = this.gatedWrapperComponent;
635
670
  this.universalWrapperComponent.addChild(gatedWrapperComponent);
636
671
  gatedWrapperComponent.load();
672
+ if ((0, import_plugin_async_cleanup.hasPendingPluginAsyncCleanups)(this.manifest.id)) {
673
+ await this.waitForPreviousAsyncCleanups();
674
+ }
637
675
  await this.onloadImpl();
638
676
  await gatedWrapperComponent.loadWithPromises();
639
677
  for (const declaration of this.getPluginApis()) {
@@ -664,6 +702,13 @@ class PluginBase extends (0, import_async_events.mixinAsyncEvents)()(import_obsi
664
702
  this.universalWrapperComponent.removeChild(gatedWrapperComponent);
665
703
  this.broadcastUnloaded();
666
704
  }
705
+ async waitForPreviousAsyncCleanups() {
706
+ const timeoutInMilliseconds = this.getAsyncCleanupTimeoutInMilliseconds();
707
+ if (await (0, import_plugin_async_cleanup.didPluginAsyncCleanupsSettle)({ pluginId: this.manifest.id, timeoutInMilliseconds })) {
708
+ return;
709
+ }
710
+ console.warn(`Plugin ${this.manifest.id}: the previous instance's async cleanups did not finish in ${String(timeoutInMilliseconds)} ms; loading anyway.`);
711
+ }
667
712
  }
668
713
  async function reloadPlugin(plugin) {
669
714
  const plugins = plugin.app.plugins;
@@ -688,4 +733,4 @@ async function showErrorAndDisablePlugin(plugin, message) {
688
733
  reloadPlugin,
689
734
  showErrorAndDisablePlugin
690
735
  });
691
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9wbHVnaW4vcGx1Z2luLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGZpbGVcbiAqXG4gKiBCYXNlIGNsYXNzIGZvciBPYnNpZGlhbiBwbHVnaW5zIHVzaW5nIGEgY29tcG9uZW50LWJhc2VkIGFyY2hpdGVjdHVyZS5cbiAqXG4gKiBQbHVnaW5CYXNlIHJlZ2lzdGVycyB1bml2ZXJzYWwgY29tcG9uZW50cyAoY29udGV4dCwgaTE4biwgZXJyb3IgaGFuZGxpbmcsIGFib3J0IHNpZ25hbCwgbGlmZWN5Y2xlIGV2ZW50cywgZGVidWcpLlxuICovXG5cbmltcG9ydCB0eXBlIHtcbiAgQ29tcG9uZW50LFxuICBJY29uTmFtZVxufSBmcm9tICdvYnNpZGlhbic7XG5pbXBvcnQgdHlwZSB7IFByb21pc2FibGUgfSBmcm9tICd0eXBlLWZlc3QnO1xuXG5pbXBvcnQgeyBtaXhpbkFzeW5jRXZlbnRzIH0gZnJvbSAnQG1uYW91bW92L3R5cGVzY3JpcHQtbGliL2FzeW5jLWV2ZW50cyc7XG5pbXBvcnQgeyBwcmludEVycm9yIH0gZnJvbSAnQG1uYW91bW92L3R5cGVzY3JpcHQtbGliL2Vycm9yJztcbmltcG9ydCB7IG5vb3BBc3luYyB9IGZyb20gJ0BtbmFvdW1vdi90eXBlc2NyaXB0LWxpYi9mdW5jdGlvbic7XG5pbXBvcnQgeyBlbnN1cmVOb25OdWxsYWJsZSB9IGZyb20gJ0BtbmFvdW1vdi90eXBlc2NyaXB0LWxpYi90eXBlLWd1YXJkcyc7XG5pbXBvcnQgeyBQbHVnaW4gfSBmcm9tICdvYnNpZGlhbic7XG5cbmltcG9ydCB0eXBlIHtcbiAgUGx1Z2luQ29uZmxpY3QsXG4gIFBsdWdpbkRlcGVuZGVuY3lcbn0gZnJvbSAnLi4vY29tcG9uZW50cy9wbHVnaW4tZ2F0ZS1jb21wb25lbnQudHMnO1xuaW1wb3J0IHR5cGUgeyBUcmFuc2xhdGlvbnNNYXAgfSBmcm9tICcuLi9pMThuL2kxOG4udHMnO1xuaW1wb3J0IHR5cGUgeyBQbHVnaW5BcGlEZWNsYXJhdGlvbiB9IGZyb20gJy4vcGx1Z2luLWFwaS50cyc7XG5pbXBvcnQgdHlwZSB7XG4gIFBsdWdpbkV2ZW50TWFwLFxuICBQbHVnaW5FdmVudFNvdXJjZVxufSBmcm9tICcuL3BsdWdpbi1ldmVudC1zb3VyY2UudHMnO1xuaW1wb3J0IHR5cGUgeyBQbHVnaW5MaWZlY3ljbGVFdmVudFBheWxvYWQgfSBmcm9tICcuL3BsdWdpbi1saWZlY3ljbGUtZXZlbnRzLnRzJztcblxuaW1wb3J0IHsgQXBwQWN0aXZlRmlsZVByb3ZpZGVyIH0gZnJvbSAnLi4vYWN0aXZlLWZpbGUtcHJvdmlkZXIudHMnO1xuaW1wb3J0IHsgQ29tbWFuZEhhbmRsZXJDb21wb25lbnQgfSBmcm9tICcuLi9jb21tYW5kLWhhbmRsZXJzL2NvbW1hbmQtaGFuZGxlci1jb21wb25lbnQudHMnO1xuaW1wb3J0IHsgVW5sb2NrQWN0aXZlTm90ZUNvbW1hbmRIYW5kbGVyIH0gZnJvbSAnLi4vY29tbWFuZC1oYW5kbGVycy91bmxvY2stYWN0aXZlLW5vdGUtY29tbWFuZC1oYW5kbGVyLnRzJztcbmltcG9ydCB7IFBsdWdpbkNvbW1hbmRSZWdpc3RyYXIgfSBmcm9tICcuLi9jb21tYW5kLXJlZ2lzdHJhci50cyc7XG5pbXBvcnQgeyBQbHVnaW5FbmFibGVSZWZ1c2VkRXJyb3IgfSBmcm9tICcuLi9jb21tdW5pdHktcGx1Z2lucy50cyc7XG5pbXBvcnQgeyBBYm9ydFNpZ25hbENvbXBvbmVudCB9IGZyb20gJy4uL2NvbXBvbmVudHMvYWJvcnQtc2lnbmFsLWNvbXBvbmVudC50cyc7XG5pbXBvcnQgeyBBc3luY0Vycm9ySGFuZGxlckNvbXBvbmVudCB9IGZyb20gJy4uL2NvbXBvbmVudHMvYXN5bmMtZXJyb3ItaGFuZGxlci1jb21wb25lbnQudHMnO1xuaW1wb3J0IHsgQ29tcG9uZW50RXggfSBmcm9tICcuLi9jb21wb25lbnRzL2NvbXBvbmVudC1leC50cyc7XG5pbXBvcnQgeyBDb25zb2xlRGVidWdDb21wb25lbnQgfSBmcm9tICcuLi9jb21wb25lbnRzL2NvbnNvbGUtZGVidWctY29tcG9uZW50LnRzJztcbmltcG9ydCB7IE1lbnVFdmVudFJlZ2lzdHJhckNvbXBvbmVudCB9IGZyb20gJy4uL2NvbXBvbmVudHMvbWVudS1ldmVudC1yZWdpc3RyYXItY29tcG9uZW50LnRzJztcbmltcG9ydCB7IE5vdGVib29rTmF2aWdhdG9yTWVudUV2ZW50UmVnaXN0cmFyQ29tcG9uZW50IH0gZnJvbSAnLi4vY29tcG9uZW50cy9ub3RlYm9vay1uYXZpZ2F0b3ItbWVudS1ldmVudC1yZWdpc3RyYXItY29tcG9uZW50LnRzJztcbmltcG9ydCB7IFBsdWdpbkNvbnRleHRDb21wb25lbnQgfSBmcm9tICcuLi9jb21wb25lbnRzL3BsdWdpbi1jb250ZXh0LWNvbXBvbmVudC50cyc7XG5pbXBvcnQgeyBQbHVnaW5HYXRlQ29tcG9uZW50IH0gZnJvbSAnLi4vY29tcG9uZW50cy9wbHVnaW4tZ2F0ZS1jb21wb25lbnQudHMnO1xuaW1wb3J0IHsgUGx1Z2luTm90aWNlQ29tcG9uZW50IH0gZnJvbSAnLi4vY29tcG9uZW50cy9wbHVnaW4tbm90aWNlLWNvbXBvbmVudC50cyc7XG5pbXBvcnQgeyBQbHVnaW5TZXR0aW5nc0NvbXBvbmVudEJhc2UgfSBmcm9tICcuLi9jb21wb25lbnRzL3BsdWdpbi1zZXR0aW5ncy1jb21wb25lbnQudHMnO1xuaW1wb3J0IHsgUGx1Z2luRGF0YUhhbmRsZXIgfSBmcm9tICcuLi9kYXRhLWhhbmRsZXIudHMnO1xuaW1wb3J0IHsgaW5pdEkxOE4gfSBmcm9tICcuLi9pMThuL2kxOG4udHMnO1xuaW1wb3J0IHsgZGVmYXVsdFRyYW5zbGF0aW9uc01hcCB9IGZyb20gJy4uL2kxOG4vbG9jYWxlcy90cmFuc2xhdGlvbnMtbWFwLnRzJztcbmltcG9ydCB7IFJlc291cmNlTG9ja0NvbXBvbmVudCB9IGZyb20gJy4uL3Jlc291cmNlLWxvY2sudHMnO1xuaW1wb3J0IHsgcHVibGlzaFBsdWdpbkFwaSB9IGZyb20gJy4vcGx1Z2luLWFwaS50cyc7XG5pbXBvcnQgeyBQbHVnaW5FdmVudFNvdXJjZUltcGwgfSBmcm9tICcuL3BsdWdpbi1ldmVudC1zb3VyY2UudHMnO1xuaW1wb3J0IHtcbiAgUExVR0lOX0xPQURFRF9FVkVOVF9OQU1FLFxuICBQTFVHSU5fVU5MT0FERURfRVZFTlRfTkFNRSxcbiAgdHJpZ2dlclBsdWdpbkxpZmVjeWNsZUV2ZW50XG59IGZyb20gJy4vcGx1Z2luLWxpZmVjeWNsZS1ldmVudHMudHMnO1xuXG4vKipcbiAqIFRoZSB1bml2ZXJzYWwgY29tcG9uZW50cyBvd25lZCBieSB7QGxpbmsgUGx1Z2luQmFzZX0sIGtleWVkIGJ5IHRoZSBuYW1lIG9mIHRoZSBhY2Nlc3NvciBleHBvc2luZ1xuICogZWFjaCBvbmUuIEV2ZXJ5IG1lbWJlciBpcyBvcHRpb25hbCBiZWNhdXNlIGEgY29tcG9uZW50IG9ubHkgZXhpc3RzIG9uY2Uge0BsaW5rIFBsdWdpbkJhc2Uub25sb2FkfVxuICogaGFzIGNyZWF0ZWQgaXQuXG4gKi9cbmludGVyZmFjZSBQbHVnaW5CYXNlQ29tcG9uZW50cyB7XG4gIHJlYWRvbmx5IGFib3J0U2lnbmFsQ29tcG9uZW50PzogQWJvcnRTaWduYWxDb21wb25lbnQ7XG4gIHJlYWRvbmx5IGFzeW5jRXJyb3JIYW5kbGVyQ29tcG9uZW50PzogQXN5bmNFcnJvckhhbmRsZXJDb21wb25lbnQ7XG4gIHJlYWRvbmx5IGNvbW1hbmRIYW5kbGVyQ29tcG9uZW50PzogQ29tbWFuZEhhbmRsZXJDb21wb25lbnQ7XG4gIHJlYWRvbmx5IGNvbnNvbGVEZWJ1Z0NvbXBvbmVudD86IENvbnNvbGVEZWJ1Z0NvbXBvbmVudDtcbiAgcmVhZG9ubHkgcGx1Z2luQ29udGV4dENvbXBvbmVudD86IFBsdWdpbkNvbnRleHRDb21wb25lbnQ7XG4gIHJlYWRvbmx5IHBsdWdpbkdhdGVDb21wb25lbnQ/OiBQbHVnaW5HYXRlQ29tcG9uZW50O1xuICByZWFkb25seSBwbHVnaW5Ob3RpY2VDb21wb25lbnQ/OiBQbHVnaW5Ob3RpY2VDb21wb25lbnQ7XG4gIHJlYWRvbmx5IHBsdWdpblNldHRpbmdzQ29tcG9uZW50PzogUGx1Z2luU2V0dGluZ3NDb21wb25lbnRCYXNlPG9iamVjdD47XG4gIHJlYWRvbmx5IHJlc291cmNlTG9ja0NvbXBvbmVudD86IFJlc291cmNlTG9ja0NvbXBvbmVudDtcbn1cblxuLyoqXG4gKiBCYXNlIGNsYXNzIGZvciBjcmVhdGluZyBPYnNpZGlhbiBwbHVnaW5zIHdpdGggYSBjb21wb25lbnQtYmFzZWQgYXJjaGl0ZWN0dXJlLlxuICpcbiAqIFJlZ2lzdGVycyB1bml2ZXJzYWwgY29tcG9uZW50cyBhdXRvbWF0aWNhbGx5LiBTdWJjbGFzc2VzIGFkZCBvciByZXBsYWNlIGNvbXBvbmVudHNcbiAqIHZpYSB7QGxpbmsgcmVtb3ZlQ2hpbGR9IC8ge0BsaW5rIGFkZENoaWxkfS5cbiAqL1xuZXhwb3J0IGFic3RyYWN0IGNsYXNzIFBsdWdpbkJhc2UgZXh0ZW5kcyBtaXhpbkFzeW5jRXZlbnRzPFBsdWdpbkV2ZW50TWFwPigpKFBsdWdpbikgaW1wbGVtZW50cyBQbHVnaW5FdmVudFNvdXJjZSB7XG4gIC8qKlxuICAgKiBHZXRzIGFib3J0IHNpZ25hbCBjb21wb25lbnQuXG4gICAqXG4gICAqIEByZXR1cm5zIGFib3J0IHNpZ25hbCBjb21wb25lbnQuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0IGFib3J0U2lnbmFsQ29tcG9uZW50KCk6IEFib3J0U2lnbmFsQ29tcG9uZW50IHtcbiAgICByZXR1cm4gZW5zdXJlTm9uTnVsbGFibGUodGhpcy5jb21wb25lbnRzLmFib3J0U2lnbmFsQ29tcG9uZW50KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXRzIGFib3J0IHNpZ25hbCBjb21wb25lbnQuXG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZSAtIEFib3J0IHNpZ25hbCBjb21wb25lbnQuXG4gICAqL1xuICBwcm90ZWN0ZWQgc2V0IGFib3J0U2lnbmFsQ29tcG9uZW50KHZhbHVlOiBBYm9ydFNpZ25hbENvbXBvbmVudCkge1xuICAgIHRoaXMuc2V0Q29tcG9uZW50KCdhYm9ydFNpZ25hbENvbXBvbmVudCcsIHZhbHVlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIGFzeW5jIGVycm9yIGhhbmRsZXIgY29tcG9uZW50LlxuICAgKlxuICAgKiBAcmV0dXJucyBhc3luYyBlcnJvciBoYW5kbGVyIGNvbXBvbmVudC5cbiAgICovXG4gIHByb3RlY3RlZCBnZXQgYXN5bmNFcnJvckhhbmRsZXJDb21wb25lbnQoKTogQXN5bmNFcnJvckhhbmRsZXJDb21wb25lbnQge1xuICAgIHJldHVybiBlbnN1cmVOb25OdWxsYWJsZSh0aGlzLmNvbXBvbmVudHMuYXN5bmNFcnJvckhhbmRsZXJDb21wb25lbnQpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldHMgYXN5bmMgZXJyb3IgaGFuZGxlciBjb21wb25lbnQuXG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZSAtIEFzeW5jIGVycm9yIGhhbmRsZXIgY29tcG9uZW50LlxuICAgKi9cbiAgcHJvdGVjdGVkIHNldCBhc3luY0Vycm9ySGFuZGxlckNvbXBvbmVudCh2YWx1ZTogQXN5bmNFcnJvckhhbmRsZXJDb21wb25lbnQpIHtcbiAgICB0aGlzLnNldENvbXBvbmVudCgnYXN5bmNFcnJvckhhbmRsZXJDb21wb25lbnQnLCB2YWx1ZSk7XG4gIH1cblxuICAvKipcbiAgICogR2V0cyB0aGUgc2hhcmVkIGNvbW1hbmQgaGFuZGxlciBjb21wb25lbnQuIFJlZ2lzdGVyIGEgcGx1Z2luJ3MgY29tbWFuZHMgb24gaXQgdmlhXG4gICAqIHtAbGluayBDb21tYW5kSGFuZGxlckNvbXBvbmVudC5yZWdpc3RlckNvbW1hbmRIYW5kbGVyc30gcmF0aGVyIHRoYW4gY29uc3RydWN0aW5nIHlvdXIgb3duXG4gICAqIHtAbGluayBDb21tYW5kSGFuZGxlckNvbXBvbmVudH0g4oCUIHRoZSBhcHAtYmFja2VkIGFjdGl2ZS1maWxlIHByb3ZpZGVyLCBjb21tYW5kIHJlZ2lzdHJhciwgbWVudVxuICAgKiBldmVudCByZWdpc3RyYXIsIGFuZCBwbHVnaW4gbmFtZSBhcmUgYWxyZWFkeSB3aXJlZC5cbiAgICpcbiAgICogQHJldHVybnMgVGhlIGNvbW1hbmQgaGFuZGxlciBjb21wb25lbnQuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0IGNvbW1hbmRIYW5kbGVyQ29tcG9uZW50KCk6IENvbW1hbmRIYW5kbGVyQ29tcG9uZW50IHtcbiAgICByZXR1cm4gZW5zdXJlTm9uTnVsbGFibGUodGhpcy5jb21wb25lbnRzLmNvbW1hbmRIYW5kbGVyQ29tcG9uZW50KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXRzIHRoZSBjb21tYW5kIGhhbmRsZXIgY29tcG9uZW50LlxuICAgKlxuICAgKiBAcGFyYW0gdmFsdWUgLSBUaGUgY29tbWFuZCBoYW5kbGVyIGNvbXBvbmVudC5cbiAgICovXG4gIHByb3RlY3RlZCBzZXQgY29tbWFuZEhhbmRsZXJDb21wb25lbnQodmFsdWU6IENvbW1hbmRIYW5kbGVyQ29tcG9uZW50KSB7XG4gICAgdGhpcy5zZXRDb21wb25lbnQoJ2NvbW1hbmRIYW5kbGVyQ29tcG9uZW50JywgdmFsdWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgY29uc29sZSBkZWJ1ZyBjb21wb25lbnQuXG4gICAqXG4gICAqIEByZXR1cm5zIGNvbnNvbGUgZGVidWcgY29tcG9uZW50LlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldCBjb25zb2xlRGVidWdDb21wb25lbnQoKTogQ29uc29sZURlYnVnQ29tcG9uZW50IHtcbiAgICByZXR1cm4gZW5zdXJlTm9uTnVsbGFibGUodGhpcy5jb21wb25lbnRzLmNvbnNvbGVEZWJ1Z0NvbXBvbmVudCk7XG4gIH1cblxuICAvKipcbiAgICogU2V0cyBjb25zb2xlIGRlYnVnIGNvbXBvbmVudC5cbiAgICpcbiAgICogQHBhcmFtIHZhbHVlIC0gQ29uc29sZSBkZWJ1ZyBjb21wb25lbnQuXG4gICAqL1xuICBwcm90ZWN0ZWQgc2V0IGNvbnNvbGVEZWJ1Z0NvbXBvbmVudCh2YWx1ZTogQ29uc29sZURlYnVnQ29tcG9uZW50KSB7XG4gICAgdGhpcy5zZXRDb21wb25lbnQoJ2NvbnNvbGVEZWJ1Z0NvbXBvbmVudCcsIHZhbHVlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIHBsdWdpbiBjb250ZXh0IGNvbXBvbmVudCAocGx1Z2luIElELCBkZWJ1ZyBjb250cm9sbGVyLCBsaWJyYXJ5IHN0eWxlcykuXG4gICAqXG4gICAqIEByZXR1cm5zIHBsdWdpbiBjb250ZXh0IGNvbXBvbmVudC5cbiAgICovXG4gIHByb3RlY3RlZCBnZXQgcGx1Z2luQ29udGV4dENvbXBvbmVudCgpOiBQbHVnaW5Db250ZXh0Q29tcG9uZW50IHtcbiAgICByZXR1cm4gZW5zdXJlTm9uTnVsbGFibGUodGhpcy5jb21wb25lbnRzLnBsdWdpbkNvbnRleHRDb21wb25lbnQpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldHMgcGx1Z2luIGNvbnRleHQgY29tcG9uZW50LlxuICAgKlxuICAgKiBAcGFyYW0gdmFsdWUgLSBQbHVnaW4gY29udGV4dCBjb21wb25lbnQuXG4gICAqL1xuICBwcm90ZWN0ZWQgc2V0IHBsdWdpbkNvbnRleHRDb21wb25lbnQodmFsdWU6IFBsdWdpbkNvbnRleHRDb21wb25lbnQpIHtcbiAgICB0aGlzLnNldENvbXBvbmVudCgncGx1Z2luQ29udGV4dENvbXBvbmVudCcsIHZhbHVlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIHRoZSBnYXRlIGhvbGRpbmcgdGhlIHBsdWdpbidzIGZlYXR1cmUgc3VyZmFjZSB1cCBvciBkb3duLlxuICAgKlxuICAgKiBSZWFjaCBmb3IgaXQgZnJvbSBhIHNldHRpbmdzIHRhYiB0byByZW5kZXIgdGhlIG92ZXJsYXAgYmFubmVyIGZvciBhXG4gICAqIHtAbGluayBjb21wb25lbnRzL3BsdWdpbi1nYXRlLWNvbXBvbmVudCFQbHVnaW5Db25mbGljdFNldmVyaXR5Lldhcm59IGNvbmZsaWN0IOKAlCB0aGUgb25lXG4gICAqIGJhbm5lciB0aGUgbGlicmFyeSBjYW5ub3QgcGxhY2UgaXRzZWxmLCBiZWNhdXNlIGEgcnVubmluZyBwbHVnaW4gYnVpbGRzIGl0cyBvd24gc2V0dGluZ3MgdGFiLlxuICAgKlxuICAgKiBSZWFkYWJsZSB0aHJvdWdob3V0IHtAbGluayBvbmxvYWRJbXBsfSwgaW5jbHVkaW5nIGl0cyBzeW5jaHJvbm91cyBwcmVmaXgsIHdoaWNoIGlzIHdoZXJlIGEgc2V0dGluZ3NcbiAgICogdGFiIGlzIGJ1aWx0LiBUaGF0IGlzIGRlbGliZXJhdGUgcmF0aGVyIHRoYW4gaW5jaWRlbnRhbDogYWRkaW5nIHRoZSBnYXRlIGlzIHdoYXQgcnVuc1xuICAgKiB7QGxpbmsgb25sb2FkSW1wbH0sIHNvIHtAbGluayBvbmxvYWR9IGFzc2lnbnMgdGhpcyBmaWVsZCBiZWZvcmUgYWRkaW5nIGl0LlxuICAgKlxuICAgKiBAcmV0dXJucyBUaGUgcGx1Z2luIGdhdGUgY29tcG9uZW50LlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldCBwbHVnaW5HYXRlQ29tcG9uZW50KCk6IFBsdWdpbkdhdGVDb21wb25lbnQge1xuICAgIHJldHVybiBlbnN1cmVOb25OdWxsYWJsZSh0aGlzLmNvbXBvbmVudHMucGx1Z2luR2F0ZUNvbXBvbmVudCk7XG4gIH1cblxuICAvKipcbiAgICogU2V0cyB0aGUgcGx1Z2luIGdhdGUgY29tcG9uZW50LlxuICAgKlxuICAgKiBAcGFyYW0gdmFsdWUgLSBUaGUgcGx1Z2luIGdhdGUgY29tcG9uZW50LlxuICAgKi9cbiAgcHJvdGVjdGVkIHNldCBwbHVnaW5HYXRlQ29tcG9uZW50KHZhbHVlOiBQbHVnaW5HYXRlQ29tcG9uZW50KSB7XG4gICAgdGhpcy5zZXRDb21wb25lbnQoJ3BsdWdpbkdhdGVDb21wb25lbnQnLCB2YWx1ZSk7XG4gIH1cblxuICAvKipcbiAgICogR2V0cyBwbHVnaW4gbm90aWNlIGNvbXBvbmVudC5cbiAgICpcbiAgICogQHJldHVybnMgcGx1Z2luIG5vdGljZSBjb21wb25lbnQuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0IHBsdWdpbk5vdGljZUNvbXBvbmVudCgpOiBQbHVnaW5Ob3RpY2VDb21wb25lbnQge1xuICAgIHJldHVybiBlbnN1cmVOb25OdWxsYWJsZSh0aGlzLmNvbXBvbmVudHMucGx1Z2luTm90aWNlQ29tcG9uZW50KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXRzIHBsdWdpbiBub3RpY2UgY29tcG9uZW50LlxuICAgKlxuICAgKiBAcGFyYW0gdmFsdWUgLSBQbHVnaW4gbm90aWNlIGNvbXBvbmVudC5cbiAgICovXG4gIHByb3RlY3RlZCBzZXQgcGx1Z2luTm90aWNlQ29tcG9uZW50KHZhbHVlOiBQbHVnaW5Ob3RpY2VDb21wb25lbnQpIHtcbiAgICB0aGlzLnNldENvbXBvbmVudCgncGx1Z2luTm90aWNlQ29tcG9uZW50JywgdmFsdWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgcGx1Z2luIHNldHRpbmdzIGNvbXBvbmVudC5cbiAgICpcbiAgICogQHJldHVybnMgcGx1Z2luIHNldHRpbmdzIGNvbXBvbmVudC5cbiAgICovXG4gIHByb3RlY3RlZCBnZXQgcGx1Z2luU2V0dGluZ3NDb21wb25lbnQoKTogUGx1Z2luU2V0dGluZ3NDb21wb25lbnRCYXNlPG9iamVjdD4ge1xuICAgIHJldHVybiBlbnN1cmVOb25OdWxsYWJsZSh0aGlzLmNvbXBvbmVudHMucGx1Z2luU2V0dGluZ3NDb21wb25lbnQpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldHMgcGx1Z2luIHNldHRpbmdzIGNvbXBvbmVudC5cbiAgICpcbiAgICogQHBhcmFtIHZhbHVlIC0gUGx1Z2luIHNldHRpbmdzIGNvbXBvbmVudC5cbiAgICovXG4gIHByb3RlY3RlZCBzZXQgcGx1Z2luU2V0dGluZ3NDb21wb25lbnQodmFsdWU6IFBsdWdpblNldHRpbmdzQ29tcG9uZW50QmFzZTxvYmplY3Q+KSB7XG4gICAgdGhpcy5zZXRDb21wb25lbnQoJ3BsdWdpblNldHRpbmdzQ29tcG9uZW50JywgdmFsdWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgdGhlIGVkaXRvciBsb2NrIGNvbXBvbmVudCwgdXNlZCB0byBsb2NrIG5vdGVzIHJlYWQtb25seSBkdXJpbmcgbG9uZyBvcGVyYXRpb25zLiBPd25lZCBieVxuICAgKiB0aGUgcGx1Z2luLCBzbyBpdHMgbG9ja3MgYXJlIHJlbGVhc2VkIGF1dG9tYXRpY2FsbHkgd2hlbiB0aGUgcGx1Z2luIHVubG9hZHMuXG4gICAqXG4gICAqIEByZXR1cm5zIEVkaXRvciBsb2NrIGNvbXBvbmVudC5cbiAgICovXG4gIHByb3RlY3RlZCBnZXQgcmVzb3VyY2VMb2NrQ29tcG9uZW50KCk6IFJlc291cmNlTG9ja0NvbXBvbmVudCB7XG4gICAgcmV0dXJuIGVuc3VyZU5vbk51bGxhYmxlKHRoaXMuY29tcG9uZW50cy5yZXNvdXJjZUxvY2tDb21wb25lbnQpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldHMgdGhlIGVkaXRvciBsb2NrIGNvbXBvbmVudC5cbiAgICpcbiAgICogQHBhcmFtIHZhbHVlIC0gRWRpdG9yIGxvY2sgY29tcG9uZW50LlxuICAgKi9cbiAgcHJvdGVjdGVkIHNldCByZXNvdXJjZUxvY2tDb21wb25lbnQodmFsdWU6IFJlc291cmNlTG9ja0NvbXBvbmVudCkge1xuICAgIHRoaXMuc2V0Q29tcG9uZW50KCdyZXNvdXJjZUxvY2tDb21wb25lbnQnLCB2YWx1ZSk7XG4gIH1cblxuICBwcml2YXRlIHJlYWRvbmx5IGNvbXBvbmVudHM6IFBsdWdpbkJhc2VDb21wb25lbnRzID0ge307XG5cbiAgLy8gRXZlcnl0aGluZyB0aGUgU1VCQ0xBU1Mgb3duczogd2hhdCBgb25sb2FkSW1wbGAgYWRkcywgYW5kIHdoYXQgaXQgYWRkcyBsYXRlci5cbiAgLy9cbiAgLy8gQSBzZWNvbmQgd3JhcHBlciByYXRoZXIgdGhhbiBvbmUsIGJlY2F1c2UgdGhlIHR3byB0aWVycyBoYXZlIG9wcG9zaXRlIGxpZmV0aW1lcy4gVGhlIHVuaXZlcnNhbFxuICAvLyBjb21wb25lbnRzIGhhdmUgdG8gT1VUTElWRSBhIGxvc3QgZGVwZW5kZW5jeSDigJQgdGhleSBhcmUgd2hhdCBzaG93cyB0aGUgbm90aWNlIG5hbWluZyB0aGUgcGx1Z2luIHRoYXRcbiAgLy8gd2VudCBhd2F5IGFuZCByZW5kZXJzIHRoZSBidXR0b24gdGhhdCBicmluZ3MgaXQgYmFjayDigJQgd2hpbGUgdGhlIHN1YmNsYXNzJ3Mgc3VyZmFjZSBpcyBleGFjdGx5IHdoYXRcbiAgLy8gbXVzdCBzdG9wIHJ1bm5pbmcuIFVubG9hZGluZyBvbmUgd3JhcHBlciBob2xkaW5nIGJvdGggd291bGQgc2lsZW5jZSB0aGUgcGx1Z2luIGF0IHRoZSBtb21lbnQgaXQgbW9zdFxuICAvLyBuZWVkcyB0byBzcGVhay5cbiAgLy9cbiAgLy8gQWx3YXlzIHByZXNlbnQsIG5ldmVyIG51bGwsIGFuZCBSRVBMQUNFRCByYXRoZXIgdGhhbiBlbXB0aWVkIHdoZW4gdGhlIHN1cmZhY2UgaXMgdG9ybiBkb3duLiBUaGF0IGtlZXBzXG4gIC8vIGBhZGRDaGlsZGAgY2FsbGFibGUgYXQgZXZlcnkgcG9pbnQgaW4gdGhlIHBsdWdpbidzIGxpZmUsIGV4YWN0bHkgYXMgaXQgd2FzIGJlZm9yZSB0aGUgdGllcnMgZXhpc3RlZDpcbiAgLy8gQSBjaGlsZCBhZGRlZCBiZWZvcmUgdGhlIGdhdGUgb3BlbnMgaXMgcXVldWVkIGFuZCBsb2FkZWQgd2hlbiBpdCBkb2VzLCB3aGljaCBpcyB3aGF0IGBDb21wb25lbnRFeGBcbiAgLy8gYWxyZWFkeSBkb2VzIGZvciBhbnkgY2hpbGQgYWRkZWQgdG8gYSBub3QteWV0LWxvYWRlZCBjb21wb25lbnQuXG4gIHByaXZhdGUgZ2F0ZWRXcmFwcGVyQ29tcG9uZW50ID0gbmV3IENvbXBvbmVudEV4KCk7XG5cbiAgLy8gVGhlIHBheWxvYWQgYnJvYWRjYXN0IHdoZW4gdGhpcyBwbHVnaW4gZmluaXNoZWQgbG9hZGluZywga2VwdCBzbyB0aGUgbWF0Y2hpbmcgdW5sb2FkZWQgYnJvYWRjYXN0XG4gIC8vIGRlc2NyaWJlcyB0aGUgc2FtZSBwbHVnaW4gd2l0aG91dCByZS1kZXJpdmluZyBpdCBmcm9tIGEgc3VyZmFjZSB0aGF0IGhhcyBzaW5jZSBiZWVuIHRvcm4gZG93bi4gTnVsbFxuICAvLyB3aGVuZXZlciBubyBsb2FkZWQgYnJvYWRjYXN0IGlzIG91dHN0YW5kaW5nLCB3aGljaCBpcyB3aGF0IGtlZXBzIHRoZSB0d28gZXZlbnRzIHBhaXJlZC5cbiAgcHJpdmF0ZSBsaWZlY3ljbGVFdmVudFBheWxvYWQ6IG51bGwgfCBQbHVnaW5MaWZlY3ljbGVFdmVudFBheWxvYWQgPSBudWxsO1xuXG4gIC8vIFRoZSBsaWJyYXJ5J3Mgb3duIGNvbXBvbmVudHMsIHdoaWNoIG91dGxpdmUgYW55IGRlcGVuZGVuY3kuXG4gIHByaXZhdGUgcmVhZG9ubHkgdW5pdmVyc2FsV3JhcHBlckNvbXBvbmVudCA9IG5ldyBDb21wb25lbnRFeCgpO1xuXG4gIC8qKlxuICAgKiBBZGRzIGEgY2hpbGQgY29tcG9uZW50LlxuICAgKlxuICAgKiBUaGUgY2hpbGQgaXMgYWRkZWQgdG8gdGhlIGludGVybmFsIHdyYXBwZXIgaG9sZGluZyB0aGUgc3ViY2xhc3MncyBvd24gc3VyZmFjZSwgd2hpY2gge0BsaW5rIG9ubG9hZH1cbiAgICogY3JlYXRlcyBhbmQgbG9hZHMgYmVmb3JlIGNhbGxpbmcge0BsaW5rIG9ubG9hZEltcGx9LiBTbyBhIGNoaWxkIGFkZGVkIGR1cmluZyB7QGxpbmsgb25sb2FkSW1wbH0gaXNcbiAgICogbG9hZGVkIGltbWVkaWF0ZWx5LCBjaGlsZHJlbi1maXJzdCwgYW5kIGlzIHVzYWJsZSBieSB0aGUgdGltZSB0aGlzIG1ldGhvZCByZXR1cm5zLlxuICAgKlxuICAgKiBUaGF0IHdyYXBwZXIgaXMgdG9ybiBkb3duIGFuZCByZWJ1aWx0IHdoZW5ldmVyIHRoZSBnYXRlIGNsb3NlcyBhbmQgb3BlbnMgYWdhaW4g4oCUIGEgZGVwZW5kZW5jeSBkZWNsYXJlZFxuICAgKiBieSB7QGxpbmsgZ2V0UGx1Z2luRGVwZW5kZW5jaWVzfSBnb2luZyBhd2F5IGFuZCBjb21pbmcgYmFjaywgb3IgYSBjb25mbGljdCBkZWNsYXJlZCBieVxuICAgKiB7QGxpbmsgZ2V0UGx1Z2luQ29uZmxpY3RzfSBhcHBlYXJpbmcgYW5kIGJlaW5nIHJlc29sdmVkIOKAlCBzbyBhIGNoaWxkIGFkZGVkIGhlcmUgbGl2ZXMgZXhhY3RseSBhcyBsb25nXG4gICAqIGFzIHRoZSBwbHVnaW4ncyBmZWF0dXJlIHN1cmZhY2UgZG9lcy4gQWRkaW5nIG9uZSB3aGlsZSB0aGUgc3VyZmFjZSBpcyBkb3duIGlzIHN0aWxsIGxlZ2l0aW1hdGUg4oCUIGl0IGlzXG4gICAqIHF1ZXVlZCBhbmQgbG9hZGVkIHdoZW4gdGhlIHN1cmZhY2UgbmV4dCBjb21lcyB1cCwgdGhlIHdheSB7QGxpbmsgQ29tcG9uZW50RXguYWRkQ2hpbGR9IGFscmVhZHkgcXVldWVzXG4gICAqIGEgY2hpbGQgYWRkZWQgdG8gYSBub3QteWV0LWxvYWRlZCBjb21wb25lbnQuXG4gICAqXG4gICAqIFRoaXMgaXMgdGhlIFNVQkNMQVNTJ3MgZG9vciwgYW5kIHRoZSBvbmx5IG9uZSBpdCBoYXM6IHRoZSB1bml2ZXJzYWwgY29tcG9uZW50cyB7QGxpbmsgb25sb2FkfSByZWdpc3RlcnNcbiAgICogdGFrZSBhIHByaXZhdGUgcm91dGUgb250byBhIGRpZmZlcmVudCB3cmFwcGVyLiBTbyBhbnl0aGluZyBvYnNlcnZpbmcgdGhpcyBtZXRob2Qg4oCUIGEgdGVzdCBjb3VudGluZyBpdHNcbiAgICogY2FsbHMsIGEgcGF0Y2ggd3JhcHBpbmcgaXQg4oCUIHNlZXMgZXhhY3RseSB0aGUgY2hpbGRyZW4gdGhlIHN1YmNsYXNzIGFkZGVkLCBhbmQgbm9uZSBvZiB0aGUgbGlicmFyeSdzLlxuICAgKiBCZWZvcmUgdGhlIHR3byB0aWVycyBleGlzdGVkIG9uZSBkb29yIGNhcnJpZWQgYm90aCwgYW5kIGEgY29uc3VtZXIgY291bnRpbmcgdGhlIHRvdGFsIGlzIHRoZSBvbmUgdGhpbmdcbiAgICogdGhlIHNwbGl0IGNvdWxkIG5vdCBrZWVwIHdvcmtpbmcuXG4gICAqXG4gICAqIEB0eXBlUGFyYW0gVENvbXBvbmVudCAtIFRoZSB0eXBlIG9mIGNvbXBvbmVudCB0byBhZGQuXG4gICAqIEBwYXJhbSBjb21wb25lbnQgLSBUaGUgY29tcG9uZW50IGluc3RhbmNlIHRvIGFkZC5cbiAgICogQHJldHVybnMgVGhlIGFkZGVkIGNvbXBvbmVudC5cbiAgICovXG4gIHB1YmxpYyBvdmVycmlkZSBhZGRDaGlsZDxUQ29tcG9uZW50IGV4dGVuZHMgQ29tcG9uZW50Pihjb21wb25lbnQ6IFRDb21wb25lbnQpOiBUQ29tcG9uZW50IHtcbiAgICByZXR1cm4gdGhpcy5nYXRlZFdyYXBwZXJDb21wb25lbnQuYWRkQ2hpbGQoY29tcG9uZW50KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDYWxsZWQgd2hlbiB0aGUgZXh0ZXJuYWwgc2V0dGluZ3MgY2hhbmdlLlxuICAgKlxuICAgKiBPdmVycmlkZSBpbiBzdWJjbGFzcyBpZiBuZWVkZWQuIE1ha2Ugc3VyZSB0byBjYWxsIGBhd2FpdCBzdXBlci5vbkV4dGVybmFsU2V0dGluZ3NDaGFuZ2UoKWAgZmlyc3QuXG4gICAqL1xuICBwdWJsaWMgb3ZlcnJpZGUgYXN5bmMgb25FeHRlcm5hbFNldHRpbmdzQ2hhbmdlKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGF3YWl0IHN1cGVyLm9uRXh0ZXJuYWxTZXR0aW5nc0NoYW5nZT8uKCk7XG4gICAgYXdhaXQgdGhpcy50cmlnZ2VyQXN5bmMoJ2V4dGVybmFsU2V0dGluZ3NDaGFuZ2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDYWxsZWQgd2hlbiB0aGUgcGx1Z2luIGlzIGxvYWRlZC5cbiAgICpcbiAgICogT3JjaGVzdHJhdGVzIGxvYWRpbmc6IHJlZ2lzdGVycyB0aGUgdW5pdmVyc2FsIGNvbXBvbmVudHMsIGxldHMgdGhlIHN1YmNsYXNzIHdpcmUgaXRzIG93blxuICAgKiBjb21wb25lbnRzIHZpYSB7QGxpbmsgb25sb2FkSW1wbH0sIHRoZW4gYXdhaXRzIHRoZSBhc3luYyB0YWlsIG9mIGV2ZXJ5IGxvYWQuXG4gICAqIEVhY2ggY29tcG9uZW50IGxvYWRzIGFzIGl0IGlzIGFkZGVkLCBjaGlsZHJlbi1maXJzdC5cbiAgICpcbiAgICogRG8gTk9UIG92ZXJyaWRlIHRoaXMgbWV0aG9kLiBPdmVycmlkZSB7QGxpbmsgb25sb2FkSW1wbH0gaW5zdGVhZC5cbiAgICovXG4gIHB1YmxpYyBvdmVycmlkZSBhc3luYyBvbmxvYWQoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdHJ5IHtcbiAgICAgIC8vIFRoZSB3cmFwcGVyIGlzIGF0dGFjaGVkIGFuZCBsb2FkZWQgYmVmb3JlIGFueXRoaW5nIGlzIHdpcmVkIHVwLCBzbyBldmVyeSBgYWRkQ2hpbGRgIGJlbG93XG4gICAgICAvLyBsb2FkcyBpdHMgY2hpbGQgc3RyYWlnaHQgYXdheSByYXRoZXIgdGhhbiBxdWV1aW5nIGl0LlxuICAgICAgLy8gVGhhdCBpcyB3aGF0IGxldHMgYSBjb21tYW5kIGhhbmRsZXIgcmVnaXN0ZXIgaXRzIG1lbnUgZXZlbnRzIGZyb20gYG9uUmVnaXN0ZXJlZGAsIHdoaWNoXG4gICAgICAvLyBgcmVnaXN0ZXJDb21tYW5kSGFuZGxlcnNgIGF3YWl0cyBhbmQgd2hpY2ggYSByZWdpc3RyYXIgcmVmdXNlcyB3aGlsZSB1bmxvYWRlZC5cbiAgICAgIC8vIEF0dGFjaGluZyBpdCB1cCBmcm9udCBhbHNvIHJlZ2lzdGVycyB0aGUgd3JhcHBlciBmb3IgdGVhcmRvd24gYmVmb3JlIGFueXRoaW5nIGNhbiB0aHJvdy5cbiAgICAgIC8vIFRoZSBsb2FkIGlzIGV4cGxpY2l0IHJhdGhlciB0aGFuIGxlZnQgdG8gYGFkZENoaWxkYCwgd2hpY2ggbG9hZHMgdGhlIGNoaWxkIG9ubHkgd2hlbiB0aGVcbiAgICAgIC8vIHBsdWdpbiBpdHNlbGYgaXMgbG9hZGVkIOKAlCB0cnVlIHdoZW4gT2JzaWRpYW4gY2FsbHMgYGxvYWQoKWAsIGJ1dCBub3Qgd2hlbiBhIGNhbGxlciBpbnZva2VzXG4gICAgICAvLyBgb25sb2FkKClgIGRpcmVjdGx5LlxuICAgICAgc3VwZXIuYWRkQ2hpbGQodGhpcy51bml2ZXJzYWxXcmFwcGVyQ29tcG9uZW50KTtcbiAgICAgIHRoaXMudW5pdmVyc2FsV3JhcHBlckNvbXBvbmVudC5sb2FkKCk7XG5cbiAgICAgIGF3YWl0IGluaXRJMThOKHRoaXMuY3JlYXRlVHJhbnNsYXRpb25zTWFwKCkpO1xuICAgICAgdGhpcy5wbHVnaW5Db250ZXh0Q29tcG9uZW50ID0gdGhpcy5hZGRVbml2ZXJzYWxDaGlsZChcbiAgICAgICAgbmV3IFBsdWdpbkNvbnRleHRDb21wb25lbnQoe1xuICAgICAgICAgIGFwcDogdGhpcy5hcHAsXG4gICAgICAgICAgcGx1Z2luSWQ6IHRoaXMubWFuaWZlc3QuaWRcbiAgICAgICAgfSlcbiAgICAgICk7XG4gICAgICB0aGlzLnBsdWdpbk5vdGljZUNvbXBvbmVudCA9IHRoaXMuYWRkVW5pdmVyc2FsQ2hpbGQoXG4gICAgICAgIG5ldyBQbHVnaW5Ob3RpY2VDb21wb25lbnQoe1xuICAgICAgICAgIGFwcDogdGhpcy5hcHAsXG4gICAgICAgICAgcGx1Z2luTmFtZTogdGhpcy5tYW5pZmVzdC5uYW1lXG4gICAgICAgIH0pXG4gICAgICApO1xuICAgICAgdGhpcy5hc3luY0Vycm9ySGFuZGxlckNvbXBvbmVudCA9IHRoaXMuYWRkVW5pdmVyc2FsQ2hpbGQobmV3IEFzeW5jRXJyb3JIYW5kbGVyQ29tcG9uZW50KHRoaXMucGx1Z2luTm90aWNlQ29tcG9uZW50KSk7XG4gICAgICB0aGlzLmFib3J0U2lnbmFsQ29tcG9uZW50ID0gdGhpcy5hZGRVbml2ZXJzYWxDaGlsZChuZXcgQWJvcnRTaWduYWxDb21wb25lbnQodGhpcy5tYW5pZmVzdC5pZCkpO1xuICAgICAgdGhpcy5jb25zb2xlRGVidWdDb21wb25lbnQgPSB0aGlzLmFkZFVuaXZlcnNhbENoaWxkKG5ldyBDb25zb2xlRGVidWdDb21wb25lbnQodGhpcy5tYW5pZmVzdC5pZCkpO1xuICAgICAgdGhpcy5yZXNvdXJjZUxvY2tDb21wb25lbnQgPSB0aGlzLmFkZFVuaXZlcnNhbENoaWxkKG5ldyBSZXNvdXJjZUxvY2tDb21wb25lbnQodGhpcy5hcHAsIHRoaXMubWFuaWZlc3QuaWQpKTtcbiAgICAgIC8vIGBOb3RlYm9vayBOYXZpZ2F0b3JgIGRyYXdzIGl0cyBvd24gZmlsZSB0cmVlIGFuZCBuZXZlciByYWlzZXMgT2JzaWRpYW4ncyBgZmlsZS1tZW51YCAvXG4gICAgICAvLyBgZmlsZXMtbWVudWAgZXZlbnRzLCBzbyBldmVyeSBwbHVnaW4ncyBjb250ZXh0LW1lbnUgaXRlbXMgd291bGQgdmFuaXNoIGZvciBhbnlvbmUgYnJvd3NpbmdcbiAgICAgIC8vIHRocm91Z2ggaXQuIFdpcmVkIGhlcmUgcmF0aGVyIHRoYW4gcGVyLXBsdWdpbjogdGhlIGJyaWRnZSBzdGF5cyBkb3JtYW50IHdoZW4gTm90ZWJvb2tcbiAgICAgIC8vIE5hdmlnYXRvciBpcyBub3QgaW5zdGFsbGVkLCBhbmQgYSBwbHVnaW4gd2l0aCBubyBmaWxlL2ZvbGRlciBoYW5kbGVycyBjb250cmlidXRlcyBub3RoaW5nLlxuICAgICAgY29uc3Qgbm90ZWJvb2tOYXZpZ2F0b3JNZW51RXZlbnRSZWdpc3RyYXJDb21wb25lbnQgPSB0aGlzLmFkZFVuaXZlcnNhbENoaWxkKFxuICAgICAgICBuZXcgTm90ZWJvb2tOYXZpZ2F0b3JNZW51RXZlbnRSZWdpc3RyYXJDb21wb25lbnQoe1xuICAgICAgICAgIGFwcDogdGhpcy5hcHAsXG4gICAgICAgICAgcGx1Z2luTmFtZTogdGhpcy5tYW5pZmVzdC5uYW1lLFxuICAgICAgICAgIHN1Ym1lbnVJY29uOiB0aGlzLmdldE5vdGVib29rTmF2aWdhdG9yTWVudVN1Ym1lbnVJY29uKClcbiAgICAgICAgfSlcbiAgICAgICk7XG4gICAgICB0aGlzLmNvbW1hbmRIYW5kbGVyQ29tcG9uZW50ID0gdGhpcy5hZGRVbml2ZXJzYWxDaGlsZChcbiAgICAgICAgbmV3IENvbW1hbmRIYW5kbGVyQ29tcG9uZW50KHtcbiAgICAgICAgICBhY3RpdmVGaWxlUHJvdmlkZXI6IG5ldyBBcHBBY3RpdmVGaWxlUHJvdmlkZXIodGhpcy5hcHApLFxuICAgICAgICAgIGFkZGl0aW9uYWxNZW51RXZlbnRSZWdpc3RyYXJzOiBbbm90ZWJvb2tOYXZpZ2F0b3JNZW51RXZlbnRSZWdpc3RyYXJDb21wb25lbnRdLFxuICAgICAgICAgIC8vIFRoZSBjb21wb25lbnQgaXMgdW5pdmVyc2FsOyB0aGUgY29tbWFuZHMgcmVnaXN0ZXJlZCBUSFJPVUdIIGl0IGFyZSBub3QuIEEgc3ViY2xhc3MgcmVnaXN0ZXJzXG4gICAgICAgICAgLy8gaXRzIG93biBmcm9tIGBvbmxvYWRJbXBsYCwgY2xvc2luZyBvdmVyIGNvbGxhYm9yYXRvcnMgdGhhdCBiZWxvbmcgdG8gdGhlIGZlYXR1cmUgc3VyZmFjZSDigJQgc29cbiAgICAgICAgICAvLyB0aG9zZSBjb21tYW5kcyBtdXN0IGdvIGRvd24gd2l0aCB0aGUgc3VyZmFjZSB3aGVuIHRoZSBnYXRlIGNsb3Nlcywgb3IgdGhleSBzaXQgaW4gdGhlIHBhbGV0dGVcbiAgICAgICAgICAvLyBjYWxsaW5nIGludG8gdG9ybi1kb3duIG9iamVjdHMsIGFuZCBhcmUgcmVnaXN0ZXJlZCBhIHNlY29uZCB0aW1lIHdoZW4gdGhlIGdhdGUgcmVvcGVucyBhbmRcbiAgICAgICAgICAvLyBgb25sb2FkSW1wbGAgcnVucyBhZ2Fpbi5cbiAgICAgICAgICAvLyBSZXNvbHZlZCBvbiBldmVyeSBjYWxsIHJhdGhlciB0aGFuIGNhcHR1cmVkIGhlcmUsIGJlY2F1c2UgYHVubG9hZEZlYXR1cmVTdXJmYWNlYCBSRVBMQUNFUyB0aGVcbiAgICAgICAgICAvLyB3cmFwcGVyIGluc3RlYWQgb2YgZW1wdHlpbmcgaXQ6IGVhY2ggY3ljbGUncyBjb21tYW5kcyBiZWxvbmcgdG8gdGhhdCBjeWNsZSdzIHdyYXBwZXIuXG4gICAgICAgICAgY29tbWFuZExpZmV0aW1lT3duZXJQcm92aWRlcjogKCk6IENvbXBvbmVudEV4ID0+IHRoaXMuZ2F0ZWRXcmFwcGVyQ29tcG9uZW50LFxuICAgICAgICAgIGNvbW1hbmRSZWdpc3RyYXI6IG5ldyBQbHVnaW5Db21tYW5kUmVnaXN0cmFyKHRoaXMpLFxuICAgICAgICAgIG1lbnVFdmVudFJlZ2lzdHJhcjogdGhpcy5hZGRVbml2ZXJzYWxDaGlsZChuZXcgTWVudUV2ZW50UmVnaXN0cmFyQ29tcG9uZW50KHRoaXMuYXBwKSksXG4gICAgICAgICAgcGx1Z2luTmFtZTogdGhpcy5tYW5pZmVzdC5uYW1lXG4gICAgICAgIH0pXG4gICAgICApO1xuICAgICAgLy8gQWx3YXlzIGF2YWlsYWJsZTsgdGhlIGNvbW1hbmQncyBvd24gYGNhbkV4ZWN1dGVgIGhpZGVzIGl0IHVubGVzcyB0aGUgYWN0aXZlIG5vdGUgaXMgbG9ja2VkLlxuICAgICAgLy8gVGhlIG9uZSBjb21tYW5kIHRoYXQgbmFtZXMgaXRzIG93bmVyIGV4cGxpY2l0bHksIG9wdGluZyBPVVQgb2YgdGhlIHN1cmZhY2Utc2NvcGVkIGRlZmF1bHQgYWJvdmU6XG4gICAgICAvLyBJdCBpcyB0aGUgcmVzY3VlIGZvciBhIG5vdGUgbGVmdCBsb2NrZWQsIGl0IGNsb3NlcyBvdmVyIG5vdGhpbmcgYnV0IHRoZSB1bml2ZXJzYWwgcmVzb3VyY2UtbG9ja1xuICAgICAgLy8gY29tcG9uZW50LCBhbmQgYSBibG9ja2VkIHBsdWdpbiBpcyBleGFjdGx5IHdoZW4gYSB1c2VyIG1heSBuZWVkIGl0LlxuICAgICAgYXdhaXQgdGhpcy5jb21tYW5kSGFuZGxlckNvbXBvbmVudC5yZWdpc3RlckNvbW1hbmRIYW5kbGVycygoKSA9PiBbXG4gICAgICAgIG5ldyBVbmxvY2tBY3RpdmVOb3RlQ29tbWFuZEhhbmRsZXIoe1xuICAgICAgICAgIGFwcDogdGhpcy5hcHAsXG4gICAgICAgICAgcmVzb3VyY2VMb2NrQ29tcG9uZW50OiB0aGlzLnJlc291cmNlTG9ja0NvbXBvbmVudFxuICAgICAgICB9KVxuICAgICAgXSwgeyBsaWZldGltZU93bmVyOiB0aGlzLmNvbW1hbmRIYW5kbGVyQ29tcG9uZW50IH0pO1xuXG4gICAgICB0aGlzLnBsdWdpblNldHRpbmdzQ29tcG9uZW50ID0gdGhpcy5hZGRVbml2ZXJzYWxDaGlsZChcbiAgICAgICAgbmV3IFBsdWdpblNldHRpbmdzQ29tcG9uZW50QmFzZTxvYmplY3Q+KHtcbiAgICAgICAgICBkYXRhSGFuZGxlcjogbmV3IFBsdWdpbkRhdGFIYW5kbGVyKHRoaXMpLFxuICAgICAgICAgIHBsdWdpbkV2ZW50U291cmNlOiBuZXcgUGx1Z2luRXZlbnRTb3VyY2VJbXBsKHRoaXMpLFxuICAgICAgICAgIHBsdWdpblNldHRpbmdzQ2xhc3M6IE9iamVjdFxuICAgICAgICB9KVxuICAgICAgKTtcblxuICAgICAgLy8gVGhlIGdhdGUuIEl0IGxvYWRzIHRoZSBmZWF0dXJlIHN1cmZhY2UgaXRzZWxmIG9uY2UgZXZlcnkgZGVjbGFyZWQgZGVwZW5kZW5jeSBpcyBzYXRpc2ZpZWQgYW5kIG5vXG4gICAgICAvLyBkZWNsYXJlZCBjb25mbGljdCBob2xkcyDigJQgd2hpY2ggZm9yIGEgcGx1Z2luIGRlY2xhcmluZyBuZWl0aGVyIGlzIGltbWVkaWF0ZWx5LCBzeW5jaHJvbm91c2x5LFxuICAgICAgLy8gYmVmb3JlIHRoaXMgbGluZSByZXR1cm5zIOKAlCBhbmQgdW5sb2FkcyBpdCBhZ2FpbiBpZiBhIGRlcGVuZGVuY3kgaXMgbGF0ZXIgZGlzYWJsZWQgb3IgdW5pbnN0YWxsZWQsXG4gICAgICAvLyBvciBhIGNvbmZsaWN0aW5nIHBsdWdpbiBpcyBlbmFibGVkLiBBIHBsdWdpbiB0aGF0IGlzIGJsb2NrZWQgdGhlcmVmb3JlIHJlYWNoZXMgYGxvYWRXaXRoUHJvbWlzZXNgXG4gICAgICAvLyBiZWxvdyBoYXZpbmcgcmVnaXN0ZXJlZCBub3RoaW5nIG9mIGl0cyBvd24sIHdpdGggb25seSB0aGUgdW5pdmVyc2FsIGNvbXBvbmVudHMgYWJvdmUgcnVubmluZyB0b1xuICAgICAgLy8gZXhwbGFpbiB3aHkgYW5kIHRvIG9mZmVyIHRoZSByZXBhaXIuXG4gICAgICAvLyBBc3NpZ25lZCBCRUZPUkUgdGhlIGFkZCwgdW5saWtlIGV2ZXJ5IHVuaXZlcnNhbCBjb21wb25lbnQgYWJvdmUsIGFuZCB0aGF0IG9yZGVyIGlzIHRoZSB3aG9sZVxuICAgICAgLy8gcG9pbnQuIEFkZGluZyB0aGlzIG9uZSBpcyB3aGF0IHJ1bnMgYG9ubG9hZEltcGxgLCBwZXIgdGhlIHBhcmFncmFwaCBhYm92ZSwgc28gdGhlIGFzc2lnbm1lbnRcbiAgICAgIC8vIHN0YXRlbWVudCBoYXMgbm90IHJldHVybmVkIHlldCB3aGlsZSB0aGUgc3ViY2xhc3MgaXMgcnVubmluZyDigJQgYW5kIGEgc2V0dGluZ3MgdGFiIGJ1aWx0IHRoZXJlXG4gICAgICAvLyByZWFkcyBgdGhpcy5wbHVnaW5HYXRlQ29tcG9uZW50YCB0byByZW5kZXIgdGhlIGBXYXJuYCBiYW5uZXIuIEFzc2lnbmluZyBhZnRlciB0aGUgYWRkIHdvdWxkXG4gICAgICAvLyBtYWtlIHRoYXQgcmVhZCB0aHJvdyBgVmFsdWUgaXMgdW5kZWZpbmVkYCBvdXQgb2YgdGhlIGdldHRlciwgd2hpY2ggaXMgYW4gb3BhcXVlIHdheSB0byBzYXlcbiAgICAgIC8vIFwidG9vIGVhcmx5XCIuIE5vdGhpbmcgYWJvdXQgY2hpbGQtYWRkIG9yZGVyIG1vdmVzOiB0aGUgc2VxdWVuY2Ugb2YgYGFkZFVuaXZlcnNhbENoaWxkYCBjYWxscyBpc1xuICAgICAgLy8gdW5jaGFuZ2VkLCBhbmQgYHNldENvbXBvbmVudGAgaXMgYSBwbGFpbiBzdG9yZS5cbiAgICAgIGNvbnN0IHBsdWdpbkdhdGVDb21wb25lbnQgPSBuZXcgUGx1Z2luR2F0ZUNvbXBvbmVudCh7XG4gICAgICAgIGNvbmZsaWN0czogdGhpcy5nZXRQbHVnaW5Db25mbGljdHMoKSxcbiAgICAgICAgZGVwZW5kZW5jaWVzOiB0aGlzLmdldFBsdWdpbkRlcGVuZGVuY2llcygpLFxuICAgICAgICBsb2FkRmVhdHVyZVN1cmZhY2U6ICgpOiBQcm9taXNlPHZvaWQ+ID0+IHRoaXMubG9hZEZlYXR1cmVTdXJmYWNlKCksXG4gICAgICAgIHBsdWdpbjogdGhpcyxcbiAgICAgICAgcGx1Z2luTm90aWNlQ29tcG9uZW50OiB0aGlzLnBsdWdpbk5vdGljZUNvbXBvbmVudCxcbiAgICAgICAgdW5sb2FkRmVhdHVyZVN1cmZhY2U6ICgpOiB2b2lkID0+IHtcbiAgICAgICAgICB0aGlzLnVubG9hZEZlYXR1cmVTdXJmYWNlKCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgdGhpcy5wbHVnaW5HYXRlQ29tcG9uZW50ID0gcGx1Z2luR2F0ZUNvbXBvbmVudDtcbiAgICAgIHRoaXMuYWRkVW5pdmVyc2FsQ2hpbGQocGx1Z2luR2F0ZUNvbXBvbmVudCk7XG5cbiAgICAgIC8vIEV2ZXJ5IGNoaWxkIGhhcyBhbHJlYWR5IGxvYWRlZCBhcyBpdCB3YXMgYWRkZWQ7IHRoaXMgYXdhaXRzIHRoZWlyIGFjY3VtdWxhdGVkIGFzeW5jIHRhaWxzIGFuZFxuICAgICAgLy8gcmVwb3J0cyBhbnkgZmFpbHVyZSBhcyBhIHNpbmdsZSBgQWdncmVnYXRlRXJyb3JgLlxuICAgICAgYXdhaXQgdGhpcy51bml2ZXJzYWxXcmFwcGVyQ29tcG9uZW50LmxvYWRXaXRoUHJvbWlzZXMoKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgcHJpbnRFcnJvcihuZXcgRXJyb3IoYEVycm9yIGxvYWRpbmcgcGx1Z2luICR7dGhpcy5tYW5pZmVzdC5uYW1lfSAoJHt0aGlzLm1hbmlmZXN0LmlkfSlgLCB7IGNhdXNlOiBlcnJvciB9KSk7XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ2FsbGVkIHdoZW4gdGhlIHBsdWdpbiBpcyB1bmxvYWRlZC5cbiAgICpcbiAgICogQW5ub3VuY2VzIHRoZSBkZXBhcnR1cmUgb24gYGFwcC53b3Jrc3BhY2VgIHNvIGFueXRoaW5nIGRlcGVuZGluZyBvbiB0aGlzIHBsdWdpbiBsZWFybnMgb2YgaXQgYXQgdGhlXG4gICAqIG1vbWVudCBpdCBoYXBwZW5zLCByYXRoZXIgdGhhbiBkaXNjb3ZlcmluZyBpdCBsYXRlciB0aHJvdWdoIGJlaGF2aW9yIHRoYXQgcXVpZXRseSBzdG9wcGVkLlxuICAgKlxuICAgKiBEbyBOT1Qgb3ZlcnJpZGUgdGhpcyBtZXRob2Q7IHB1dCB0ZWFyZG93biBvbiBhIGNvbXBvbmVudCBpbnN0ZWFkLCB3aGljaCB1bmxvYWRzIHdpdGggdGhlIHBsdWdpbi5cbiAgICovXG4gIHB1YmxpYyBvdmVycmlkZSBvbnVubG9hZCgpOiB2b2lkIHtcbiAgICB0aGlzLmJyb2FkY2FzdFVubG9hZGVkKCk7XG4gICAgc3VwZXIub251bmxvYWQoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmVzIGEgY2hpbGQgY29tcG9uZW50LlxuICAgKlxuICAgKiBAdHlwZVBhcmFtIFRDb21wb25lbnQgLSBUaGUgdHlwZSBvZiBjb21wb25lbnQgdG8gcmVtb3ZlLlxuICAgKiBAcGFyYW0gY29tcG9uZW50IC0gVGhlIGNvbXBvbmVudCBpbnN0YW5jZSB0byByZW1vdmUuXG4gICAqIEByZXR1cm5zIFRoZSByZW1vdmVkIGNvbXBvbmVudC5cbiAgICovXG4gIHB1YmxpYyBvdmVycmlkZSByZW1vdmVDaGlsZDxUQ29tcG9uZW50IGV4dGVuZHMgQ29tcG9uZW50Pihjb21wb25lbnQ6IFRDb21wb25lbnQpOiBUQ29tcG9uZW50IHtcbiAgICAvLyBSb3V0ZWQgYnkgb3duZXJzaGlwIHJhdGhlciB0aGFuIGJ5IHdoaWNoIHRpZXIgYGFkZENoaWxkYCB3b3VsZCBoYXZlIGNob3NlbiwgYmVjYXVzZSB0aGUgdHdvIGRvIG5vdFxuICAgIC8vIGFsd2F5cyBhZ3JlZTogYSB1bml2ZXJzYWwgY29tcG9uZW50IGlzIHBhcmVudGVkIGRpcmVjdGx5IG9uIHRoZSB1bml2ZXJzYWwgd3JhcHBlciwgeWV0IGEgc3ViY2xhc3NcbiAgICAvLyByZXBsYWNpbmcgb25lIGdvZXMgdGhyb3VnaCB0aGUgc2FtZSBwdWJsaWMgYHJlbW92ZUNoaWxkYCBhcyBpdCB3b3VsZCBmb3IgaXRzIG93biBjaGlsZHJlbi5cbiAgICByZXR1cm4gdGhpcy5nYXRlZFdyYXBwZXJDb21wb25lbnQuaGFzQ2hpbGQoY29tcG9uZW50KSA/IHRoaXMuZ2F0ZWRXcmFwcGVyQ29tcG9uZW50LnJlbW92ZUNoaWxkKGNvbXBvbmVudCkgOiB0aGlzLnVuaXZlcnNhbFdyYXBwZXJDb21wb25lbnQucmVtb3ZlQ2hpbGQoY29tcG9uZW50KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQcm92aWRlcyB0aGUgdHJhbnNsYXRpb25zIG1hcCB1c2VkIHRvIGluaXRpYWxpemUgaTE4biBkdXJpbmcge0BsaW5rIG9ubG9hZH0uXG4gICAqXG4gICAqIE92ZXJyaWRlIGluIHN1YmNsYXNzIHRvIHN1cHBseSBwbHVnaW4tc3BlY2lmaWMgdHJhbnNsYXRpb25zLiBUaGUgZGVmYXVsdCByZXR1cm5zIHRoZSBidWlsdC1pblxuICAgKiBgQG1uYW91bW92L29ic2lkaWFuLWxpYmAgdHJhbnNsYXRpb25zLlxuICAgKlxuICAgKiBAcmV0dXJucyBUaGUgdHJhbnNsYXRpb25zIG1hcC5cbiAgICovXG4gIHByb3RlY3RlZCBjcmVhdGVUcmFuc2xhdGlvbnNNYXAoKTogVHJhbnNsYXRpb25zTWFwIHtcbiAgICByZXR1cm4gZGVmYXVsdFRyYW5zbGF0aW9uc01hcDtcbiAgfVxuXG4gIC8qKlxuICAgKiBQcm92aWRlcyB0aGUgaWNvbiBzaG93biBvbiB0aGUgcGx1Z2luJ3MgcGFyZW50IGVudHJ5IGluIGBOb3RlYm9vayBOYXZpZ2F0b3JgJ3MgY29udGV4dCBtZW51cy5cbiAgICpcbiAgICogT3ZlcnJpZGUgaW4gc3ViY2xhc3MgdG8gYnJhbmQgdGhhdCBlbnRyeTsgdGhlIGRlZmF1bHQgbGVhdmVzIGl0IHdpdGhvdXQgYW4gaWNvbi4gVGhlIGVudHJ5IGlzXG4gICAqIHRpdGxlZCB3aXRoIHRoZSBwbHVnaW4gbmFtZSBhbmQgaXMgYWRkZWQgYXV0b21hdGljYWxseSDigJQgc2VlXG4gICAqIHtAbGluayBOb3RlYm9va05hdmlnYXRvck1lbnVFdmVudFJlZ2lzdHJhckNvbXBvbmVudH0uXG4gICAqXG4gICAqIEByZXR1cm5zIFRoZSBpY29uLCBvciBgJydgIGZvciBubyBpY29uLlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldE5vdGVib29rTmF2aWdhdG9yTWVudVN1Ym1lbnVJY29uKCk6IEljb25OYW1lIHtcbiAgICByZXR1cm4gJyc7XG4gIH1cblxuICAvKipcbiAgICogUHJvdmlkZXMgdGhlIEFQSXMgdGhpcyBwbHVnaW4gZXhwb3NlcyB0byBvdGhlciBwbHVnaW5zLlxuICAgKlxuICAgKiBPdmVycmlkZSBpbiBzdWJjbGFzcyB0byBwdWJsaXNoIG9uZS4gVGhlIGRlZmF1bHQgcHVibGlzaGVzIG5vbmUuIENhbGxlZCBhZnRlciB7QGxpbmsgb25sb2FkSW1wbH0sIHNvIGFcbiAgICogZGVjbGFyYXRpb24gbWF5IHJlZmVyZW5jZSBhbnl0aGluZyBpdCBjcmVhdGVkOyB0aGUgcmV0dXJuZWQgZGVjbGFyYXRpb25zIGFyZSBwdWJsaXNoZWQgdGhyb3VnaFxuICAgKiBgcHVibGlzaFBsdWdpbkFwaWAgYW5kIHJldm9rZWQgd2hlbiB0aGUgcGx1Z2luJ3MgZmVhdHVyZSBzdXJmYWNlIHVubG9hZHMuXG4gICAqXG4gICAqIFJldHVybmluZyBhIExJU1QgcmF0aGVyIHRoYW4gYSBzaW5nbGUgQVBJIGlzIGRlbGliZXJhdGU6IHRoZSByZWdpc3RyeSBzdXBwb3J0cyBzZXZlcmFsIGNvbnRyYWN0XG4gICAqIHZlcnNpb25zIHB1Ymxpc2hlZCBzaWRlIGJ5IHNpZGUsIHdoaWNoIGlzIGhvdyBhIHByb3ZpZGVyIHNoaXBzIGEgYnJlYWtpbmcgYDIuMC4wYCB3aXRob3V0IHN0cmFuZGluZ1xuICAgKiBjb25zdW1lcnMgc3RpbGwgcGlubmVkIHRvIGBeMWAuXG4gICAqXG4gICAqIEV2ZXJ5IGRlY2xhcmF0aW9uIGhlcmUgaXMgcHVibGlzaGVkIEJFRk9SRSB0aGUgYG9ic2lkaWFuLWxpYjpwbHVnaW4tbG9hZGVkYCBicm9hZGNhc3QsIHdoaWNoIGlzXG4gICAqIHdoYXQgbGV0cyBhIGxpc3RlbmVyIGNhbGwgdGhlc2UgQVBJcyB0aGUgbW9tZW50IGl0IGhlYXJzIHRoYXQgZXZlbnQuXG4gICAqXG4gICAqIEByZXR1cm5zIFRoZSBBUEkgZGVjbGFyYXRpb25zLlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldFBsdWdpbkFwaXMoKTogUGx1Z2luQXBpRGVjbGFyYXRpb25bXSB7XG4gICAgcmV0dXJuIFtdO1xuICB9XG5cbiAgLyoqXG4gICAqIFByb3ZpZGVzIHRoZSBwbHVnaW5zIHRoaXMgb25lIHJlZnVzZXMsIG9yIHdhcm5zIGFib3V0LCBydW5uaW5nIGJlc2lkZS5cbiAgICpcbiAgICogT3ZlcnJpZGUgaW4gc3ViY2xhc3MgdG8gZGVjbGFyZSBhbiBvdmVybGFwLiBUaGUgZGVmYXVsdCBkZWNsYXJlcyBub25lLlxuICAgKlxuICAgKiBBIGBCbG9ja2AgY29uZmxpY3QgaXMgdGhlIG1pcnJvciBpbWFnZSBvZiBhIGRlcGVuZGVuY3k6IHdoaWxlIGEgY29uZmxpY3RpbmcgcGx1Z2luIGlzIGVuYWJsZWQgYXQgYVxuICAgKiBjb25mbGljdGluZyB2ZXJzaW9uLCB7QGxpbmsgb25sb2FkSW1wbH0gZG9lcyBub3QgcnVuIGF0IGFsbCBhbmQgdGhlIHBsdWdpbiByZWdpc3RlcnMgbm90aGluZy4gRGVjbGFyZVxuICAgKiBpdCB3aGVuIGJvdGggcGx1Z2lucyBhY3Rpbmcgb24gdGhlIHNhbWUgb3BlcmF0aW9uIGRhbWFnZXMgdGhlIHZhdWx0IOKAlCB0aGVyZSBpcyBubyByZWxpYWJsZSB3YXkgdG8gd2luXG4gICAqIHRoYXQgcmFjZSwgYmVjYXVzZSB3aGljaGV2ZXIgcGx1Z2luIGxvYWRlZCBmaXJzdCBrZWVwcyBhIGhhbmQgb24gdGhlIHdoZWVsLCBzbyByZWZ1c2luZyBkZXRlcm1pbmlzdGljYWxseVxuICAgKiBiZWF0cyBjb21wZXRpbmcgdW5wcmVkaWN0YWJseS4gQSBgV2FybmAgY29uZmxpY3QgZGVjbGFyZXMgYW4gb3ZlcmxhcCB0aGF0IGlzIG1lcmVseSBhbm5veWluZywgc3VjaCBhcyBhXG4gICAqIGR1cGxpY2F0ZWQgY29tbWFuZDogYm90aCBwbHVnaW5zIGtlZXAgcnVubmluZyBhbmQgdGhlIHVzZXIgaXMgdG9sZC5cbiAgICpcbiAgICogVW5saWtlIGEgZGVwZW5kZW5jeSwgYSBjb25mbGljdGluZyBwbHVnaW4gbmVlZCBub3QgcHVibGlzaCBhbnl0aGluZyDigJQgaXQgaXMgZGV0ZWN0ZWQgYnkgcmVhZGluZyBpdHNcbiAgICogaW5zdGFsbGVkIHZlcnNpb24sIHdoaWNoIGlzIHRoZSBvbmx5IHRoaW5nIGFib3V0IGFub3RoZXIgcGx1Z2luIHRoYXQgcmVhZHMgdGhlIHNhbWUgcmVnYXJkbGVzcyBvZiBsb2FkXG4gICAqIG9yZGVyLlxuICAgKlxuICAgKiBAcmV0dXJucyBUaGUgZGVjbGFyZWQgY29uZmxpY3RzLlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldFBsdWdpbkNvbmZsaWN0cygpOiBQbHVnaW5Db25mbGljdFtdIHtcbiAgICByZXR1cm4gW107XG4gIH1cblxuICAvKipcbiAgICogUHJvdmlkZXMgdGhlIHBsdWdpbnMgdGhpcyBvbmUgY2Fubm90IHdvcmsgd2l0aG91dC5cbiAgICpcbiAgICogT3ZlcnJpZGUgaW4gc3ViY2xhc3MgdG8gZGVjbGFyZSBhIG1hbmRhdG9yeSBkZXBlbmRlbmN5LiBUaGUgZGVmYXVsdCBkZWNsYXJlcyBub25lLCBhbmQgc3VjaCBhIHBsdWdpblxuICAgKiBsb2FkcyBleGFjdGx5IGFzIGl0IGFsd2F5cyBoYXMuXG4gICAqXG4gICAqIEEgZGVjbGFyZWQgZGVwZW5kZW5jeSBpcyBNQU5EQVRPUlksIHVubGlrZSB0aGUgb2ZmZXIgYFBsdWdpblN1Z2dlc3Rpb25Db21wb25lbnRgIG1ha2VzOiB3aGlsZSBvbmUgaXNcbiAgICogbWlzc2luZywgZGlzYWJsZWQsIG9yIHRvbyBvbGQsIHtAbGluayBvbmxvYWRJbXBsfSBkb2VzIG5vdCBydW4gYXQgYWxsIGFuZCB0aGUgcGx1Z2luIHJlZ2lzdGVycyBub3RoaW5nXG4gICAqIOKAlCBubyBjb21tYW5kcywgbm8gaGFuZGxlcnMsIG5vIHBhdGNoZXMuIEl0IHN0YXlzIGVuYWJsZWQgaW4gT2JzaWRpYW4ncyBsaXN0IHJhdGhlciB0aGFuIGRpc2FibGluZ1xuICAgKiBpdHNlbGYsIGJlY2F1c2UgdGhlIGVuYWJsZWQgc2V0IGlzIHRoZSB1c2VyJ3MgdG8gY2hhbmdlLCBhbmQgaXQgZXhwbGFpbnMgaXRzZWxmIHRocm91Z2ggYSBub3RpY2UgYW5kIGFcbiAgICogc2V0dGluZ3MgYmFubmVyIHRoYXQgaW5zdGFsbHMgdGhlIG1pc3NpbmcgcGx1Z2luIGluIG9uZSBjbGljay4gVGhlIGxvYWQgY29tcGxldGVzIHRoZSBtb21lbnQgdGhlXG4gICAqIGRlcGVuZGVuY3kgYXJyaXZlcywgd2l0aCBubyByZXN0YXJ0LlxuICAgKlxuICAgKiBBIGRlcGVuZGVuY3kgbXVzdCBwdWJsaXNoIGFuIEFQSSB0aHJvdWdoIGBwdWJsaXNoUGx1Z2luQXBpYCwgd2hpY2ggaXMgd2hhdCBtYWtlcyBpdHMgcHJlc2VuY2UsXG4gICAqIGFic2VuY2UsIHZlcnNpb24gYW5kIGRlcGFydHVyZSBhbGwgb2JzZXJ2YWJsZSB0aHJvdWdoIG9uZSBtZWNoYW5pc20uIEEgcGx1Z2luIHdpdGggbm90aGluZyB0byBleHBvc2VcbiAgICogY2FuIHB1Ymxpc2ggYW4gZW1wdHkgQVBJIHB1cmVseSBzbyBpdCBjYW4gYmUgZGVwZW5kZWQgdXBvbi5cbiAgICpcbiAgICogQHJldHVybnMgVGhlIGRlY2xhcmVkIGRlcGVuZGVuY2llcy5cbiAgICovXG4gIHByb3RlY3RlZCBnZXRQbHVnaW5EZXBlbmRlbmNpZXMoKTogUGx1Z2luRGVwZW5kZW5jeVtdIHtcbiAgICByZXR1cm4gW107XG4gIH1cblxuICAvKipcbiAgICogQ2FsbGVkIGR1cmluZyB7QGxpbmsgb25sb2FkfSB0byB3aXJlIHBsdWdpbi1zcGVjaWZpYyBjaGlsZCBjb21wb25lbnRzLlxuICAgKlxuICAgKiBPdmVycmlkZSBpbiBzdWJjbGFzcyB0byBhZGQgY2hpbGQgY29tcG9uZW50cyB2aWEge0BsaW5rIGFkZENoaWxkfS4gVGhlIHVuaXZlcnNhbCBjb21wb25lbnRzIGFyZVxuICAgKiBhdmFpbGFibGUgaGVyZS4gQ2hpbGRyZW4gYXJlIGxvYWRlZCBzZXF1ZW50aWFsbHkgaW4gdGhlIG9yZGVyIHRoZXkgYXJlIGFkZGVkIChjaGlsZHJlbi1maXJzdCkuXG4gICAqXG4gICAqIEByZXR1cm5zIEEge0BsaW5rIFByb21pc2V9IHRoYXQgcmVzb2x2ZXMgd2hlbiB0aGUgc3ViY2xhc3MgbG9hZCBsb2dpYyBpcyBjb21wbGV0ZS5cbiAgICovXG4gIHByb3RlY3RlZCBvbmxvYWRJbXBsKCk6IFByb21pc2FibGU8dm9pZD4ge1xuICAgIHJldHVybiBub29wQXN5bmMoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdG9yZXMgYSB1bml2ZXJzYWwgY29tcG9uZW50LCB1bmxvYWRpbmcgd2hpY2hldmVyIGNvbXBvbmVudCB0aGUga2V5IGhlbGQgYmVmb3JlLlxuICAgKlxuICAgKiBLZXllZCBieSBuYW1lIHJhdGhlciB0aGFuIGhhbmRlZCB0aGUgcHJldmlvdXMgdmFsdWUgYmVjYXVzZSBga2V5b2YgdGhpc2AgZXhjbHVkZXMgcHJpdmF0ZVxuICAgKiBtZW1iZXJzLCBzbyB0aGUgY29tcG9uZW50cyBsaXZlIGluIGEgc2luZ2xlIHtAbGluayBQbHVnaW5CYXNlQ29tcG9uZW50c30gYmFnIHdob3NlIGtleXMgQVJFXG4gICAqIGluZGV4YWJsZS5cbiAgICpcbiAgICogQHR5cGVQYXJhbSBUS2V5IC0gVGhlIGtleSBvZiB0aGUgY29tcG9uZW50IHRvIHN0b3JlLlxuICAgKiBAcGFyYW0ga2V5IC0gVGhlIGtleSBvZiB0aGUgY29tcG9uZW50IHRvIHN0b3JlLlxuICAgKiBAcGFyYW0gdmFsdWUgLSBUaGUgY29tcG9uZW50IHRvIHN0b3JlLlxuICAgKi9cbiAgLyoqXG4gICAqIEFkZHMgYSBjb21wb25lbnQgdG8gdGhlIHVuaXZlcnNhbCB0aWVyLCB3aGljaCBvdXRsaXZlcyBhbnkgZGVwZW5kZW5jeS5cbiAgICpcbiAgICogUHJpdmF0ZSBvbiBwdXJwb3NlOiBvbmx5IHRoaXMgY2xhc3MgZGVjaWRlcyB3aGF0IGlzIHVuaXZlcnNhbC4gQSBzdWJjbGFzcyBhZGRpbmcgb25lIG9mIGl0cyBvd24gZ29lc1xuICAgKiB0aHJvdWdoIHtAbGluayBhZGRDaGlsZH0gYW5kIGxhbmRzIGluIHRoZSBnYXRlZCB0aWVyLCB3aGVyZSBpdCBiZWxvbmdzLlxuICAgKlxuICAgKiBAdHlwZVBhcmFtIFRDb21wb25lbnQgLSBUaGUgdHlwZSBvZiBjb21wb25lbnQgdG8gYWRkLlxuICAgKiBAcGFyYW0gY29tcG9uZW50IC0gVGhlIGNvbXBvbmVudCBpbnN0YW5jZSB0byBhZGQuXG4gICAqIEByZXR1cm5zIFRoZSBhZGRlZCBjb21wb25lbnQuXG4gICAqL1xuICBwcml2YXRlIGFkZFVuaXZlcnNhbENoaWxkPFRDb21wb25lbnQgZXh0ZW5kcyBDb21wb25lbnQ+KGNvbXBvbmVudDogVENvbXBvbmVudCk6IFRDb21wb25lbnQge1xuICAgIHJldHVybiB0aGlzLnVuaXZlcnNhbFdyYXBwZXJDb21wb25lbnQuYWRkQ2hpbGQoY29tcG9uZW50KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBbm5vdW5jZXMgb24gYGFwcC53b3Jrc3BhY2VgIHRoYXQgdGhpcyBwbHVnaW4gaXMgbG9hZGVkIGFuZCBpdHMgQVBJcyBhcmUgY2FsbGFibGUuXG4gICAqL1xuICBwcml2YXRlIGJyb2FkY2FzdExvYWRlZCgpOiB2b2lkIHtcbiAgICB0aGlzLmxpZmVjeWNsZUV2ZW50UGF5bG9hZCA9IHtcbiAgICAgIGFwaVZlcnNpb25zOiB0aGlzLmdldFBsdWdpbkFwaXMoKS5tYXAoKGRlY2xhcmF0aW9uKSA9PiBkZWNsYXJhdGlvbi5hcGlWZXJzaW9uKSxcbiAgICAgIGRlcGVuZGVuY3lQbHVnaW5JZHM6IHRoaXMuZ2V0UGx1Z2luRGVwZW5kZW5jaWVzKCkubWFwKChkZXBlbmRlbmN5KSA9PiBkZXBlbmRlbmN5LnBsdWdpbklkKSxcbiAgICAgIHBsdWdpbklkOiB0aGlzLm1hbmlmZXN0LmlkLFxuICAgICAgcGx1Z2luTmFtZTogdGhpcy5tYW5pZmVzdC5uYW1lLFxuICAgICAgcGx1Z2luVmVyc2lvbjogdGhpcy5tYW5pZmVzdC52ZXJzaW9uXG4gICAgfTtcblxuICAgIHRyaWdnZXJQbHVnaW5MaWZlY3ljbGVFdmVudCh7XG4gICAgICBhcHA6IHRoaXMuYXBwLFxuICAgICAgbmFtZTogUExVR0lOX0xPQURFRF9FVkVOVF9OQU1FLFxuICAgICAgcGF5bG9hZDogdGhpcy5saWZlY3ljbGVFdmVudFBheWxvYWRcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBbm5vdW5jZXMgb24gYGFwcC53b3Jrc3BhY2VgIHRoYXQgdGhpcyBwbHVnaW4ncyBzdXJmYWNlIGhhcyBnb25lIGF3YXkuXG4gICAqXG4gICAqIFNpbGVudCB1bmxlc3MgYSBsb2FkZWQgYnJvYWRjYXN0IGlzIG91dHN0YW5kaW5nLCBzbyB0aGUgdHdvIGV2ZW50cyBzdGF5IHBhaXJlZDogYSBwbHVnaW4gdGhhdCBuZXZlclxuICAgKiBnb3QgcGFzdCBpdHMgZGVwZW5kZW5jeSBnYXRlIG5ldmVyIGFubm91bmNlZCBpdHNlbGYsIGFuZCBtdXN0IG5vdCBhbm5vdW5jZSBhIGRlcGFydHVyZSBlaXRoZXIuXG4gICAqL1xuICBwcml2YXRlIGJyb2FkY2FzdFVubG9hZGVkKCk6IHZvaWQge1xuICAgIGNvbnN0IHBheWxvYWQgPSB0aGlzLmxpZmVjeWNsZUV2ZW50UGF5bG9hZDtcbiAgICBpZiAoIXBheWxvYWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLmxpZmVjeWNsZUV2ZW50UGF5bG9hZCA9IG51bGw7XG4gICAgdHJpZ2dlclBsdWdpbkxpZmVjeWNsZUV2ZW50KHtcbiAgICAgIGFwcDogdGhpcy5hcHAsXG4gICAgICBuYW1lOiBQTFVHSU5fVU5MT0FERURfRVZFTlRfTkFNRSxcbiAgICAgIHBheWxvYWRcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBCdWlsZHMgYW5kIGxvYWRzIHRoZSBzdWJjbGFzcydzIGZlYXR1cmUgc3VyZmFjZSwgdGhlbiBwdWJsaXNoZXMgaXRzIEFQSXMgYW5kIGFubm91bmNlcyBpdHNlbGYuXG4gICAqXG4gICAqIE5PVCBpZGVtcG90ZW50LCBkZWxpYmVyYXRlbHkuIGBQbHVnaW5HYXRlQ29tcG9uZW50YCBvd25zIHRoZSB1cC9kb3duIHN0YXRlIG1hY2hpbmUgYW5kIGNhbGxzXG4gICAqIHRoaXMgb25seSBvbiBhIHJlYWwgdHJhbnNpdGlvbjsgYSBzZWNvbmQgZ3VhcmQgaGVyZSB3b3VsZCBiZSBhIHNlY29uZCBjb3B5IG9mIHRoYXQgc3RhdGUsIHdoaWNoIGlzIHRoZVxuICAgKiBraW5kIG9mIGR1cGxpY2F0ZSB0aGF0IGRyaWZ0cy5cbiAgICpcbiAgICogQHJldHVybnMgQSB7QGxpbmsgUHJvbWlzZX0gdGhhdCByZXNvbHZlcyBvbmNlIHRoZSBzdXJmYWNlIGlzIGxvYWRlZCBhbmQgdGhlIGJyb2FkY2FzdCBoYXMgYmVlbiBtYWRlLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBsb2FkRmVhdHVyZVN1cmZhY2UoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgLy8gTG9hZGVkIGV4cGxpY2l0bHkgZm9yIHRoZSBzYW1lIHJlYXNvbiB0aGUgdW5pdmVyc2FsIHdyYXBwZXIgaXM6IGBhZGRDaGlsZGAgbG9hZHMgYSBjaGlsZCBvbmx5IG9uY2VcbiAgICAvLyBpdHMgcGFyZW50IGlzIGxvYWRlZCwgYW5kIHRoZSBzdXJmYWNlIGhhcyB0byBiZSBsaXZlIGJlZm9yZSBgb25sb2FkSW1wbGAgc3RhcnRzIGFkZGluZyB0byBpdC5cbiAgICBjb25zdCBnYXRlZFdyYXBwZXJDb21wb25lbnQgPSB0aGlzLmdhdGVkV3JhcHBlckNvbXBvbmVudDtcbiAgICB0aGlzLnVuaXZlcnNhbFdyYXBwZXJDb21wb25lbnQuYWRkQ2hpbGQoZ2F0ZWRXcmFwcGVyQ29tcG9uZW50KTtcbiAgICBnYXRlZFdyYXBwZXJDb21wb25lbnQubG9hZCgpO1xuXG4gICAgYXdhaXQgdGhpcy5vbmxvYWRJbXBsKCk7XG4gICAgYXdhaXQgZ2F0ZWRXcmFwcGVyQ29tcG9uZW50LmxvYWRXaXRoUHJvbWlzZXMoKTtcblxuICAgIGZvciAoY29uc3QgZGVjbGFyYXRpb24gb2YgdGhpcy5nZXRQbHVnaW5BcGlzKCkpIHtcbiAgICAgIHB1Ymxpc2hQbHVnaW5BcGkoe1xuICAgICAgICAuLi5kZWNsYXJhdGlvbixcbiAgICAgICAgLy8gUmV2b2tlZCB3aXRoIHRoZSBTVVJGQUNFLCBub3Qgd2l0aCB0aGUgcGx1Z2luOiBhIHBsdWdpbiB3aG9zZSBkZXBlbmRlbmN5IGdvZXMgYXdheSBrZWVwcyBydW5uaW5nXG4gICAgICAgIC8vIGl0cyB1bml2ZXJzYWwgY29tcG9uZW50cywgYW5kIGEgY29uc3VtZXIgbXVzdCBub3QgYmUgbGVmdCBob2xkaW5nIGEgaGFuZGxlIGludG8gdGhlIGhhbGYgb2YgaXRcbiAgICAgICAgLy8gdGhhdCB3YXMganVzdCB0b3JuIGRvd24uXG4gICAgICAgIGNvbXBvbmVudDogZ2F0ZWRXcmFwcGVyQ29tcG9uZW50LFxuICAgICAgICBwbHVnaW46IHRoaXNcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHRoaXMuYnJvYWRjYXN0TG9hZGVkKCk7XG4gIH1cblxuICBwcml2YXRlIHNldENvbXBvbmVudDxUS2V5IGV4dGVuZHMga2V5b2YgUGx1Z2luQmFzZUNvbXBvbmVudHM+KGtleTogVEtleSwgdmFsdWU6IE5vbk51bGxhYmxlPFBsdWdpbkJhc2VDb21wb25lbnRzW1RLZXldPik6IHZvaWQge1xuICAgIGNvbnN0IG9sZENvbXBvbmVudCA9IHRoaXMuY29tcG9uZW50c1trZXldO1xuICAgIGlmIChvbGRDb21wb25lbnQpIHtcbiAgICAgIHRoaXMucmVtb3ZlQ2hpbGQob2xkQ29tcG9uZW50KTtcbiAgICB9XG4gICAgdGhpcy5jb21wb25lbnRzW2tleV0gPSB2YWx1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUZWFycyB0aGUgc3ViY2xhc3MncyBmZWF0dXJlIHN1cmZhY2UgZG93biwgbGVhdmluZyB0aGUgdW5pdmVyc2FsIGNvbXBvbmVudHMgcnVubmluZy5cbiAgICovXG4gIHByaXZhdGUgdW5sb2FkRmVhdHVyZVN1cmZhY2UoKTogdm9pZCB7XG4gICAgY29uc3QgZ2F0ZWRXcmFwcGVyQ29tcG9uZW50ID0gdGhpcy5nYXRlZFdyYXBwZXJDb21wb25lbnQ7XG5cbiAgICAvLyBSZXBsYWNlZCBCRUZPUkUgdGhlIG9sZCBvbmUgaXMgdW5sb2FkZWQsIHNvIGFueXRoaW5nIHRoYXQgcmVzdW1lcyBtaWQtdGVhcmRvd24gYW5kIGNhbGxzIGBhZGRDaGlsZGBcbiAgICAvLyBwYXJrcyBpdHMgY2hpbGQgb24gdGhlIGZyZXNoIHN1cmZhY2UgcmF0aGVyIHRoYW4gb24gdGhlIG9uZSBiZWluZyB0b3JuIGRvd24g4oCUIHdoZXJlIGBDb21wb25lbnRFeGBcbiAgICAvLyB3b3VsZCByZWZ1c2UgaXQgb3V0cmlnaHQsIHNpbmNlIGl0IHJlZnVzZXMgY2hpbGRyZW4gYWRkZWQgdG8gYW4gYWxyZWFkeS11bmxvYWRlZCBjb21wb25lbnQuXG4gICAgdGhpcy5nYXRlZFdyYXBwZXJDb21wb25lbnQgPSBuZXcgQ29tcG9uZW50RXgoKTtcbiAgICB0aGlzLnVuaXZlcnNhbFdyYXBwZXJDb21wb25lbnQucmVtb3ZlQ2hpbGQoZ2F0ZWRXcmFwcGVyQ29tcG9uZW50KTtcblxuICAgIHRoaXMuYnJvYWRjYXN0VW5sb2FkZWQoKTtcbiAgfVxufVxuXG4vKipcbiAqIFJlbG9hZHMgdGhlIHNwZWNpZmllZCBwbHVnaW4gYnkgZGlzYWJsaW5nIGFuZCB0aGVuIHJlLWVuYWJsaW5nIGl0LlxuICpcbiAqIEBwYXJhbSBwbHVnaW4gLSBUaGUgcGx1Z2luIHRvIHJlbG9hZC5cbiAqIEByZXR1cm5zIEEge0BsaW5rIFByb21pc2V9IHRoYXQgcmVzb2x2ZXMgd2hlbiB0aGUgcGx1Z2luIGlzIHJlbG9hZGVkLlxuICogQHRocm93cyB7QGxpbmsgUGx1Z2luRW5hYmxlUmVmdXNlZEVycm9yfSBJZiBPYnNpZGlhbiByZWZ1c2VkIHRvIGVuYWJsZSB0aGUgcGx1Z2luIGFnYWluLCB3aGljaCBsZWF2ZXMgaXRcbiAqIGRpc2FibGVkLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcmVsb2FkUGx1Z2luKHBsdWdpbjogUGx1Z2luKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IHBsdWdpbnMgPSBwbHVnaW4uYXBwLnBsdWdpbnM7XG4gIGNvbnN0IHBsdWdpbklkID0gcGx1Z2luLm1hbmlmZXN0LmlkO1xuICBhd2FpdCBwbHVnaW5zLmRpc2FibGVQbHVnaW4ocGx1Z2luSWQpO1xuICBpZiAoIWF3YWl0IHBsdWdpbnMuZW5hYmxlUGx1Z2luKHBsdWdpbklkKSkge1xuICAgIHRocm93IG5ldyBQbHVnaW5FbmFibGVSZWZ1c2VkRXJyb3IocGx1Z2luSWQpO1xuICB9XG59XG5cbi8qKlxuICogRGlzcGxheXMgYW4gZXJyb3IgbWVzc2FnZSBhcyBhIG5vdGljZSwgbG9ncyBpdCB0byB0aGUgY29uc29sZSwgYW5kIGRpc2FibGVzIHRoZSBzcGVjaWZpZWQgcGx1Z2luLlxuICpcbiAqIEBwYXJhbSBwbHVnaW4gLSBUaGUgcGx1Z2luIHRvIGRpc2FibGUuXG4gKiBAcGFyYW0gbWVzc2FnZSAtIFRoZSBlcnJvciBtZXNzYWdlIHRvIGRpc3BsYXkgYW5kIGxvZy5cbiAqIEByZXR1cm5zIEEge0BsaW5rIFByb21pc2V9IHRoYXQgcmVzb2x2ZXMgd2hlbiB0aGUgcGx1Z2luIGlzIGRpc2FibGVkLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gc2hvd0Vycm9yQW5kRGlzYWJsZVBsdWdpbihwbHVnaW46IFBsdWdpbiwgbWVzc2FnZTogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IHBsdWdpbk5vdGljZUNvbXBvbmVudCA9IG5ldyBQbHVnaW5Ob3RpY2VDb21wb25lbnQoe1xuICAgIGFwcDogcGx1Z2luLmFwcCxcbiAgICBwbHVnaW5OYW1lOiBwbHVnaW4ubWFuaWZlc3QubmFtZVxuICB9KTtcbiAgcGx1Z2luTm90aWNlQ29tcG9uZW50LnNob3dOb3RpY2UobWVzc2FnZSk7XG4gIHByaW50RXJyb3IobmV3IEVycm9yKG1lc3NhZ2UpKTtcbiAgYXdhaXQgcGx1Z2luLmFwcC5wbHVnaW5zLmRpc2FibGVQbHVnaW4ocGx1Z2luLm1hbmlmZXN0LmlkKTtcbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFjQSwwQkFBaUM7QUFDakMsbUJBQTJCO0FBQzNCLHNCQUEwQjtBQUMxQix5QkFBa0M7QUFDbEMsc0JBQXVCO0FBY3ZCLGtDQUFzQztBQUN0Qyx1Q0FBd0M7QUFDeEMsZ0RBQStDO0FBQy9DLCtCQUF1QztBQUN2QywrQkFBeUM7QUFDekMsb0NBQXFDO0FBQ3JDLDJDQUEyQztBQUMzQywwQkFBNEI7QUFDNUIscUNBQXNDO0FBQ3RDLDRDQUE0QztBQUM1QywrREFBNkQ7QUFDN0Qsc0NBQXVDO0FBQ3ZDLG1DQUFvQztBQUNwQyxxQ0FBc0M7QUFDdEMsdUNBQTRDO0FBQzVDLDBCQUFrQztBQUNsQyxrQkFBeUI7QUFDekIsOEJBQXVDO0FBQ3ZDLDJCQUFzQztBQUN0Qyx3QkFBaUM7QUFDakMsaUNBQXNDO0FBQ3RDLHFDQUlPO0FBeUJBLE1BQWUsdUJBQW1CLHNDQUFpQyxFQUFFLHNCQUFNLEVBQStCO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBTS9HLElBQWMsdUJBQTZDO0FBQ3pELGVBQU8sc0NBQWtCLEtBQUssV0FBVyxvQkFBb0I7QUFBQSxFQUMvRDtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQU9BLElBQWMscUJBQXFCLE9BQTZCO0FBQzlELFNBQUssYUFBYSx3QkFBd0IsS0FBSztBQUFBLEVBQ2pEO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBT0EsSUFBYyw2QkFBeUQ7QUFDckUsZUFBTyxzQ0FBa0IsS0FBSyxXQUFXLDBCQUEw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
736
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9wbHVnaW4vcGx1Z2luLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGZpbGVcbiAqXG4gKiBCYXNlIGNsYXNzIGZvciBPYnNpZGlhbiBwbHVnaW5zIHVzaW5nIGEgY29tcG9uZW50LWJhc2VkIGFyY2hpdGVjdHVyZS5cbiAqXG4gKiBQbHVnaW5CYXNlIHJlZ2lzdGVycyB1bml2ZXJzYWwgY29tcG9uZW50cyAoY29udGV4dCwgaTE4biwgZXJyb3IgaGFuZGxpbmcsIGFib3J0IHNpZ25hbCwgbGlmZWN5Y2xlIGV2ZW50cywgZGVidWcpLlxuICovXG5cbmltcG9ydCB0eXBlIHtcbiAgQ29tcG9uZW50LFxuICBJY29uTmFtZVxufSBmcm9tICdvYnNpZGlhbic7XG5pbXBvcnQgdHlwZSB7IFByb21pc2FibGUgfSBmcm9tICd0eXBlLWZlc3QnO1xuXG5pbXBvcnQgeyBtaXhpbkFzeW5jRXZlbnRzIH0gZnJvbSAnQG1uYW91bW92L3R5cGVzY3JpcHQtbGliL2FzeW5jLWV2ZW50cyc7XG5pbXBvcnQgeyBwcmludEVycm9yIH0gZnJvbSAnQG1uYW91bW92L3R5cGVzY3JpcHQtbGliL2Vycm9yJztcbmltcG9ydCB7IG5vb3BBc3luYyB9IGZyb20gJ0BtbmFvdW1vdi90eXBlc2NyaXB0LWxpYi9mdW5jdGlvbic7XG5pbXBvcnQgeyBlbnN1cmVOb25OdWxsYWJsZSB9IGZyb20gJ0BtbmFvdW1vdi90eXBlc2NyaXB0LWxpYi90eXBlLWd1YXJkcyc7XG5pbXBvcnQgeyBQbHVnaW4gfSBmcm9tICdvYnNpZGlhbic7XG5cbmltcG9ydCB0eXBlIHtcbiAgUGx1Z2luQ29uZmxpY3QsXG4gIFBsdWdpbkRlcGVuZGVuY3lcbn0gZnJvbSAnLi4vY29tcG9uZW50cy9wbHVnaW4tZ2F0ZS1jb21wb25lbnQudHMnO1xuaW1wb3J0IHR5cGUgeyBUcmFuc2xhdGlvbnNNYXAgfSBmcm9tICcuLi9pMThuL2kxOG4udHMnO1xuaW1wb3J0IHR5cGUgeyBQbHVnaW5BcGlEZWNsYXJhdGlvbiB9IGZyb20gJy4vcGx1Z2luLWFwaS50cyc7XG5pbXBvcnQgdHlwZSB7XG4gIFBsdWdpbkV2ZW50TWFwLFxuICBQbHVnaW5FdmVudFNvdXJjZVxufSBmcm9tICcuL3BsdWdpbi1ldmVudC1zb3VyY2UudHMnO1xuaW1wb3J0IHR5cGUgeyBQbHVnaW5MaWZlY3ljbGVFdmVudFBheWxvYWQgfSBmcm9tICcuL3BsdWdpbi1saWZlY3ljbGUtZXZlbnRzLnRzJztcblxuaW1wb3J0IHsgQXBwQWN0aXZlRmlsZVByb3ZpZGVyIH0gZnJvbSAnLi4vYWN0aXZlLWZpbGUtcHJvdmlkZXIudHMnO1xuaW1wb3J0IHsgQ29tbWFuZEhhbmRsZXJDb21wb25lbnQgfSBmcm9tICcuLi9jb21tYW5kLWhhbmRsZXJzL2NvbW1hbmQtaGFuZGxlci1jb21wb25lbnQudHMnO1xuaW1wb3J0IHsgVW5sb2NrQWN0aXZlTm90ZUNvbW1hbmRIYW5kbGVyIH0gZnJvbSAnLi4vY29tbWFuZC1oYW5kbGVycy91bmxvY2stYWN0aXZlLW5vdGUtY29tbWFuZC1oYW5kbGVyLnRzJztcbmltcG9ydCB7IFBsdWdpbkNvbW1hbmRSZWdpc3RyYXIgfSBmcm9tICcuLi9jb21tYW5kLXJlZ2lzdHJhci50cyc7XG5pbXBvcnQgeyBQbHVnaW5FbmFibGVSZWZ1c2VkRXJyb3IgfSBmcm9tICcuLi9jb21tdW5pdHktcGx1Z2lucy50cyc7XG5pbXBvcnQgeyBBYm9ydFNpZ25hbENvbXBvbmVudCB9IGZyb20gJy4uL2NvbXBvbmVudHMvYWJvcnQtc2lnbmFsLWNvbXBvbmVudC50cyc7XG5pbXBvcnQgeyBBc3luY0Vycm9ySGFuZGxlckNvbXBvbmVudCB9IGZyb20gJy4uL2NvbXBvbmVudHMvYXN5bmMtZXJyb3ItaGFuZGxlci1jb21wb25lbnQudHMnO1xuaW1wb3J0IHsgQ29tcG9uZW50RXggfSBmcm9tICcuLi9jb21wb25lbnRzL2NvbXBvbmVudC1leC50cyc7XG5pbXBvcnQgeyBDb25zb2xlRGVidWdDb21wb25lbnQgfSBmcm9tICcuLi9jb21wb25lbnRzL2NvbnNvbGUtZGVidWctY29tcG9uZW50LnRzJztcbmltcG9ydCB7IE1lbnVFdmVudFJlZ2lzdHJhckNvbXBvbmVudCB9IGZyb20gJy4uL2NvbXBvbmVudHMvbWVudS1ldmVudC1yZWdpc3RyYXItY29tcG9uZW50LnRzJztcbmltcG9ydCB7IE5vdGVib29rTmF2aWdhdG9yTWVudUV2ZW50UmVnaXN0cmFyQ29tcG9uZW50IH0gZnJvbSAnLi4vY29tcG9uZW50cy9ub3RlYm9vay1uYXZpZ2F0b3ItbWVudS1ldmVudC1yZWdpc3RyYXItY29tcG9uZW50LnRzJztcbmltcG9ydCB7IFBsdWdpbkNvbnRleHRDb21wb25lbnQgfSBmcm9tICcuLi9jb21wb25lbnRzL3BsdWdpbi1jb250ZXh0LWNvbXBvbmVudC50cyc7XG5pbXBvcnQgeyBQbHVnaW5HYXRlQ29tcG9uZW50IH0gZnJvbSAnLi4vY29tcG9uZW50cy9wbHVnaW4tZ2F0ZS1jb21wb25lbnQudHMnO1xuaW1wb3J0IHsgUGx1Z2luTm90aWNlQ29tcG9uZW50IH0gZnJvbSAnLi4vY29tcG9uZW50cy9wbHVnaW4tbm90aWNlLWNvbXBvbmVudC50cyc7XG5pbXBvcnQgeyBQbHVnaW5TZXR0aW5nc0NvbXBvbmVudEJhc2UgfSBmcm9tICcuLi9jb21wb25lbnRzL3BsdWdpbi1zZXR0aW5ncy1jb21wb25lbnQudHMnO1xuaW1wb3J0IHsgUGx1Z2luRGF0YUhhbmRsZXIgfSBmcm9tICcuLi9kYXRhLWhhbmRsZXIudHMnO1xuaW1wb3J0IHsgaW5pdEkxOE4gfSBmcm9tICcuLi9pMThuL2kxOG4udHMnO1xuaW1wb3J0IHsgZGVmYXVsdFRyYW5zbGF0aW9uc01hcCB9IGZyb20gJy4uL2kxOG4vbG9jYWxlcy90cmFuc2xhdGlvbnMtbWFwLnRzJztcbmltcG9ydCB7IFJlc291cmNlTG9ja0NvbXBvbmVudCB9IGZyb20gJy4uL3Jlc291cmNlLWxvY2sudHMnO1xuaW1wb3J0IHsgcHVibGlzaFBsdWdpbkFwaSB9IGZyb20gJy4vcGx1Z2luLWFwaS50cyc7XG5pbXBvcnQge1xuICBERUZBVUxUX1BMVUdJTl9BU1lOQ19DTEVBTlVQX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTLFxuICBkaWRQbHVnaW5Bc3luY0NsZWFudXBzU2V0dGxlLFxuICBoYXNQZW5kaW5nUGx1Z2luQXN5bmNDbGVhbnVwcyxcbiAgcmVnaXN0ZXJQbHVnaW5Bc3luY0NsZWFudXBcbn0gZnJvbSAnLi9wbHVnaW4tYXN5bmMtY2xlYW51cC50cyc7XG5pbXBvcnQgeyBQbHVnaW5FdmVudFNvdXJjZUltcGwgfSBmcm9tICcuL3BsdWdpbi1ldmVudC1zb3VyY2UudHMnO1xuaW1wb3J0IHtcbiAgUExVR0lOX0xPQURFRF9FVkVOVF9OQU1FLFxuICBQTFVHSU5fVU5MT0FERURfRVZFTlRfTkFNRSxcbiAgdHJpZ2dlclBsdWdpbkxpZmVjeWNsZUV2ZW50XG59IGZyb20gJy4vcGx1Z2luLWxpZmVjeWNsZS1ldmVudHMudHMnO1xuXG4vKipcbiAqIFRoZSB1bml2ZXJzYWwgY29tcG9uZW50cyBvd25lZCBieSB7QGxpbmsgUGx1Z2luQmFzZX0sIGtleWVkIGJ5IHRoZSBuYW1lIG9mIHRoZSBhY2Nlc3NvciBleHBvc2luZ1xuICogZWFjaCBvbmUuIEV2ZXJ5IG1lbWJlciBpcyBvcHRpb25hbCBiZWNhdXNlIGEgY29tcG9uZW50IG9ubHkgZXhpc3RzIG9uY2Uge0BsaW5rIFBsdWdpbkJhc2Uub25sb2FkfVxuICogaGFzIGNyZWF0ZWQgaXQuXG4gKi9cbmludGVyZmFjZSBQbHVnaW5CYXNlQ29tcG9uZW50cyB7XG4gIHJlYWRvbmx5IGFib3J0U2lnbmFsQ29tcG9uZW50PzogQWJvcnRTaWduYWxDb21wb25lbnQ7XG4gIHJlYWRvbmx5IGFzeW5jRXJyb3JIYW5kbGVyQ29tcG9uZW50PzogQXN5bmNFcnJvckhhbmRsZXJDb21wb25lbnQ7XG4gIHJlYWRvbmx5IGNvbW1hbmRIYW5kbGVyQ29tcG9uZW50PzogQ29tbWFuZEhhbmRsZXJDb21wb25lbnQ7XG4gIHJlYWRvbmx5IGNvbnNvbGVEZWJ1Z0NvbXBvbmVudD86IENvbnNvbGVEZWJ1Z0NvbXBvbmVudDtcbiAgcmVhZG9ubHkgcGx1Z2luQ29udGV4dENvbXBvbmVudD86IFBsdWdpbkNvbnRleHRDb21wb25lbnQ7XG4gIHJlYWRvbmx5IHBsdWdpbkdhdGVDb21wb25lbnQ/OiBQbHVnaW5HYXRlQ29tcG9uZW50O1xuICByZWFkb25seSBwbHVnaW5Ob3RpY2VDb21wb25lbnQ/OiBQbHVnaW5Ob3RpY2VDb21wb25lbnQ7XG4gIHJlYWRvbmx5IHBsdWdpblNldHRpbmdzQ29tcG9uZW50PzogUGx1Z2luU2V0dGluZ3NDb21wb25lbnRCYXNlPG9iamVjdD47XG4gIHJlYWRvbmx5IHJlc291cmNlTG9ja0NvbXBvbmVudD86IFJlc291cmNlTG9ja0NvbXBvbmVudDtcbn1cblxuLyoqXG4gKiBCYXNlIGNsYXNzIGZvciBjcmVhdGluZyBPYnNpZGlhbiBwbHVnaW5zIHdpdGggYSBjb21wb25lbnQtYmFzZWQgYXJjaGl0ZWN0dXJlLlxuICpcbiAqIFJlZ2lzdGVycyB1bml2ZXJzYWwgY29tcG9uZW50cyBhdXRvbWF0aWNhbGx5LiBTdWJjbGFzc2VzIGFkZCBvciByZXBsYWNlIGNvbXBvbmVudHNcbiAqIHZpYSB7QGxpbmsgcmVtb3ZlQ2hpbGR9IC8ge0BsaW5rIGFkZENoaWxkfS5cbiAqL1xuZXhwb3J0IGFic3RyYWN0IGNsYXNzIFBsdWdpbkJhc2UgZXh0ZW5kcyBtaXhpbkFzeW5jRXZlbnRzPFBsdWdpbkV2ZW50TWFwPigpKFBsdWdpbikgaW1wbGVtZW50cyBQbHVnaW5FdmVudFNvdXJjZSB7XG4gIC8qKlxuICAgKiBHZXRzIGFib3J0IHNpZ25hbCBjb21wb25lbnQuXG4gICAqXG4gICAqIEByZXR1cm5zIGFib3J0IHNpZ25hbCBjb21wb25lbnQuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0IGFib3J0U2lnbmFsQ29tcG9uZW50KCk6IEFib3J0U2lnbmFsQ29tcG9uZW50IHtcbiAgICByZXR1cm4gZW5zdXJlTm9uTnVsbGFibGUodGhpcy5jb21wb25lbnRzLmFib3J0U2lnbmFsQ29tcG9uZW50KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXRzIGFib3J0IHNpZ25hbCBjb21wb25lbnQuXG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZSAtIEFib3J0IHNpZ25hbCBjb21wb25lbnQuXG4gICAqL1xuICBwcm90ZWN0ZWQgc2V0IGFib3J0U2lnbmFsQ29tcG9uZW50KHZhbHVlOiBBYm9ydFNpZ25hbENvbXBvbmVudCkge1xuICAgIHRoaXMuc2V0Q29tcG9uZW50KCdhYm9ydFNpZ25hbENvbXBvbmVudCcsIHZhbHVlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIGFzeW5jIGVycm9yIGhhbmRsZXIgY29tcG9uZW50LlxuICAgKlxuICAgKiBAcmV0dXJucyBhc3luYyBlcnJvciBoYW5kbGVyIGNvbXBvbmVudC5cbiAgICovXG4gIHByb3RlY3RlZCBnZXQgYXN5bmNFcnJvckhhbmRsZXJDb21wb25lbnQoKTogQXN5bmNFcnJvckhhbmRsZXJDb21wb25lbnQge1xuICAgIHJldHVybiBlbnN1cmVOb25OdWxsYWJsZSh0aGlzLmNvbXBvbmVudHMuYXN5bmNFcnJvckhhbmRsZXJDb21wb25lbnQpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldHMgYXN5bmMgZXJyb3IgaGFuZGxlciBjb21wb25lbnQuXG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZSAtIEFzeW5jIGVycm9yIGhhbmRsZXIgY29tcG9uZW50LlxuICAgKi9cbiAgcHJvdGVjdGVkIHNldCBhc3luY0Vycm9ySGFuZGxlckNvbXBvbmVudCh2YWx1ZTogQXN5bmNFcnJvckhhbmRsZXJDb21wb25lbnQpIHtcbiAgICB0aGlzLnNldENvbXBvbmVudCgnYXN5bmNFcnJvckhhbmRsZXJDb21wb25lbnQnLCB2YWx1ZSk7XG4gIH1cblxuICAvKipcbiAgICogR2V0cyB0aGUgc2hhcmVkIGNvbW1hbmQgaGFuZGxlciBjb21wb25lbnQuIFJlZ2lzdGVyIGEgcGx1Z2luJ3MgY29tbWFuZHMgb24gaXQgdmlhXG4gICAqIHtAbGluayBDb21tYW5kSGFuZGxlckNvbXBvbmVudC5yZWdpc3RlckNvbW1hbmRIYW5kbGVyc30gcmF0aGVyIHRoYW4gY29uc3RydWN0aW5nIHlvdXIgb3duXG4gICAqIHtAbGluayBDb21tYW5kSGFuZGxlckNvbXBvbmVudH0g4oCUIHRoZSBhcHAtYmFja2VkIGFjdGl2ZS1maWxlIHByb3ZpZGVyLCBjb21tYW5kIHJlZ2lzdHJhciwgbWVudVxuICAgKiBldmVudCByZWdpc3RyYXIsIGFuZCBwbHVnaW4gbmFtZSBhcmUgYWxyZWFkeSB3aXJlZC5cbiAgICpcbiAgICogQHJldHVybnMgVGhlIGNvbW1hbmQgaGFuZGxlciBjb21wb25lbnQuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0IGNvbW1hbmRIYW5kbGVyQ29tcG9uZW50KCk6IENvbW1hbmRIYW5kbGVyQ29tcG9uZW50IHtcbiAgICByZXR1cm4gZW5zdXJlTm9uTnVsbGFibGUodGhpcy5jb21wb25lbnRzLmNvbW1hbmRIYW5kbGVyQ29tcG9uZW50KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXRzIHRoZSBjb21tYW5kIGhhbmRsZXIgY29tcG9uZW50LlxuICAgKlxuICAgKiBAcGFyYW0gdmFsdWUgLSBUaGUgY29tbWFuZCBoYW5kbGVyIGNvbXBvbmVudC5cbiAgICovXG4gIHByb3RlY3RlZCBzZXQgY29tbWFuZEhhbmRsZXJDb21wb25lbnQodmFsdWU6IENvbW1hbmRIYW5kbGVyQ29tcG9uZW50KSB7XG4gICAgdGhpcy5zZXRDb21wb25lbnQoJ2NvbW1hbmRIYW5kbGVyQ29tcG9uZW50JywgdmFsdWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgY29uc29sZSBkZWJ1ZyBjb21wb25lbnQuXG4gICAqXG4gICAqIEByZXR1cm5zIGNvbnNvbGUgZGVidWcgY29tcG9uZW50LlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldCBjb25zb2xlRGVidWdDb21wb25lbnQoKTogQ29uc29sZURlYnVnQ29tcG9uZW50IHtcbiAgICByZXR1cm4gZW5zdXJlTm9uTnVsbGFibGUodGhpcy5jb21wb25lbnRzLmNvbnNvbGVEZWJ1Z0NvbXBvbmVudCk7XG4gIH1cblxuICAvKipcbiAgICogU2V0cyBjb25zb2xlIGRlYnVnIGNvbXBvbmVudC5cbiAgICpcbiAgICogQHBhcmFtIHZhbHVlIC0gQ29uc29sZSBkZWJ1ZyBjb21wb25lbnQuXG4gICAqL1xuICBwcm90ZWN0ZWQgc2V0IGNvbnNvbGVEZWJ1Z0NvbXBvbmVudCh2YWx1ZTogQ29uc29sZURlYnVnQ29tcG9uZW50KSB7XG4gICAgdGhpcy5zZXRDb21wb25lbnQoJ2NvbnNvbGVEZWJ1Z0NvbXBvbmVudCcsIHZhbHVlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIHBsdWdpbiBjb250ZXh0IGNvbXBvbmVudCAocGx1Z2luIElELCBkZWJ1ZyBjb250cm9sbGVyLCBsaWJyYXJ5IHN0eWxlcykuXG4gICAqXG4gICAqIEByZXR1cm5zIHBsdWdpbiBjb250ZXh0IGNvbXBvbmVudC5cbiAgICovXG4gIHByb3RlY3RlZCBnZXQgcGx1Z2luQ29udGV4dENvbXBvbmVudCgpOiBQbHVnaW5Db250ZXh0Q29tcG9uZW50IHtcbiAgICByZXR1cm4gZW5zdXJlTm9uTnVsbGFibGUodGhpcy5jb21wb25lbnRzLnBsdWdpbkNvbnRleHRDb21wb25lbnQpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldHMgcGx1Z2luIGNvbnRleHQgY29tcG9uZW50LlxuICAgKlxuICAgKiBAcGFyYW0gdmFsdWUgLSBQbHVnaW4gY29udGV4dCBjb21wb25lbnQuXG4gICAqL1xuICBwcm90ZWN0ZWQgc2V0IHBsdWdpbkNvbnRleHRDb21wb25lbnQodmFsdWU6IFBsdWdpbkNvbnRleHRDb21wb25lbnQpIHtcbiAgICB0aGlzLnNldENvbXBvbmVudCgncGx1Z2luQ29udGV4dENvbXBvbmVudCcsIHZhbHVlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIHRoZSBnYXRlIGhvbGRpbmcgdGhlIHBsdWdpbidzIGZlYXR1cmUgc3VyZmFjZSB1cCBvciBkb3duLlxuICAgKlxuICAgKiBSZWFjaCBmb3IgaXQgZnJvbSBhIHNldHRpbmdzIHRhYiB0byByZW5kZXIgdGhlIG92ZXJsYXAgYmFubmVyIGZvciBhXG4gICAqIHtAbGluayBjb21wb25lbnRzL3BsdWdpbi1nYXRlLWNvbXBvbmVudCFQbHVnaW5Db25mbGljdFNldmVyaXR5Lldhcm59IGNvbmZsaWN0IOKAlCB0aGUgb25lXG4gICAqIGJhbm5lciB0aGUgbGlicmFyeSBjYW5ub3QgcGxhY2UgaXRzZWxmLCBiZWNhdXNlIGEgcnVubmluZyBwbHVnaW4gYnVpbGRzIGl0cyBvd24gc2V0dGluZ3MgdGFiLlxuICAgKlxuICAgKiBSZWFkYWJsZSB0aHJvdWdob3V0IHtAbGluayBvbmxvYWRJbXBsfSwgaW5jbHVkaW5nIGl0cyBzeW5jaHJvbm91cyBwcmVmaXgsIHdoaWNoIGlzIHdoZXJlIGEgc2V0dGluZ3NcbiAgICogdGFiIGlzIGJ1aWx0LiBUaGF0IGlzIGRlbGliZXJhdGUgcmF0aGVyIHRoYW4gaW5jaWRlbnRhbDogYWRkaW5nIHRoZSBnYXRlIGlzIHdoYXQgcnVuc1xuICAgKiB7QGxpbmsgb25sb2FkSW1wbH0sIHNvIHtAbGluayBvbmxvYWR9IGFzc2lnbnMgdGhpcyBmaWVsZCBiZWZvcmUgYWRkaW5nIGl0LlxuICAgKlxuICAgKiBAcmV0dXJucyBUaGUgcGx1Z2luIGdhdGUgY29tcG9uZW50LlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldCBwbHVnaW5HYXRlQ29tcG9uZW50KCk6IFBsdWdpbkdhdGVDb21wb25lbnQge1xuICAgIHJldHVybiBlbnN1cmVOb25OdWxsYWJsZSh0aGlzLmNvbXBvbmVudHMucGx1Z2luR2F0ZUNvbXBvbmVudCk7XG4gIH1cblxuICAvKipcbiAgICogU2V0cyB0aGUgcGx1Z2luIGdhdGUgY29tcG9uZW50LlxuICAgKlxuICAgKiBAcGFyYW0gdmFsdWUgLSBUaGUgcGx1Z2luIGdhdGUgY29tcG9uZW50LlxuICAgKi9cbiAgcHJvdGVjdGVkIHNldCBwbHVnaW5HYXRlQ29tcG9uZW50KHZhbHVlOiBQbHVnaW5HYXRlQ29tcG9uZW50KSB7XG4gICAgdGhpcy5zZXRDb21wb25lbnQoJ3BsdWdpbkdhdGVDb21wb25lbnQnLCB2YWx1ZSk7XG4gIH1cblxuICAvKipcbiAgICogR2V0cyBwbHVnaW4gbm90aWNlIGNvbXBvbmVudC5cbiAgICpcbiAgICogQHJldHVybnMgcGx1Z2luIG5vdGljZSBjb21wb25lbnQuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0IHBsdWdpbk5vdGljZUNvbXBvbmVudCgpOiBQbHVnaW5Ob3RpY2VDb21wb25lbnQge1xuICAgIHJldHVybiBlbnN1cmVOb25OdWxsYWJsZSh0aGlzLmNvbXBvbmVudHMucGx1Z2luTm90aWNlQ29tcG9uZW50KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXRzIHBsdWdpbiBub3RpY2UgY29tcG9uZW50LlxuICAgKlxuICAgKiBAcGFyYW0gdmFsdWUgLSBQbHVnaW4gbm90aWNlIGNvbXBvbmVudC5cbiAgICovXG4gIHByb3RlY3RlZCBzZXQgcGx1Z2luTm90aWNlQ29tcG9uZW50KHZhbHVlOiBQbHVnaW5Ob3RpY2VDb21wb25lbnQpIHtcbiAgICB0aGlzLnNldENvbXBvbmVudCgncGx1Z2luTm90aWNlQ29tcG9uZW50JywgdmFsdWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgcGx1Z2luIHNldHRpbmdzIGNvbXBvbmVudC5cbiAgICpcbiAgICogQHJldHVybnMgcGx1Z2luIHNldHRpbmdzIGNvbXBvbmVudC5cbiAgICovXG4gIHByb3RlY3RlZCBnZXQgcGx1Z2luU2V0dGluZ3NDb21wb25lbnQoKTogUGx1Z2luU2V0dGluZ3NDb21wb25lbnRCYXNlPG9iamVjdD4ge1xuICAgIHJldHVybiBlbnN1cmVOb25OdWxsYWJsZSh0aGlzLmNvbXBvbmVudHMucGx1Z2luU2V0dGluZ3NDb21wb25lbnQpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldHMgcGx1Z2luIHNldHRpbmdzIGNvbXBvbmVudC5cbiAgICpcbiAgICogQHBhcmFtIHZhbHVlIC0gUGx1Z2luIHNldHRpbmdzIGNvbXBvbmVudC5cbiAgICovXG4gIHByb3RlY3RlZCBzZXQgcGx1Z2luU2V0dGluZ3NDb21wb25lbnQodmFsdWU6IFBsdWdpblNldHRpbmdzQ29tcG9uZW50QmFzZTxvYmplY3Q+KSB7XG4gICAgdGhpcy5zZXRDb21wb25lbnQoJ3BsdWdpblNldHRpbmdzQ29tcG9uZW50JywgdmFsdWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgdGhlIGVkaXRvciBsb2NrIGNvbXBvbmVudCwgdXNlZCB0byBsb2NrIG5vdGVzIHJlYWQtb25seSBkdXJpbmcgbG9uZyBvcGVyYXRpb25zLiBPd25lZCBieVxuICAgKiB0aGUgcGx1Z2luLCBzbyBpdHMgbG9ja3MgYXJlIHJlbGVhc2VkIGF1dG9tYXRpY2FsbHkgd2hlbiB0aGUgcGx1Z2luIHVubG9hZHMuXG4gICAqXG4gICAqIEByZXR1cm5zIEVkaXRvciBsb2NrIGNvbXBvbmVudC5cbiAgICovXG4gIHByb3RlY3RlZCBnZXQgcmVzb3VyY2VMb2NrQ29tcG9uZW50KCk6IFJlc291cmNlTG9ja0NvbXBvbmVudCB7XG4gICAgcmV0dXJuIGVuc3VyZU5vbk51bGxhYmxlKHRoaXMuY29tcG9uZW50cy5yZXNvdXJjZUxvY2tDb21wb25lbnQpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldHMgdGhlIGVkaXRvciBsb2NrIGNvbXBvbmVudC5cbiAgICpcbiAgICogQHBhcmFtIHZhbHVlIC0gRWRpdG9yIGxvY2sgY29tcG9uZW50LlxuICAgKi9cbiAgcHJvdGVjdGVkIHNldCByZXNvdXJjZUxvY2tDb21wb25lbnQodmFsdWU6IFJlc291cmNlTG9ja0NvbXBvbmVudCkge1xuICAgIHRoaXMuc2V0Q29tcG9uZW50KCdyZXNvdXJjZUxvY2tDb21wb25lbnQnLCB2YWx1ZSk7XG4gIH1cblxuICBwcml2YXRlIHJlYWRvbmx5IGNvbXBvbmVudHM6IFBsdWdpbkJhc2VDb21wb25lbnRzID0ge307XG5cbiAgLy8gRXZlcnl0aGluZyB0aGUgU1VCQ0xBU1Mgb3duczogd2hhdCBgb25sb2FkSW1wbGAgYWRkcywgYW5kIHdoYXQgaXQgYWRkcyBsYXRlci5cbiAgLy9cbiAgLy8gQSBzZWNvbmQgd3JhcHBlciByYXRoZXIgdGhhbiBvbmUsIGJlY2F1c2UgdGhlIHR3byB0aWVycyBoYXZlIG9wcG9zaXRlIGxpZmV0aW1lcy4gVGhlIHVuaXZlcnNhbFxuICAvLyBjb21wb25lbnRzIGhhdmUgdG8gT1VUTElWRSBhIGxvc3QgZGVwZW5kZW5jeSDigJQgdGhleSBhcmUgd2hhdCBzaG93cyB0aGUgbm90aWNlIG5hbWluZyB0aGUgcGx1Z2luIHRoYXRcbiAgLy8gd2VudCBhd2F5IGFuZCByZW5kZXJzIHRoZSBidXR0b24gdGhhdCBicmluZ3MgaXQgYmFjayDigJQgd2hpbGUgdGhlIHN1YmNsYXNzJ3Mgc3VyZmFjZSBpcyBleGFjdGx5IHdoYXRcbiAgLy8gbXVzdCBzdG9wIHJ1bm5pbmcuIFVubG9hZGluZyBvbmUgd3JhcHBlciBob2xkaW5nIGJvdGggd291bGQgc2lsZW5jZSB0aGUgcGx1Z2luIGF0IHRoZSBtb21lbnQgaXQgbW9zdFxuICAvLyBuZWVkcyB0byBzcGVhay5cbiAgLy9cbiAgLy8gQWx3YXlzIHByZXNlbnQsIG5ldmVyIG51bGwsIGFuZCBSRVBMQUNFRCByYXRoZXIgdGhhbiBlbXB0aWVkIHdoZW4gdGhlIHN1cmZhY2UgaXMgdG9ybiBkb3duLiBUaGF0IGtlZXBzXG4gIC8vIGBhZGRDaGlsZGAgY2FsbGFibGUgYXQgZXZlcnkgcG9pbnQgaW4gdGhlIHBsdWdpbidzIGxpZmUsIGV4YWN0bHkgYXMgaXQgd2FzIGJlZm9yZSB0aGUgdGllcnMgZXhpc3RlZDpcbiAgLy8gQSBjaGlsZCBhZGRlZCBiZWZvcmUgdGhlIGdhdGUgb3BlbnMgaXMgcXVldWVkIGFuZCBsb2FkZWQgd2hlbiBpdCBkb2VzLCB3aGljaCBpcyB3aGF0IGBDb21wb25lbnRFeGBcbiAgLy8gYWxyZWFkeSBkb2VzIGZvciBhbnkgY2hpbGQgYWRkZWQgdG8gYSBub3QteWV0LWxvYWRlZCBjb21wb25lbnQuXG4gIHByaXZhdGUgZ2F0ZWRXcmFwcGVyQ29tcG9uZW50ID0gbmV3IENvbXBvbmVudEV4KCk7XG5cbiAgLy8gVGhlIHBheWxvYWQgYnJvYWRjYXN0IHdoZW4gdGhpcyBwbHVnaW4gZmluaXNoZWQgbG9hZGluZywga2VwdCBzbyB0aGUgbWF0Y2hpbmcgdW5sb2FkZWQgYnJvYWRjYXN0XG4gIC8vIGRlc2NyaWJlcyB0aGUgc2FtZSBwbHVnaW4gd2l0aG91dCByZS1kZXJpdmluZyBpdCBmcm9tIGEgc3VyZmFjZSB0aGF0IGhhcyBzaW5jZSBiZWVuIHRvcm4gZG93bi4gTnVsbFxuICAvLyB3aGVuZXZlciBubyBsb2FkZWQgYnJvYWRjYXN0IGlzIG91dHN0YW5kaW5nLCB3aGljaCBpcyB3aGF0IGtlZXBzIHRoZSB0d28gZXZlbnRzIHBhaXJlZC5cbiAgcHJpdmF0ZSBsaWZlY3ljbGVFdmVudFBheWxvYWQ6IG51bGwgfCBQbHVnaW5MaWZlY3ljbGVFdmVudFBheWxvYWQgPSBudWxsO1xuXG4gIC8vIFRoZSBsaWJyYXJ5J3Mgb3duIGNvbXBvbmVudHMsIHdoaWNoIG91dGxpdmUgYW55IGRlcGVuZGVuY3kuXG4gIHByaXZhdGUgcmVhZG9ubHkgdW5pdmVyc2FsV3JhcHBlckNvbXBvbmVudCA9IG5ldyBDb21wb25lbnRFeCgpO1xuXG4gIC8qKlxuICAgKiBBZGRzIGEgY2hpbGQgY29tcG9uZW50LlxuICAgKlxuICAgKiBUaGUgY2hpbGQgaXMgYWRkZWQgdG8gdGhlIGludGVybmFsIHdyYXBwZXIgaG9sZGluZyB0aGUgc3ViY2xhc3MncyBvd24gc3VyZmFjZSwgd2hpY2gge0BsaW5rIG9ubG9hZH1cbiAgICogY3JlYXRlcyBhbmQgbG9hZHMgYmVmb3JlIGNhbGxpbmcge0BsaW5rIG9ubG9hZEltcGx9LiBTbyBhIGNoaWxkIGFkZGVkIGR1cmluZyB7QGxpbmsgb25sb2FkSW1wbH0gaXNcbiAgICogbG9hZGVkIGltbWVkaWF0ZWx5LCBjaGlsZHJlbi1maXJzdCwgYW5kIGlzIHVzYWJsZSBieSB0aGUgdGltZSB0aGlzIG1ldGhvZCByZXR1cm5zLlxuICAgKlxuICAgKiBUaGF0IHdyYXBwZXIgaXMgdG9ybiBkb3duIGFuZCByZWJ1aWx0IHdoZW5ldmVyIHRoZSBnYXRlIGNsb3NlcyBhbmQgb3BlbnMgYWdhaW4g4oCUIGEgZGVwZW5kZW5jeSBkZWNsYXJlZFxuICAgKiBieSB7QGxpbmsgZ2V0UGx1Z2luRGVwZW5kZW5jaWVzfSBnb2luZyBhd2F5IGFuZCBjb21pbmcgYmFjaywgb3IgYSBjb25mbGljdCBkZWNsYXJlZCBieVxuICAgKiB7QGxpbmsgZ2V0UGx1Z2luQ29uZmxpY3RzfSBhcHBlYXJpbmcgYW5kIGJlaW5nIHJlc29sdmVkIOKAlCBzbyBhIGNoaWxkIGFkZGVkIGhlcmUgbGl2ZXMgZXhhY3RseSBhcyBsb25nXG4gICAqIGFzIHRoZSBwbHVnaW4ncyBmZWF0dXJlIHN1cmZhY2UgZG9lcy4gQWRkaW5nIG9uZSB3aGlsZSB0aGUgc3VyZmFjZSBpcyBkb3duIGlzIHN0aWxsIGxlZ2l0aW1hdGUg4oCUIGl0IGlzXG4gICAqIHF1ZXVlZCBhbmQgbG9hZGVkIHdoZW4gdGhlIHN1cmZhY2UgbmV4dCBjb21lcyB1cCwgdGhlIHdheSB7QGxpbmsgQ29tcG9uZW50RXguYWRkQ2hpbGR9IGFscmVhZHkgcXVldWVzXG4gICAqIGEgY2hpbGQgYWRkZWQgdG8gYSBub3QteWV0LWxvYWRlZCBjb21wb25lbnQuXG4gICAqXG4gICAqIFRoaXMgaXMgdGhlIFNVQkNMQVNTJ3MgZG9vciwgYW5kIHRoZSBvbmx5IG9uZSBpdCBoYXM6IHRoZSB1bml2ZXJzYWwgY29tcG9uZW50cyB7QGxpbmsgb25sb2FkfSByZWdpc3RlcnNcbiAgICogdGFrZSBhIHByaXZhdGUgcm91dGUgb250byBhIGRpZmZlcmVudCB3cmFwcGVyLiBTbyBhbnl0aGluZyBvYnNlcnZpbmcgdGhpcyBtZXRob2Qg4oCUIGEgdGVzdCBjb3VudGluZyBpdHNcbiAgICogY2FsbHMsIGEgcGF0Y2ggd3JhcHBpbmcgaXQg4oCUIHNlZXMgZXhhY3RseSB0aGUgY2hpbGRyZW4gdGhlIHN1YmNsYXNzIGFkZGVkLCBhbmQgbm9uZSBvZiB0aGUgbGlicmFyeSdzLlxuICAgKiBCZWZvcmUgdGhlIHR3byB0aWVycyBleGlzdGVkIG9uZSBkb29yIGNhcnJpZWQgYm90aCwgYW5kIGEgY29uc3VtZXIgY291bnRpbmcgdGhlIHRvdGFsIGlzIHRoZSBvbmUgdGhpbmdcbiAgICogdGhlIHNwbGl0IGNvdWxkIG5vdCBrZWVwIHdvcmtpbmcuXG4gICAqXG4gICAqIEB0eXBlUGFyYW0gVENvbXBvbmVudCAtIFRoZSB0eXBlIG9mIGNvbXBvbmVudCB0byBhZGQuXG4gICAqIEBwYXJhbSBjb21wb25lbnQgLSBUaGUgY29tcG9uZW50IGluc3RhbmNlIHRvIGFkZC5cbiAgICogQHJldHVybnMgVGhlIGFkZGVkIGNvbXBvbmVudC5cbiAgICovXG4gIHB1YmxpYyBvdmVycmlkZSBhZGRDaGlsZDxUQ29tcG9uZW50IGV4dGVuZHMgQ29tcG9uZW50Pihjb21wb25lbnQ6IFRDb21wb25lbnQpOiBUQ29tcG9uZW50IHtcbiAgICByZXR1cm4gdGhpcy5nYXRlZFdyYXBwZXJDb21wb25lbnQuYWRkQ2hpbGQoY29tcG9uZW50KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDYWxsZWQgd2hlbiB0aGUgZXh0ZXJuYWwgc2V0dGluZ3MgY2hhbmdlLlxuICAgKlxuICAgKiBPdmVycmlkZSBpbiBzdWJjbGFzcyBpZiBuZWVkZWQuIE1ha2Ugc3VyZSB0byBjYWxsIGBhd2FpdCBzdXBlci5vbkV4dGVybmFsU2V0dGluZ3NDaGFuZ2UoKWAgZmlyc3QuXG4gICAqL1xuICBwdWJsaWMgb3ZlcnJpZGUgYXN5bmMgb25FeHRlcm5hbFNldHRpbmdzQ2hhbmdlKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGF3YWl0IHN1cGVyLm9uRXh0ZXJuYWxTZXR0aW5nc0NoYW5nZT8uKCk7XG4gICAgYXdhaXQgdGhpcy50cmlnZ2VyQXN5bmMoJ2V4dGVybmFsU2V0dGluZ3NDaGFuZ2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDYWxsZWQgd2hlbiB0aGUgcGx1Z2luIGlzIGxvYWRlZC5cbiAgICpcbiAgICogT3JjaGVzdHJhdGVzIGxvYWRpbmc6IHJlZ2lzdGVycyB0aGUgdW5pdmVyc2FsIGNvbXBvbmVudHMsIGxldHMgdGhlIHN1YmNsYXNzIHdpcmUgaXRzIG93blxuICAgKiBjb21wb25lbnRzIHZpYSB7QGxpbmsgb25sb2FkSW1wbH0sIHRoZW4gYXdhaXRzIHRoZSBhc3luYyB0YWlsIG9mIGV2ZXJ5IGxvYWQuXG4gICAqIEVhY2ggY29tcG9uZW50IGxvYWRzIGFzIGl0IGlzIGFkZGVkLCBjaGlsZHJlbi1maXJzdC5cbiAgICpcbiAgICogRG8gTk9UIG92ZXJyaWRlIHRoaXMgbWV0aG9kLiBPdmVycmlkZSB7QGxpbmsgb25sb2FkSW1wbH0gaW5zdGVhZC5cbiAgICovXG4gIHB1YmxpYyBvdmVycmlkZSBhc3luYyBvbmxvYWQoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdHJ5IHtcbiAgICAgIC8vIEJlZm9yZSBhbnl0aGluZyBlbHNlOiB0aGUgcHJldmlvdXMgaW5zdGFuY2Ugb2YgdGhpcyBwbHVnaW4gbWF5IHN0aWxsIGJlIGNsb3Npbmcgd2hhdCB0aGlzIG9uZSBpcyBhYm91dCB0b1xuICAgICAgLy8gb3BlbiwgYmVjYXVzZSBPYnNpZGlhbiBydW5zIGBvbnVubG9hZGAgc3luY2hyb25vdXNseSBhbmQgYXdhaXRzIG5vdGhpbmcgaXQgc3RhcnRlZC4gQXdhaXRlZCBvbmx5IHdoZW4gc29tZSBhcmVcbiAgICAgIC8vIHBlbmRpbmcsIHNvIGEgcGx1Z2luIHdpdGggbm9uZSBhdHRhY2hlcyBpdHMgd3JhcHBlciBiZWxvdyB3aXRob3V0IHlpZWxkaW5nIGZpcnN0LlxuICAgICAgaWYgKGhhc1BlbmRpbmdQbHVnaW5Bc3luY0NsZWFudXBzKHRoaXMubWFuaWZlc3QuaWQpKSB7XG4gICAgICAgIGF3YWl0IHRoaXMud2FpdEZvclByZXZpb3VzQXN5bmNDbGVhbnVwcygpO1xuICAgICAgfVxuXG4gICAgICAvLyBUaGUgd3JhcHBlciBpcyBhdHRhY2hlZCBhbmQgbG9hZGVkIGJlZm9yZSBhbnl0aGluZyBpcyB3aXJlZCB1cCwgc28gZXZlcnkgYGFkZENoaWxkYCBiZWxvd1xuICAgICAgLy8gbG9hZHMgaXRzIGNoaWxkIHN0cmFpZ2h0IGF3YXkgcmF0aGVyIHRoYW4gcXVldWluZyBpdC5cbiAgICAgIC8vIFRoYXQgaXMgd2hhdCBsZXRzIGEgY29tbWFuZCBoYW5kbGVyIHJlZ2lzdGVyIGl0cyBtZW51IGV2ZW50cyBmcm9tIGBvblJlZ2lzdGVyZWRgLCB3aGljaFxuICAgICAgLy8gYHJlZ2lzdGVyQ29tbWFuZEhhbmRsZXJzYCBhd2FpdHMgYW5kIHdoaWNoIGEgcmVnaXN0cmFyIHJlZnVzZXMgd2hpbGUgdW5sb2FkZWQuXG4gICAgICAvLyBBdHRhY2hpbmcgaXQgdXAgZnJvbnQgYWxzbyByZWdpc3RlcnMgdGhlIHdyYXBwZXIgZm9yIHRlYXJkb3duIGJlZm9yZSBhbnl0aGluZyBjYW4gdGhyb3cuXG4gICAgICAvLyBUaGUgbG9hZCBpcyBleHBsaWNpdCByYXRoZXIgdGhhbiBsZWZ0IHRvIGBhZGRDaGlsZGAsIHdoaWNoIGxvYWRzIHRoZSBjaGlsZCBvbmx5IHdoZW4gdGhlXG4gICAgICAvLyBwbHVnaW4gaXRzZWxmIGlzIGxvYWRlZCDigJQgdHJ1ZSB3aGVuIE9ic2lkaWFuIGNhbGxzIGBsb2FkKClgLCBidXQgbm90IHdoZW4gYSBjYWxsZXIgaW52b2tlc1xuICAgICAgLy8gYG9ubG9hZCgpYCBkaXJlY3RseS5cbiAgICAgIHN1cGVyLmFkZENoaWxkKHRoaXMudW5pdmVyc2FsV3JhcHBlckNvbXBvbmVudCk7XG4gICAgICB0aGlzLnVuaXZlcnNhbFdyYXBwZXJDb21wb25lbnQubG9hZCgpO1xuXG4gICAgICBhd2FpdCBpbml0STE4Tih0aGlzLmNyZWF0ZVRyYW5zbGF0aW9uc01hcCgpKTtcbiAgICAgIHRoaXMucGx1Z2luQ29udGV4dENvbXBvbmVudCA9IHRoaXMuYWRkVW5pdmVyc2FsQ2hpbGQoXG4gICAgICAgIG5ldyBQbHVnaW5Db250ZXh0Q29tcG9uZW50KHtcbiAgICAgICAgICBhcHA6IHRoaXMuYXBwLFxuICAgICAgICAgIHBsdWdpbklkOiB0aGlzLm1hbmlmZXN0LmlkXG4gICAgICAgIH0pXG4gICAgICApO1xuICAgICAgdGhpcy5wbHVnaW5Ob3RpY2VDb21wb25lbnQgPSB0aGlzLmFkZFVuaXZlcnNhbENoaWxkKFxuICAgICAgICBuZXcgUGx1Z2luTm90aWNlQ29tcG9uZW50KHtcbiAgICAgICAgICBhcHA6IHRoaXMuYXBwLFxuICAgICAgICAgIHBsdWdpbk5hbWU6IHRoaXMubWFuaWZlc3QubmFtZVxuICAgICAgICB9KVxuICAgICAgKTtcbiAgICAgIHRoaXMuYXN5bmNFcnJvckhhbmRsZXJDb21wb25lbnQgPSB0aGlzLmFkZFVuaXZlcnNhbENoaWxkKG5ldyBBc3luY0Vycm9ySGFuZGxlckNvbXBvbmVudCh0aGlzLnBsdWdpbk5vdGljZUNvbXBvbmVudCkpO1xuICAgICAgdGhpcy5hYm9ydFNpZ25hbENvbXBvbmVudCA9IHRoaXMuYWRkVW5pdmVyc2FsQ2hpbGQobmV3IEFib3J0U2lnbmFsQ29tcG9uZW50KHRoaXMubWFuaWZlc3QuaWQpKTtcbiAgICAgIHRoaXMuY29uc29sZURlYnVnQ29tcG9uZW50ID0gdGhpcy5hZGRVbml2ZXJzYWxDaGlsZChuZXcgQ29uc29sZURlYnVnQ29tcG9uZW50KHRoaXMubWFuaWZlc3QuaWQpKTtcbiAgICAgIHRoaXMucmVzb3VyY2VMb2NrQ29tcG9uZW50ID0gdGhpcy5hZGRVbml2ZXJzYWxDaGlsZChuZXcgUmVzb3VyY2VMb2NrQ29tcG9uZW50KHRoaXMuYXBwLCB0aGlzLm1hbmlmZXN0LmlkKSk7XG4gICAgICAvLyBgTm90ZWJvb2sgTmF2aWdhdG9yYCBkcmF3cyBpdHMgb3duIGZpbGUgdHJlZSBhbmQgbmV2ZXIgcmFpc2VzIE9ic2lkaWFuJ3MgYGZpbGUtbWVudWAgL1xuICAgICAgLy8gYGZpbGVzLW1lbnVgIGV2ZW50cywgc28gZXZlcnkgcGx1Z2luJ3MgY29udGV4dC1tZW51IGl0ZW1zIHdvdWxkIHZhbmlzaCBmb3IgYW55b25lIGJyb3dzaW5nXG4gICAgICAvLyB0aHJvdWdoIGl0LiBXaXJlZCBoZXJlIHJhdGhlciB0aGFuIHBlci1wbHVnaW46IHRoZSBicmlkZ2Ugc3RheXMgZG9ybWFudCB3aGVuIE5vdGVib29rXG4gICAgICAvLyBOYXZpZ2F0b3IgaXMgbm90IGluc3RhbGxlZCwgYW5kIGEgcGx1Z2luIHdpdGggbm8gZmlsZS9mb2xkZXIgaGFuZGxlcnMgY29udHJpYnV0ZXMgbm90aGluZy5cbiAgICAgIGNvbnN0IG5vdGVib29rTmF2aWdhdG9yTWVudUV2ZW50UmVnaXN0cmFyQ29tcG9uZW50ID0gdGhpcy5hZGRVbml2ZXJzYWxDaGlsZChcbiAgICAgICAgbmV3IE5vdGVib29rTmF2aWdhdG9yTWVudUV2ZW50UmVnaXN0cmFyQ29tcG9uZW50KHtcbiAgICAgICAgICBhcHA6IHRoaXMuYXBwLFxuICAgICAgICAgIHBsdWdpbk5hbWU6IHRoaXMubWFuaWZlc3QubmFtZSxcbiAgICAgICAgICBzdWJtZW51SWNvbjogdGhpcy5nZXROb3RlYm9va05hdmlnYXRvck1lbnVTdWJtZW51SWNvbigpXG4gICAgICAgIH0pXG4gICAgICApO1xuICAgICAgdGhpcy5jb21tYW5kSGFuZGxlckNvbXBvbmVudCA9IHRoaXMuYWRkVW5pdmVyc2FsQ2hpbGQoXG4gICAgICAgIG5ldyBDb21tYW5kSGFuZGxlckNvbXBvbmVudCh7XG4gICAgICAgICAgYWN0aXZlRmlsZVByb3ZpZGVyOiBuZXcgQXBwQWN0aXZlRmlsZVByb3ZpZGVyKHRoaXMuYXBwKSxcbiAgICAgICAgICBhZGRpdGlvbmFsTWVudUV2ZW50UmVnaXN0cmFyczogW25vdGVib29rTmF2aWdhdG9yTWVudUV2ZW50UmVnaXN0cmFyQ29tcG9uZW50XSxcbiAgICAgICAgICAvLyBUaGUgY29tcG9uZW50IGlzIHVuaXZlcnNhbDsgdGhlIGNvbW1hbmRzIHJlZ2lzdGVyZWQgVEhST1VHSCBpdCBhcmUgbm90LiBBIHN1YmNsYXNzIHJlZ2lzdGVyc1xuICAgICAgICAgIC8vIGl0cyBvd24gZnJvbSBgb25sb2FkSW1wbGAsIGNsb3Npbmcgb3ZlciBjb2xsYWJvcmF0b3JzIHRoYXQgYmVsb25nIHRvIHRoZSBmZWF0dXJlIHN1cmZhY2Ug4oCUIHNvXG4gICAgICAgICAgLy8gdGhvc2UgY29tbWFuZHMgbXVzdCBnbyBkb3duIHdpdGggdGhlIHN1cmZhY2Ugd2hlbiB0aGUgZ2F0ZSBjbG9zZXMsIG9yIHRoZXkgc2l0IGluIHRoZSBwYWxldHRlXG4gICAgICAgICAgLy8gY2FsbGluZyBpbnRvIHRvcm4tZG93biBvYmplY3RzLCBhbmQgYXJlIHJlZ2lzdGVyZWQgYSBzZWNvbmQgdGltZSB3aGVuIHRoZSBnYXRlIHJlb3BlbnMgYW5kXG4gICAgICAgICAgLy8gYG9ubG9hZEltcGxgIHJ1bnMgYWdhaW4uXG4gICAgICAgICAgLy8gUmVzb2x2ZWQgb24gZXZlcnkgY2FsbCByYXRoZXIgdGhhbiBjYXB0dXJlZCBoZXJlLCBiZWNhdXNlIGB1bmxvYWRGZWF0dXJlU3VyZmFjZWAgUkVQTEFDRVMgdGhlXG4gICAgICAgICAgLy8gd3JhcHBlciBpbnN0ZWFkIG9mIGVtcHR5aW5nIGl0OiBlYWNoIGN5Y2xlJ3MgY29tbWFuZHMgYmVsb25nIHRvIHRoYXQgY3ljbGUncyB3cmFwcGVyLlxuICAgICAgICAgIGNvbW1hbmRMaWZldGltZU93bmVyUHJvdmlkZXI6ICgpOiBDb21wb25lbnRFeCA9PiB0aGlzLmdhdGVkV3JhcHBlckNvbXBvbmVudCxcbiAgICAgICAgICBjb21tYW5kUmVnaXN0cmFyOiBuZXcgUGx1Z2luQ29tbWFuZFJlZ2lzdHJhcih0aGlzKSxcbiAgICAgICAgICBtZW51RXZlbnRSZWdpc3RyYXI6IHRoaXMuYWRkVW5pdmVyc2FsQ2hpbGQobmV3IE1lbnVFdmVudFJlZ2lzdHJhckNvbXBvbmVudCh0aGlzLmFwcCkpLFxuICAgICAgICAgIHBsdWdpbk5hbWU6IHRoaXMubWFuaWZlc3QubmFtZVxuICAgICAgICB9KVxuICAgICAgKTtcbiAgICAgIC8vIEFsd2F5cyBhdmFpbGFibGU7IHRoZSBjb21tYW5kJ3Mgb3duIGBjYW5FeGVjdXRlYCBoaWRlcyBpdCB1bmxlc3MgdGhlIGFjdGl2ZSBub3RlIGlzIGxvY2tlZC5cbiAgICAgIC8vIFRoZSBvbmUgY29tbWFuZCB0aGF0IG5hbWVzIGl0cyBvd25lciBleHBsaWNpdGx5LCBvcHRpbmcgT1VUIG9mIHRoZSBzdXJmYWNlLXNjb3BlZCBkZWZhdWx0IGFib3ZlOlxuICAgICAgLy8gSXQgaXMgdGhlIHJlc2N1ZSBmb3IgYSBub3RlIGxlZnQgbG9ja2VkLCBpdCBjbG9zZXMgb3ZlciBub3RoaW5nIGJ1dCB0aGUgdW5pdmVyc2FsIHJlc291cmNlLWxvY2tcbiAgICAgIC8vIGNvbXBvbmVudCwgYW5kIGEgYmxvY2tlZCBwbHVnaW4gaXMgZXhhY3RseSB3aGVuIGEgdXNlciBtYXkgbmVlZCBpdC5cbiAgICAgIGF3YWl0IHRoaXMuY29tbWFuZEhhbmRsZXJDb21wb25lbnQucmVnaXN0ZXJDb21tYW5kSGFuZGxlcnMoKCkgPT4gW1xuICAgICAgICBuZXcgVW5sb2NrQWN0aXZlTm90ZUNvbW1hbmRIYW5kbGVyKHtcbiAgICAgICAgICBhcHA6IHRoaXMuYXBwLFxuICAgICAgICAgIHJlc291cmNlTG9ja0NvbXBvbmVudDogdGhpcy5yZXNvdXJjZUxvY2tDb21wb25lbnRcbiAgICAgICAgfSlcbiAgICAgIF0sIHsgbGlmZXRpbWVPd25lcjogdGhpcy5jb21tYW5kSGFuZGxlckNvbXBvbmVudCB9KTtcblxuICAgICAgdGhpcy5wbHVnaW5TZXR0aW5nc0NvbXBvbmVudCA9IHRoaXMuYWRkVW5pdmVyc2FsQ2hpbGQoXG4gICAgICAgIG5ldyBQbHVnaW5TZXR0aW5nc0NvbXBvbmVudEJhc2U8b2JqZWN0Pih7XG4gICAgICAgICAgZGF0YUhhbmRsZXI6IG5ldyBQbHVnaW5EYXRhSGFuZGxlcih0aGlzKSxcbiAgICAgICAgICBwbHVnaW5FdmVudFNvdXJjZTogbmV3IFBsdWdpbkV2ZW50U291cmNlSW1wbCh0aGlzKSxcbiAgICAgICAgICBwbHVnaW5TZXR0aW5nc0NsYXNzOiBPYmplY3RcbiAgICAgICAgfSlcbiAgICAgICk7XG5cbiAgICAgIC8vIFRoZSBnYXRlLiBJdCBsb2FkcyB0aGUgZmVhdHVyZSBzdXJmYWNlIGl0c2VsZiBvbmNlIGV2ZXJ5IGRlY2xhcmVkIGRlcGVuZGVuY3kgaXMgc2F0aXNmaWVkIGFuZCBub1xuICAgICAgLy8gZGVjbGFyZWQgY29uZmxpY3QgaG9sZHMg4oCUIHdoaWNoIGZvciBhIHBsdWdpbiBkZWNsYXJpbmcgbmVpdGhlciBpcyBpbW1lZGlhdGVseSwgc3luY2hyb25vdXNseSxcbiAgICAgIC8vIGJlZm9yZSB0aGlzIGxpbmUgcmV0dXJucyDigJQgYW5kIHVubG9hZHMgaXQgYWdhaW4gaWYgYSBkZXBlbmRlbmN5IGlzIGxhdGVyIGRpc2FibGVkIG9yIHVuaW5zdGFsbGVkLFxuICAgICAgLy8gb3IgYSBjb25mbGljdGluZyBwbHVnaW4gaXMgZW5hYmxlZC4gQSBwbHVnaW4gdGhhdCBpcyBibG9ja2VkIHRoZXJlZm9yZSByZWFjaGVzIGBsb2FkV2l0aFByb21pc2VzYFxuICAgICAgLy8gYmVsb3cgaGF2aW5nIHJlZ2lzdGVyZWQgbm90aGluZyBvZiBpdHMgb3duLCB3aXRoIG9ubHkgdGhlIHVuaXZlcnNhbCBjb21wb25lbnRzIGFib3ZlIHJ1bm5pbmcgdG9cbiAgICAgIC8vIGV4cGxhaW4gd2h5IGFuZCB0byBvZmZlciB0aGUgcmVwYWlyLlxuICAgICAgLy8gQXNzaWduZWQgQkVGT1JFIHRoZSBhZGQsIHVubGlrZSBldmVyeSB1bml2ZXJzYWwgY29tcG9uZW50IGFib3ZlLCBhbmQgdGhhdCBvcmRlciBpcyB0aGUgd2hvbGVcbiAgICAgIC8vIHBvaW50LiBBZGRpbmcgdGhpcyBvbmUgaXMgd2hhdCBydW5zIGBvbmxvYWRJbXBsYCwgcGVyIHRoZSBwYXJhZ3JhcGggYWJvdmUsIHNvIHRoZSBhc3NpZ25tZW50XG4gICAgICAvLyBzdGF0ZW1lbnQgaGFzIG5vdCByZXR1cm5lZCB5ZXQgd2hpbGUgdGhlIHN1YmNsYXNzIGlzIHJ1bm5pbmcg4oCUIGFuZCBhIHNldHRpbmdzIHRhYiBidWlsdCB0aGVyZVxuICAgICAgLy8gcmVhZHMgYHRoaXMucGx1Z2luR2F0ZUNvbXBvbmVudGAgdG8gcmVuZGVyIHRoZSBgV2FybmAgYmFubmVyLiBBc3NpZ25pbmcgYWZ0ZXIgdGhlIGFkZCB3b3VsZFxuICAgICAgLy8gbWFrZSB0aGF0IHJlYWQgdGhyb3cgYFZhbHVlIGlzIHVuZGVmaW5lZGAgb3V0IG9mIHRoZSBnZXR0ZXIsIHdoaWNoIGlzIGFuIG9wYXF1ZSB3YXkgdG8gc2F5XG4gICAgICAvLyBcInRvbyBlYXJseVwiLiBOb3RoaW5nIGFib3V0IGNoaWxkLWFkZCBvcmRlciBtb3ZlczogdGhlIHNlcXVlbmNlIG9mIGBhZGRVbml2ZXJzYWxDaGlsZGAgY2FsbHMgaXNcbiAgICAgIC8vIHVuY2hhbmdlZCwgYW5kIGBzZXRDb21wb25lbnRgIGlzIGEgcGxhaW4gc3RvcmUuXG4gICAgICBjb25zdCBwbHVnaW5HYXRlQ29tcG9uZW50ID0gbmV3IFBsdWdpbkdhdGVDb21wb25lbnQoe1xuICAgICAgICBjb25mbGljdHM6IHRoaXMuZ2V0UGx1Z2luQ29uZmxpY3RzKCksXG4gICAgICAgIGRlcGVuZGVuY2llczogdGhpcy5nZXRQbHVnaW5EZXBlbmRlbmNpZXMoKSxcbiAgICAgICAgbG9hZEZlYXR1cmVTdXJmYWNlOiAoKTogUHJvbWlzZTx2b2lkPiA9PiB0aGlzLmxvYWRGZWF0dXJlU3VyZmFjZSgpLFxuICAgICAgICBwbHVnaW46IHRoaXMsXG4gICAgICAgIHBsdWdpbk5vdGljZUNvbXBvbmVudDogdGhpcy5wbHVnaW5Ob3RpY2VDb21wb25lbnQsXG4gICAgICAgIHVubG9hZEZlYXR1cmVTdXJmYWNlOiAoKTogdm9pZCA9PiB7XG4gICAgICAgICAgdGhpcy51bmxvYWRGZWF0dXJlU3VyZmFjZSgpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHRoaXMucGx1Z2luR2F0ZUNvbXBvbmVudCA9IHBsdWdpbkdhdGVDb21wb25lbnQ7XG4gICAgICB0aGlzLmFkZFVuaXZlcnNhbENoaWxkKHBsdWdpbkdhdGVDb21wb25lbnQpO1xuXG4gICAgICAvLyBFdmVyeSBjaGlsZCBoYXMgYWxyZWFkeSBsb2FkZWQgYXMgaXQgd2FzIGFkZGVkOyB0aGlzIGF3YWl0cyB0aGVpciBhY2N1bXVsYXRlZCBhc3luYyB0YWlscyBhbmRcbiAgICAgIC8vIHJlcG9ydHMgYW55IGZhaWx1cmUgYXMgYSBzaW5nbGUgYEFnZ3JlZ2F0ZUVycm9yYC5cbiAgICAgIGF3YWl0IHRoaXMudW5pdmVyc2FsV3JhcHBlckNvbXBvbmVudC5sb2FkV2l0aFByb21pc2VzKCk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHByaW50RXJyb3IobmV3IEVycm9yKGBFcnJvciBsb2FkaW5nIHBsdWdpbiAke3RoaXMubWFuaWZlc3QubmFtZX0gKCR7dGhpcy5tYW5pZmVzdC5pZH0pYCwgeyBjYXVzZTogZXJyb3IgfSkpO1xuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENhbGxlZCB3aGVuIHRoZSBwbHVnaW4gaXMgdW5sb2FkZWQuXG4gICAqXG4gICAqIEFubm91bmNlcyB0aGUgZGVwYXJ0dXJlIG9uIGBhcHAud29ya3NwYWNlYCBzbyBhbnl0aGluZyBkZXBlbmRpbmcgb24gdGhpcyBwbHVnaW4gbGVhcm5zIG9mIGl0IGF0IHRoZVxuICAgKiBtb21lbnQgaXQgaGFwcGVucywgcmF0aGVyIHRoYW4gZGlzY292ZXJpbmcgaXQgbGF0ZXIgdGhyb3VnaCBiZWhhdmlvciB0aGF0IHF1aWV0bHkgc3RvcHBlZC5cbiAgICpcbiAgICogRG8gTk9UIG92ZXJyaWRlIHRoaXMgbWV0aG9kOyBwdXQgdGVhcmRvd24gb24gYSBjb21wb25lbnQgaW5zdGVhZCwgd2hpY2ggdW5sb2FkcyB3aXRoIHRoZSBwbHVnaW4uXG4gICAqL1xuICBwdWJsaWMgb3ZlcnJpZGUgb251bmxvYWQoKTogdm9pZCB7XG4gICAgdGhpcy5icm9hZGNhc3RVbmxvYWRlZCgpO1xuICAgIHN1cGVyLm9udW5sb2FkKCk7XG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlcyBhIGNoaWxkIGNvbXBvbmVudC5cbiAgICpcbiAgICogQHR5cGVQYXJhbSBUQ29tcG9uZW50IC0gVGhlIHR5cGUgb2YgY29tcG9uZW50IHRvIHJlbW92ZS5cbiAgICogQHBhcmFtIGNvbXBvbmVudCAtIFRoZSBjb21wb25lbnQgaW5zdGFuY2UgdG8gcmVtb3ZlLlxuICAgKiBAcmV0dXJucyBUaGUgcmVtb3ZlZCBjb21wb25lbnQuXG4gICAqL1xuICBwdWJsaWMgb3ZlcnJpZGUgcmVtb3ZlQ2hpbGQ8VENvbXBvbmVudCBleHRlbmRzIENvbXBvbmVudD4oY29tcG9uZW50OiBUQ29tcG9uZW50KTogVENvbXBvbmVudCB7XG4gICAgLy8gUm91dGVkIGJ5IG93bmVyc2hpcCByYXRoZXIgdGhhbiBieSB3aGljaCB0aWVyIGBhZGRDaGlsZGAgd291bGQgaGF2ZSBjaG9zZW4sIGJlY2F1c2UgdGhlIHR3byBkbyBub3RcbiAgICAvLyBhbHdheXMgYWdyZWU6IGEgdW5pdmVyc2FsIGNvbXBvbmVudCBpcyBwYXJlbnRlZCBkaXJlY3RseSBvbiB0aGUgdW5pdmVyc2FsIHdyYXBwZXIsIHlldCBhIHN1YmNsYXNzXG4gICAgLy8gcmVwbGFjaW5nIG9uZSBnb2VzIHRocm91Z2ggdGhlIHNhbWUgcHVibGljIGByZW1vdmVDaGlsZGAgYXMgaXQgd291bGQgZm9yIGl0cyBvd24gY2hpbGRyZW4uXG4gICAgcmV0dXJuIHRoaXMuZ2F0ZWRXcmFwcGVyQ29tcG9uZW50Lmhhc0NoaWxkKGNvbXBvbmVudCkgPyB0aGlzLmdhdGVkV3JhcHBlckNvbXBvbmVudC5yZW1vdmVDaGlsZChjb21wb25lbnQpIDogdGhpcy51bml2ZXJzYWxXcmFwcGVyQ29tcG9uZW50LnJlbW92ZUNoaWxkKGNvbXBvbmVudCk7XG4gIH1cblxuICAvKipcbiAgICogUHJvdmlkZXMgdGhlIHRyYW5zbGF0aW9ucyBtYXAgdXNlZCB0byBpbml0aWFsaXplIGkxOG4gZHVyaW5nIHtAbGluayBvbmxvYWR9LlxuICAgKlxuICAgKiBPdmVycmlkZSBpbiBzdWJjbGFzcyB0byBzdXBwbHkgcGx1Z2luLXNwZWNpZmljIHRyYW5zbGF0aW9ucy4gVGhlIGRlZmF1bHQgcmV0dXJucyB0aGUgYnVpbHQtaW5cbiAgICogYEBtbmFvdW1vdi9vYnNpZGlhbi1saWJgIHRyYW5zbGF0aW9ucy4gQSBsYW5ndWFnZSBtYXkgbWFwIHRvIGEgYExvY2FsZUxvYWRlcmAgaW5zdGVhZCBvZiBpdHMgdHJhbnNsYXRpb25zLCBzb1xuICAgKiBvbmx5IHRoZSBzaG93biBsYW5ndWFnZSBpcyBpbml0aWFsaXplZDsgc2VlIHtAbGluayBodHRwczovL21uYW91bW92LmRldi9vYnNpZGlhbi1saWIvZ3VpZGVzL3RyYW5zbGF0aW9ucy99LlxuICAgKlxuICAgKiBAcmV0dXJucyBUaGUgdHJhbnNsYXRpb25zIG1hcC5cbiAgICovXG4gIHByb3RlY3RlZCBjcmVhdGVUcmFuc2xhdGlvbnNNYXAoKTogVHJhbnNsYXRpb25zTWFwIHtcbiAgICByZXR1cm4gZGVmYXVsdFRyYW5zbGF0aW9uc01hcDtcbiAgfVxuXG4gIC8qKlxuICAgKiBQcm92aWRlcyBob3cgbG9uZyBhIG5ldyBpbnN0YW5jZSB3YWl0cyBmb3IgdGhlIHByZXZpb3VzIGluc3RhbmNlJ3MgYXN5bmMgY2xlYW51cHMgYmVmb3JlIGxvYWRpbmcgYW55d2F5LlxuICAgKlxuICAgKiBPdmVycmlkZSBpbiBzdWJjbGFzcyB0byBjaGFuZ2UgaXQuIFRoZSBkZWZhdWx0IGlzIDEwIHNlY29uZHMuXG4gICAqXG4gICAqIEByZXR1cm5zIFRoZSB0aW1lb3V0IGluIG1pbGxpc2Vjb25kcy5cbiAgICovXG4gIHByb3RlY3RlZCBnZXRBc3luY0NsZWFudXBUaW1lb3V0SW5NaWxsaXNlY29uZHMoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gREVGQVVMVF9QTFVHSU5fQVNZTkNfQ0xFQU5VUF9USU1FT1VUX0lOX01JTExJU0VDT05EUztcbiAgfVxuXG4gIC8qKlxuICAgKiBQcm92aWRlcyB0aGUgaWNvbiBzaG93biBvbiB0aGUgcGx1Z2luJ3MgcGFyZW50IGVudHJ5IGluIGBOb3RlYm9vayBOYXZpZ2F0b3JgJ3MgY29udGV4dCBtZW51cy5cbiAgICpcbiAgICogT3ZlcnJpZGUgaW4gc3ViY2xhc3MgdG8gYnJhbmQgdGhhdCBlbnRyeTsgdGhlIGRlZmF1bHQgbGVhdmVzIGl0IHdpdGhvdXQgYW4gaWNvbi4gVGhlIGVudHJ5IGlzXG4gICAqIHRpdGxlZCB3aXRoIHRoZSBwbHVnaW4gbmFtZSBhbmQgaXMgYWRkZWQgYXV0b21hdGljYWxseSDigJQgc2VlXG4gICAqIHtAbGluayBOb3RlYm9va05hdmlnYXRvck1lbnVFdmVudFJlZ2lzdHJhckNvbXBvbmVudH0uXG4gICAqXG4gICAqIEByZXR1cm5zIFRoZSBpY29uLCBvciBgJydgIGZvciBubyBpY29uLlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldE5vdGVib29rTmF2aWdhdG9yTWVudVN1Ym1lbnVJY29uKCk6IEljb25OYW1lIHtcbiAgICByZXR1cm4gJyc7XG4gIH1cblxuICAvKipcbiAgICogUHJvdmlkZXMgdGhlIEFQSXMgdGhpcyBwbHVnaW4gZXhwb3NlcyB0byBvdGhlciBwbHVnaW5zLlxuICAgKlxuICAgKiBPdmVycmlkZSBpbiBzdWJjbGFzcyB0byBwdWJsaXNoIG9uZS4gVGhlIGRlZmF1bHQgcHVibGlzaGVzIG5vbmUuIENhbGxlZCBhZnRlciB7QGxpbmsgb25sb2FkSW1wbH0sIHNvIGFcbiAgICogZGVjbGFyYXRpb24gbWF5IHJlZmVyZW5jZSBhbnl0aGluZyBpdCBjcmVhdGVkOyB0aGUgcmV0dXJuZWQgZGVjbGFyYXRpb25zIGFyZSBwdWJsaXNoZWQgdGhyb3VnaFxuICAgKiBgcHVibGlzaFBsdWdpbkFwaWAgYW5kIHJldm9rZWQgd2hlbiB0aGUgcGx1Z2luJ3MgZmVhdHVyZSBzdXJmYWNlIHVubG9hZHMuXG4gICAqXG4gICAqIFJldHVybmluZyBhIExJU1QgcmF0aGVyIHRoYW4gYSBzaW5nbGUgQVBJIGlzIGRlbGliZXJhdGU6IHRoZSByZWdpc3RyeSBzdXBwb3J0cyBzZXZlcmFsIGNvbnRyYWN0XG4gICAqIHZlcnNpb25zIHB1Ymxpc2hlZCBzaWRlIGJ5IHNpZGUsIHdoaWNoIGlzIGhvdyBhIHByb3ZpZGVyIHNoaXBzIGEgYnJlYWtpbmcgYDIuMC4wYCB3aXRob3V0IHN0cmFuZGluZ1xuICAgKiBjb25zdW1lcnMgc3RpbGwgcGlubmVkIHRvIGBeMWAuXG4gICAqXG4gICAqIEV2ZXJ5IGRlY2xhcmF0aW9uIGhlcmUgaXMgcHVibGlzaGVkIEJFRk9SRSB0aGUgYG9ic2lkaWFuLWxpYjpwbHVnaW4tbG9hZGVkYCBicm9hZGNhc3QsIHdoaWNoIGlzXG4gICAqIHdoYXQgbGV0cyBhIGxpc3RlbmVyIGNhbGwgdGhlc2UgQVBJcyB0aGUgbW9tZW50IGl0IGhlYXJzIHRoYXQgZXZlbnQuXG4gICAqXG4gICAqIEByZXR1cm5zIFRoZSBBUEkgZGVjbGFyYXRpb25zLlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldFBsdWdpbkFwaXMoKTogUGx1Z2luQXBpRGVjbGFyYXRpb25bXSB7XG4gICAgcmV0dXJuIFtdO1xuICB9XG5cbiAgLyoqXG4gICAqIFByb3ZpZGVzIHRoZSBwbHVnaW5zIHRoaXMgb25lIHJlZnVzZXMsIG9yIHdhcm5zIGFib3V0LCBydW5uaW5nIGJlc2lkZS5cbiAgICpcbiAgICogT3ZlcnJpZGUgaW4gc3ViY2xhc3MgdG8gZGVjbGFyZSBhbiBvdmVybGFwLiBUaGUgZGVmYXVsdCBkZWNsYXJlcyBub25lLlxuICAgKlxuICAgKiBBIGBCbG9ja2AgY29uZmxpY3QgaXMgdGhlIG1pcnJvciBpbWFnZSBvZiBhIGRlcGVuZGVuY3k6IHdoaWxlIGEgY29uZmxpY3RpbmcgcGx1Z2luIGlzIGVuYWJsZWQgYXQgYVxuICAgKiBjb25mbGljdGluZyB2ZXJzaW9uLCB7QGxpbmsgb25sb2FkSW1wbH0gZG9lcyBub3QgcnVuIGF0IGFsbCBhbmQgdGhlIHBsdWdpbiByZWdpc3RlcnMgbm90aGluZy4gRGVjbGFyZVxuICAgKiBpdCB3aGVuIGJvdGggcGx1Z2lucyBhY3Rpbmcgb24gdGhlIHNhbWUgb3BlcmF0aW9uIGRhbWFnZXMgdGhlIHZhdWx0IOKAlCB0aGVyZSBpcyBubyByZWxpYWJsZSB3YXkgdG8gd2luXG4gICAqIHRoYXQgcmFjZSwgYmVjYXVzZSB3aGljaGV2ZXIgcGx1Z2luIGxvYWRlZCBmaXJzdCBrZWVwcyBhIGhhbmQgb24gdGhlIHdoZWVsLCBzbyByZWZ1c2luZyBkZXRlcm1pbmlzdGljYWxseVxuICAgKiBiZWF0cyBjb21wZXRpbmcgdW5wcmVkaWN0YWJseS4gQSBgV2FybmAgY29uZmxpY3QgZGVjbGFyZXMgYW4gb3ZlcmxhcCB0aGF0IGlzIG1lcmVseSBhbm5veWluZywgc3VjaCBhcyBhXG4gICAqIGR1cGxpY2F0ZWQgY29tbWFuZDogYm90aCBwbHVnaW5zIGtlZXAgcnVubmluZyBhbmQgdGhlIHVzZXIgaXMgdG9sZC5cbiAgICpcbiAgICogVW5saWtlIGEgZGVwZW5kZW5jeSwgYSBjb25mbGljdGluZyBwbHVnaW4gbmVlZCBub3QgcHVibGlzaCBhbnl0aGluZyDigJQgaXQgaXMgZGV0ZWN0ZWQgYnkgcmVhZGluZyBpdHNcbiAgICogaW5zdGFsbGVkIHZlcnNpb24sIHdoaWNoIGlzIHRoZSBvbmx5IHRoaW5nIGFib3V0IGFub3RoZXIgcGx1Z2luIHRoYXQgcmVhZHMgdGhlIHNhbWUgcmVnYXJkbGVzcyBvZiBsb2FkXG4gICAqIG9yZGVyLlxuICAgKlxuICAgKiBAcmV0dXJucyBUaGUgZGVjbGFyZWQgY29uZmxpY3RzLlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldFBsdWdpbkNvbmZsaWN0cygpOiBQbHVnaW5Db25mbGljdFtdIHtcbiAgICByZXR1cm4gW107XG4gIH1cblxuICAvKipcbiAgICogUHJvdmlkZXMgdGhlIHBsdWdpbnMgdGhpcyBvbmUgY2Fubm90IHdvcmsgd2l0aG91dC5cbiAgICpcbiAgICogT3ZlcnJpZGUgaW4gc3ViY2xhc3MgdG8gZGVjbGFyZSBhIG1hbmRhdG9yeSBkZXBlbmRlbmN5LiBUaGUgZGVmYXVsdCBkZWNsYXJlcyBub25lLCBhbmQgc3VjaCBhIHBsdWdpblxuICAgKiBsb2FkcyBleGFjdGx5IGFzIGl0IGFsd2F5cyBoYXMuXG4gICAqXG4gICAqIEEgZGVjbGFyZWQgZGVwZW5kZW5jeSBpcyBNQU5EQVRPUlksIHVubGlrZSB0aGUgb2ZmZXIgYFBsdWdpblN1Z2dlc3Rpb25Db21wb25lbnRgIG1ha2VzOiB3aGlsZSBvbmUgaXNcbiAgICogbWlzc2luZywgZGlzYWJsZWQsIG9yIHRvbyBvbGQsIHtAbGluayBvbmxvYWRJbXBsfSBkb2VzIG5vdCBydW4gYXQgYWxsIGFuZCB0aGUgcGx1Z2luIHJlZ2lzdGVycyBub3RoaW5nXG4gICAqIOKAlCBubyBjb21tYW5kcywgbm8gaGFuZGxlcnMsIG5vIHBhdGNoZXMuIEl0IHN0YXlzIGVuYWJsZWQgaW4gT2JzaWRpYW4ncyBsaXN0IHJhdGhlciB0aGFuIGRpc2FibGluZ1xuICAgKiBpdHNlbGYsIGJlY2F1c2UgdGhlIGVuYWJsZWQgc2V0IGlzIHRoZSB1c2VyJ3MgdG8gY2hhbmdlLCBhbmQgaXQgZXhwbGFpbnMgaXRzZWxmIHRocm91Z2ggYSBub3RpY2UgYW5kIGFcbiAgICogc2V0dGluZ3MgYmFubmVyIHRoYXQgaW5zdGFsbHMgdGhlIG1pc3NpbmcgcGx1Z2luIGluIG9uZSBjbGljay4gVGhlIGxvYWQgY29tcGxldGVzIHRoZSBtb21lbnQgdGhlXG4gICAqIGRlcGVuZGVuY3kgYXJyaXZlcywgd2l0aCBubyByZXN0YXJ0LlxuICAgKlxuICAgKiBBIGRlcGVuZGVuY3kgbXVzdCBwdWJsaXNoIGFuIEFQSSB0aHJvdWdoIGBwdWJsaXNoUGx1Z2luQXBpYCwgd2hpY2ggaXMgd2hhdCBtYWtlcyBpdHMgcHJlc2VuY2UsXG4gICAqIGFic2VuY2UsIHZlcnNpb24gYW5kIGRlcGFydHVyZSBhbGwgb2JzZXJ2YWJsZSB0aHJvdWdoIG9uZSBtZWNoYW5pc20uIEEgcGx1Z2luIHdpdGggbm90aGluZyB0byBleHBvc2VcbiAgICogY2FuIHB1Ymxpc2ggYW4gZW1wdHkgQVBJIHB1cmVseSBzbyBpdCBjYW4gYmUgZGVwZW5kZWQgdXBvbi5cbiAgICpcbiAgICogQHJldHVybnMgVGhlIGRlY2xhcmVkIGRlcGVuZGVuY2llcy5cbiAgICovXG4gIHByb3RlY3RlZCBnZXRQbHVnaW5EZXBlbmRlbmNpZXMoKTogUGx1Z2luRGVwZW5kZW5jeVtdIHtcbiAgICByZXR1cm4gW107XG4gIH1cblxuICAvKipcbiAgICogQ2FsbGVkIGR1cmluZyB7QGxpbmsgb25sb2FkfSB0byB3aXJlIHBsdWdpbi1zcGVjaWZpYyBjaGlsZCBjb21wb25lbnRzLlxuICAgKlxuICAgKiBPdmVycmlkZSBpbiBzdWJjbGFzcyB0byBhZGQgY2hpbGQgY29tcG9uZW50cyB2aWEge0BsaW5rIGFkZENoaWxkfS4gVGhlIHVuaXZlcnNhbCBjb21wb25lbnRzIGFyZVxuICAgKiBhdmFpbGFibGUgaGVyZS4gQ2hpbGRyZW4gYXJlIGxvYWRlZCBzZXF1ZW50aWFsbHkgaW4gdGhlIG9yZGVyIHRoZXkgYXJlIGFkZGVkIChjaGlsZHJlbi1maXJzdCkuXG4gICAqXG4gICAqIEByZXR1cm5zIEEge0BsaW5rIFByb21pc2V9IHRoYXQgcmVzb2x2ZXMgd2hlbiB0aGUgc3ViY2xhc3MgbG9hZCBsb2dpYyBpcyBjb21wbGV0ZS5cbiAgICovXG4gIHByb3RlY3RlZCBvbmxvYWRJbXBsKCk6IFByb21pc2FibGU8dm9pZD4ge1xuICAgIHJldHVybiBub29wQXN5bmMoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWdpc3RlcnMgYW4gYXN5bmMgY2xlYW51cCB0aGF0IHRoZSBuZXh0IGluc3RhbmNlIG9mIHRoaXMgcGx1Z2luIGF3YWl0cyBiZWZvcmUgaXQgc3RhcnRzLlxuICAgKlxuICAgKiBVc2UgaXQgZm9yIHRlYXJkb3duIHRoYXQgY2Fubm90IGZpbmlzaCBzeW5jaHJvbm91c2x5IGFuZCBtdXN0IGZpbmlzaCBiZWZvcmUgdGhlIHJlc291cmNlIGlzIG9wZW5lZCBhZ2Fpbiwgc3VjaFxuICAgKiBhcyBjbG9zaW5nIGFuIEluZGV4ZWREQiBjb25uZWN0aW9uLiBPYnNpZGlhbidzIGBvbnVubG9hZGAgaXMgc3luY2hyb25vdXMgYW5kIGF3YWl0cyBub3RoaW5nLCBzbyB3aXRob3V0IHRoaXMgYVxuICAgKiByZWxvYWQgc3RhcnRzIHRoZSBuZXcgaW5zdGFuY2Ugd2hpbGUgdGhlIG9sZCBvbmUgc3RpbGwgaG9sZHMgdGhlIGRhdGFiYXNlLlxuICAgKlxuICAgKiBTY29wZWQgbGlrZSB7QGxpbmsgYWRkQ2hpbGR9OiB0aGUgY2xlYW51cCBzdGFydHMgd2hlbiB0aGUgcGx1Z2luJ3MgZmVhdHVyZSBzdXJmYWNlIHVubG9hZHMsIHdoaWNoIGlzIG9uIHBsdWdpblxuICAgKiB1bmxvYWQgYW5kIHdoZW5ldmVyIHRoZSBnYXRlIGNsb3Nlcy4gVGhlIG5leHQgbG9hZCBvZiB0aGUgcGx1Z2luLCBhbmQgdGhlIG5leHQgb3BlbmluZyBvZiB0aGUgZ2F0ZSwgYXdhaXQgaXQsXG4gICAqIGJvdW5kZWQgYnkge0BsaW5rIGdldEFzeW5jQ2xlYW51cFRpbWVvdXRJbk1pbGxpc2Vjb25kc30uIEEgY2xlYW51cCB0aGF0IHRocm93cyBpcyBwcmludGVkLCBuZXZlciByZXRocm93bi5cbiAgICpcbiAgICogQHBhcmFtIGNsZWFudXAgLSBUaGUgY2xlYW51cCB0byBydW4uXG4gICAqL1xuICBwcm90ZWN0ZWQgcmVnaXN0ZXJBc3luY0NsZWFudXAoY2xlYW51cDogKCkgPT4gUHJvbWlzYWJsZTx2b2lkPik6IHZvaWQge1xuICAgIHJlZ2lzdGVyUGx1Z2luQXN5bmNDbGVhbnVwKHtcbiAgICAgIGNsZWFudXAsXG4gICAgICBjb21wb25lbnQ6IHRoaXMuZ2F0ZWRXcmFwcGVyQ29tcG9uZW50LFxuICAgICAgcGx1Z2luSWQ6IHRoaXMubWFuaWZlc3QuaWRcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdG9yZXMgYSB1bml2ZXJzYWwgY29tcG9uZW50LCB1bmxvYWRpbmcgd2hpY2hldmVyIGNvbXBvbmVudCB0aGUga2V5IGhlbGQgYmVmb3JlLlxuICAgKlxuICAgKiBLZXllZCBieSBuYW1lIHJhdGhlciB0aGFuIGhhbmRlZCB0aGUgcHJldmlvdXMgdmFsdWUgYmVjYXVzZSBga2V5b2YgdGhpc2AgZXhjbHVkZXMgcHJpdmF0ZVxuICAgKiBtZW1iZXJzLCBzbyB0aGUgY29tcG9uZW50cyBsaXZlIGluIGEgc2luZ2xlIHtAbGluayBQbHVnaW5CYXNlQ29tcG9uZW50c30gYmFnIHdob3NlIGtleXMgQVJFXG4gICAqIGluZGV4YWJsZS5cbiAgICpcbiAgICogQHR5cGVQYXJhbSBUS2V5IC0gVGhlIGtleSBvZiB0aGUgY29tcG9uZW50IHRvIHN0b3JlLlxuICAgKiBAcGFyYW0ga2V5IC0gVGhlIGtleSBvZiB0aGUgY29tcG9uZW50IHRvIHN0b3JlLlxuICAgKiBAcGFyYW0gdmFsdWUgLSBUaGUgY29tcG9uZW50IHRvIHN0b3JlLlxuICAgKi9cbiAgLyoqXG4gICAqIEFkZHMgYSBjb21wb25lbnQgdG8gdGhlIHVuaXZlcnNhbCB0aWVyLCB3aGljaCBvdXRsaXZlcyBhbnkgZGVwZW5kZW5jeS5cbiAgICpcbiAgICogUHJpdmF0ZSBvbiBwdXJwb3NlOiBvbmx5IHRoaXMgY2xhc3MgZGVjaWRlcyB3aGF0IGlzIHVuaXZlcnNhbC4gQSBzdWJjbGFzcyBhZGRpbmcgb25lIG9mIGl0cyBvd24gZ29lc1xuICAgKiB0aHJvdWdoIHtAbGluayBhZGRDaGlsZH0gYW5kIGxhbmRzIGluIHRoZSBnYXRlZCB0aWVyLCB3aGVyZSBpdCBiZWxvbmdzLlxuICAgKlxuICAgKiBAdHlwZVBhcmFtIFRDb21wb25lbnQgLSBUaGUgdHlwZSBvZiBjb21wb25lbnQgdG8gYWRkLlxuICAgKiBAcGFyYW0gY29tcG9uZW50IC0gVGhlIGNvbXBvbmVudCBpbnN0YW5jZSB0byBhZGQuXG4gICAqIEByZXR1cm5zIFRoZSBhZGRlZCBjb21wb25lbnQuXG4gICAqL1xuICBwcml2YXRlIGFkZFVuaXZlcnNhbENoaWxkPFRDb21wb25lbnQgZXh0ZW5kcyBDb21wb25lbnQ+KGNvbXBvbmVudDogVENvbXBvbmVudCk6IFRDb21wb25lbnQge1xuICAgIHJldHVybiB0aGlzLnVuaXZlcnNhbFdyYXBwZXJDb21wb25lbnQuYWRkQ2hpbGQoY29tcG9uZW50KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBbm5vdW5jZXMgb24gYGFwcC53b3Jrc3BhY2VgIHRoYXQgdGhpcyBwbHVnaW4gaXMgbG9hZGVkIGFuZCBpdHMgQVBJcyBhcmUgY2FsbGFibGUuXG4gICAqL1xuICBwcml2YXRlIGJyb2FkY2FzdExvYWRlZCgpOiB2b2lkIHtcbiAgICB0aGlzLmxpZmVjeWNsZUV2ZW50UGF5bG9hZCA9IHtcbiAgICAgIGFwaVZlcnNpb25zOiB0aGlzLmdldFBsdWdpbkFwaXMoKS5tYXAoKGRlY2xhcmF0aW9uKSA9PiBkZWNsYXJhdGlvbi5hcGlWZXJzaW9uKSxcbiAgICAgIGRlcGVuZGVuY3lQbHVnaW5JZHM6IHRoaXMuZ2V0UGx1Z2luRGVwZW5kZW5jaWVzKCkubWFwKChkZXBlbmRlbmN5KSA9PiBkZXBlbmRlbmN5LnBsdWdpbklkKSxcbiAgICAgIHBsdWdpbklkOiB0aGlzLm1hbmlmZXN0LmlkLFxuICAgICAgcGx1Z2luTmFtZTogdGhpcy5tYW5pZmVzdC5uYW1lLFxuICAgICAgcGx1Z2luVmVyc2lvbjogdGhpcy5tYW5pZmVzdC52ZXJzaW9uXG4gICAgfTtcblxuICAgIHRyaWdnZXJQbHVnaW5MaWZlY3ljbGVFdmVudCh7XG4gICAgICBhcHA6IHRoaXMuYXBwLFxuICAgICAgbmFtZTogUExVR0lOX0xPQURFRF9FVkVOVF9OQU1FLFxuICAgICAgcGF5bG9hZDogdGhpcy5saWZlY3ljbGVFdmVudFBheWxvYWRcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBbm5vdW5jZXMgb24gYGFwcC53b3Jrc3BhY2VgIHRoYXQgdGhpcyBwbHVnaW4ncyBzdXJmYWNlIGhhcyBnb25lIGF3YXkuXG4gICAqXG4gICAqIFNpbGVudCB1bmxlc3MgYSBsb2FkZWQgYnJvYWRjYXN0IGlzIG91dHN0YW5kaW5nLCBzbyB0aGUgdHdvIGV2ZW50cyBzdGF5IHBhaXJlZDogYSBwbHVnaW4gdGhhdCBuZXZlclxuICAgKiBnb3QgcGFzdCBpdHMgZGVwZW5kZW5jeSBnYXRlIG5ldmVyIGFubm91bmNlZCBpdHNlbGYsIGFuZCBtdXN0IG5vdCBhbm5vdW5jZSBhIGRlcGFydHVyZSBlaXRoZXIuXG4gICAqL1xuICBwcml2YXRlIGJyb2FkY2FzdFVubG9hZGVkKCk6IHZvaWQge1xuICAgIGNvbnN0IHBheWxvYWQgPSB0aGlzLmxpZmVjeWNsZUV2ZW50UGF5bG9hZDtcbiAgICBpZiAoIXBheWxvYWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLmxpZmVjeWNsZUV2ZW50UGF5bG9hZCA9IG51bGw7XG4gICAgdHJpZ2dlclBsdWdpbkxpZmVjeWNsZUV2ZW50KHtcbiAgICAgIGFwcDogdGhpcy5hcHAsXG4gICAgICBuYW1lOiBQTFVHSU5fVU5MT0FERURfRVZFTlRfTkFNRSxcbiAgICAgIHBheWxvYWRcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBCdWlsZHMgYW5kIGxvYWRzIHRoZSBzdWJjbGFzcydzIGZlYXR1cmUgc3VyZmFjZSwgdGhlbiBwdWJsaXNoZXMgaXRzIEFQSXMgYW5kIGFubm91bmNlcyBpdHNlbGYuXG4gICAqXG4gICAqIE5PVCBpZGVtcG90ZW50LCBkZWxpYmVyYXRlbHkuIGBQbHVnaW5HYXRlQ29tcG9uZW50YCBvd25zIHRoZSB1cC9kb3duIHN0YXRlIG1hY2hpbmUgYW5kIGNhbGxzXG4gICAqIHRoaXMgb25seSBvbiBhIHJlYWwgdHJhbnNpdGlvbjsgYSBzZWNvbmQgZ3VhcmQgaGVyZSB3b3VsZCBiZSBhIHNlY29uZCBjb3B5IG9mIHRoYXQgc3RhdGUsIHdoaWNoIGlzIHRoZVxuICAgKiBraW5kIG9mIGR1cGxpY2F0ZSB0aGF0IGRyaWZ0cy5cbiAgICpcbiAgICogQHJldHVybnMgQSB7QGxpbmsgUHJvbWlzZX0gdGhhdCByZXNvbHZlcyBvbmNlIHRoZSBzdXJmYWNlIGlzIGxvYWRlZCBhbmQgdGhlIGJyb2FkY2FzdCBoYXMgYmVlbiBtYWRlLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBsb2FkRmVhdHVyZVN1cmZhY2UoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgLy8gTG9hZGVkIGV4cGxpY2l0bHkgZm9yIHRoZSBzYW1lIHJlYXNvbiB0aGUgdW5pdmVyc2FsIHdyYXBwZXIgaXM6IGBhZGRDaGlsZGAgbG9hZHMgYSBjaGlsZCBvbmx5IG9uY2VcbiAgICAvLyBpdHMgcGFyZW50IGlzIGxvYWRlZCwgYW5kIHRoZSBzdXJmYWNlIGhhcyB0byBiZSBsaXZlIGJlZm9yZSBgb25sb2FkSW1wbGAgc3RhcnRzIGFkZGluZyB0byBpdC5cbiAgICBjb25zdCBnYXRlZFdyYXBwZXJDb21wb25lbnQgPSB0aGlzLmdhdGVkV3JhcHBlckNvbXBvbmVudDtcbiAgICB0aGlzLnVuaXZlcnNhbFdyYXBwZXJDb21wb25lbnQuYWRkQ2hpbGQoZ2F0ZWRXcmFwcGVyQ29tcG9uZW50KTtcbiAgICBnYXRlZFdyYXBwZXJDb21wb25lbnQubG9hZCgpO1xuXG4gICAgLy8gQSBzdXJmYWNlIHJlb3BlbmVkIGFmdGVyIHRoZSBnYXRlIGNsb3NlZCB3YWl0cyBmb3IgdGhlIGNsZWFudXBzIHRoZSBwcmV2aW91cyBzdXJmYWNlIHN0YXJ0ZWQuIE9ubHkgd2hlbiBzb21lXG4gICAgLy8gYXJlIHBlbmRpbmcsIHNvIGEgZmlyc3QgbG9hZCwgd2hlcmUgYG9ubG9hZGAgYWxyZWFkeSB3YWl0ZWQsIHN0aWxsIHJ1bnMgYG9ubG9hZEltcGxgIHN5bmNocm9ub3VzbHkuXG4gICAgaWYgKGhhc1BlbmRpbmdQbHVnaW5Bc3luY0NsZWFudXBzKHRoaXMubWFuaWZlc3QuaWQpKSB7XG4gICAgICBhd2FpdCB0aGlzLndhaXRGb3JQcmV2aW91c0FzeW5jQ2xlYW51cHMoKTtcbiAgICB9XG5cbiAgICBhd2FpdCB0aGlzLm9ubG9hZEltcGwoKTtcbiAgICBhd2FpdCBnYXRlZFdyYXBwZXJDb21wb25lbnQubG9hZFdpdGhQcm9taXNlcygpO1xuXG4gICAgZm9yIChjb25zdCBkZWNsYXJhdGlvbiBvZiB0aGlzLmdldFBsdWdpbkFwaXMoKSkge1xuICAgICAgcHVibGlzaFBsdWdpbkFwaSh7XG4gICAgICAgIC4uLmRlY2xhcmF0aW9uLFxuICAgICAgICAvLyBSZXZva2VkIHdpdGggdGhlIFNVUkZBQ0UsIG5vdCB3aXRoIHRoZSBwbHVnaW46IGEgcGx1Z2luIHdob3NlIGRlcGVuZGVuY3kgZ29lcyBhd2F5IGtlZXBzIHJ1bm5pbmdcbiAgICAgICAgLy8gaXRzIHVuaXZlcnNhbCBjb21wb25lbnRzLCBhbmQgYSBjb25zdW1lciBtdXN0IG5vdCBiZSBsZWZ0IGhvbGRpbmcgYSBoYW5kbGUgaW50byB0aGUgaGFsZiBvZiBpdFxuICAgICAgICAvLyB0aGF0IHdhcyBqdXN0IHRvcm4gZG93bi5cbiAgICAgICAgY29tcG9uZW50OiBnYXRlZFdyYXBwZXJDb21wb25lbnQsXG4gICAgICAgIHBsdWdpbjogdGhpc1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgdGhpcy5icm9hZGNhc3RMb2FkZWQoKTtcbiAgfVxuXG4gIHByaXZhdGUgc2V0Q29tcG9uZW50PFRLZXkgZXh0ZW5kcyBrZXlvZiBQbHVnaW5CYXNlQ29tcG9uZW50cz4oa2V5OiBUS2V5LCB2YWx1ZTogTm9uTnVsbGFibGU8UGx1Z2luQmFzZUNvbXBvbmVudHNbVEtleV0+KTogdm9pZCB7XG4gICAgY29uc3Qgb2xkQ29tcG9uZW50ID0gdGhpcy5jb21wb25lbnRzW2tleV07XG4gICAgaWYgKG9sZENvbXBvbmVudCkge1xuICAgICAgdGhpcy5yZW1vdmVDaGlsZChvbGRDb21wb25lbnQpO1xuICAgIH1cbiAgICB0aGlzLmNvbXBvbmVudHNba2V5XSA9IHZhbHVlO1xuICB9XG5cbiAgLyoqXG4gICAqIFRlYXJzIHRoZSBzdWJjbGFzcydzIGZlYXR1cmUgc3VyZmFjZSBkb3duLCBsZWF2aW5nIHRoZSB1bml2ZXJzYWwgY29tcG9uZW50cyBydW5uaW5nLlxuICAgKi9cbiAgcHJpdmF0ZSB1bmxvYWRGZWF0dXJlU3VyZmFjZSgpOiB2b2lkIHtcbiAgICBjb25zdCBnYXRlZFdyYXBwZXJDb21wb25lbnQgPSB0aGlzLmdhdGVkV3JhcHBlckNvbXBvbmVudDtcblxuICAgIC8vIFJlcGxhY2VkIEJFRk9SRSB0aGUgb2xkIG9uZSBpcyB1bmxvYWRlZCwgc28gYW55dGhpbmcgdGhhdCByZXN1bWVzIG1pZC10ZWFyZG93biBhbmQgY2FsbHMgYGFkZENoaWxkYFxuICAgIC8vIHBhcmtzIGl0cyBjaGlsZCBvbiB0aGUgZnJlc2ggc3VyZmFjZSByYXRoZXIgdGhhbiBvbiB0aGUgb25lIGJlaW5nIHRvcm4gZG93biDigJQgd2hlcmUgYENvbXBvbmVudEV4YFxuICAgIC8vIHdvdWxkIHJlZnVzZSBpdCBvdXRyaWdodCwgc2luY2UgaXQgcmVmdXNlcyBjaGlsZHJlbiBhZGRlZCB0byBhbiBhbHJlYWR5LXVubG9hZGVkIGNvbXBvbmVudC5cbiAgICB0aGlzLmdhdGVkV3JhcHBlckNvbXBvbmVudCA9IG5ldyBDb21wb25lbnRFeCgpO1xuICAgIHRoaXMudW5pdmVyc2FsV3JhcHBlckNvbXBvbmVudC5yZW1vdmVDaGlsZChnYXRlZFdyYXBwZXJDb21wb25lbnQpO1xuXG4gICAgdGhpcy5icm9hZGNhc3RVbmxvYWRlZCgpO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyB3YWl0Rm9yUHJldmlvdXNBc3luY0NsZWFudXBzKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHRpbWVvdXRJbk1pbGxpc2Vjb25kcyA9IHRoaXMuZ2V0QXN5bmNDbGVhbnVwVGltZW91dEluTWlsbGlzZWNvbmRzKCk7XG4gICAgaWYgKGF3YWl0IGRpZFBsdWdpbkFzeW5jQ2xlYW51cHNTZXR0bGUoeyBwbHVnaW5JZDogdGhpcy5tYW5pZmVzdC5pZCwgdGltZW91dEluTWlsbGlzZWNvbmRzIH0pKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc29sZS53YXJuKGBQbHVnaW4gJHt0aGlzLm1hbmlmZXN0LmlkfTogdGhlIHByZXZpb3VzIGluc3RhbmNlJ3MgYXN5bmMgY2xlYW51cHMgZGlkIG5vdCBmaW5pc2ggaW4gJHtTdHJpbmcodGltZW91dEluTWlsbGlzZWNvbmRzKX0gbXM7IGxvYWRpbmcgYW55d2F5LmApO1xuICB9XG59XG5cbi8qKlxuICogUmVsb2FkcyB0aGUgc3BlY2lmaWVkIHBsdWdpbiBieSBkaXNhYmxpbmcgYW5kIHRoZW4gcmUtZW5hYmxpbmcgaXQuXG4gKlxuICogQHBhcmFtIHBsdWdpbiAtIFRoZSBwbHVnaW4gdG8gcmVsb2FkLlxuICogQHJldHVybnMgQSB7QGxpbmsgUHJvbWlzZX0gdGhhdCByZXNvbHZlcyB3aGVuIHRoZSBwbHVnaW4gaXMgcmVsb2FkZWQuXG4gKiBAdGhyb3dzIHtAbGluayBQbHVnaW5FbmFibGVSZWZ1c2VkRXJyb3J9IElmIE9ic2lkaWFuIHJlZnVzZWQgdG8gZW5hYmxlIHRoZSBwbHVnaW4gYWdhaW4sIHdoaWNoIGxlYXZlcyBpdFxuICogZGlzYWJsZWQuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByZWxvYWRQbHVnaW4ocGx1Z2luOiBQbHVnaW4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgcGx1Z2lucyA9IHBsdWdpbi5hcHAucGx1Z2lucztcbiAgY29uc3QgcGx1Z2luSWQgPSBwbHVnaW4ubWFuaWZlc3QuaWQ7XG4gIGF3YWl0IHBsdWdpbnMuZGlzYWJsZVBsdWdpbihwbHVnaW5JZCk7XG4gIGlmICghYXdhaXQgcGx1Z2lucy5lbmFibGVQbHVnaW4ocGx1Z2luSWQpKSB7XG4gICAgdGhyb3cgbmV3IFBsdWdpbkVuYWJsZVJlZnVzZWRFcnJvcihwbHVnaW5JZCk7XG4gIH1cbn1cblxuLyoqXG4gKiBEaXNwbGF5cyBhbiBlcnJvciBtZXNzYWdlIGFzIGEgbm90aWNlLCBsb2dzIGl0IHRvIHRoZSBjb25zb2xlLCBhbmQgZGlzYWJsZXMgdGhlIHNwZWNpZmllZCBwbHVnaW4uXG4gKlxuICogQHBhcmFtIHBsdWdpbiAtIFRoZSBwbHVnaW4gdG8gZGlzYWJsZS5cbiAqIEBwYXJhbSBtZXNzYWdlIC0gVGhlIGVycm9yIG1lc3NhZ2UgdG8gZGlzcGxheSBhbmQgbG9nLlxuICogQHJldHVybnMgQSB7QGxpbmsgUHJvbWlzZX0gdGhhdCByZXNvbHZlcyB3aGVuIHRoZSBwbHVnaW4gaXMgZGlzYWJsZWQuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBzaG93RXJyb3JBbmREaXNhYmxlUGx1Z2luKHBsdWdpbjogUGx1Z2luLCBtZXNzYWdlOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgcGx1Z2luTm90aWNlQ29tcG9uZW50ID0gbmV3IFBsdWdpbk5vdGljZUNvbXBvbmVudCh7XG4gICAgYXBwOiBwbHVnaW4uYXBwLFxuICAgIHBsdWdpbk5hbWU6IHBsdWdpbi5tYW5pZmVzdC5uYW1lXG4gIH0pO1xuICBwbHVnaW5Ob3RpY2VDb21wb25lbnQuc2hvd05vdGljZShtZXNzYWdlKTtcbiAgcHJpbnRFcnJvcihuZXcgRXJyb3IobWVzc2FnZSkpO1xuICBhd2FpdCBwbHVnaW4uYXBwLnBsdWdpbnMuZGlzYWJsZVBsdWdpbihwbHVnaW4ubWFuaWZlc3QuaWQpO1xufVxuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQWNBLDBCQUFpQztBQUNqQyxtQkFBMkI7QUFDM0Isc0JBQTBCO0FBQzFCLHlCQUFrQztBQUNsQyxzQkFBdUI7QUFjdkIsa0NBQXNDO0FBQ3RDLHVDQUF3QztBQUN4QyxnREFBK0M7QUFDL0MsK0JBQXVDO0FBQ3ZDLCtCQUF5QztBQUN6QyxvQ0FBcUM7QUFDckMsMkNBQTJDO0FBQzNDLDBCQUE0QjtBQUM1QixxQ0FBc0M7QUFDdEMsNENBQTRDO0FBQzVDLCtEQUE2RDtBQUM3RCxzQ0FBdUM7QUFDdkMsbUNBQW9DO0FBQ3BDLHFDQUFzQztBQUN0Qyx1Q0FBNEM7QUFDNUMsMEJBQWtDO0FBQ2xDLGtCQUF5QjtBQUN6Qiw4QkFBdUM7QUFDdkMsMkJBQXNDO0FBQ3RDLHdCQUFpQztBQUNqQyxrQ0FLTztBQUNQLGlDQUFzQztBQUN0QyxxQ0FJTztBQXlCQSxNQUFlLHVCQUFtQixzQ0FBaUMsRUFBRSxzQkFBTSxFQUErQjtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQU0vRyxJQUFjLHVCQUE2QztBQUN6RCxlQUFPLHNDQUFrQixLQUFLLFdBQVcsb0JBQW9CO0FBQUEsRUFDL0Q7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFPQSxJQUFjLHFCQUFxQixPQUE2QjtBQUM5RCxTQUFLLGFBQWEsd0JBQXdCLEtBQUs7QUFBQSxFQUNqRDtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQU9BLElBQWMsNkJBQXlEO0FBQ3JFLGVBQU8sc0NBQWtCLEtBQUssV0FBVywwQkFBMEI7QUFBQSxFQUNyRTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQU9BLElBQWMsMkJBQTJCLE9BQW1DO0FBQzFFLFNBQUssYUFBYSw4QkFBOEIsS0FBSztBQUFBLEVBQ3ZEO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBVUEsSUFBYywwQkFBbUQ7QUFDL0QsZUFBTyxzQ0FBa0IsS0FBSyxXQUFXLHVCQUF1QjtBQUFBLEVBQ2xFO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBT0EsSUFBYyx3QkFBd0IsT0FBZ0M7QUFDcEUsU0FBSyxhQUFhLDJCQUEyQixLQUFLO0FBQUEsRUFDcEQ7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFPQSxJQUFjLHdCQUErQztBQUMzRCxlQUFPLHNDQUFrQixLQUFLLFdBQVcscUJBQXFCO0FBQUEsRUFDaEU7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFPQSxJQUFjLHNCQUFzQixPQUE4QjtBQUNoRSxTQUFLLGFBQWEseUJBQXlCLEtBQUs7QUFBQSxFQUNsRDtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQU9BLElBQWMseUJBQWlEO0FBQzdELGVBQU8sc0NBQWtCLEtBQUssV0FBVyxzQkFBc0I7QUFBQSxFQUNqRTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQU9BLElBQWMsdUJBQXVCLE9BQStCO0FBQ2xFLFNBQUssYUFBYSwwQkFBMEIsS0FBSztBQUFBLEVBQ25EO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQWVBLElBQWMsc0JBQTJDO0FBQ3ZELGVBQU8sc0NBQWtCLEtBQUssV0FBVyxtQkFBbUI7QUFBQSxFQUM5RDtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQU9BLElBQWMsb0JBQW9CLE9BQTRCO0FBQzVELFNBQUssYUFBYSx1QkFBdUIsS0FBSztBQUFBLEVBQ2hEO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBT0EsSUFBYyx3QkFBK0M7QUFDM0QsZUFBTyxzQ0FBa0IsS0FBSyxXQUFXLHFCQUFxQjtBQUFBLEVBQ2hFO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBT0EsSUFBYyxzQkFBc0IsT0FBOEI7QUFDaEUsU0FBSyxhQUFhLHlCQUF5QixLQUFLO0FBQUEsRUFDbEQ7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFPQSxJQUFjLDBCQUErRDtBQUMzRSxlQUFPLHNDQUFrQixLQUFLLFdBQVcsdUJBQXVCO0FBQUEsRUFDbEU7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFPQSxJQUFjLHdCQUF3QixPQUE0QztBQUNoRixTQUFLLGFBQWEsMkJBQTJCLEtBQUs7QUFBQSxFQUNwRDtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBUUEsSUFBYyx3QkFBK0M7QUFDM0QsZUFBTyxzQ0FBa0IsS0FBSyxXQUFXLHFCQUFxQjtBQUFBLEVBQ2hFO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBT0EsSUFBYyxzQkFBc0IsT0FBOEI7QUFDaEUsU0FBSyxhQUFhLHlCQUF5QixLQUFLO0FBQUEsRUFDbEQ7QUFBQSxFQUVpQixhQUFtQyxDQUFDO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFjN0Msd0JBQXdCLElBQUksZ0NBQVk7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQUt4Qyx3QkFBNEQ7QUFBQTtBQUFBLEVBR25ELDRCQUE0QixJQUFJLGdDQUFZO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUEwQjdDLFNBQXVDLFdBQW1DO0FBQ3hGLFdBQU8sS0FBSyxzQkFBc0IsU0FBUyxTQUFTO0FBQUEsRUFDdEQ7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFPQSxNQUFzQiwyQkFBMEM7QUFDOUQsVUFBTSxNQUFNLDJCQUEyQjtBQUN2QyxVQUFNLEtBQUssYUFBYSx3QkFBd0I7QUFBQSxFQUNsRDtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBV0EsTUFBc0IsU0FBd0I7QUFDNUMsUUFBSTtBQUlGLGNBQUksMkRBQThCLEtBQUssU0FBUyxFQUFFLEdBQUc7QUFDbkQsY0FBTSxLQUFLLDZCQUE2QjtBQUFBLE1BQzFDO0FBVUEsWUFBTSxTQUFTLEtBQUsseUJBQXlCO0FBQzdDLFdBQUssMEJBQTBCLEtBQUs7QUFFcEMsZ0JBQU0sc0JBQVMsS0FBSyxzQkFBc0IsQ0FBQztBQUMzQyxXQUFLLHlCQUF5QixLQUFLO0FBQUEsUUFDakMsSUFBSSx1REFBdUI7QUFBQSxVQUN6QixLQUFLLEtBQUs7QUFBQSxVQUNWLFVBQVUsS0FBSyxTQUFTO0FBQUEsUUFDMUIsQ0FBQztBQUFBLE1BQ0g7QUFDQSxXQUFLLHdCQUF3QixLQUFLO0FBQUEsUUFDaEMsSUFBSSxxREFBc0I7QUFBQSxVQUN4QixLQUFLLEtBQUs7QUFBQSxVQUNWLFlBQVksS0FBSyxTQUFTO0FBQUEsUUFDNUIsQ0FBQztBQUFBLE1BQ0g7QUFDQSxXQUFLLDZCQUE2QixLQUFLLGtCQUFrQixJQUFJLGdFQUEyQixLQUFLLHFCQUFxQixDQUFDO0FBQ25ILFdBQUssdUJBQXVCLEtBQUssa0JBQWtCLElBQUksbURBQXFCLEtBQUssU0FBUyxFQUFFLENBQUM7QUFDN0YsV0FBSyx3QkFBd0IsS0FBSyxrQkFBa0IsSUFBSSxxREFBc0IsS0FBSyxTQUFTLEVBQUUsQ0FBQztBQUMvRixXQUFLLHdCQUF3QixLQUFLLGtCQUFrQixJQUFJLDJDQUFzQixLQUFLLEtBQUssS0FBSyxTQUFTLEVBQUUsQ0FBQztBQUt6RyxZQUFNLCtDQUErQyxLQUFLO0FBQUEsUUFDeEQsSUFBSSxzR0FBNkM7QUFBQSxVQUMvQyxLQUFLLEtBQUs7QUFBQSxVQUNWLFlBQVksS0FBSyxTQUFTO0FBQUEsVUFDMUIsYUFBYSxLQUFLLG9DQUFvQztBQUFBLFFBQ3hELENBQUM7QUFBQSxNQUNIO0FBQ0EsV0FBSywwQkFBMEIsS0FBSztBQUFBLFFBQ2xDLElBQUkseURBQXdCO0FBQUEsVUFDMUIsb0JBQW9CLElBQUksa0RBQXNCLEtBQUssR0FBRztBQUFBLFVBQ3RELCtCQUErQixDQUFDLDRDQUE0QztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsVUFRNUUsOEJBQThCLE1BQW1CLEtBQUs7QUFBQSxVQUN0RCxrQkFBa0IsSUFBSSxnREFBdUIsSUFBSTtBQUFBLFVBQ2pELG9CQUFvQixLQUFLLGtCQUFrQixJQUFJLGtFQUE0QixLQUFLLEdBQUcsQ0FBQztBQUFBLFVBQ3BGLFlBQVksS0FBSyxTQUFTO0FBQUEsUUFDNUIsQ0FBQztBQUFBLE1BQ0g7QUFLQSxZQUFNLEtBQUssd0JBQXdCLHdCQUF3QixNQUFNO0FBQUEsUUFDL0QsSUFBSSx5RUFBK0I7QUFBQSxVQUNqQyxLQUFLLEtBQUs7QUFBQSxVQUNWLHVCQUF1QixLQUFLO0FBQUEsUUFDOUIsQ0FBQztBQUFBLE1BQ0gsR0FBRyxFQUFFLGVBQWUsS0FBSyx3QkFBd0IsQ0FBQztBQUVsRCxXQUFLLDBCQUEwQixLQUFLO0FBQUEsUUFDbEMsSUFBSSw2REFBb0M7QUFBQSxVQUN0QyxhQUFhLElBQUksc0NBQWtCLElBQUk7QUFBQSxVQUN2QyxtQkFBbUIsSUFBSSxpREFBc0IsSUFBSTtBQUFBLFVBQ2pELHFCQUFxQjtBQUFBLFFBQ3ZCLENBQUM7QUFBQSxNQUNIO0FBZUEsWUFBTSxzQkFBc0IsSUFBSSxpREFBb0I7QUFBQSxRQUNsRCxXQUFXLEtBQUssbUJBQW1CO0FBQUEsUUFDbkMsY0FBYyxLQUFLLHNCQUFzQjtBQUFBLFFBQ3pDLG9CQUFvQixNQUFxQixLQUFLLG1CQUFtQjtBQUFBLFFBQ2pFLFFBQVE7QUFBQSxRQUNSLHVCQUF1QixLQUFLO0FBQUEsUUFDNUIsc0JBQXNCLE1BQVk7QUFDaEMsZUFBSyxxQkFBcUI7QUFBQSxRQUM1QjtBQUFBLE1BQ0YsQ0FBQztBQUNELFdBQUssc0JBQXNCO0FBQzNCLFdBQUssa0JBQWtCLG1CQUFtQjtBQUkxQyxZQUFNLEtBQUssMEJBQTBCLGlCQUFpQjtBQUFBLElBQ3hELFNBQVMsT0FBTztBQUNkLG1DQUFXLElBQUksTUFBTSx3QkFBd0IsS0FBSyxTQUFTLElBQUksS0FBSyxLQUFLLFNBQVMsRUFBRSxLQUFLLEVBQUUsT0FBTyxNQUFNLENBQUMsQ0FBQztBQUMxRyxZQUFNO0FBQUEsSUFDUjtBQUFBLEVBQ0Y7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFVZ0IsV0FBaUI7QUFDL0IsU0FBSyxrQkFBa0I7QUFDdkIsVUFBTSxTQUFTO0FBQUEsRUFDakI7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBU2dCLFlBQTBDLFdBQW1DO0FBSTNGLFdBQU8sS0FBSyxzQkFBc0IsU0FBUyxTQUFTLElBQUksS0FBSyxzQkFBc0IsWUFBWSxTQUFTLElBQUksS0FBSywwQkFBMEIsWUFBWSxTQUFTO0FBQUEsRUFDbEs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQVdVLHdCQUF5QztBQUNqRCxXQUFPO0FBQUEsRUFDVDtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFTVSx1Q0FBK0M7QUFDdkQsV0FBTztBQUFBLEVBQ1Q7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQVdVLHNDQUFnRDtBQUN4RCxXQUFPO0FBQUEsRUFDVDtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFrQlUsZ0JBQXdDO0FBQ2hELFdBQU8sQ0FBQztBQUFBLEVBQ1Y7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQW9CVSxxQkFBdUM7QUFDL0MsV0FBTyxDQUFDO0FBQUEsRUFDVjtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFxQlUsd0JBQTRDO0FBQ3BELFdBQU8sQ0FBQztBQUFBLEVBQ1Y7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFVVSxhQUErQjtBQUN2QyxlQUFPLDJCQUFVO0FBQUEsRUFDbkI7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBZVUscUJBQXFCLFNBQXVDO0FBQ3BFLGdFQUEyQjtBQUFBLE1BQ3pCO0FBQUEsTUFDQSxXQUFXLEtBQUs7QUFBQSxNQUNoQixVQUFVLEtBQUssU0FBUztBQUFBLElBQzFCLENBQUM7QUFBQSxFQUNIO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUF1QlEsa0JBQWdELFdBQW1DO0FBQ3pGLFdBQU8sS0FBSywwQkFBMEIsU0FBUyxTQUFTO0FBQUEsRUFDMUQ7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQUtRLGtCQUF3QjtBQUM5QixTQUFLLHdCQUF3QjtBQUFBLE1BQzNCLGFBQWEsS0FBSyxjQUFjLEVBQUUsSUFBSSxDQUFDLGdCQUFnQixZQUFZLFVBQVU7QUFBQSxNQUM3RSxxQkFBcUIsS0FBSyxzQkFBc0IsRUFBRSxJQUFJLENBQUMsZUFBZSxXQUFXLFFBQVE7QUFBQSxNQUN6RixVQUFVLEtBQUssU0FBUztBQUFBLE1BQ3hCLFlBQVksS0FBSyxTQUFTO0FBQUEsTUFDMUIsZUFBZSxLQUFLLFNBQVM7QUFBQSxJQUMvQjtBQUVBLG9FQUE0QjtBQUFBLE1BQzFCLEtBQUssS0FBSztBQUFBLE1BQ1YsTUFBTTtBQUFBLE1BQ04sU0FBUyxLQUFLO0FBQUEsSUFDaEIsQ0FBQztBQUFBLEVBQ0g7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQVFRLG9CQUEwQjtBQUNoQyxVQUFNLFVBQVUsS0FBSztBQUNyQixRQUFJLENBQUMsU0FBUztBQUNaO0FBQUEsSUFDRjtBQUVBLFNBQUssd0JBQXdCO0FBQzdCLG9FQUE0QjtBQUFBLE1BQzFCLEtBQUssS0FBSztBQUFBLE1BQ1YsTUFBTTtBQUFBLE1BQ047QUFBQSxJQUNGLENBQUM7QUFBQSxFQUNIO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFXQSxNQUFjLHFCQUFvQztBQUdoRCxVQUFNLHdCQUF3QixLQUFLO0FBQ25DLFNBQUssMEJBQTBCLFNBQVMscUJBQXFCO0FBQzdELDBCQUFzQixLQUFLO0FBSTNCLFlBQUksMkRBQThCLEtBQUssU0FBUyxFQUFFLEdBQUc7QUFDbkQsWUFBTSxLQUFLLDZCQUE2QjtBQUFBLElBQzFDO0FBRUEsVUFBTSxLQUFLLFdBQVc7QUFDdEIsVUFBTSxzQkFBc0IsaUJBQWlCO0FBRTdDLGVBQVcsZUFBZSxLQUFLLGNBQWMsR0FBRztBQUM5Qyw4Q0FBaUI7QUFBQSxRQUNmLEdBQUc7QUFBQTtBQUFBO0FBQUE7QUFBQSxRQUlILFdBQVc7QUFBQSxRQUNYLFFBQVE7QUFBQSxNQUNWLENBQUM7QUFBQSxJQUNIO0FBRUEsU0FBSyxnQkFBZ0I7QUFBQSxFQUN2QjtBQUFBLEVBRVEsYUFBc0QsS0FBVyxPQUFzRDtBQUM3SCxVQUFNLGVBQWUsS0FBSyxXQUFXLEdBQUc7QUFDeEMsUUFBSSxjQUFjO0FBQ2hCLFdBQUssWUFBWSxZQUFZO0FBQUEsSUFDL0I7QUFDQSxTQUFLLFdBQVcsR0FBRyxJQUFJO0FBQUEsRUFDekI7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQUtRLHVCQUE2QjtBQUNuQyxVQUFNLHdCQUF3QixLQUFLO0FBS25DLFNBQUssd0JBQXdCLElBQUksZ0NBQVk7QUFDN0MsU0FBSywwQkFBMEIsWUFBWSxxQkFBcUI7QUFFaEUsU0FBSyxrQkFBa0I7QUFBQSxFQUN6QjtBQUFBLEVBRUEsTUFBYywrQkFBOEM7QUFDMUQsVUFBTSx3QkFBd0IsS0FBSyxxQ0FBcUM7QUFDeEUsUUFBSSxVQUFNLDBEQUE2QixFQUFFLFVBQVUsS0FBSyxTQUFTLElBQUksc0JBQXNCLENBQUMsR0FBRztBQUM3RjtBQUFBLElBQ0Y7QUFFQSxZQUFRLEtBQUssVUFBVSxLQUFLLFNBQVMsRUFBRSw4REFBOEQsT0FBTyxxQkFBcUIsQ0FBQyxzQkFBc0I7QUFBQSxFQUMxSjtBQUNGO0FBVUEsZUFBc0IsYUFBYSxRQUErQjtBQUNoRSxRQUFNLFVBQVUsT0FBTyxJQUFJO0FBQzNCLFFBQU0sV0FBVyxPQUFPLFNBQVM7QUFDakMsUUFBTSxRQUFRLGNBQWMsUUFBUTtBQUNwQyxNQUFJLENBQUMsTUFBTSxRQUFRLGFBQWEsUUFBUSxHQUFHO0FBQ3pDLFVBQU0sSUFBSSxrREFBeUIsUUFBUTtBQUFBLEVBQzdDO0FBQ0Y7QUFTQSxlQUFzQiwwQkFBMEIsUUFBZ0IsU0FBZ0M7QUFDOUYsUUFBTSx3QkFBd0IsSUFBSSxxREFBc0I7QUFBQSxJQUN0RCxLQUFLLE9BQU87QUFBQSxJQUNaLFlBQVksT0FBTyxTQUFTO0FBQUEsRUFDOUIsQ0FBQztBQUNELHdCQUFzQixXQUFXLE9BQU87QUFDeEMsK0JBQVcsSUFBSSxNQUFNLE9BQU8sQ0FBQztBQUM3QixRQUFNLE9BQU8sSUFBSSxRQUFRLGNBQWMsT0FBTyxTQUFTLEVBQUU7QUFDM0Q7IiwibmFtZXMiOltdfQ==
@@ -216,11 +216,20 @@ export declare abstract class PluginBase extends PluginBase_base implements Plug
216
216
  * Provides the translations map used to initialize i18n during {@link onload}.
217
217
  *
218
218
  * Override in subclass to supply plugin-specific translations. The default returns the built-in
219
- * `@mnaoumov/obsidian-lib` translations.
219
+ * `@mnaoumov/obsidian-lib` translations. A language may map to a `LocaleLoader` instead of its translations, so
220
+ * only the shown language is initialized; see {@link https://mnaoumov.dev/obsidian-lib/guides/translations/}.
220
221
  *
221
222
  * @returns The translations map.
222
223
  */
223
224
  protected createTranslationsMap(): TranslationsMap;
225
+ /**
226
+ * Provides how long a new instance waits for the previous instance's async cleanups before loading anyway.
227
+ *
228
+ * Override in subclass to change it. The default is 10 seconds.
229
+ *
230
+ * @returns The timeout in milliseconds.
231
+ */
232
+ protected getAsyncCleanupTimeoutInMilliseconds(): number;
224
233
  /**
225
234
  * Provides the icon shown on the plugin's parent entry in `Notebook Navigator`'s context menus.
226
235
  *
@@ -296,6 +305,20 @@ export declare abstract class PluginBase extends PluginBase_base implements Plug
296
305
  * @returns A {@link Promise} that resolves when the subclass load logic is complete.
297
306
  */
298
307
  protected onloadImpl(): Promisable<void>;
308
+ /**
309
+ * Registers an async cleanup that the next instance of this plugin awaits before it starts.
310
+ *
311
+ * Use it for teardown that cannot finish synchronously and must finish before the resource is opened again, such
312
+ * as closing an IndexedDB connection. Obsidian's `onunload` is synchronous and awaits nothing, so without this a
313
+ * reload starts the new instance while the old one still holds the database.
314
+ *
315
+ * Scoped like {@link addChild}: the cleanup starts when the plugin's feature surface unloads, which is on plugin
316
+ * unload and whenever the gate closes. The next load of the plugin, and the next opening of the gate, await it,
317
+ * bounded by {@link getAsyncCleanupTimeoutInMilliseconds}. A cleanup that throws is printed, never rethrown.
318
+ *
319
+ * @param cleanup - The cleanup to run.
320
+ */
321
+ protected registerAsyncCleanup(cleanup: () => Promisable<void>): void;
299
322
  /**
300
323
  * Stores a universal component, unloading whichever component the key held before.
301
324
  *
@@ -344,6 +367,7 @@ export declare abstract class PluginBase extends PluginBase_base implements Plug
344
367
  * Tears the subclass's feature surface down, leaving the universal components running.
345
368
  */
346
369
  private unloadFeatureSurface;
370
+ private waitForPreviousAsyncCleanups;
347
371
  }
348
372
  /**
349
373
  * Reloads the specified plugin by disabling and then re-enabling it.
@@ -17,6 +17,7 @@ export { getCanvasReferences } from './canvas.mjs';
17
17
  export { CaseInsensitiveFileIndex, getCaseInsensitiveFileIndex, setCaseInsensitiveFileIndex, unsetCaseInsensitiveFileIndex } from './case-insensitive-file-index.mjs';
18
18
  export { createCodeBlockRegExp } from './code-block-reg-exp.mjs';
19
19
  export { captureCodeBlockFocus, claimCodeBlockRenderHandoff, CODE_BLOCK_RENDER_HANDOFF_LIFETIME_IN_MILLISECONDS, recordCodeBlockRenderHandoff, restoreCodeBlockFocus } from './code-block-render-handoff.mjs';
20
+ export { createLivePreviewOnlyExtension, createSourceModeOnlyExtension, isLivePreview } from './codemirror/editor-mode-extension.mjs';
20
21
  export { createIncrementalParseStateField } from './codemirror/incremental-parse-state-field.mjs';
21
22
  export { createInlineTokenWidgetsExtension, execAll, toGlobalRegExp } from './codemirror/inline-token-widgets.mjs';
22
23
  export { dispatchToAllMarkdownEditorViews, getAllMarkdownEditorViews } from './codemirror/markdown-editor-views.mjs';
@@ -116,7 +117,7 @@ export { loadGitRenames, parseGitRenameLog } from './git-rename-history.mjs';
116
117
  export { formatHotkey, getHotkeyFromKeyboardEvent, isSameHotkey } from './hotkey.mjs';
117
118
  export { PluginHoverLinkSourceRegistrar } from './hover-link-source-registrar.mjs';
118
119
  export { appendCodeBlock, appendTextOrFragmentClone, applySpellcheckMode, asCodeBlock, createFragmentWithCodeBlocks } from './html-element.mjs';
119
- export { DEFAULT_NS, initI18N, t } from './i18n/i18n.mjs';
120
+ export { DEFAULT_NS, getLanguagesToLoad, initI18N, t } from './i18n/i18n.mjs';
120
121
  export { en } from './i18n/locales/en.mjs';
121
122
  export { DEFAULT_LANGUAGE, defaultTranslationsMap } from './i18n/locales/translations-map.mjs';
122
123
  export { createInlineTokenPostProcessor, DEFAULT_INLINE_TOKEN_SKIP_SELECTOR, registerInlineTokenRenderer } from './inline-token-renderer.mjs';
@@ -137,6 +138,7 @@ export { addSingleChoiceMenuItems } from './menu.mjs';
137
138
  export { ADVANCED_METADATA_CACHE_PLUGIN_ID, BACKLINK_CACHE_PLUGIN_ID, CachedMetadataExFeature, ensureMetadataCacheReady, getBacklinksForFileOrPath, getBacklinksForFileSafe, getCacheSafe, getFrontmatterSafe, getReferences, hasBacklinkCachePlugin, isCachedMetadataEx, parseMetadata, registerFileCacheForNonExistingFile, registerFiles, unregisterFileCacheForNonExistingFile, unregisterFiles } from './metadata-cache.mjs';
138
139
  export { getMobileAppInfo } from './mobile-app-info.mjs';
139
140
  export { alert } from './modals/alert.mjs';
141
+ export { formatCodeBlock, showCodeBlockBuilder } from './modals/code-block-builder.mjs';
140
142
  export { confirm } from './modals/confirm.mjs';
141
143
  export { MinimizableModal } from './modals/minimizable-modal.mjs';
142
144
  export { ModalCommandBuilder, ModalCommandsRenderMode } from './modals/modal-command-builder.mjs';
@@ -156,6 +158,7 @@ export { PathSettings, pathsValidator } from './path-settings.mjs';
156
158
  export { printToPdf } from './pdf.mjs';
157
159
  export { PluginCliHandlerRegistrar } from './plugin-cli-handler-registrar.mjs';
158
160
  export { findPluginApi, getValidatePluginApiPayloadsDebugSwitch, PluginApiPayloadKind, PluginApiRevokedError, PluginApiUnavailabilityReason, PluginApiUnavailableError, PluginApiValidationError, publishPluginApi, watchPluginApi } from './plugin/plugin-api.mjs';
161
+ export { DEFAULT_PLUGIN_ASYNC_CLEANUP_TIMEOUT_IN_MILLISECONDS, didPluginAsyncCleanupsSettle, hasPendingPluginAsyncCleanups, PLUGIN_ASYNC_CLEANUPS_STATE_KEY, registerPluginAsyncCleanup, trackPluginAsyncCleanup } from './plugin/plugin-async-cleanup.mjs';
159
162
  export { addPluginCssClasses, initDebugController, initPluginContext } from './plugin/plugin-context.mjs';
160
163
  export { PluginEventSourceImpl } from './plugin/plugin-event-source.mjs';
161
164
  export { getInstalledPluginState, getInstalledPluginVersion, installAndEnablePlugin, InstalledPluginState, updatePlugin } from './plugin/plugin-install-state.mjs';