obsidian-dev-utils 101.6.0 → 101.7.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 (64) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/dist/integration-test-plugin/main.js +4410 -3705
  3. package/dist/lib/cjs/__merged.cjs +26 -1
  4. package/dist/lib/cjs/__merged.d.cts +4 -1
  5. package/dist/lib/cjs/generated-during-build.cjs +1 -1
  6. package/dist/lib/cjs/obsidian/components/component-ex.cjs +14 -1
  7. package/dist/lib/cjs/obsidian/components/component-ex.d.cts +11 -0
  8. package/dist/lib/cjs/obsidian/components/index.cjs +4 -1
  9. package/dist/lib/cjs/obsidian/components/index.d.cts +1 -0
  10. package/dist/lib/cjs/obsidian/components/plugin-gate-component.cjs +520 -0
  11. package/dist/lib/cjs/obsidian/components/plugin-gate-component.d.cts +299 -0
  12. package/dist/lib/cjs/obsidian/components/plugin-suggestion-component.cjs +17 -38
  13. package/dist/lib/cjs/obsidian/components/plugin-suggestion-component.d.cts +25 -18
  14. package/dist/lib/cjs/obsidian/components/rename-delete-handler-component.cjs +7 -2
  15. package/dist/lib/cjs/obsidian/css-class.cjs +3 -1
  16. package/dist/lib/cjs/obsidian/css-class.d.cts +9 -0
  17. package/dist/lib/cjs/obsidian/html-element.cjs +27 -3
  18. package/dist/lib/cjs/obsidian/html-element.d.cts +36 -0
  19. package/dist/lib/cjs/obsidian/i18n/locales/en.cjs +15 -1
  20. package/dist/lib/cjs/obsidian/i18n/locales/en.d.cts +14 -0
  21. package/dist/lib/cjs/obsidian/i18n/locales/translations-map.d.cts +14 -0
  22. package/dist/lib/cjs/obsidian/plugin/index.cjs +7 -1
  23. package/dist/lib/cjs/obsidian/plugin/index.d.cts +2 -0
  24. package/dist/lib/cjs/obsidian/plugin/plugin-api.cjs +2 -2
  25. package/dist/lib/cjs/obsidian/plugin/plugin-api.d.cts +34 -15
  26. package/dist/lib/cjs/obsidian/plugin/plugin-install-state.cjs +208 -0
  27. package/dist/lib/cjs/obsidian/plugin/plugin-install-state.d.cts +113 -0
  28. package/dist/lib/cjs/obsidian/plugin/plugin-lifecycle-events.cjs +161 -0
  29. package/dist/lib/cjs/obsidian/plugin/plugin-lifecycle-events.d.cts +119 -0
  30. package/dist/lib/cjs/obsidian/plugin/plugin.cjs +241 -21
  31. package/dist/lib/cjs/obsidian/plugin/plugin.d.cts +133 -4
  32. package/dist/lib/esm/__merged.d.mts +4 -1
  33. package/dist/lib/esm/__merged.mjs +30 -2
  34. package/dist/lib/esm/generated-during-build.mjs +1 -1
  35. package/dist/lib/esm/obsidian/components/component-ex.d.mts +11 -0
  36. package/dist/lib/esm/obsidian/components/component-ex.mjs +14 -1
  37. package/dist/lib/esm/obsidian/components/index.d.mts +1 -0
  38. package/dist/lib/esm/obsidian/components/index.mjs +3 -1
  39. package/dist/lib/esm/obsidian/components/plugin-gate-component.d.mts +299 -0
  40. package/dist/lib/esm/obsidian/components/plugin-gate-component.mjs +428 -0
  41. package/dist/lib/esm/obsidian/components/plugin-suggestion-component.d.mts +25 -18
  42. package/dist/lib/esm/obsidian/components/plugin-suggestion-component.mjs +21 -41
  43. package/dist/lib/esm/obsidian/components/rename-delete-handler-component.mjs +7 -2
  44. package/dist/lib/esm/obsidian/css-class.d.mts +9 -0
  45. package/dist/lib/esm/obsidian/css-class.mjs +3 -1
  46. package/dist/lib/esm/obsidian/html-element.d.mts +36 -0
  47. package/dist/lib/esm/obsidian/html-element.mjs +24 -2
  48. package/dist/lib/esm/obsidian/i18n/locales/en.d.mts +14 -0
  49. package/dist/lib/esm/obsidian/i18n/locales/en.mjs +15 -1
  50. package/dist/lib/esm/obsidian/i18n/locales/translations-map.d.mts +14 -0
  51. package/dist/lib/esm/obsidian/plugin/index.d.mts +2 -0
  52. package/dist/lib/esm/obsidian/plugin/index.mjs +5 -1
  53. package/dist/lib/esm/obsidian/plugin/plugin-api.d.mts +34 -15
  54. package/dist/lib/esm/obsidian/plugin/plugin-api.mjs +2 -2
  55. package/dist/lib/esm/obsidian/plugin/plugin-install-state.d.mts +113 -0
  56. package/dist/lib/esm/obsidian/plugin/plugin-install-state.mjs +106 -0
  57. package/dist/lib/esm/obsidian/plugin/plugin-lifecycle-events.d.mts +119 -0
  58. package/dist/lib/esm/obsidian/plugin/plugin-lifecycle-events.mjs +54 -0
  59. package/dist/lib/esm/obsidian/plugin/plugin.d.mts +133 -4
  60. package/dist/lib/esm/obsidian/plugin/plugin.mjs +245 -21
  61. package/obsidian/components/plugin-gate-component/package.json +6 -0
  62. package/obsidian/plugin/plugin-install-state/package.json +6 -0
  63. package/obsidian/plugin/plugin-lifecycle-events/package.json +6 -0
  64. package/package.json +1 -1
@@ -163,13 +163,16 @@ var import_console_debug_component = require('../components/console-debug-compon
163
163
  var import_menu_event_registrar_component = require('../components/menu-event-registrar-component.cjs');
164
164
  var import_notebook_navigator_menu_event_registrar_component = require('../components/notebook-navigator-menu-event-registrar-component.cjs');
165
165
  var import_plugin_context_component = require('../components/plugin-context-component.cjs');
166
+ var import_plugin_gate_component = require('../components/plugin-gate-component.cjs');
166
167
  var import_plugin_notice_component = require('../components/plugin-notice-component.cjs');
167
168
  var import_plugin_settings_component = require('../components/plugin-settings-component.cjs');
168
169
  var import_data_handler = require('../data-handler.cjs');
169
170
  var import_i18n = require('../i18n/i18n.cjs');
170
171
  var import_translations_map = require('../i18n/locales/translations-map.cjs');
171
172
  var import_resource_lock = require('../resource-lock.cjs');
173
+ var import_plugin_api = require('./plugin-api.cjs');
172
174
  var import_plugin_event_source = require('./plugin-event-source.cjs');
175
+ var import_plugin_lifecycle_events = require('./plugin-lifecycle-events.cjs');
173
176
  class PluginBase extends (0, import_async_events.mixinAsyncEvents)()(import_obsidian.Plugin) {
174
177
  /**
175
178
  * Gets abort signal component.
@@ -254,6 +257,26 @@ class PluginBase extends (0, import_async_events.mixinAsyncEvents)()(import_obsi
254
257
  set pluginContextComponent(value) {
255
258
  this.setComponent("pluginContextComponent", value);
256
259
  }
260
+ /**
261
+ * Gets the gate holding the plugin's feature surface up or down.
262
+ *
263
+ * Reach for it from a settings tab to render the overlap banner for a
264
+ * {@link obsidian/components/plugin-gate-component!PluginConflictSeverity.Warn} conflict — the one
265
+ * banner the library cannot place itself, because a running plugin builds its own settings tab.
266
+ *
267
+ * @returns The plugin gate component.
268
+ */
269
+ get pluginGateComponent() {
270
+ return (0, import_type_guards.ensureNonNullable)(this.components.pluginGateComponent);
271
+ }
272
+ /**
273
+ * Sets the plugin gate component.
274
+ *
275
+ * @param value - The plugin gate component.
276
+ */
277
+ set pluginGateComponent(value) {
278
+ this.setComponent("pluginGateComponent", value);
279
+ }
257
280
  /**
258
281
  * Gets plugin notice component.
259
282
  *
@@ -304,20 +327,45 @@ class PluginBase extends (0, import_async_events.mixinAsyncEvents)()(import_obsi
304
327
  this.setComponent("resourceLockComponent", value);
305
328
  }
306
329
  components = {};
307
- wrapperComponent = new import_component_ex.ComponentEx();
330
+ // Everything the SUBCLASS owns: what `onloadImpl` adds, and what it adds later.
331
+ //
332
+ // A second wrapper rather than one, because the two tiers have opposite lifetimes. The universal
333
+ // Components have to OUTLIVE a lost dependency — they are what shows the notice naming the plugin that
334
+ // Went away and renders the button that brings it back — while the subclass's surface is exactly what
335
+ // Must stop running. Unloading one wrapper holding both would silence the plugin at the moment it most
336
+ // Needs to speak.
337
+ //
338
+ // Always present, never null, and REPLACED rather than emptied when the surface is torn down. That keeps
339
+ // `addChild` callable at every point in the plugin's life, exactly as it was before the tiers existed:
340
+ // A child added before the gate opens is queued and loaded when it does, which is what `ComponentEx`
341
+ // Already does for any child added to a not-yet-loaded component.
342
+ gatedWrapperComponent = new import_component_ex.ComponentEx();
343
+ // The payload broadcast when this plugin finished loading, kept so the matching unloaded broadcast
344
+ // Describes the same plugin without re-deriving it from a surface that has since been torn down. Null
345
+ // Whenever no loaded broadcast is outstanding, which is what keeps the two events paired.
346
+ lifecycleEventPayload = null;
347
+ // The library's own components, which outlive any dependency.
348
+ universalWrapperComponent = new import_component_ex.ComponentEx();
308
349
  /**
309
350
  * Adds a child component.
310
351
  *
311
- * The child is added to an internal wrapper component, which {@link onload} attaches and loads
312
- * before wiring anything up. So a child added during {@link onloadImpl} is loaded immediately,
313
- * children-first, and is usable by the time this method returns.
352
+ * The child is added to the internal wrapper holding the subclass's own surface, which {@link onload}
353
+ * creates and loads before calling {@link onloadImpl}. So a child added during {@link onloadImpl} is
354
+ * loaded immediately, children-first, and is usable by the time this method returns.
355
+ *
356
+ * That wrapper is torn down and rebuilt whenever the gate closes and opens again — a dependency declared
357
+ * by {@link getPluginDependencies} going away and coming back, or a conflict declared by
358
+ * {@link getPluginConflicts} appearing and being resolved — so a child added here lives exactly as long
359
+ * as the plugin's feature surface does. Adding one while the surface is down is still legitimate — it is
360
+ * queued and loaded when the surface next comes up, the way {@link ComponentEx.addChild} already queues
361
+ * a child added to a not-yet-loaded component.
314
362
  *
315
363
  * @typeParam TComponent - The type of component to add.
316
364
  * @param component - The component instance to add.
317
365
  * @returns The added component.
318
366
  */
319
367
  addChild(component) {
320
- return this.wrapperComponent.addChild(component);
368
+ return this.gatedWrapperComponent.addChild(component);
321
369
  }
322
370
  /**
323
371
  * Called when the external settings change.
@@ -339,38 +387,38 @@ class PluginBase extends (0, import_async_events.mixinAsyncEvents)()(import_obsi
339
387
  */
340
388
  async onload() {
341
389
  try {
342
- super.addChild(this.wrapperComponent);
343
- this.wrapperComponent.load();
390
+ super.addChild(this.universalWrapperComponent);
391
+ this.universalWrapperComponent.load();
344
392
  await (0, import_i18n.initI18N)(this.createTranslationsMap());
345
- this.pluginContextComponent = this.addChild(
393
+ this.pluginContextComponent = this.addUniversalChild(
346
394
  new import_plugin_context_component.PluginContextComponent({
347
395
  app: this.app,
348
396
  pluginId: this.manifest.id
349
397
  })
350
398
  );
351
- this.pluginNoticeComponent = this.addChild(
399
+ this.pluginNoticeComponent = this.addUniversalChild(
352
400
  new import_plugin_notice_component.PluginNoticeComponent({
353
401
  app: this.app,
354
402
  pluginName: this.manifest.name
355
403
  })
356
404
  );
357
- this.asyncErrorHandlerComponent = this.addChild(new import_async_error_handler_component.AsyncErrorHandlerComponent(this.pluginNoticeComponent));
358
- this.abortSignalComponent = this.addChild(new import_abort_signal_component.AbortSignalComponent(this.manifest.id));
359
- this.consoleDebugComponent = this.addChild(new import_console_debug_component.ConsoleDebugComponent(this.manifest.id));
360
- this.resourceLockComponent = this.addChild(new import_resource_lock.ResourceLockComponent(this.app, this.manifest.id));
361
- const notebookNavigatorMenuEventRegistrarComponent = this.addChild(
405
+ this.asyncErrorHandlerComponent = this.addUniversalChild(new import_async_error_handler_component.AsyncErrorHandlerComponent(this.pluginNoticeComponent));
406
+ this.abortSignalComponent = this.addUniversalChild(new import_abort_signal_component.AbortSignalComponent(this.manifest.id));
407
+ this.consoleDebugComponent = this.addUniversalChild(new import_console_debug_component.ConsoleDebugComponent(this.manifest.id));
408
+ this.resourceLockComponent = this.addUniversalChild(new import_resource_lock.ResourceLockComponent(this.app, this.manifest.id));
409
+ const notebookNavigatorMenuEventRegistrarComponent = this.addUniversalChild(
362
410
  new import_notebook_navigator_menu_event_registrar_component.NotebookNavigatorMenuEventRegistrarComponent({
363
411
  app: this.app,
364
412
  pluginName: this.manifest.name,
365
413
  submenuIcon: this.getNotebookNavigatorMenuSubmenuIcon()
366
414
  })
367
415
  );
368
- this.commandHandlerComponent = this.addChild(
416
+ this.commandHandlerComponent = this.addUniversalChild(
369
417
  new import_command_handler_component.CommandHandlerComponent({
370
418
  activeFileProvider: new import_active_file_provider.AppActiveFileProvider(this.app),
371
419
  additionalMenuEventRegistrars: [notebookNavigatorMenuEventRegistrarComponent],
372
420
  commandRegistrar: new import_command_registrar.PluginCommandRegistrar(this),
373
- menuEventRegistrar: this.addChild(new import_menu_event_registrar_component.MenuEventRegistrarComponent(this.app)),
421
+ menuEventRegistrar: this.addUniversalChild(new import_menu_event_registrar_component.MenuEventRegistrarComponent(this.app)),
374
422
  pluginName: this.manifest.name
375
423
  })
376
424
  );
@@ -380,20 +428,43 @@ class PluginBase extends (0, import_async_events.mixinAsyncEvents)()(import_obsi
380
428
  resourceLockComponent: this.resourceLockComponent
381
429
  })
382
430
  ]);
383
- this.pluginSettingsComponent = this.addChild(
431
+ this.pluginSettingsComponent = this.addUniversalChild(
384
432
  new import_plugin_settings_component.PluginSettingsComponentBase({
385
433
  dataHandler: new import_data_handler.PluginDataHandler(this),
386
434
  pluginEventSource: new import_plugin_event_source.PluginEventSourceImpl(this),
387
435
  pluginSettingsClass: Object
388
436
  })
389
437
  );
390
- await this.onloadImpl();
391
- await this.wrapperComponent.loadWithPromises();
438
+ this.pluginGateComponent = this.addUniversalChild(
439
+ new import_plugin_gate_component.PluginGateComponent({
440
+ conflicts: this.getPluginConflicts(),
441
+ dependencies: this.getPluginDependencies(),
442
+ loadFeatureSurface: () => this.loadFeatureSurface(),
443
+ plugin: this,
444
+ pluginNoticeComponent: this.pluginNoticeComponent,
445
+ unloadFeatureSurface: () => {
446
+ this.unloadFeatureSurface();
447
+ }
448
+ })
449
+ );
450
+ await this.universalWrapperComponent.loadWithPromises();
392
451
  } catch (error) {
393
452
  (0, import_error.printError)(new Error(`Error loading plugin ${this.manifest.name} (${this.manifest.id})`, { cause: error }));
394
453
  throw error;
395
454
  }
396
455
  }
456
+ /**
457
+ * Called when the plugin is unloaded.
458
+ *
459
+ * Announces the departure on `app.workspace` so anything depending on this plugin learns of it at the
460
+ * moment it happens, rather than discovering it later through behavior that quietly stopped.
461
+ *
462
+ * Do NOT override this method; put teardown on a component instead, which unloads with the plugin.
463
+ */
464
+ onunload() {
465
+ this.broadcastUnloaded();
466
+ super.onunload();
467
+ }
397
468
  /**
398
469
  * Removes a child component.
399
470
  *
@@ -402,7 +473,10 @@ class PluginBase extends (0, import_async_events.mixinAsyncEvents)()(import_obsi
402
473
  * @returns The removed component.
403
474
  */
404
475
  removeChild(component) {
405
- return this.wrapperComponent.removeChild(component);
476
+ if (this.gatedWrapperComponent.hasChild(component)) {
477
+ return this.gatedWrapperComponent.removeChild(component);
478
+ }
479
+ return this.universalWrapperComponent.removeChild(component);
406
480
  }
407
481
  /**
408
482
  * Provides the translations map used to initialize i18n during {@link onload}.
@@ -427,6 +501,68 @@ class PluginBase extends (0, import_async_events.mixinAsyncEvents)()(import_obsi
427
501
  getNotebookNavigatorMenuSubmenuIcon() {
428
502
  return "";
429
503
  }
504
+ /**
505
+ * Provides the APIs this plugin exposes to other plugins.
506
+ *
507
+ * Override in subclass to publish one. The default publishes none. Called after {@link onloadImpl}, so a
508
+ * declaration may reference anything it created; the returned declarations are published through
509
+ * `publishPluginApi` and revoked when the plugin's feature surface unloads.
510
+ *
511
+ * Returning a LIST rather than a single API is deliberate: the registry supports several contract
512
+ * versions published side by side, which is how a provider ships a breaking `2.0.0` without stranding
513
+ * consumers still pinned to `^1`.
514
+ *
515
+ * Every declaration here is published BEFORE the `obsidian-dev-utils:plugin-loaded` broadcast, which is
516
+ * what lets a listener call these APIs the moment it hears that event.
517
+ *
518
+ * @returns The API declarations.
519
+ */
520
+ getPluginApis() {
521
+ return [];
522
+ }
523
+ /**
524
+ * Provides the plugins this one refuses, or warns about, running beside.
525
+ *
526
+ * Override in subclass to declare an overlap. The default declares none.
527
+ *
528
+ * A `Block` conflict is the mirror image of a dependency: while a conflicting plugin is enabled at a
529
+ * conflicting version, {@link onloadImpl} does not run at all and the plugin registers nothing. Declare
530
+ * it when both plugins acting on the same operation damages the vault — there is no reliable way to win
531
+ * that race, because whichever plugin loaded first keeps a hand on the wheel, so refusing deterministically
532
+ * beats competing unpredictably. A `Warn` conflict declares an overlap that is merely annoying, such as a
533
+ * duplicated command: both plugins keep running and the user is told.
534
+ *
535
+ * Unlike a dependency, a conflicting plugin need not publish anything — it is detected by reading its
536
+ * installed version, which is the only thing about another plugin that reads the same regardless of load
537
+ * order.
538
+ *
539
+ * @returns The declared conflicts.
540
+ */
541
+ getPluginConflicts() {
542
+ return [];
543
+ }
544
+ /**
545
+ * Provides the plugins this one cannot work without.
546
+ *
547
+ * Override in subclass to declare a mandatory dependency. The default declares none, and such a plugin
548
+ * loads exactly as it always has.
549
+ *
550
+ * A declared dependency is MANDATORY, unlike the offer `PluginSuggestionComponent` makes: while one is
551
+ * missing, disabled, or too old, {@link onloadImpl} does not run at all and the plugin registers nothing
552
+ * — no commands, no handlers, no patches. It stays enabled in Obsidian's list rather than disabling
553
+ * itself, because the enabled set is the user's to change, and it explains itself through a notice and a
554
+ * settings banner that installs the missing plugin in one click. The load completes the moment the
555
+ * dependency arrives, with no restart.
556
+ *
557
+ * A dependency must publish an API through `publishPluginApi`, which is what makes its presence,
558
+ * absence, version and departure all observable through one mechanism. A plugin with nothing to expose
559
+ * can publish an empty API purely so it can be depended upon.
560
+ *
561
+ * @returns The declared dependencies.
562
+ */
563
+ getPluginDependencies() {
564
+ return [];
565
+ }
430
566
  /**
431
567
  * Called during {@link onload} to wire plugin-specific child components.
432
568
  *
@@ -449,6 +585,81 @@ class PluginBase extends (0, import_async_events.mixinAsyncEvents)()(import_obsi
449
585
  * @param key - The key of the component to store.
450
586
  * @param value - The component to store.
451
587
  */
588
+ /**
589
+ * Adds a component to the universal tier, which outlives any dependency.
590
+ *
591
+ * Private on purpose: only this class decides what is universal. A subclass adding one of its own goes
592
+ * through {@link addChild} and lands in the gated tier, where it belongs.
593
+ *
594
+ * @typeParam TComponent - The type of component to add.
595
+ * @param component - The component instance to add.
596
+ * @returns The added component.
597
+ */
598
+ addUniversalChild(component) {
599
+ return this.universalWrapperComponent.addChild(component);
600
+ }
601
+ /**
602
+ * Announces on `app.workspace` that this plugin is loaded and its APIs are callable.
603
+ */
604
+ broadcastLoaded() {
605
+ this.lifecycleEventPayload = {
606
+ apiVersions: this.getPluginApis().map((declaration) => declaration.apiVersion),
607
+ dependencyPluginIds: this.getPluginDependencies().map((dependency) => dependency.pluginId),
608
+ pluginId: this.manifest.id,
609
+ pluginName: this.manifest.name,
610
+ pluginVersion: this.manifest.version
611
+ };
612
+ (0, import_plugin_lifecycle_events.triggerPluginLifecycleEvent)({
613
+ app: this.app,
614
+ name: import_plugin_lifecycle_events.PLUGIN_LOADED_EVENT_NAME,
615
+ payload: this.lifecycleEventPayload
616
+ });
617
+ }
618
+ /**
619
+ * Announces on `app.workspace` that this plugin's surface has gone away.
620
+ *
621
+ * Silent unless a loaded broadcast is outstanding, so the two events stay paired: a plugin that never
622
+ * got past its dependency gate never announced itself, and must not announce a departure either.
623
+ */
624
+ broadcastUnloaded() {
625
+ const payload = this.lifecycleEventPayload;
626
+ if (!payload) {
627
+ return;
628
+ }
629
+ this.lifecycleEventPayload = null;
630
+ (0, import_plugin_lifecycle_events.triggerPluginLifecycleEvent)({
631
+ app: this.app,
632
+ name: import_plugin_lifecycle_events.PLUGIN_UNLOADED_EVENT_NAME,
633
+ payload
634
+ });
635
+ }
636
+ /**
637
+ * Builds and loads the subclass's feature surface, then publishes its APIs and announces itself.
638
+ *
639
+ * NOT idempotent, deliberately. `PluginGateComponent` owns the up/down state machine and calls
640
+ * this only on a real transition; a second guard here would be a second copy of that state, which is the
641
+ * kind of duplicate that drifts.
642
+ *
643
+ * @returns A {@link Promise} that resolves once the surface is loaded and the broadcast has been made.
644
+ */
645
+ async loadFeatureSurface() {
646
+ const gatedWrapperComponent = this.gatedWrapperComponent;
647
+ this.universalWrapperComponent.addChild(gatedWrapperComponent);
648
+ gatedWrapperComponent.load();
649
+ await this.onloadImpl();
650
+ await gatedWrapperComponent.loadWithPromises();
651
+ for (const declaration of this.getPluginApis()) {
652
+ (0, import_plugin_api.publishPluginApi)({
653
+ ...declaration,
654
+ // Revoked with the SURFACE, not with the plugin: a plugin whose dependency goes away keeps running
655
+ // Its universal components, and a consumer must not be left holding a handle into the half of it
656
+ // That was just torn down.
657
+ component: gatedWrapperComponent,
658
+ plugin: this
659
+ });
660
+ }
661
+ this.broadcastLoaded();
662
+ }
452
663
  setComponent(key, value) {
453
664
  const oldComponent = this.components[key];
454
665
  if (oldComponent) {
@@ -456,6 +667,15 @@ class PluginBase extends (0, import_async_events.mixinAsyncEvents)()(import_obsi
456
667
  }
457
668
  this.components[key] = value;
458
669
  }
670
+ /**
671
+ * Tears the subclass's feature surface down, leaving the universal components running.
672
+ */
673
+ unloadFeatureSurface() {
674
+ const gatedWrapperComponent = this.gatedWrapperComponent;
675
+ this.gatedWrapperComponent = new import_component_ex.ComponentEx();
676
+ this.universalWrapperComponent.removeChild(gatedWrapperComponent);
677
+ this.broadcastUnloaded();
678
+ }
459
679
  }
460
680
  async function reloadPlugin(plugin) {
461
681
  const plugins = plugin.app.plugins;
@@ -478,4 +698,4 @@ async function showErrorAndDisablePlugin(plugin, message) {
478
698
  reloadPlugin,
479
699
  showErrorAndDisablePlugin
480
700
  });
481
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vLi4vLi4vc3JjL29ic2lkaWFuL3BsdWdpbi9wbHVnaW4udHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQGZpbGVcbiAqXG4gKiBCYXNlIGNsYXNzIGZvciBPYnNpZGlhbiBwbHVnaW5zIHVzaW5nIGEgY29tcG9uZW50LWJhc2VkIGFyY2hpdGVjdHVyZS5cbiAqXG4gKiBQbHVnaW5CYXNlIHJlZ2lzdGVycyB1bml2ZXJzYWwgY29tcG9uZW50cyAoY29udGV4dCwgaTE4biwgZXJyb3IgaGFuZGxpbmcsIGFib3J0IHNpZ25hbCwgbGlmZWN5Y2xlIGV2ZW50cywgZGVidWcpLlxuICovXG5cbmltcG9ydCB0eXBlIHtcbiAgQ29tcG9uZW50LFxuICBJY29uTmFtZVxufSBmcm9tICdvYnNpZGlhbic7XG5pbXBvcnQgdHlwZSB7IFByb21pc2FibGUgfSBmcm9tICd0eXBlLWZlc3QnO1xuXG5pbXBvcnQgeyBQbHVnaW4gfSBmcm9tICdvYnNpZGlhbic7XG5cbmltcG9ydCB0eXBlIHsgVHJhbnNsYXRpb25zTWFwIH0gZnJvbSAnLi4vaTE4bi9pMThuLnRzJztcbmltcG9ydCB0eXBlIHtcbiAgUGx1Z2luRXZlbnRNYXAsXG4gIFBsdWdpbkV2ZW50U291cmNlXG59IGZyb20gJy4vcGx1Z2luLWV2ZW50LXNvdXJjZS50cyc7XG5cbmltcG9ydCB7IG1peGluQXN5bmNFdmVudHMgfSBmcm9tICcuLi8uLi9hc3luYy1ldmVudHMudHMnO1xuaW1wb3J0IHsgcHJpbnRFcnJvciB9IGZyb20gJy4uLy4uL2Vycm9yLnRzJztcbmltcG9ydCB7IG5vb3BBc3luYyB9IGZyb20gJy4uLy4uL2Z1bmN0aW9uLnRzJztcbmltcG9ydCB7IGVuc3VyZU5vbk51bGxhYmxlIH0gZnJvbSAnLi4vLi4vdHlwZS1ndWFyZHMudHMnO1xuaW1wb3J0IHsgQXBwQWN0aXZlRmlsZVByb3ZpZGVyIH0gZnJvbSAnLi4vYWN0aXZlLWZpbGUtcHJvdmlkZXIudHMnO1xuaW1wb3J0IHsgQ29tbWFuZEhhbmRsZXJDb21wb25lbnQgfSBmcm9tICcuLi9jb21tYW5kLWhhbmRsZXJzL2NvbW1hbmQtaGFuZGxlci1jb21wb25lbnQudHMnO1xuaW1wb3J0IHsgVW5sb2NrQWN0aXZlTm90ZUNvbW1hbmRIYW5kbGVyIH0gZnJvbSAnLi4vY29tbWFuZC1oYW5kbGVycy91bmxvY2stYWN0aXZlLW5vdGUtY29tbWFuZC1oYW5kbGVyLnRzJztcbmltcG9ydCB7IFBsdWdpbkNvbW1hbmRSZWdpc3RyYXIgfSBmcm9tICcuLi9jb21tYW5kLXJlZ2lzdHJhci50cyc7XG5pbXBvcnQgeyBBYm9ydFNpZ25hbENvbXBvbmVudCB9IGZyb20gJy4uL2NvbXBvbmVudHMvYWJvcnQtc2lnbmFsLWNvbXBvbmVudC50cyc7XG5pbXBvcnQgeyBBc3luY0Vycm9ySGFuZGxlckNvbXBvbmVudCB9IGZyb20gJy4uL2NvbXBvbmVudHMvYXN5bmMtZXJyb3ItaGFuZGxlci1jb21wb25lbnQudHMnO1xuaW1wb3J0IHsgQ29tcG9uZW50RXggfSBmcm9tICcuLi9jb21wb25lbnRzL2NvbXBvbmVudC1leC50cyc7XG5pbXBvcnQgeyBDb25zb2xlRGVidWdDb21wb25lbnQgfSBmcm9tICcuLi9jb21wb25lbnRzL2NvbnNvbGUtZGVidWctY29tcG9uZW50LnRzJztcbmltcG9ydCB7IE1lbnVFdmVudFJlZ2lzdHJhckNvbXBvbmVudCB9IGZyb20gJy4uL2NvbXBvbmVudHMvbWVudS1ldmVudC1yZWdpc3RyYXItY29tcG9uZW50LnRzJztcbmltcG9ydCB7IE5vdGVib29rTmF2aWdhdG9yTWVudUV2ZW50UmVnaXN0cmFyQ29tcG9uZW50IH0gZnJvbSAnLi4vY29tcG9uZW50cy9ub3RlYm9vay1uYXZpZ2F0b3ItbWVudS1ldmVudC1yZWdpc3RyYXItY29tcG9uZW50LnRzJztcbmltcG9ydCB7IFBsdWdpbkNvbnRleHRDb21wb25lbnQgfSBmcm9tICcuLi9jb21wb25lbnRzL3BsdWdpbi1jb250ZXh0LWNvbXBvbmVudC50cyc7XG5pbXBvcnQgeyBQbHVnaW5Ob3RpY2VDb21wb25lbnQgfSBmcm9tICcuLi9jb21wb25lbnRzL3BsdWdpbi1ub3RpY2UtY29tcG9uZW50LnRzJztcbmltcG9ydCB7IFBsdWdpblNldHRpbmdzQ29tcG9uZW50QmFzZSB9IGZyb20gJy4uL2NvbXBvbmVudHMvcGx1Z2luLXNldHRpbmdzLWNvbXBvbmVudC50cyc7XG5pbXBvcnQgeyBQbHVnaW5EYXRhSGFuZGxlciB9IGZyb20gJy4uL2RhdGEtaGFuZGxlci50cyc7XG5pbXBvcnQgeyBpbml0STE4TiB9IGZyb20gJy4uL2kxOG4vaTE4bi50cyc7XG5pbXBvcnQgeyBkZWZhdWx0VHJhbnNsYXRpb25zTWFwIH0gZnJvbSAnLi4vaTE4bi9sb2NhbGVzL3RyYW5zbGF0aW9ucy1tYXAudHMnO1xuaW1wb3J0IHsgUmVzb3VyY2VMb2NrQ29tcG9uZW50IH0gZnJvbSAnLi4vcmVzb3VyY2UtbG9jay50cyc7XG5pbXBvcnQgeyBQbHVnaW5FdmVudFNvdXJjZUltcGwgfSBmcm9tICcuL3BsdWdpbi1ldmVudC1zb3VyY2UudHMnO1xuXG4vKipcbiAqIFRoZSB1bml2ZXJzYWwgY29tcG9uZW50cyBvd25lZCBieSB7QGxpbmsgUGx1Z2luQmFzZX0sIGtleWVkIGJ5IHRoZSBuYW1lIG9mIHRoZSBhY2Nlc3NvciBleHBvc2luZ1xuICogZWFjaCBvbmUuIEV2ZXJ5IG1lbWJlciBpcyBvcHRpb25hbCBiZWNhdXNlIGEgY29tcG9uZW50IG9ubHkgZXhpc3RzIG9uY2Uge0BsaW5rIFBsdWdpbkJhc2Uub25sb2FkfVxuICogaGFzIGNyZWF0ZWQgaXQuXG4gKi9cbmludGVyZmFjZSBQbHVnaW5CYXNlQ29tcG9uZW50cyB7XG4gIGFib3J0U2lnbmFsQ29tcG9uZW50PzogQWJvcnRTaWduYWxDb21wb25lbnQ7XG4gIGFzeW5jRXJyb3JIYW5kbGVyQ29tcG9uZW50PzogQXN5bmNFcnJvckhhbmRsZXJDb21wb25lbnQ7XG4gIGNvbW1hbmRIYW5kbGVyQ29tcG9uZW50PzogQ29tbWFuZEhhbmRsZXJDb21wb25lbnQ7XG4gIGNvbnNvbGVEZWJ1Z0NvbXBvbmVudD86IENvbnNvbGVEZWJ1Z0NvbXBvbmVudDtcbiAgcGx1Z2luQ29udGV4dENvbXBvbmVudD86IFBsdWdpbkNvbnRleHRDb21wb25lbnQ7XG4gIHBsdWdpbk5vdGljZUNvbXBvbmVudD86IFBsdWdpbk5vdGljZUNvbXBvbmVudDtcbiAgcGx1Z2luU2V0dGluZ3NDb21wb25lbnQ/OiBQbHVnaW5TZXR0aW5nc0NvbXBvbmVudEJhc2U8b2JqZWN0PjtcbiAgcmVzb3VyY2VMb2NrQ29tcG9uZW50PzogUmVzb3VyY2VMb2NrQ29tcG9uZW50O1xufVxuXG4vKipcbiAqIEJhc2UgY2xhc3MgZm9yIGNyZWF0aW5nIE9ic2lkaWFuIHBsdWdpbnMgd2l0aCBhIGNvbXBvbmVudC1iYXNlZCBhcmNoaXRlY3R1cmUuXG4gKlxuICogUmVnaXN0ZXJzIHVuaXZlcnNhbCBjb21wb25lbnRzIGF1dG9tYXRpY2FsbHkuIFN1YmNsYXNzZXMgYWRkIG9yIHJlcGxhY2UgY29tcG9uZW50c1xuICogdmlhIHtAbGluayByZW1vdmVDaGlsZH0gLyB7QGxpbmsgYWRkQ2hpbGR9LlxuICovXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgUGx1Z2luQmFzZSBleHRlbmRzIG1peGluQXN5bmNFdmVudHM8UGx1Z2luRXZlbnRNYXA+KCkoUGx1Z2luKSBpbXBsZW1lbnRzIFBsdWdpbkV2ZW50U291cmNlIHtcbiAgLyoqXG4gICAqIEdldHMgYWJvcnQgc2lnbmFsIGNvbXBvbmVudC5cbiAgICpcbiAgICogQHJldHVybnMgYWJvcnQgc2lnbmFsIGNvbXBvbmVudC5cbiAgICovXG4gIHByb3RlY3RlZCBnZXQgYWJvcnRTaWduYWxDb21wb25lbnQoKTogQWJvcnRTaWduYWxDb21wb25lbnQge1xuICAgIHJldHVybiBlbnN1cmVOb25OdWxsYWJsZSh0aGlzLmNvbXBvbmVudHMuYWJvcnRTaWduYWxDb21wb25lbnQpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldHMgYWJvcnQgc2lnbmFsIGNvbXBvbmVudC5cbiAgICpcbiAgICogQHBhcmFtIHZhbHVlIC0gQWJvcnQgc2lnbmFsIGNvbXBvbmVudC5cbiAgICovXG4gIHByb3RlY3RlZCBzZXQgYWJvcnRTaWduYWxDb21wb25lbnQodmFsdWU6IEFib3J0U2lnbmFsQ29tcG9uZW50KSB7XG4gICAgdGhpcy5zZXRDb21wb25lbnQoJ2Fib3J0U2lnbmFsQ29tcG9uZW50JywgdmFsdWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgYXN5bmMgZXJyb3IgaGFuZGxlciBjb21wb25lbnQuXG4gICAqXG4gICAqIEByZXR1cm5zIGFzeW5jIGVycm9yIGhhbmRsZXIgY29tcG9uZW50LlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldCBhc3luY0Vycm9ySGFuZGxlckNvbXBvbmVudCgpOiBBc3luY0Vycm9ySGFuZGxlckNvbXBvbmVudCB7XG4gICAgcmV0dXJuIGVuc3VyZU5vbk51bGxhYmxlKHRoaXMuY29tcG9uZW50cy5hc3luY0Vycm9ySGFuZGxlckNvbXBvbmVudCk7XG4gIH1cblxuICAvKipcbiAgICogU2V0cyBhc3luYyBlcnJvciBoYW5kbGVyIGNvbXBvbmVudC5cbiAgICpcbiAgICogQHBhcmFtIHZhbHVlIC0gQXN5bmMgZXJyb3IgaGFuZGxlciBjb21wb25lbnQuXG4gICAqL1xuICBwcm90ZWN0ZWQgc2V0IGFzeW5jRXJyb3JIYW5kbGVyQ29tcG9uZW50KHZhbHVlOiBBc3luY0Vycm9ySGFuZGxlckNvbXBvbmVudCkge1xuICAgIHRoaXMuc2V0Q29tcG9uZW50KCdhc3luY0Vycm9ySGFuZGxlckNvbXBvbmVudCcsIHZhbHVlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIHRoZSBzaGFyZWQgY29tbWFuZCBoYW5kbGVyIGNvbXBvbmVudC4gUmVnaXN0ZXIgYSBwbHVnaW4ncyBjb21tYW5kcyBvbiBpdCB2aWFcbiAgICoge0BsaW5rIENvbW1hbmRIYW5kbGVyQ29tcG9uZW50LnJlZ2lzdGVyQ29tbWFuZEhhbmRsZXJzfSByYXRoZXIgdGhhbiBjb25zdHJ1Y3RpbmcgeW91ciBvd25cbiAgICoge0BsaW5rIENvbW1hbmRIYW5kbGVyQ29tcG9uZW50fSBcdTIwMTQgdGhlIGFwcC1iYWNrZWQgYWN0aXZlLWZpbGUgcHJvdmlkZXIsIGNvbW1hbmQgcmVnaXN0cmFyLCBtZW51XG4gICAqIGV2ZW50IHJlZ2lzdHJhciwgYW5kIHBsdWdpbiBuYW1lIGFyZSBhbHJlYWR5IHdpcmVkLlxuICAgKlxuICAgKiBAcmV0dXJucyBUaGUgY29tbWFuZCBoYW5kbGVyIGNvbXBvbmVudC5cbiAgICovXG4gIHByb3RlY3RlZCBnZXQgY29tbWFuZEhhbmRsZXJDb21wb25lbnQoKTogQ29tbWFuZEhhbmRsZXJDb21wb25lbnQge1xuICAgIHJldHVybiBlbnN1cmVOb25OdWxsYWJsZSh0aGlzLmNvbXBvbmVudHMuY29tbWFuZEhhbmRsZXJDb21wb25lbnQpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldHMgdGhlIGNvbW1hbmQgaGFuZGxlciBjb21wb25lbnQuXG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZSAtIFRoZSBjb21tYW5kIGhhbmRsZXIgY29tcG9uZW50LlxuICAgKi9cbiAgcHJvdGVjdGVkIHNldCBjb21tYW5kSGFuZGxlckNvbXBvbmVudCh2YWx1ZTogQ29tbWFuZEhhbmRsZXJDb21wb25lbnQpIHtcbiAgICB0aGlzLnNldENvbXBvbmVudCgnY29tbWFuZEhhbmRsZXJDb21wb25lbnQnLCB2YWx1ZSk7XG4gIH1cblxuICAvKipcbiAgICogR2V0cyBjb25zb2xlIGRlYnVnIGNvbXBvbmVudC5cbiAgICpcbiAgICogQHJldHVybnMgY29uc29sZSBkZWJ1ZyBjb21wb25lbnQuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0IGNvbnNvbGVEZWJ1Z0NvbXBvbmVudCgpOiBDb25zb2xlRGVidWdDb21wb25lbnQge1xuICAgIHJldHVybiBlbnN1cmVOb25OdWxsYWJsZSh0aGlzLmNvbXBvbmVudHMuY29uc29sZURlYnVnQ29tcG9uZW50KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXRzIGNvbnNvbGUgZGVidWcgY29tcG9uZW50LlxuICAgKlxuICAgKiBAcGFyYW0gdmFsdWUgLSBDb25zb2xlIGRlYnVnIGNvbXBvbmVudC5cbiAgICovXG4gIHByb3RlY3RlZCBzZXQgY29uc29sZURlYnVnQ29tcG9uZW50KHZhbHVlOiBDb25zb2xlRGVidWdDb21wb25lbnQpIHtcbiAgICB0aGlzLnNldENvbXBvbmVudCgnY29uc29sZURlYnVnQ29tcG9uZW50JywgdmFsdWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgcGx1Z2luIGNvbnRleHQgY29tcG9uZW50IChwbHVnaW4gSUQsIGRlYnVnIGNvbnRyb2xsZXIsIGxpYnJhcnkgc3R5bGVzKS5cbiAgICpcbiAgICogQHJldHVybnMgcGx1Z2luIGNvbnRleHQgY29tcG9uZW50LlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldCBwbHVnaW5Db250ZXh0Q29tcG9uZW50KCk6IFBsdWdpbkNvbnRleHRDb21wb25lbnQge1xuICAgIHJldHVybiBlbnN1cmVOb25OdWxsYWJsZSh0aGlzLmNvbXBvbmVudHMucGx1Z2luQ29udGV4dENvbXBvbmVudCk7XG4gIH1cblxuICAvKipcbiAgICogU2V0cyBwbHVnaW4gY29udGV4dCBjb21wb25lbnQuXG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZSAtIFBsdWdpbiBjb250ZXh0IGNvbXBvbmVudC5cbiAgICovXG4gIHByb3RlY3RlZCBzZXQgcGx1Z2luQ29udGV4dENvbXBvbmVudCh2YWx1ZTogUGx1Z2luQ29udGV4dENvbXBvbmVudCkge1xuICAgIHRoaXMuc2V0Q29tcG9uZW50KCdwbHVnaW5Db250ZXh0Q29tcG9uZW50JywgdmFsdWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgcGx1Z2luIG5vdGljZSBjb21wb25lbnQuXG4gICAqXG4gICAqIEByZXR1cm5zIHBsdWdpbiBub3RpY2UgY29tcG9uZW50LlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldCBwbHVnaW5Ob3RpY2VDb21wb25lbnQoKTogUGx1Z2luTm90aWNlQ29tcG9uZW50IHtcbiAgICByZXR1cm4gZW5zdXJlTm9uTnVsbGFibGUodGhpcy5jb21wb25lbnRzLnBsdWdpbk5vdGljZUNvbXBvbmVudCk7XG4gIH1cblxuICAvKipcbiAgICogU2V0cyBwbHVnaW4gbm90aWNlIGNvbXBvbmVudC5cbiAgICpcbiAgICogQHBhcmFtIHZhbHVlIC0gUGx1Z2luIG5vdGljZSBjb21wb25lbnQuXG4gICAqL1xuICBwcm90ZWN0ZWQgc2V0IHBsdWdpbk5vdGljZUNvbXBvbmVudCh2YWx1ZTogUGx1Z2luTm90aWNlQ29tcG9uZW50KSB7XG4gICAgdGhpcy5zZXRDb21wb25lbnQoJ3BsdWdpbk5vdGljZUNvbXBvbmVudCcsIHZhbHVlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIHBsdWdpbiBzZXR0aW5ncyBjb21wb25lbnQuXG4gICAqXG4gICAqIEByZXR1cm5zIHBsdWdpbiBzZXR0aW5ncyBjb21wb25lbnQuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0IHBsdWdpblNldHRpbmdzQ29tcG9uZW50KCk6IFBsdWdpblNldHRpbmdzQ29tcG9uZW50QmFzZTxvYmplY3Q+IHtcbiAgICByZXR1cm4gZW5zdXJlTm9uTnVsbGFibGUodGhpcy5jb21wb25lbnRzLnBsdWdpblNldHRpbmdzQ29tcG9uZW50KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXRzIHBsdWdpbiBzZXR0aW5ncyBjb21wb25lbnQuXG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZSAtIFBsdWdpbiBzZXR0aW5ncyBjb21wb25lbnQuXG4gICAqL1xuICBwcm90ZWN0ZWQgc2V0IHBsdWdpblNldHRpbmdzQ29tcG9uZW50KHZhbHVlOiBQbHVnaW5TZXR0aW5nc0NvbXBvbmVudEJhc2U8b2JqZWN0Pikge1xuICAgIHRoaXMuc2V0Q29tcG9uZW50KCdwbHVnaW5TZXR0aW5nc0NvbXBvbmVudCcsIHZhbHVlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIHRoZSBlZGl0b3IgbG9jayBjb21wb25lbnQsIHVzZWQgdG8gbG9jayBub3RlcyByZWFkLW9ubHkgZHVyaW5nIGxvbmcgb3BlcmF0aW9ucy4gT3duZWQgYnlcbiAgICogdGhlIHBsdWdpbiwgc28gaXRzIGxvY2tzIGFyZSByZWxlYXNlZCBhdXRvbWF0aWNhbGx5IHdoZW4gdGhlIHBsdWdpbiB1bmxvYWRzLlxuICAgKlxuICAgKiBAcmV0dXJucyBFZGl0b3IgbG9jayBjb21wb25lbnQuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0IHJlc291cmNlTG9ja0NvbXBvbmVudCgpOiBSZXNvdXJjZUxvY2tDb21wb25lbnQge1xuICAgIHJldHVybiBlbnN1cmVOb25OdWxsYWJsZSh0aGlzLmNvbXBvbmVudHMucmVzb3VyY2VMb2NrQ29tcG9uZW50KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXRzIHRoZSBlZGl0b3IgbG9jayBjb21wb25lbnQuXG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZSAtIEVkaXRvciBsb2NrIGNvbXBvbmVudC5cbiAgICovXG4gIHByb3RlY3RlZCBzZXQgcmVzb3VyY2VMb2NrQ29tcG9uZW50KHZhbHVlOiBSZXNvdXJjZUxvY2tDb21wb25lbnQpIHtcbiAgICB0aGlzLnNldENvbXBvbmVudCgncmVzb3VyY2VMb2NrQ29tcG9uZW50JywgdmFsdWUpO1xuICB9XG5cbiAgcHJpdmF0ZSByZWFkb25seSBjb21wb25lbnRzOiBQbHVnaW5CYXNlQ29tcG9uZW50cyA9IHt9O1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgd3JhcHBlckNvbXBvbmVudCA9IG5ldyBDb21wb25lbnRFeCgpO1xuXG4gIC8qKlxuICAgKiBBZGRzIGEgY2hpbGQgY29tcG9uZW50LlxuICAgKlxuICAgKiBUaGUgY2hpbGQgaXMgYWRkZWQgdG8gYW4gaW50ZXJuYWwgd3JhcHBlciBjb21wb25lbnQsIHdoaWNoIHtAbGluayBvbmxvYWR9IGF0dGFjaGVzIGFuZCBsb2Fkc1xuICAgKiBiZWZvcmUgd2lyaW5nIGFueXRoaW5nIHVwLiBTbyBhIGNoaWxkIGFkZGVkIGR1cmluZyB7QGxpbmsgb25sb2FkSW1wbH0gaXMgbG9hZGVkIGltbWVkaWF0ZWx5LFxuICAgKiBjaGlsZHJlbi1maXJzdCwgYW5kIGlzIHVzYWJsZSBieSB0aGUgdGltZSB0aGlzIG1ldGhvZCByZXR1cm5zLlxuICAgKlxuICAgKiBAdHlwZVBhcmFtIFRDb21wb25lbnQgLSBUaGUgdHlwZSBvZiBjb21wb25lbnQgdG8gYWRkLlxuICAgKiBAcGFyYW0gY29tcG9uZW50IC0gVGhlIGNvbXBvbmVudCBpbnN0YW5jZSB0byBhZGQuXG4gICAqIEByZXR1cm5zIFRoZSBhZGRlZCBjb21wb25lbnQuXG4gICAqL1xuICBwdWJsaWMgb3ZlcnJpZGUgYWRkQ2hpbGQ8VENvbXBvbmVudCBleHRlbmRzIENvbXBvbmVudD4oY29tcG9uZW50OiBUQ29tcG9uZW50KTogVENvbXBvbmVudCB7XG4gICAgcmV0dXJuIHRoaXMud3JhcHBlckNvbXBvbmVudC5hZGRDaGlsZChjb21wb25lbnQpO1xuICB9XG5cbiAgLyoqXG4gICAqIENhbGxlZCB3aGVuIHRoZSBleHRlcm5hbCBzZXR0aW5ncyBjaGFuZ2UuXG4gICAqXG4gICAqIE92ZXJyaWRlIGluIHN1YmNsYXNzIGlmIG5lZWRlZC4gTWFrZSBzdXJlIHRvIGNhbGwgYGF3YWl0IHN1cGVyLm9uRXh0ZXJuYWxTZXR0aW5nc0NoYW5nZSgpYCBmaXJzdC5cbiAgICovXG4gIHB1YmxpYyBvdmVycmlkZSBhc3luYyBvbkV4dGVybmFsU2V0dGluZ3NDaGFuZ2UoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgc3VwZXIub25FeHRlcm5hbFNldHRpbmdzQ2hhbmdlPy4oKTtcbiAgICBhd2FpdCB0aGlzLnRyaWdnZXJBc3luYygnZXh0ZXJuYWxTZXR0aW5nc0NoYW5nZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIENhbGxlZCB3aGVuIHRoZSBwbHVnaW4gaXMgbG9hZGVkLlxuICAgKlxuICAgKiBPcmNoZXN0cmF0ZXMgbG9hZGluZzogcmVnaXN0ZXJzIHRoZSB1bml2ZXJzYWwgY29tcG9uZW50cywgbGV0cyB0aGUgc3ViY2xhc3Mgd2lyZSBpdHMgb3duXG4gICAqIGNvbXBvbmVudHMgdmlhIHtAbGluayBvbmxvYWRJbXBsfSwgdGhlbiBhd2FpdHMgdGhlIGFzeW5jIHRhaWwgb2YgZXZlcnkgbG9hZC5cbiAgICogRWFjaCBjb21wb25lbnQgbG9hZHMgYXMgaXQgaXMgYWRkZWQsIGNoaWxkcmVuLWZpcnN0LlxuICAgKlxuICAgKiBEbyBOT1Qgb3ZlcnJpZGUgdGhpcyBtZXRob2QuIE92ZXJyaWRlIHtAbGluayBvbmxvYWRJbXBsfSBpbnN0ZWFkLlxuICAgKi9cbiAgcHVibGljIG92ZXJyaWRlIGFzeW5jIG9ubG9hZCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0cnkge1xuICAgICAgLy8gVGhlIHdyYXBwZXIgaXMgYXR0YWNoZWQgYW5kIGxvYWRlZCBiZWZvcmUgYW55dGhpbmcgaXMgd2lyZWQgdXAsIHNvIGV2ZXJ5IGBhZGRDaGlsZGAgYmVsb3dcbiAgICAgIC8vIExvYWRzIGl0cyBjaGlsZCBzdHJhaWdodCBhd2F5IHJhdGhlciB0aGFuIHF1ZXVpbmcgaXQuXG4gICAgICAvLyBUaGF0IGlzIHdoYXQgbGV0cyBhIGNvbW1hbmQgaGFuZGxlciByZWdpc3RlciBpdHMgbWVudSBldmVudHMgZnJvbSBgb25SZWdpc3RlcmVkYCwgd2hpY2hcbiAgICAgIC8vIGByZWdpc3RlckNvbW1hbmRIYW5kbGVyc2AgYXdhaXRzIGFuZCB3aGljaCBhIHJlZ2lzdHJhciByZWZ1c2VzIHdoaWxlIHVubG9hZGVkLlxuICAgICAgLy8gQXR0YWNoaW5nIGl0IHVwIGZyb250IGFsc28gcmVnaXN0ZXJzIHRoZSB3cmFwcGVyIGZvciB0ZWFyZG93biBiZWZvcmUgYW55dGhpbmcgY2FuIHRocm93LlxuICAgICAgLy8gVGhlIGxvYWQgaXMgZXhwbGljaXQgcmF0aGVyIHRoYW4gbGVmdCB0byBgYWRkQ2hpbGRgLCB3aGljaCBsb2FkcyB0aGUgY2hpbGQgb25seSB3aGVuIHRoZVxuICAgICAgLy8gUGx1Z2luIGl0c2VsZiBpcyBsb2FkZWQgXHUyMDE0IHRydWUgd2hlbiBPYnNpZGlhbiBjYWxscyBgbG9hZCgpYCwgYnV0IG5vdCB3aGVuIGEgY2FsbGVyIGludm9rZXNcbiAgICAgIC8vIGBvbmxvYWQoKWAgZGlyZWN0bHkuXG4gICAgICBzdXBlci5hZGRDaGlsZCh0aGlzLndyYXBwZXJDb21wb25lbnQpO1xuICAgICAgdGhpcy53cmFwcGVyQ29tcG9uZW50LmxvYWQoKTtcblxuICAgICAgYXdhaXQgaW5pdEkxOE4odGhpcy5jcmVhdGVUcmFuc2xhdGlvbnNNYXAoKSk7XG4gICAgICB0aGlzLnBsdWdpbkNvbnRleHRDb21wb25lbnQgPSB0aGlzLmFkZENoaWxkKFxuICAgICAgICBuZXcgUGx1Z2luQ29udGV4dENvbXBvbmVudCh7XG4gICAgICAgICAgYXBwOiB0aGlzLmFwcCxcbiAgICAgICAgICBwbHVnaW5JZDogdGhpcy5tYW5pZmVzdC5pZFxuICAgICAgICB9KVxuICAgICAgKTtcbiAgICAgIHRoaXMucGx1Z2luTm90aWNlQ29tcG9uZW50ID0gdGhpcy5hZGRDaGlsZChcbiAgICAgICAgbmV3IFBsdWdpbk5vdGljZUNvbXBvbmVudCh7XG4gICAgICAgICAgYXBwOiB0aGlzLmFwcCxcbiAgICAgICAgICBwbHVnaW5OYW1lOiB0aGlzLm1hbmlmZXN0Lm5hbWVcbiAgICAgICAgfSlcbiAgICAgICk7XG4gICAgICB0aGlzLmFzeW5jRXJyb3JIYW5kbGVyQ29tcG9uZW50ID0gdGhpcy5hZGRDaGlsZChuZXcgQXN5bmNFcnJvckhhbmRsZXJDb21wb25lbnQodGhpcy5wbHVnaW5Ob3RpY2VDb21wb25lbnQpKTtcbiAgICAgIHRoaXMuYWJvcnRTaWduYWxDb21wb25lbnQgPSB0aGlzLmFkZENoaWxkKG5ldyBBYm9ydFNpZ25hbENvbXBvbmVudCh0aGlzLm1hbmlmZXN0LmlkKSk7XG4gICAgICB0aGlzLmNvbnNvbGVEZWJ1Z0NvbXBvbmVudCA9IHRoaXMuYWRkQ2hpbGQobmV3IENvbnNvbGVEZWJ1Z0NvbXBvbmVudCh0aGlzLm1hbmlmZXN0LmlkKSk7XG4gICAgICB0aGlzLnJlc291cmNlTG9ja0NvbXBvbmVudCA9IHRoaXMuYWRkQ2hpbGQobmV3IFJlc291cmNlTG9ja0NvbXBvbmVudCh0aGlzLmFwcCwgdGhpcy5tYW5pZmVzdC5pZCkpO1xuICAgICAgLy8gTm90ZWJvb2sgTmF2aWdhdG9yIGRyYXdzIGl0cyBvd24gZmlsZSB0cmVlIGFuZCBuZXZlciByYWlzZXMgT2JzaWRpYW4ncyBgZmlsZS1tZW51YCAvXG4gICAgICAvLyBgZmlsZXMtbWVudWAgZXZlbnRzLCBzbyBldmVyeSBwbHVnaW4ncyBjb250ZXh0LW1lbnUgaXRlbXMgd291bGQgdmFuaXNoIGZvciBhbnlvbmUgYnJvd3NpbmdcbiAgICAgIC8vIFRocm91Z2ggaXQuIFdpcmVkIGhlcmUgcmF0aGVyIHRoYW4gcGVyLXBsdWdpbjogdGhlIGJyaWRnZSBzdGF5cyBkb3JtYW50IHdoZW4gTm90ZWJvb2tcbiAgICAgIC8vIE5hdmlnYXRvciBpcyBub3QgaW5zdGFsbGVkLCBhbmQgYSBwbHVnaW4gd2l0aCBubyBmaWxlL2ZvbGRlciBoYW5kbGVycyBjb250cmlidXRlcyBub3RoaW5nLlxuICAgICAgY29uc3Qgbm90ZWJvb2tOYXZpZ2F0b3JNZW51RXZlbnRSZWdpc3RyYXJDb21wb25lbnQgPSB0aGlzLmFkZENoaWxkKFxuICAgICAgICBuZXcgTm90ZWJvb2tOYXZpZ2F0b3JNZW51RXZlbnRSZWdpc3RyYXJDb21wb25lbnQoe1xuICAgICAgICAgIGFwcDogdGhpcy5hcHAsXG4gICAgICAgICAgcGx1Z2luTmFtZTogdGhpcy5tYW5pZmVzdC5uYW1lLFxuICAgICAgICAgIHN1Ym1lbnVJY29uOiB0aGlzLmdldE5vdGVib29rTmF2aWdhdG9yTWVudVN1Ym1lbnVJY29uKClcbiAgICAgICAgfSlcbiAgICAgICk7XG4gICAgICB0aGlzLmNvbW1hbmRIYW5kbGVyQ29tcG9uZW50ID0gdGhpcy5hZGRDaGlsZChcbiAgICAgICAgbmV3IENvbW1hbmRIYW5kbGVyQ29tcG9uZW50KHtcbiAgICAgICAgICBhY3RpdmVGaWxlUHJvdmlkZXI6IG5ldyBBcHBBY3RpdmVGaWxlUHJvdmlkZXIodGhpcy5hcHApLFxuICAgICAgICAgIGFkZGl0aW9uYWxNZW51RXZlbnRSZWdpc3RyYXJzOiBbbm90ZWJvb2tOYXZpZ2F0b3JNZW51RXZlbnRSZWdpc3RyYXJDb21wb25lbnRdLFxuICAgICAgICAgIGNvbW1hbmRSZWdpc3RyYXI6IG5ldyBQbHVnaW5Db21tYW5kUmVnaXN0cmFyKHRoaXMpLFxuICAgICAgICAgIG1lbnVFdmVudFJlZ2lzdHJhcjogdGhpcy5hZGRDaGlsZChuZXcgTWVudUV2ZW50UmVnaXN0cmFyQ29tcG9uZW50KHRoaXMuYXBwKSksXG4gICAgICAgICAgcGx1Z2luTmFtZTogdGhpcy5tYW5pZmVzdC5uYW1lXG4gICAgICAgIH0pXG4gICAgICApO1xuICAgICAgLy8gQWx3YXlzIGF2YWlsYWJsZTsgdGhlIGNvbW1hbmQncyBvd24gYGNhbkV4ZWN1dGVgIGhpZGVzIGl0IHVubGVzcyB0aGUgYWN0aXZlIG5vdGUgaXMgbG9ja2VkLlxuICAgICAgYXdhaXQgdGhpcy5jb21tYW5kSGFuZGxlckNvbXBvbmVudC5yZWdpc3RlckNvbW1hbmRIYW5kbGVycygoKSA9PiBbXG4gICAgICAgIG5ldyBVbmxvY2tBY3RpdmVOb3RlQ29tbWFuZEhhbmRsZXIoe1xuICAgICAgICAgIGFwcDogdGhpcy5hcHAsXG4gICAgICAgICAgcmVzb3VyY2VMb2NrQ29tcG9uZW50OiB0aGlzLnJlc291cmNlTG9ja0NvbXBvbmVudFxuICAgICAgICB9KVxuICAgICAgXSk7XG5cbiAgICAgIHRoaXMucGx1Z2luU2V0dGluZ3NDb21wb25lbnQgPSB0aGlzLmFkZENoaWxkKFxuICAgICAgICBuZXcgUGx1Z2luU2V0dGluZ3NDb21wb25lbnRCYXNlPG9iamVjdD4oe1xuICAgICAgICAgIGRhdGFIYW5kbGVyOiBuZXcgUGx1Z2luRGF0YUhhbmRsZXIodGhpcyksXG4gICAgICAgICAgcGx1Z2luRXZlbnRTb3VyY2U6IG5ldyBQbHVnaW5FdmVudFNvdXJjZUltcGwodGhpcyksXG4gICAgICAgICAgcGx1Z2luU2V0dGluZ3NDbGFzczogT2JqZWN0XG4gICAgICAgIH0pXG4gICAgICApO1xuXG4gICAgICBhd2FpdCB0aGlzLm9ubG9hZEltcGwoKTtcblxuICAgICAgLy8gRXZlcnkgY2hpbGQgaGFzIGFscmVhZHkgbG9hZGVkIGFzIGl0IHdhcyBhZGRlZDsgdGhpcyBhd2FpdHMgdGhlaXIgYWNjdW11bGF0ZWQgYXN5bmMgdGFpbHMgYW5kXG4gICAgICAvLyBSZXBvcnRzIGFueSBmYWlsdXJlIGFzIGEgc2luZ2xlIGBBZ2dyZWdhdGVFcnJvcmAuXG4gICAgICBhd2FpdCB0aGlzLndyYXBwZXJDb21wb25lbnQubG9hZFdpdGhQcm9taXNlcygpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBwcmludEVycm9yKG5ldyBFcnJvcihgRXJyb3IgbG9hZGluZyBwbHVnaW4gJHt0aGlzLm1hbmlmZXN0Lm5hbWV9ICgke3RoaXMubWFuaWZlc3QuaWR9KWAsIHsgY2F1c2U6IGVycm9yIH0pKTtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmVzIGEgY2hpbGQgY29tcG9uZW50LlxuICAgKlxuICAgKiBAdHlwZVBhcmFtIFRDb21wb25lbnQgLSBUaGUgdHlwZSBvZiBjb21wb25lbnQgdG8gcmVtb3ZlLlxuICAgKiBAcGFyYW0gY29tcG9uZW50IC0gVGhlIGNvbXBvbmVudCBpbnN0YW5jZSB0byByZW1vdmUuXG4gICAqIEByZXR1cm5zIFRoZSByZW1vdmVkIGNvbXBvbmVudC5cbiAgICovXG4gIHB1YmxpYyBvdmVycmlkZSByZW1vdmVDaGlsZDxUQ29tcG9uZW50IGV4dGVuZHMgQ29tcG9uZW50Pihjb21wb25lbnQ6IFRDb21wb25lbnQpOiBUQ29tcG9uZW50IHtcbiAgICByZXR1cm4gdGhpcy53cmFwcGVyQ29tcG9uZW50LnJlbW92ZUNoaWxkKGNvbXBvbmVudCk7XG4gIH1cblxuICAvKipcbiAgICogUHJvdmlkZXMgdGhlIHRyYW5zbGF0aW9ucyBtYXAgdXNlZCB0byBpbml0aWFsaXplIGkxOG4gZHVyaW5nIHtAbGluayBvbmxvYWR9LlxuICAgKlxuICAgKiBPdmVycmlkZSBpbiBzdWJjbGFzcyB0byBzdXBwbHkgcGx1Z2luLXNwZWNpZmljIHRyYW5zbGF0aW9ucy4gVGhlIGRlZmF1bHQgcmV0dXJucyB0aGUgYnVpbHQtaW5cbiAgICogYG9ic2lkaWFuLWRldi11dGlsc2AgdHJhbnNsYXRpb25zLlxuICAgKlxuICAgKiBAcmV0dXJucyBUaGUgdHJhbnNsYXRpb25zIG1hcC5cbiAgICovXG4gIHByb3RlY3RlZCBjcmVhdGVUcmFuc2xhdGlvbnNNYXAoKTogVHJhbnNsYXRpb25zTWFwIHtcbiAgICByZXR1cm4gZGVmYXVsdFRyYW5zbGF0aW9uc01hcDtcbiAgfVxuXG4gIC8qKlxuICAgKiBQcm92aWRlcyB0aGUgaWNvbiBzaG93biBvbiB0aGUgcGx1Z2luJ3MgcGFyZW50IGVudHJ5IGluIE5vdGVib29rIE5hdmlnYXRvcidzIGNvbnRleHQgbWVudXMuXG4gICAqXG4gICAqIE92ZXJyaWRlIGluIHN1YmNsYXNzIHRvIGJyYW5kIHRoYXQgZW50cnk7IHRoZSBkZWZhdWx0IGxlYXZlcyBpdCB3aXRob3V0IGFuIGljb24uIFRoZSBlbnRyeSBpc1xuICAgKiB0aXRsZWQgd2l0aCB0aGUgcGx1Z2luIG5hbWUgYW5kIGlzIGFkZGVkIGF1dG9tYXRpY2FsbHkgXHUyMDE0IHNlZVxuICAgKiB7QGxpbmsgTm90ZWJvb2tOYXZpZ2F0b3JNZW51RXZlbnRSZWdpc3RyYXJDb21wb25lbnR9LlxuICAgKlxuICAgKiBAcmV0dXJucyBUaGUgaWNvbiwgb3IgYCcnYCBmb3Igbm8gaWNvbi5cbiAgICovXG4gIHByb3RlY3RlZCBnZXROb3RlYm9va05hdmlnYXRvck1lbnVTdWJtZW51SWNvbigpOiBJY29uTmFtZSB7XG4gICAgcmV0dXJuICcnO1xuICB9XG5cbiAgLyoqXG4gICAqIENhbGxlZCBkdXJpbmcge0BsaW5rIG9ubG9hZH0gdG8gd2lyZSBwbHVnaW4tc3BlY2lmaWMgY2hpbGQgY29tcG9uZW50cy5cbiAgICpcbiAgICogT3ZlcnJpZGUgaW4gc3ViY2xhc3MgdG8gYWRkIGNoaWxkIGNvbXBvbmVudHMgdmlhIHtAbGluayBhZGRDaGlsZH0uIFRoZSB1bml2ZXJzYWwgY29tcG9uZW50cyBhcmVcbiAgICogYXZhaWxhYmxlIGhlcmUuIENoaWxkcmVuIGFyZSBsb2FkZWQgc2VxdWVudGlhbGx5IGluIHRoZSBvcmRlciB0aGV5IGFyZSBhZGRlZCAoY2hpbGRyZW4tZmlyc3QpLlxuICAgKlxuICAgKiBAcmV0dXJucyBBIHtAbGluayBQcm9taXNlfSB0aGF0IHJlc29sdmVzIHdoZW4gdGhlIHN1YmNsYXNzIGxvYWQgbG9naWMgaXMgY29tcGxldGUuXG4gICAqL1xuICBwcm90ZWN0ZWQgb25sb2FkSW1wbCgpOiBQcm9taXNhYmxlPHZvaWQ+IHtcbiAgICByZXR1cm4gbm9vcEFzeW5jKCk7XG4gIH1cblxuICAvKipcbiAgICogU3RvcmVzIGEgdW5pdmVyc2FsIGNvbXBvbmVudCwgdW5sb2FkaW5nIHdoaWNoZXZlciBjb21wb25lbnQgdGhlIGtleSBoZWxkIGJlZm9yZS5cbiAgICpcbiAgICogS2V5ZWQgYnkgbmFtZSByYXRoZXIgdGhhbiBoYW5kZWQgdGhlIHByZXZpb3VzIHZhbHVlIGJlY2F1c2UgYGtleW9mIHRoaXNgIGV4Y2x1ZGVzIHByaXZhdGVcbiAgICogbWVtYmVycywgc28gdGhlIGNvbXBvbmVudHMgbGl2ZSBpbiBhIHNpbmdsZSB7QGxpbmsgUGx1Z2luQmFzZUNvbXBvbmVudHN9IGJhZyB3aG9zZSBrZXlzIEFSRVxuICAgKiBpbmRleGFibGUuXG4gICAqXG4gICAqIEB0eXBlUGFyYW0gVEtleSAtIFRoZSBrZXkgb2YgdGhlIGNvbXBvbmVudCB0byBzdG9yZS5cbiAgICogQHBhcmFtIGtleSAtIFRoZSBrZXkgb2YgdGhlIGNvbXBvbmVudCB0byBzdG9yZS5cbiAgICogQHBhcmFtIHZhbHVlIC0gVGhlIGNvbXBvbmVudCB0byBzdG9yZS5cbiAgICovXG4gIHByaXZhdGUgc2V0Q29tcG9uZW50PFRLZXkgZXh0ZW5kcyBrZXlvZiBQbHVnaW5CYXNlQ29tcG9uZW50cz4oa2V5OiBUS2V5LCB2YWx1ZTogTm9uTnVsbGFibGU8UGx1Z2luQmFzZUNvbXBvbmVudHNbVEtleV0+KTogdm9pZCB7XG4gICAgY29uc3Qgb2xkQ29tcG9uZW50ID0gdGhpcy5jb21wb25lbnRzW2tleV07XG4gICAgaWYgKG9sZENvbXBvbmVudCkge1xuICAgICAgdGhpcy5yZW1vdmVDaGlsZChvbGRDb21wb25lbnQpO1xuICAgIH1cbiAgICB0aGlzLmNvbXBvbmVudHNba2V5XSA9IHZhbHVlO1xuICB9XG59XG5cbi8qKlxuICogUmVsb2FkcyB0aGUgc3BlY2lmaWVkIHBsdWdpbiBieSBkaXNhYmxpbmcgYW5kIHRoZW4gcmUtZW5hYmxpbmcgaXQuXG4gKlxuICogQHBhcmFtIHBsdWdpbiAtIFRoZSBwbHVnaW4gdG8gcmVsb2FkLlxuICogQHJldHVybnMgQSB7QGxpbmsgUHJvbWlzZX0gdGhhdCByZXNvbHZlcyB3aGVuIHRoZSBwbHVnaW4gaXMgcmVsb2FkZWQuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByZWxvYWRQbHVnaW4ocGx1Z2luOiBQbHVnaW4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgcGx1Z2lucyA9IHBsdWdpbi5hcHAucGx1Z2lucztcbiAgY29uc3QgcGx1Z2luSWQgPSBwbHVnaW4ubWFuaWZlc3QuaWQ7XG4gIGF3YWl0IHBsdWdpbnMuZGlzYWJsZVBsdWdpbihwbHVnaW5JZCk7XG4gIGF3YWl0IHBsdWdpbnMuZW5hYmxlUGx1Z2luKHBsdWdpbklkKTtcbn1cblxuLyoqXG4gKiBEaXNwbGF5cyBhbiBlcnJvciBtZXNzYWdlIGFzIGEgbm90aWNlLCBsb2dzIGl0IHRvIHRoZSBjb25zb2xlLCBhbmQgZGlzYWJsZXMgdGhlIHNwZWNpZmllZCBwbHVnaW4uXG4gKlxuICogQHBhcmFtIHBsdWdpbiAtIFRoZSBwbHVnaW4gdG8gZGlzYWJsZS5cbiAqIEBwYXJhbSBtZXNzYWdlIC0gVGhlIGVycm9yIG1lc3NhZ2UgdG8gZGlzcGxheSBhbmQgbG9nLlxuICogQHJldHVybnMgQSB7QGxpbmsgUHJvbWlzZX0gdGhhdCByZXNvbHZlcyB3aGVuIHRoZSBwbHVnaW4gaXMgZGlzYWJsZWQuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBzaG93RXJyb3JBbmREaXNhYmxlUGx1Z2luKHBsdWdpbjogUGx1Z2luLCBtZXNzYWdlOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgcGx1Z2luTm90aWNlQ29tcG9uZW50ID0gbmV3IFBsdWdpbk5vdGljZUNvbXBvbmVudCh7XG4gICAgYXBwOiBwbHVnaW4uYXBwLFxuICAgIHBsdWdpbk5hbWU6IHBsdWdpbi5tYW5pZmVzdC5uYW1lXG4gIH0pO1xuICBwbHVnaW5Ob3RpY2VDb21wb25lbnQuc2hvd05vdGljZShtZXNzYWdlKTtcbiAgcHJpbnRFcnJvcihuZXcgRXJyb3IobWVzc2FnZSkpO1xuICBhd2FpdCBwbHVnaW4uYXBwLnBsdWdpbnMuZGlzYWJsZVBsdWdpbihwbHVnaW4ubWFuaWZlc3QuaWQpO1xufVxuIl0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBY0Esc0JBQXVCO0FBUXZCLDBCQUFpQztBQUNqQyxtQkFBMkI7QUFDM0Isc0JBQTBCO0FBQzFCLHlCQUFrQztBQUNsQyxrQ0FBc0M7QUFDdEMsdUNBQXdDO0FBQ3hDLGdEQUErQztBQUMvQywrQkFBdUM7QUFDdkMsb0NBQXFDO0FBQ3JDLDJDQUEyQztBQUMzQywwQkFBNEI7QUFDNUIscUNBQXNDO0FBQ3RDLDRDQUE0QztBQUM1QywrREFBNkQ7QUFDN0Qsc0NB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
701
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vLi4vLi4vc3JjL29ic2lkaWFuL3BsdWdpbi9wbHVnaW4udHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQGZpbGVcbiAqXG4gKiBCYXNlIGNsYXNzIGZvciBPYnNpZGlhbiBwbHVnaW5zIHVzaW5nIGEgY29tcG9uZW50LWJhc2VkIGFyY2hpdGVjdHVyZS5cbiAqXG4gKiBQbHVnaW5CYXNlIHJlZ2lzdGVycyB1bml2ZXJzYWwgY29tcG9uZW50cyAoY29udGV4dCwgaTE4biwgZXJyb3IgaGFuZGxpbmcsIGFib3J0IHNpZ25hbCwgbGlmZWN5Y2xlIGV2ZW50cywgZGVidWcpLlxuICovXG5cbmltcG9ydCB0eXBlIHtcbiAgQ29tcG9uZW50LFxuICBJY29uTmFtZVxufSBmcm9tICdvYnNpZGlhbic7XG5pbXBvcnQgdHlwZSB7IFByb21pc2FibGUgfSBmcm9tICd0eXBlLWZlc3QnO1xuXG5pbXBvcnQgeyBQbHVnaW4gfSBmcm9tICdvYnNpZGlhbic7XG5cbmltcG9ydCB0eXBlIHtcbiAgUGx1Z2luQ29uZmxpY3QsXG4gIFBsdWdpbkRlcGVuZGVuY3lcbn0gZnJvbSAnLi4vY29tcG9uZW50cy9wbHVnaW4tZ2F0ZS1jb21wb25lbnQudHMnO1xuaW1wb3J0IHR5cGUgeyBUcmFuc2xhdGlvbnNNYXAgfSBmcm9tICcuLi9pMThuL2kxOG4udHMnO1xuaW1wb3J0IHR5cGUgeyBQbHVnaW5BcGlEZWNsYXJhdGlvbiB9IGZyb20gJy4vcGx1Z2luLWFwaS50cyc7XG5pbXBvcnQgdHlwZSB7XG4gIFBsdWdpbkV2ZW50TWFwLFxuICBQbHVnaW5FdmVudFNvdXJjZVxufSBmcm9tICcuL3BsdWdpbi1ldmVudC1zb3VyY2UudHMnO1xuaW1wb3J0IHR5cGUgeyBQbHVnaW5MaWZlY3ljbGVFdmVudFBheWxvYWQgfSBmcm9tICcuL3BsdWdpbi1saWZlY3ljbGUtZXZlbnRzLnRzJztcblxuaW1wb3J0IHsgbWl4aW5Bc3luY0V2ZW50cyB9IGZyb20gJy4uLy4uL2FzeW5jLWV2ZW50cy50cyc7XG5pbXBvcnQgeyBwcmludEVycm9yIH0gZnJvbSAnLi4vLi4vZXJyb3IudHMnO1xuaW1wb3J0IHsgbm9vcEFzeW5jIH0gZnJvbSAnLi4vLi4vZnVuY3Rpb24udHMnO1xuaW1wb3J0IHsgZW5zdXJlTm9uTnVsbGFibGUgfSBmcm9tICcuLi8uLi90eXBlLWd1YXJkcy50cyc7XG5pbXBvcnQgeyBBcHBBY3RpdmVGaWxlUHJvdmlkZXIgfSBmcm9tICcuLi9hY3RpdmUtZmlsZS1wcm92aWRlci50cyc7XG5pbXBvcnQgeyBDb21tYW5kSGFuZGxlckNvbXBvbmVudCB9IGZyb20gJy4uL2NvbW1hbmQtaGFuZGxlcnMvY29tbWFuZC1oYW5kbGVyLWNvbXBvbmVudC50cyc7XG5pbXBvcnQgeyBVbmxvY2tBY3RpdmVOb3RlQ29tbWFuZEhhbmRsZXIgfSBmcm9tICcuLi9jb21tYW5kLWhhbmRsZXJzL3VubG9jay1hY3RpdmUtbm90ZS1jb21tYW5kLWhhbmRsZXIudHMnO1xuaW1wb3J0IHsgUGx1Z2luQ29tbWFuZFJlZ2lzdHJhciB9IGZyb20gJy4uL2NvbW1hbmQtcmVnaXN0cmFyLnRzJztcbmltcG9ydCB7IEFib3J0U2lnbmFsQ29tcG9uZW50IH0gZnJvbSAnLi4vY29tcG9uZW50cy9hYm9ydC1zaWduYWwtY29tcG9uZW50LnRzJztcbmltcG9ydCB7IEFzeW5jRXJyb3JIYW5kbGVyQ29tcG9uZW50IH0gZnJvbSAnLi4vY29tcG9uZW50cy9hc3luYy1lcnJvci1oYW5kbGVyLWNvbXBvbmVudC50cyc7XG5pbXBvcnQgeyBDb21wb25lbnRFeCB9IGZyb20gJy4uL2NvbXBvbmVudHMvY29tcG9uZW50LWV4LnRzJztcbmltcG9ydCB7IENvbnNvbGVEZWJ1Z0NvbXBvbmVudCB9IGZyb20gJy4uL2NvbXBvbmVudHMvY29uc29sZS1kZWJ1Zy1jb21wb25lbnQudHMnO1xuaW1wb3J0IHsgTWVudUV2ZW50UmVnaXN0cmFyQ29tcG9uZW50IH0gZnJvbSAnLi4vY29tcG9uZW50cy9tZW51LWV2ZW50LXJlZ2lzdHJhci1jb21wb25lbnQudHMnO1xuaW1wb3J0IHsgTm90ZWJvb2tOYXZpZ2F0b3JNZW51RXZlbnRSZWdpc3RyYXJDb21wb25lbnQgfSBmcm9tICcuLi9jb21wb25lbnRzL25vdGVib29rLW5hdmlnYXRvci1tZW51LWV2ZW50LXJlZ2lzdHJhci1jb21wb25lbnQudHMnO1xuaW1wb3J0IHsgUGx1Z2luQ29udGV4dENvbXBvbmVudCB9IGZyb20gJy4uL2NvbXBvbmVudHMvcGx1Z2luLWNvbnRleHQtY29tcG9uZW50LnRzJztcbmltcG9ydCB7IFBsdWdpbkdhdGVDb21wb25lbnQgfSBmcm9tICcuLi9jb21wb25lbnRzL3BsdWdpbi1nYXRlLWNvbXBvbmVudC50cyc7XG5pbXBvcnQgeyBQbHVnaW5Ob3RpY2VDb21wb25lbnQgfSBmcm9tICcuLi9jb21wb25lbnRzL3BsdWdpbi1ub3RpY2UtY29tcG9uZW50LnRzJztcbmltcG9ydCB7IFBsdWdpblNldHRpbmdzQ29tcG9uZW50QmFzZSB9IGZyb20gJy4uL2NvbXBvbmVudHMvcGx1Z2luLXNldHRpbmdzLWNvbXBvbmVudC50cyc7XG5pbXBvcnQgeyBQbHVnaW5EYXRhSGFuZGxlciB9IGZyb20gJy4uL2RhdGEtaGFuZGxlci50cyc7XG5pbXBvcnQgeyBpbml0STE4TiB9IGZyb20gJy4uL2kxOG4vaTE4bi50cyc7XG5pbXBvcnQgeyBkZWZhdWx0VHJhbnNsYXRpb25zTWFwIH0gZnJvbSAnLi4vaTE4bi9sb2NhbGVzL3RyYW5zbGF0aW9ucy1tYXAudHMnO1xuaW1wb3J0IHsgUmVzb3VyY2VMb2NrQ29tcG9uZW50IH0gZnJvbSAnLi4vcmVzb3VyY2UtbG9jay50cyc7XG5pbXBvcnQgeyBwdWJsaXNoUGx1Z2luQXBpIH0gZnJvbSAnLi9wbHVnaW4tYXBpLnRzJztcbmltcG9ydCB7IFBsdWdpbkV2ZW50U291cmNlSW1wbCB9IGZyb20gJy4vcGx1Z2luLWV2ZW50LXNvdXJjZS50cyc7XG5pbXBvcnQge1xuICBQTFVHSU5fTE9BREVEX0VWRU5UX05BTUUsXG4gIFBMVUdJTl9VTkxPQURFRF9FVkVOVF9OQU1FLFxuICB0cmlnZ2VyUGx1Z2luTGlmZWN5Y2xlRXZlbnRcbn0gZnJvbSAnLi9wbHVnaW4tbGlmZWN5Y2xlLWV2ZW50cy50cyc7XG5cbi8qKlxuICogVGhlIHVuaXZlcnNhbCBjb21wb25lbnRzIG93bmVkIGJ5IHtAbGluayBQbHVnaW5CYXNlfSwga2V5ZWQgYnkgdGhlIG5hbWUgb2YgdGhlIGFjY2Vzc29yIGV4cG9zaW5nXG4gKiBlYWNoIG9uZS4gRXZlcnkgbWVtYmVyIGlzIG9wdGlvbmFsIGJlY2F1c2UgYSBjb21wb25lbnQgb25seSBleGlzdHMgb25jZSB7QGxpbmsgUGx1Z2luQmFzZS5vbmxvYWR9XG4gKiBoYXMgY3JlYXRlZCBpdC5cbiAqL1xuaW50ZXJmYWNlIFBsdWdpbkJhc2VDb21wb25lbnRzIHtcbiAgYWJvcnRTaWduYWxDb21wb25lbnQ/OiBBYm9ydFNpZ25hbENvbXBvbmVudDtcbiAgYXN5bmNFcnJvckhhbmRsZXJDb21wb25lbnQ/OiBBc3luY0Vycm9ySGFuZGxlckNvbXBvbmVudDtcbiAgY29tbWFuZEhhbmRsZXJDb21wb25lbnQ/OiBDb21tYW5kSGFuZGxlckNvbXBvbmVudDtcbiAgY29uc29sZURlYnVnQ29tcG9uZW50PzogQ29uc29sZURlYnVnQ29tcG9uZW50O1xuICBwbHVnaW5Db250ZXh0Q29tcG9uZW50PzogUGx1Z2luQ29udGV4dENvbXBvbmVudDtcbiAgcGx1Z2luR2F0ZUNvbXBvbmVudD86IFBsdWdpbkdhdGVDb21wb25lbnQ7XG4gIHBsdWdpbk5vdGljZUNvbXBvbmVudD86IFBsdWdpbk5vdGljZUNvbXBvbmVudDtcbiAgcGx1Z2luU2V0dGluZ3NDb21wb25lbnQ/OiBQbHVnaW5TZXR0aW5nc0NvbXBvbmVudEJhc2U8b2JqZWN0PjtcbiAgcmVzb3VyY2VMb2NrQ29tcG9uZW50PzogUmVzb3VyY2VMb2NrQ29tcG9uZW50O1xufVxuXG4vKipcbiAqIEJhc2UgY2xhc3MgZm9yIGNyZWF0aW5nIE9ic2lkaWFuIHBsdWdpbnMgd2l0aCBhIGNvbXBvbmVudC1iYXNlZCBhcmNoaXRlY3R1cmUuXG4gKlxuICogUmVnaXN0ZXJzIHVuaXZlcnNhbCBjb21wb25lbnRzIGF1dG9tYXRpY2FsbHkuIFN1YmNsYXNzZXMgYWRkIG9yIHJlcGxhY2UgY29tcG9uZW50c1xuICogdmlhIHtAbGluayByZW1vdmVDaGlsZH0gLyB7QGxpbmsgYWRkQ2hpbGR9LlxuICovXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgUGx1Z2luQmFzZSBleHRlbmRzIG1peGluQXN5bmNFdmVudHM8UGx1Z2luRXZlbnRNYXA+KCkoUGx1Z2luKSBpbXBsZW1lbnRzIFBsdWdpbkV2ZW50U291cmNlIHtcbiAgLyoqXG4gICAqIEdldHMgYWJvcnQgc2lnbmFsIGNvbXBvbmVudC5cbiAgICpcbiAgICogQHJldHVybnMgYWJvcnQgc2lnbmFsIGNvbXBvbmVudC5cbiAgICovXG4gIHByb3RlY3RlZCBnZXQgYWJvcnRTaWduYWxDb21wb25lbnQoKTogQWJvcnRTaWduYWxDb21wb25lbnQge1xuICAgIHJldHVybiBlbnN1cmVOb25OdWxsYWJsZSh0aGlzLmNvbXBvbmVudHMuYWJvcnRTaWduYWxDb21wb25lbnQpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldHMgYWJvcnQgc2lnbmFsIGNvbXBvbmVudC5cbiAgICpcbiAgICogQHBhcmFtIHZhbHVlIC0gQWJvcnQgc2lnbmFsIGNvbXBvbmVudC5cbiAgICovXG4gIHByb3RlY3RlZCBzZXQgYWJvcnRTaWduYWxDb21wb25lbnQodmFsdWU6IEFib3J0U2lnbmFsQ29tcG9uZW50KSB7XG4gICAgdGhpcy5zZXRDb21wb25lbnQoJ2Fib3J0U2lnbmFsQ29tcG9uZW50JywgdmFsdWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgYXN5bmMgZXJyb3IgaGFuZGxlciBjb21wb25lbnQuXG4gICAqXG4gICAqIEByZXR1cm5zIGFzeW5jIGVycm9yIGhhbmRsZXIgY29tcG9uZW50LlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldCBhc3luY0Vycm9ySGFuZGxlckNvbXBvbmVudCgpOiBBc3luY0Vycm9ySGFuZGxlckNvbXBvbmVudCB7XG4gICAgcmV0dXJuIGVuc3VyZU5vbk51bGxhYmxlKHRoaXMuY29tcG9uZW50cy5hc3luY0Vycm9ySGFuZGxlckNvbXBvbmVudCk7XG4gIH1cblxuICAvKipcbiAgICogU2V0cyBhc3luYyBlcnJvciBoYW5kbGVyIGNvbXBvbmVudC5cbiAgICpcbiAgICogQHBhcmFtIHZhbHVlIC0gQXN5bmMgZXJyb3IgaGFuZGxlciBjb21wb25lbnQuXG4gICAqL1xuICBwcm90ZWN0ZWQgc2V0IGFzeW5jRXJyb3JIYW5kbGVyQ29tcG9uZW50KHZhbHVlOiBBc3luY0Vycm9ySGFuZGxlckNvbXBvbmVudCkge1xuICAgIHRoaXMuc2V0Q29tcG9uZW50KCdhc3luY0Vycm9ySGFuZGxlckNvbXBvbmVudCcsIHZhbHVlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIHRoZSBzaGFyZWQgY29tbWFuZCBoYW5kbGVyIGNvbXBvbmVudC4gUmVnaXN0ZXIgYSBwbHVnaW4ncyBjb21tYW5kcyBvbiBpdCB2aWFcbiAgICoge0BsaW5rIENvbW1hbmRIYW5kbGVyQ29tcG9uZW50LnJlZ2lzdGVyQ29tbWFuZEhhbmRsZXJzfSByYXRoZXIgdGhhbiBjb25zdHJ1Y3RpbmcgeW91ciBvd25cbiAgICoge0BsaW5rIENvbW1hbmRIYW5kbGVyQ29tcG9uZW50fSBcdTIwMTQgdGhlIGFwcC1iYWNrZWQgYWN0aXZlLWZpbGUgcHJvdmlkZXIsIGNvbW1hbmQgcmVnaXN0cmFyLCBtZW51XG4gICAqIGV2ZW50IHJlZ2lzdHJhciwgYW5kIHBsdWdpbiBuYW1lIGFyZSBhbHJlYWR5IHdpcmVkLlxuICAgKlxuICAgKiBAcmV0dXJucyBUaGUgY29tbWFuZCBoYW5kbGVyIGNvbXBvbmVudC5cbiAgICovXG4gIHByb3RlY3RlZCBnZXQgY29tbWFuZEhhbmRsZXJDb21wb25lbnQoKTogQ29tbWFuZEhhbmRsZXJDb21wb25lbnQge1xuICAgIHJldHVybiBlbnN1cmVOb25OdWxsYWJsZSh0aGlzLmNvbXBvbmVudHMuY29tbWFuZEhhbmRsZXJDb21wb25lbnQpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldHMgdGhlIGNvbW1hbmQgaGFuZGxlciBjb21wb25lbnQuXG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZSAtIFRoZSBjb21tYW5kIGhhbmRsZXIgY29tcG9uZW50LlxuICAgKi9cbiAgcHJvdGVjdGVkIHNldCBjb21tYW5kSGFuZGxlckNvbXBvbmVudCh2YWx1ZTogQ29tbWFuZEhhbmRsZXJDb21wb25lbnQpIHtcbiAgICB0aGlzLnNldENvbXBvbmVudCgnY29tbWFuZEhhbmRsZXJDb21wb25lbnQnLCB2YWx1ZSk7XG4gIH1cblxuICAvKipcbiAgICogR2V0cyBjb25zb2xlIGRlYnVnIGNvbXBvbmVudC5cbiAgICpcbiAgICogQHJldHVybnMgY29uc29sZSBkZWJ1ZyBjb21wb25lbnQuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0IGNvbnNvbGVEZWJ1Z0NvbXBvbmVudCgpOiBDb25zb2xlRGVidWdDb21wb25lbnQge1xuICAgIHJldHVybiBlbnN1cmVOb25OdWxsYWJsZSh0aGlzLmNvbXBvbmVudHMuY29uc29sZURlYnVnQ29tcG9uZW50KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXRzIGNvbnNvbGUgZGVidWcgY29tcG9uZW50LlxuICAgKlxuICAgKiBAcGFyYW0gdmFsdWUgLSBDb25zb2xlIGRlYnVnIGNvbXBvbmVudC5cbiAgICovXG4gIHByb3RlY3RlZCBzZXQgY29uc29sZURlYnVnQ29tcG9uZW50KHZhbHVlOiBDb25zb2xlRGVidWdDb21wb25lbnQpIHtcbiAgICB0aGlzLnNldENvbXBvbmVudCgnY29uc29sZURlYnVnQ29tcG9uZW50JywgdmFsdWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgcGx1Z2luIGNvbnRleHQgY29tcG9uZW50IChwbHVnaW4gSUQsIGRlYnVnIGNvbnRyb2xsZXIsIGxpYnJhcnkgc3R5bGVzKS5cbiAgICpcbiAgICogQHJldHVybnMgcGx1Z2luIGNvbnRleHQgY29tcG9uZW50LlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldCBwbHVnaW5Db250ZXh0Q29tcG9uZW50KCk6IFBsdWdpbkNvbnRleHRDb21wb25lbnQge1xuICAgIHJldHVybiBlbnN1cmVOb25OdWxsYWJsZSh0aGlzLmNvbXBvbmVudHMucGx1Z2luQ29udGV4dENvbXBvbmVudCk7XG4gIH1cblxuICAvKipcbiAgICogU2V0cyBwbHVnaW4gY29udGV4dCBjb21wb25lbnQuXG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZSAtIFBsdWdpbiBjb250ZXh0IGNvbXBvbmVudC5cbiAgICovXG4gIHByb3RlY3RlZCBzZXQgcGx1Z2luQ29udGV4dENvbXBvbmVudCh2YWx1ZTogUGx1Z2luQ29udGV4dENvbXBvbmVudCkge1xuICAgIHRoaXMuc2V0Q29tcG9uZW50KCdwbHVnaW5Db250ZXh0Q29tcG9uZW50JywgdmFsdWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgdGhlIGdhdGUgaG9sZGluZyB0aGUgcGx1Z2luJ3MgZmVhdHVyZSBzdXJmYWNlIHVwIG9yIGRvd24uXG4gICAqXG4gICAqIFJlYWNoIGZvciBpdCBmcm9tIGEgc2V0dGluZ3MgdGFiIHRvIHJlbmRlciB0aGUgb3ZlcmxhcCBiYW5uZXIgZm9yIGFcbiAgICoge0BsaW5rIG9ic2lkaWFuL2NvbXBvbmVudHMvcGx1Z2luLWdhdGUtY29tcG9uZW50IVBsdWdpbkNvbmZsaWN0U2V2ZXJpdHkuV2Fybn0gY29uZmxpY3QgXHUyMDE0IHRoZSBvbmVcbiAgICogYmFubmVyIHRoZSBsaWJyYXJ5IGNhbm5vdCBwbGFjZSBpdHNlbGYsIGJlY2F1c2UgYSBydW5uaW5nIHBsdWdpbiBidWlsZHMgaXRzIG93biBzZXR0aW5ncyB0YWIuXG4gICAqXG4gICAqIEByZXR1cm5zIFRoZSBwbHVnaW4gZ2F0ZSBjb21wb25lbnQuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0IHBsdWdpbkdhdGVDb21wb25lbnQoKTogUGx1Z2luR2F0ZUNvbXBvbmVudCB7XG4gICAgcmV0dXJuIGVuc3VyZU5vbk51bGxhYmxlKHRoaXMuY29tcG9uZW50cy5wbHVnaW5HYXRlQ29tcG9uZW50KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXRzIHRoZSBwbHVnaW4gZ2F0ZSBjb21wb25lbnQuXG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZSAtIFRoZSBwbHVnaW4gZ2F0ZSBjb21wb25lbnQuXG4gICAqL1xuICBwcm90ZWN0ZWQgc2V0IHBsdWdpbkdhdGVDb21wb25lbnQodmFsdWU6IFBsdWdpbkdhdGVDb21wb25lbnQpIHtcbiAgICB0aGlzLnNldENvbXBvbmVudCgncGx1Z2luR2F0ZUNvbXBvbmVudCcsIHZhbHVlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIHBsdWdpbiBub3RpY2UgY29tcG9uZW50LlxuICAgKlxuICAgKiBAcmV0dXJucyBwbHVnaW4gbm90aWNlIGNvbXBvbmVudC5cbiAgICovXG4gIHByb3RlY3RlZCBnZXQgcGx1Z2luTm90aWNlQ29tcG9uZW50KCk6IFBsdWdpbk5vdGljZUNvbXBvbmVudCB7XG4gICAgcmV0dXJuIGVuc3VyZU5vbk51bGxhYmxlKHRoaXMuY29tcG9uZW50cy5wbHVnaW5Ob3RpY2VDb21wb25lbnQpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldHMgcGx1Z2luIG5vdGljZSBjb21wb25lbnQuXG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZSAtIFBsdWdpbiBub3RpY2UgY29tcG9uZW50LlxuICAgKi9cbiAgcHJvdGVjdGVkIHNldCBwbHVnaW5Ob3RpY2VDb21wb25lbnQodmFsdWU6IFBsdWdpbk5vdGljZUNvbXBvbmVudCkge1xuICAgIHRoaXMuc2V0Q29tcG9uZW50KCdwbHVnaW5Ob3RpY2VDb21wb25lbnQnLCB2YWx1ZSk7XG4gIH1cblxuICAvKipcbiAgICogR2V0cyBwbHVnaW4gc2V0dGluZ3MgY29tcG9uZW50LlxuICAgKlxuICAgKiBAcmV0dXJucyBwbHVnaW4gc2V0dGluZ3MgY29tcG9uZW50LlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldCBwbHVnaW5TZXR0aW5nc0NvbXBvbmVudCgpOiBQbHVnaW5TZXR0aW5nc0NvbXBvbmVudEJhc2U8b2JqZWN0PiB7XG4gICAgcmV0dXJuIGVuc3VyZU5vbk51bGxhYmxlKHRoaXMuY29tcG9uZW50cy5wbHVnaW5TZXR0aW5nc0NvbXBvbmVudCk7XG4gIH1cblxuICAvKipcbiAgICogU2V0cyBwbHVnaW4gc2V0dGluZ3MgY29tcG9uZW50LlxuICAgKlxuICAgKiBAcGFyYW0gdmFsdWUgLSBQbHVnaW4gc2V0dGluZ3MgY29tcG9uZW50LlxuICAgKi9cbiAgcHJvdGVjdGVkIHNldCBwbHVnaW5TZXR0aW5nc0NvbXBvbmVudCh2YWx1ZTogUGx1Z2luU2V0dGluZ3NDb21wb25lbnRCYXNlPG9iamVjdD4pIHtcbiAgICB0aGlzLnNldENvbXBvbmVudCgncGx1Z2luU2V0dGluZ3NDb21wb25lbnQnLCB2YWx1ZSk7XG4gIH1cblxuICAvKipcbiAgICogR2V0cyB0aGUgZWRpdG9yIGxvY2sgY29tcG9uZW50LCB1c2VkIHRvIGxvY2sgbm90ZXMgcmVhZC1vbmx5IGR1cmluZyBsb25nIG9wZXJhdGlvbnMuIE93bmVkIGJ5XG4gICAqIHRoZSBwbHVnaW4sIHNvIGl0cyBsb2NrcyBhcmUgcmVsZWFzZWQgYXV0b21hdGljYWxseSB3aGVuIHRoZSBwbHVnaW4gdW5sb2Fkcy5cbiAgICpcbiAgICogQHJldHVybnMgRWRpdG9yIGxvY2sgY29tcG9uZW50LlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldCByZXNvdXJjZUxvY2tDb21wb25lbnQoKTogUmVzb3VyY2VMb2NrQ29tcG9uZW50IHtcbiAgICByZXR1cm4gZW5zdXJlTm9uTnVsbGFibGUodGhpcy5jb21wb25lbnRzLnJlc291cmNlTG9ja0NvbXBvbmVudCk7XG4gIH1cblxuICAvKipcbiAgICogU2V0cyB0aGUgZWRpdG9yIGxvY2sgY29tcG9uZW50LlxuICAgKlxuICAgKiBAcGFyYW0gdmFsdWUgLSBFZGl0b3IgbG9jayBjb21wb25lbnQuXG4gICAqL1xuICBwcm90ZWN0ZWQgc2V0IHJlc291cmNlTG9ja0NvbXBvbmVudCh2YWx1ZTogUmVzb3VyY2VMb2NrQ29tcG9uZW50KSB7XG4gICAgdGhpcy5zZXRDb21wb25lbnQoJ3Jlc291cmNlTG9ja0NvbXBvbmVudCcsIHZhbHVlKTtcbiAgfVxuXG4gIHByaXZhdGUgcmVhZG9ubHkgY29tcG9uZW50czogUGx1Z2luQmFzZUNvbXBvbmVudHMgPSB7fTtcblxuICAvLyBFdmVyeXRoaW5nIHRoZSBTVUJDTEFTUyBvd25zOiB3aGF0IGBvbmxvYWRJbXBsYCBhZGRzLCBhbmQgd2hhdCBpdCBhZGRzIGxhdGVyLlxuICAvL1xuICAvLyBBIHNlY29uZCB3cmFwcGVyIHJhdGhlciB0aGFuIG9uZSwgYmVjYXVzZSB0aGUgdHdvIHRpZXJzIGhhdmUgb3Bwb3NpdGUgbGlmZXRpbWVzLiBUaGUgdW5pdmVyc2FsXG4gIC8vIENvbXBvbmVudHMgaGF2ZSB0byBPVVRMSVZFIGEgbG9zdCBkZXBlbmRlbmN5IFx1MjAxNCB0aGV5IGFyZSB3aGF0IHNob3dzIHRoZSBub3RpY2UgbmFtaW5nIHRoZSBwbHVnaW4gdGhhdFxuICAvLyBXZW50IGF3YXkgYW5kIHJlbmRlcnMgdGhlIGJ1dHRvbiB0aGF0IGJyaW5ncyBpdCBiYWNrIFx1MjAxNCB3aGlsZSB0aGUgc3ViY2xhc3MncyBzdXJmYWNlIGlzIGV4YWN0bHkgd2hhdFxuICAvLyBNdXN0IHN0b3AgcnVubmluZy4gVW5sb2FkaW5nIG9uZSB3cmFwcGVyIGhvbGRpbmcgYm90aCB3b3VsZCBzaWxlbmNlIHRoZSBwbHVnaW4gYXQgdGhlIG1vbWVudCBpdCBtb3N0XG4gIC8vIE5lZWRzIHRvIHNwZWFrLlxuICAvL1xuICAvLyBBbHdheXMgcHJlc2VudCwgbmV2ZXIgbnVsbCwgYW5kIFJFUExBQ0VEIHJhdGhlciB0aGFuIGVtcHRpZWQgd2hlbiB0aGUgc3VyZmFjZSBpcyB0b3JuIGRvd24uIFRoYXQga2VlcHNcbiAgLy8gYGFkZENoaWxkYCBjYWxsYWJsZSBhdCBldmVyeSBwb2ludCBpbiB0aGUgcGx1Z2luJ3MgbGlmZSwgZXhhY3RseSBhcyBpdCB3YXMgYmVmb3JlIHRoZSB0aWVycyBleGlzdGVkOlxuICAvLyBBIGNoaWxkIGFkZGVkIGJlZm9yZSB0aGUgZ2F0ZSBvcGVucyBpcyBxdWV1ZWQgYW5kIGxvYWRlZCB3aGVuIGl0IGRvZXMsIHdoaWNoIGlzIHdoYXQgYENvbXBvbmVudEV4YFxuICAvLyBBbHJlYWR5IGRvZXMgZm9yIGFueSBjaGlsZCBhZGRlZCB0byBhIG5vdC15ZXQtbG9hZGVkIGNvbXBvbmVudC5cbiAgcHJpdmF0ZSBnYXRlZFdyYXBwZXJDb21wb25lbnQgPSBuZXcgQ29tcG9uZW50RXgoKTtcblxuICAvLyBUaGUgcGF5bG9hZCBicm9hZGNhc3Qgd2hlbiB0aGlzIHBsdWdpbiBmaW5pc2hlZCBsb2FkaW5nLCBrZXB0IHNvIHRoZSBtYXRjaGluZyB1bmxvYWRlZCBicm9hZGNhc3RcbiAgLy8gRGVzY3JpYmVzIHRoZSBzYW1lIHBsdWdpbiB3aXRob3V0IHJlLWRlcml2aW5nIGl0IGZyb20gYSBzdXJmYWNlIHRoYXQgaGFzIHNpbmNlIGJlZW4gdG9ybiBkb3duLiBOdWxsXG4gIC8vIFdoZW5ldmVyIG5vIGxvYWRlZCBicm9hZGNhc3QgaXMgb3V0c3RhbmRpbmcsIHdoaWNoIGlzIHdoYXQga2VlcHMgdGhlIHR3byBldmVudHMgcGFpcmVkLlxuICBwcml2YXRlIGxpZmVjeWNsZUV2ZW50UGF5bG9hZDogbnVsbCB8IFBsdWdpbkxpZmVjeWNsZUV2ZW50UGF5bG9hZCA9IG51bGw7XG5cbiAgLy8gVGhlIGxpYnJhcnkncyBvd24gY29tcG9uZW50cywgd2hpY2ggb3V0bGl2ZSBhbnkgZGVwZW5kZW5jeS5cbiAgcHJpdmF0ZSByZWFkb25seSB1bml2ZXJzYWxXcmFwcGVyQ29tcG9uZW50ID0gbmV3IENvbXBvbmVudEV4KCk7XG5cbiAgLyoqXG4gICAqIEFkZHMgYSBjaGlsZCBjb21wb25lbnQuXG4gICAqXG4gICAqIFRoZSBjaGlsZCBpcyBhZGRlZCB0byB0aGUgaW50ZXJuYWwgd3JhcHBlciBob2xkaW5nIHRoZSBzdWJjbGFzcydzIG93biBzdXJmYWNlLCB3aGljaCB7QGxpbmsgb25sb2FkfVxuICAgKiBjcmVhdGVzIGFuZCBsb2FkcyBiZWZvcmUgY2FsbGluZyB7QGxpbmsgb25sb2FkSW1wbH0uIFNvIGEgY2hpbGQgYWRkZWQgZHVyaW5nIHtAbGluayBvbmxvYWRJbXBsfSBpc1xuICAgKiBsb2FkZWQgaW1tZWRpYXRlbHksIGNoaWxkcmVuLWZpcnN0LCBhbmQgaXMgdXNhYmxlIGJ5IHRoZSB0aW1lIHRoaXMgbWV0aG9kIHJldHVybnMuXG4gICAqXG4gICAqIFRoYXQgd3JhcHBlciBpcyB0b3JuIGRvd24gYW5kIHJlYnVpbHQgd2hlbmV2ZXIgdGhlIGdhdGUgY2xvc2VzIGFuZCBvcGVucyBhZ2FpbiBcdTIwMTQgYSBkZXBlbmRlbmN5IGRlY2xhcmVkXG4gICAqIGJ5IHtAbGluayBnZXRQbHVnaW5EZXBlbmRlbmNpZXN9IGdvaW5nIGF3YXkgYW5kIGNvbWluZyBiYWNrLCBvciBhIGNvbmZsaWN0IGRlY2xhcmVkIGJ5XG4gICAqIHtAbGluayBnZXRQbHVnaW5Db25mbGljdHN9IGFwcGVhcmluZyBhbmQgYmVpbmcgcmVzb2x2ZWQgXHUyMDE0IHNvIGEgY2hpbGQgYWRkZWQgaGVyZSBsaXZlcyBleGFjdGx5IGFzIGxvbmdcbiAgICogYXMgdGhlIHBsdWdpbidzIGZlYXR1cmUgc3VyZmFjZSBkb2VzLiBBZGRpbmcgb25lIHdoaWxlIHRoZSBzdXJmYWNlIGlzIGRvd24gaXMgc3RpbGwgbGVnaXRpbWF0ZSBcdTIwMTQgaXQgaXNcbiAgICogcXVldWVkIGFuZCBsb2FkZWQgd2hlbiB0aGUgc3VyZmFjZSBuZXh0IGNvbWVzIHVwLCB0aGUgd2F5IHtAbGluayBDb21wb25lbnRFeC5hZGRDaGlsZH0gYWxyZWFkeSBxdWV1ZXNcbiAgICogYSBjaGlsZCBhZGRlZCB0byBhIG5vdC15ZXQtbG9hZGVkIGNvbXBvbmVudC5cbiAgICpcbiAgICogQHR5cGVQYXJhbSBUQ29tcG9uZW50IC0gVGhlIHR5cGUgb2YgY29tcG9uZW50IHRvIGFkZC5cbiAgICogQHBhcmFtIGNvbXBvbmVudCAtIFRoZSBjb21wb25lbnQgaW5zdGFuY2UgdG8gYWRkLlxuICAgKiBAcmV0dXJucyBUaGUgYWRkZWQgY29tcG9uZW50LlxuICAgKi9cbiAgcHVibGljIG92ZXJyaWRlIGFkZENoaWxkPFRDb21wb25lbnQgZXh0ZW5kcyBDb21wb25lbnQ+KGNvbXBvbmVudDogVENvbXBvbmVudCk6IFRDb21wb25lbnQge1xuICAgIHJldHVybiB0aGlzLmdhdGVkV3JhcHBlckNvbXBvbmVudC5hZGRDaGlsZChjb21wb25lbnQpO1xuICB9XG5cbiAgLyoqXG4gICAqIENhbGxlZCB3aGVuIHRoZSBleHRlcm5hbCBzZXR0aW5ncyBjaGFuZ2UuXG4gICAqXG4gICAqIE92ZXJyaWRlIGluIHN1YmNsYXNzIGlmIG5lZWRlZC4gTWFrZSBzdXJlIHRvIGNhbGwgYGF3YWl0IHN1cGVyLm9uRXh0ZXJuYWxTZXR0aW5nc0NoYW5nZSgpYCBmaXJzdC5cbiAgICovXG4gIHB1YmxpYyBvdmVycmlkZSBhc3luYyBvbkV4dGVybmFsU2V0dGluZ3NDaGFuZ2UoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgc3VwZXIub25FeHRlcm5hbFNldHRpbmdzQ2hhbmdlPy4oKTtcbiAgICBhd2FpdCB0aGlzLnRyaWdnZXJBc3luYygnZXh0ZXJuYWxTZXR0aW5nc0NoYW5nZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIENhbGxlZCB3aGVuIHRoZSBwbHVnaW4gaXMgbG9hZGVkLlxuICAgKlxuICAgKiBPcmNoZXN0cmF0ZXMgbG9hZGluZzogcmVnaXN0ZXJzIHRoZSB1bml2ZXJzYWwgY29tcG9uZW50cywgbGV0cyB0aGUgc3ViY2xhc3Mgd2lyZSBpdHMgb3duXG4gICAqIGNvbXBvbmVudHMgdmlhIHtAbGluayBvbmxvYWRJbXBsfSwgdGhlbiBhd2FpdHMgdGhlIGFzeW5jIHRhaWwgb2YgZXZlcnkgbG9hZC5cbiAgICogRWFjaCBjb21wb25lbnQgbG9hZHMgYXMgaXQgaXMgYWRkZWQsIGNoaWxkcmVuLWZpcnN0LlxuICAgKlxuICAgKiBEbyBOT1Qgb3ZlcnJpZGUgdGhpcyBtZXRob2QuIE92ZXJyaWRlIHtAbGluayBvbmxvYWRJbXBsfSBpbnN0ZWFkLlxuICAgKi9cbiAgcHVibGljIG92ZXJyaWRlIGFzeW5jIG9ubG9hZCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0cnkge1xuICAgICAgLy8gVGhlIHdyYXBwZXIgaXMgYXR0YWNoZWQgYW5kIGxvYWRlZCBiZWZvcmUgYW55dGhpbmcgaXMgd2lyZWQgdXAsIHNvIGV2ZXJ5IGBhZGRDaGlsZGAgYmVsb3dcbiAgICAgIC8vIExvYWRzIGl0cyBjaGlsZCBzdHJhaWdodCBhd2F5IHJhdGhlciB0aGFuIHF1ZXVpbmcgaXQuXG4gICAgICAvLyBUaGF0IGlzIHdoYXQgbGV0cyBhIGNvbW1hbmQgaGFuZGxlciByZWdpc3RlciBpdHMgbWVudSBldmVudHMgZnJvbSBgb25SZWdpc3RlcmVkYCwgd2hpY2hcbiAgICAgIC8vIGByZWdpc3RlckNvbW1hbmRIYW5kbGVyc2AgYXdhaXRzIGFuZCB3aGljaCBhIHJlZ2lzdHJhciByZWZ1c2VzIHdoaWxlIHVubG9hZGVkLlxuICAgICAgLy8gQXR0YWNoaW5nIGl0IHVwIGZyb250IGFsc28gcmVnaXN0ZXJzIHRoZSB3cmFwcGVyIGZvciB0ZWFyZG93biBiZWZvcmUgYW55dGhpbmcgY2FuIHRocm93LlxuICAgICAgLy8gVGhlIGxvYWQgaXMgZXhwbGljaXQgcmF0aGVyIHRoYW4gbGVmdCB0byBgYWRkQ2hpbGRgLCB3aGljaCBsb2FkcyB0aGUgY2hpbGQgb25seSB3aGVuIHRoZVxuICAgICAgLy8gUGx1Z2luIGl0c2VsZiBpcyBsb2FkZWQgXHUyMDE0IHRydWUgd2hlbiBPYnNpZGlhbiBjYWxscyBgbG9hZCgpYCwgYnV0IG5vdCB3aGVuIGEgY2FsbGVyIGludm9rZXNcbiAgICAgIC8vIGBvbmxvYWQoKWAgZGlyZWN0bHkuXG4gICAgICBzdXBlci5hZGRDaGlsZCh0aGlzLnVuaXZlcnNhbFdyYXBwZXJDb21wb25lbnQpO1xuICAgICAgdGhpcy51bml2ZXJzYWxXcmFwcGVyQ29tcG9uZW50LmxvYWQoKTtcblxuICAgICAgYXdhaXQgaW5pdEkxOE4odGhpcy5jcmVhdGVUcmFuc2xhdGlvbnNNYXAoKSk7XG4gICAgICB0aGlzLnBsdWdpbkNvbnRleHRDb21wb25lbnQgPSB0aGlzLmFkZFVuaXZlcnNhbENoaWxkKFxuICAgICAgICBuZXcgUGx1Z2luQ29udGV4dENvbXBvbmVudCh7XG4gICAgICAgICAgYXBwOiB0aGlzLmFwcCxcbiAgICAgICAgICBwbHVnaW5JZDogdGhpcy5tYW5pZmVzdC5pZFxuICAgICAgICB9KVxuICAgICAgKTtcbiAgICAgIHRoaXMucGx1Z2luTm90aWNlQ29tcG9uZW50ID0gdGhpcy5hZGRVbml2ZXJzYWxDaGlsZChcbiAgICAgICAgbmV3IFBsdWdpbk5vdGljZUNvbXBvbmVudCh7XG4gICAgICAgICAgYXBwOiB0aGlzLmFwcCxcbiAgICAgICAgICBwbHVnaW5OYW1lOiB0aGlzLm1hbmlmZXN0Lm5hbWVcbiAgICAgICAgfSlcbiAgICAgICk7XG4gICAgICB0aGlzLmFzeW5jRXJyb3JIYW5kbGVyQ29tcG9uZW50ID0gdGhpcy5hZGRVbml2ZXJzYWxDaGlsZChuZXcgQXN5bmNFcnJvckhhbmRsZXJDb21wb25lbnQodGhpcy5wbHVnaW5Ob3RpY2VDb21wb25lbnQpKTtcbiAgICAgIHRoaXMuYWJvcnRTaWduYWxDb21wb25lbnQgPSB0aGlzLmFkZFVuaXZlcnNhbENoaWxkKG5ldyBBYm9ydFNpZ25hbENvbXBvbmVudCh0aGlzLm1hbmlmZXN0LmlkKSk7XG4gICAgICB0aGlzLmNvbnNvbGVEZWJ1Z0NvbXBvbmVudCA9IHRoaXMuYWRkVW5pdmVyc2FsQ2hpbGQobmV3IENvbnNvbGVEZWJ1Z0NvbXBvbmVudCh0aGlzLm1hbmlmZXN0LmlkKSk7XG4gICAgICB0aGlzLnJlc291cmNlTG9ja0NvbXBvbmVudCA9IHRoaXMuYWRkVW5pdmVyc2FsQ2hpbGQobmV3IFJlc291cmNlTG9ja0NvbXBvbmVudCh0aGlzLmFwcCwgdGhpcy5tYW5pZmVzdC5pZCkpO1xuICAgICAgLy8gTm90ZWJvb2sgTmF2aWdhdG9yIGRyYXdzIGl0cyBvd24gZmlsZSB0cmVlIGFuZCBuZXZlciByYWlzZXMgT2JzaWRpYW4ncyBgZmlsZS1tZW51YCAvXG4gICAgICAvLyBgZmlsZXMtbWVudWAgZXZlbnRzLCBzbyBldmVyeSBwbHVnaW4ncyBjb250ZXh0LW1lbnUgaXRlbXMgd291bGQgdmFuaXNoIGZvciBhbnlvbmUgYnJvd3NpbmdcbiAgICAgIC8vIFRocm91Z2ggaXQuIFdpcmVkIGhlcmUgcmF0aGVyIHRoYW4gcGVyLXBsdWdpbjogdGhlIGJyaWRnZSBzdGF5cyBkb3JtYW50IHdoZW4gTm90ZWJvb2tcbiAgICAgIC8vIE5hdmlnYXRvciBpcyBub3QgaW5zdGFsbGVkLCBhbmQgYSBwbHVnaW4gd2l0aCBubyBmaWxlL2ZvbGRlciBoYW5kbGVycyBjb250cmlidXRlcyBub3RoaW5nLlxuICAgICAgY29uc3Qgbm90ZWJvb2tOYXZpZ2F0b3JNZW51RXZlbnRSZWdpc3RyYXJDb21wb25lbnQgPSB0aGlzLmFkZFVuaXZlcnNhbENoaWxkKFxuICAgICAgICBuZXcgTm90ZWJvb2tOYXZpZ2F0b3JNZW51RXZlbnRSZWdpc3RyYXJDb21wb25lbnQoe1xuICAgICAgICAgIGFwcDogdGhpcy5hcHAsXG4gICAgICAgICAgcGx1Z2luTmFtZTogdGhpcy5tYW5pZmVzdC5uYW1lLFxuICAgICAgICAgIHN1Ym1lbnVJY29uOiB0aGlzLmdldE5vdGVib29rTmF2aWdhdG9yTWVudVN1Ym1lbnVJY29uKClcbiAgICAgICAgfSlcbiAgICAgICk7XG4gICAgICB0aGlzLmNvbW1hbmRIYW5kbGVyQ29tcG9uZW50ID0gdGhpcy5hZGRVbml2ZXJzYWxDaGlsZChcbiAgICAgICAgbmV3IENvbW1hbmRIYW5kbGVyQ29tcG9uZW50KHtcbiAgICAgICAgICBhY3RpdmVGaWxlUHJvdmlkZXI6IG5ldyBBcHBBY3RpdmVGaWxlUHJvdmlkZXIodGhpcy5hcHApLFxuICAgICAgICAgIGFkZGl0aW9uYWxNZW51RXZlbnRSZWdpc3RyYXJzOiBbbm90ZWJvb2tOYXZpZ2F0b3JNZW51RXZlbnRSZWdpc3RyYXJDb21wb25lbnRdLFxuICAgICAgICAgIGNvbW1hbmRSZWdpc3RyYXI6IG5ldyBQbHVnaW5Db21tYW5kUmVnaXN0cmFyKHRoaXMpLFxuICAgICAgICAgIG1lbnVFdmVudFJlZ2lzdHJhcjogdGhpcy5hZGRVbml2ZXJzYWxDaGlsZChuZXcgTWVudUV2ZW50UmVnaXN0cmFyQ29tcG9uZW50KHRoaXMuYXBwKSksXG4gICAgICAgICAgcGx1Z2luTmFtZTogdGhpcy5tYW5pZmVzdC5uYW1lXG4gICAgICAgIH0pXG4gICAgICApO1xuICAgICAgLy8gQWx3YXlzIGF2YWlsYWJsZTsgdGhlIGNvbW1hbmQncyBvd24gYGNhbkV4ZWN1dGVgIGhpZGVzIGl0IHVubGVzcyB0aGUgYWN0aXZlIG5vdGUgaXMgbG9ja2VkLlxuICAgICAgYXdhaXQgdGhpcy5jb21tYW5kSGFuZGxlckNvbXBvbmVudC5yZWdpc3RlckNvbW1hbmRIYW5kbGVycygoKSA9PiBbXG4gICAgICAgIG5ldyBVbmxvY2tBY3RpdmVOb3RlQ29tbWFuZEhhbmRsZXIoe1xuICAgICAgICAgIGFwcDogdGhpcy5hcHAsXG4gICAgICAgICAgcmVzb3VyY2VMb2NrQ29tcG9uZW50OiB0aGlzLnJlc291cmNlTG9ja0NvbXBvbmVudFxuICAgICAgICB9KVxuICAgICAgXSk7XG5cbiAgICAgIHRoaXMucGx1Z2luU2V0dGluZ3NDb21wb25lbnQgPSB0aGlzLmFkZFVuaXZlcnNhbENoaWxkKFxuICAgICAgICBuZXcgUGx1Z2luU2V0dGluZ3NDb21wb25lbnRCYXNlPG9iamVjdD4oe1xuICAgICAgICAgIGRhdGFIYW5kbGVyOiBuZXcgUGx1Z2luRGF0YUhhbmRsZXIodGhpcyksXG4gICAgICAgICAgcGx1Z2luRXZlbnRTb3VyY2U6IG5ldyBQbHVnaW5FdmVudFNvdXJjZUltcGwodGhpcyksXG4gICAgICAgICAgcGx1Z2luU2V0dGluZ3NDbGFzczogT2JqZWN0XG4gICAgICAgIH0pXG4gICAgICApO1xuXG4gICAgICAvLyBUaGUgZ2F0ZS4gSXQgbG9hZHMgdGhlIGZlYXR1cmUgc3VyZmFjZSBpdHNlbGYgb25jZSBldmVyeSBkZWNsYXJlZCBkZXBlbmRlbmN5IGlzIHNhdGlzZmllZCBhbmQgbm9cbiAgICAgIC8vIERlY2xhcmVkIGNvbmZsaWN0IGhvbGRzIFx1MjAxNCB3aGljaCBmb3IgYSBwbHVnaW4gZGVjbGFyaW5nIG5laXRoZXIgaXMgaW1tZWRpYXRlbHksIHN5bmNocm9ub3VzbHksXG4gICAgICAvLyBCZWZvcmUgdGhpcyBsaW5lIHJldHVybnMgXHUyMDE0IGFuZCB1bmxvYWRzIGl0IGFnYWluIGlmIGEgZGVwZW5kZW5jeSBpcyBsYXRlciBkaXNhYmxlZCBvciB1bmluc3RhbGxlZCxcbiAgICAgIC8vIE9yIGEgY29uZmxpY3RpbmcgcGx1Z2luIGlzIGVuYWJsZWQuIEEgcGx1Z2luIHRoYXQgaXMgYmxvY2tlZCB0aGVyZWZvcmUgcmVhY2hlcyBgbG9hZFdpdGhQcm9taXNlc2BcbiAgICAgIC8vIEJlbG93IGhhdmluZyByZWdpc3RlcmVkIG5vdGhpbmcgb2YgaXRzIG93biwgd2l0aCBvbmx5IHRoZSB1bml2ZXJzYWwgY29tcG9uZW50cyBhYm92ZSBydW5uaW5nIHRvXG4gICAgICAvLyBFeHBsYWluIHdoeSBhbmQgdG8gb2ZmZXIgdGhlIHJlcGFpci5cbiAgICAgIHRoaXMucGx1Z2luR2F0ZUNvbXBvbmVudCA9IHRoaXMuYWRkVW5pdmVyc2FsQ2hpbGQoXG4gICAgICAgIG5ldyBQbHVnaW5HYXRlQ29tcG9uZW50KHtcbiAgICAgICAgICBjb25mbGljdHM6IHRoaXMuZ2V0UGx1Z2luQ29uZmxpY3RzKCksXG4gICAgICAgICAgZGVwZW5kZW5jaWVzOiB0aGlzLmdldFBsdWdpbkRlcGVuZGVuY2llcygpLFxuICAgICAgICAgIGxvYWRGZWF0dXJlU3VyZmFjZTogKCk6IFByb21pc2U8dm9pZD4gPT4gdGhpcy5sb2FkRmVhdHVyZVN1cmZhY2UoKSxcbiAgICAgICAgICBwbHVnaW46IHRoaXMsXG4gICAgICAgICAgcGx1Z2luTm90aWNlQ29tcG9uZW50OiB0aGlzLnBsdWdpbk5vdGljZUNvbXBvbmVudCxcbiAgICAgICAgICB1bmxvYWRGZWF0dXJlU3VyZmFjZTogKCk6IHZvaWQgPT4ge1xuICAgICAgICAgICAgdGhpcy51bmxvYWRGZWF0dXJlU3VyZmFjZSgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICAgICk7XG5cbiAgICAgIC8vIEV2ZXJ5IGNoaWxkIGhhcyBhbHJlYWR5IGxvYWRlZCBhcyBpdCB3YXMgYWRkZWQ7IHRoaXMgYXdhaXRzIHRoZWlyIGFjY3VtdWxhdGVkIGFzeW5jIHRhaWxzIGFuZFxuICAgICAgLy8gUmVwb3J0cyBhbnkgZmFpbHVyZSBhcyBhIHNpbmdsZSBgQWdncmVnYXRlRXJyb3JgLlxuICAgICAgYXdhaXQgdGhpcy51bml2ZXJzYWxXcmFwcGVyQ29tcG9uZW50LmxvYWRXaXRoUHJvbWlzZXMoKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgcHJpbnRFcnJvcihuZXcgRXJyb3IoYEVycm9yIGxvYWRpbmcgcGx1Z2luICR7dGhpcy5tYW5pZmVzdC5uYW1lfSAoJHt0aGlzLm1hbmlmZXN0LmlkfSlgLCB7IGNhdXNlOiBlcnJvciB9KSk7XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ2FsbGVkIHdoZW4gdGhlIHBsdWdpbiBpcyB1bmxvYWRlZC5cbiAgICpcbiAgICogQW5ub3VuY2VzIHRoZSBkZXBhcnR1cmUgb24gYGFwcC53b3Jrc3BhY2VgIHNvIGFueXRoaW5nIGRlcGVuZGluZyBvbiB0aGlzIHBsdWdpbiBsZWFybnMgb2YgaXQgYXQgdGhlXG4gICAqIG1vbWVudCBpdCBoYXBwZW5zLCByYXRoZXIgdGhhbiBkaXNjb3ZlcmluZyBpdCBsYXRlciB0aHJvdWdoIGJlaGF2aW9yIHRoYXQgcXVpZXRseSBzdG9wcGVkLlxuICAgKlxuICAgKiBEbyBOT1Qgb3ZlcnJpZGUgdGhpcyBtZXRob2Q7IHB1dCB0ZWFyZG93biBvbiBhIGNvbXBvbmVudCBpbnN0ZWFkLCB3aGljaCB1bmxvYWRzIHdpdGggdGhlIHBsdWdpbi5cbiAgICovXG4gIHB1YmxpYyBvdmVycmlkZSBvbnVubG9hZCgpOiB2b2lkIHtcbiAgICB0aGlzLmJyb2FkY2FzdFVubG9hZGVkKCk7XG4gICAgc3VwZXIub251bmxvYWQoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmVzIGEgY2hpbGQgY29tcG9uZW50LlxuICAgKlxuICAgKiBAdHlwZVBhcmFtIFRDb21wb25lbnQgLSBUaGUgdHlwZSBvZiBjb21wb25lbnQgdG8gcmVtb3ZlLlxuICAgKiBAcGFyYW0gY29tcG9uZW50IC0gVGhlIGNvbXBvbmVudCBpbnN0YW5jZSB0byByZW1vdmUuXG4gICAqIEByZXR1cm5zIFRoZSByZW1vdmVkIGNvbXBvbmVudC5cbiAgICovXG4gIHB1YmxpYyBvdmVycmlkZSByZW1vdmVDaGlsZDxUQ29tcG9uZW50IGV4dGVuZHMgQ29tcG9uZW50Pihjb21wb25lbnQ6IFRDb21wb25lbnQpOiBUQ29tcG9uZW50IHtcbiAgICAvLyBSb3V0ZWQgYnkgb3duZXJzaGlwIHJhdGhlciB0aGFuIGJ5IHdoaWNoIHRpZXIgYGFkZENoaWxkYCB3b3VsZCBoYXZlIGNob3NlbiwgYmVjYXVzZSB0aGUgdHdvIGRvIG5vdFxuICAgIC8vIEFsd2F5cyBhZ3JlZTogYSB1bml2ZXJzYWwgY29tcG9uZW50IGlzIHBhcmVudGVkIGRpcmVjdGx5IG9uIHRoZSB1bml2ZXJzYWwgd3JhcHBlciwgeWV0IGEgc3ViY2xhc3NcbiAgICAvLyBSZXBsYWNpbmcgb25lIGdvZXMgdGhyb3VnaCB0aGUgc2FtZSBwdWJsaWMgYHJlbW92ZUNoaWxkYCBhcyBpdCB3b3VsZCBmb3IgaXRzIG93biBjaGlsZHJlbi5cbiAgICBpZiAodGhpcy5nYXRlZFdyYXBwZXJDb21wb25lbnQuaGFzQ2hpbGQoY29tcG9uZW50KSkge1xuICAgICAgcmV0dXJuIHRoaXMuZ2F0ZWRXcmFwcGVyQ29tcG9uZW50LnJlbW92ZUNoaWxkKGNvbXBvbmVudCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMudW5pdmVyc2FsV3JhcHBlckNvbXBvbmVudC5yZW1vdmVDaGlsZChjb21wb25lbnQpO1xuICB9XG5cbiAgLyoqXG4gICAqIFByb3ZpZGVzIHRoZSB0cmFuc2xhdGlvbnMgbWFwIHVzZWQgdG8gaW5pdGlhbGl6ZSBpMThuIGR1cmluZyB7QGxpbmsgb25sb2FkfS5cbiAgICpcbiAgICogT3ZlcnJpZGUgaW4gc3ViY2xhc3MgdG8gc3VwcGx5IHBsdWdpbi1zcGVjaWZpYyB0cmFuc2xhdGlvbnMuIFRoZSBkZWZhdWx0IHJldHVybnMgdGhlIGJ1aWx0LWluXG4gICAqIGBvYnNpZGlhbi1kZXYtdXRpbHNgIHRyYW5zbGF0aW9ucy5cbiAgICpcbiAgICogQHJldHVybnMgVGhlIHRyYW5zbGF0aW9ucyBtYXAuXG4gICAqL1xuICBwcm90ZWN0ZWQgY3JlYXRlVHJhbnNsYXRpb25zTWFwKCk6IFRyYW5zbGF0aW9uc01hcCB7XG4gICAgcmV0dXJuIGRlZmF1bHRUcmFuc2xhdGlvbnNNYXA7XG4gIH1cblxuICAvKipcbiAgICogUHJvdmlkZXMgdGhlIGljb24gc2hvd24gb24gdGhlIHBsdWdpbidzIHBhcmVudCBlbnRyeSBpbiBOb3RlYm9vayBOYXZpZ2F0b3IncyBjb250ZXh0IG1lbnVzLlxuICAgKlxuICAgKiBPdmVycmlkZSBpbiBzdWJjbGFzcyB0byBicmFuZCB0aGF0IGVudHJ5OyB0aGUgZGVmYXVsdCBsZWF2ZXMgaXQgd2l0aG91dCBhbiBpY29uLiBUaGUgZW50cnkgaXNcbiAgICogdGl0bGVkIHdpdGggdGhlIHBsdWdpbiBuYW1lIGFuZCBpcyBhZGRlZCBhdXRvbWF0aWNhbGx5IFx1MjAxNCBzZWVcbiAgICoge0BsaW5rIE5vdGVib29rTmF2aWdhdG9yTWVudUV2ZW50UmVnaXN0cmFyQ29tcG9uZW50fS5cbiAgICpcbiAgICogQHJldHVybnMgVGhlIGljb24sIG9yIGAnJ2AgZm9yIG5vIGljb24uXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0Tm90ZWJvb2tOYXZpZ2F0b3JNZW51U3VibWVudUljb24oKTogSWNvbk5hbWUge1xuICAgIHJldHVybiAnJztcbiAgfVxuXG4gIC8qKlxuICAgKiBQcm92aWRlcyB0aGUgQVBJcyB0aGlzIHBsdWdpbiBleHBvc2VzIHRvIG90aGVyIHBsdWdpbnMuXG4gICAqXG4gICAqIE92ZXJyaWRlIGluIHN1YmNsYXNzIHRvIHB1Ymxpc2ggb25lLiBUaGUgZGVmYXVsdCBwdWJsaXNoZXMgbm9uZS4gQ2FsbGVkIGFmdGVyIHtAbGluayBvbmxvYWRJbXBsfSwgc28gYVxuICAgKiBkZWNsYXJhdGlvbiBtYXkgcmVmZXJlbmNlIGFueXRoaW5nIGl0IGNyZWF0ZWQ7IHRoZSByZXR1cm5lZCBkZWNsYXJhdGlvbnMgYXJlIHB1Ymxpc2hlZCB0aHJvdWdoXG4gICAqIGBwdWJsaXNoUGx1Z2luQXBpYCBhbmQgcmV2b2tlZCB3aGVuIHRoZSBwbHVnaW4ncyBmZWF0dXJlIHN1cmZhY2UgdW5sb2Fkcy5cbiAgICpcbiAgICogUmV0dXJuaW5nIGEgTElTVCByYXRoZXIgdGhhbiBhIHNpbmdsZSBBUEkgaXMgZGVsaWJlcmF0ZTogdGhlIHJlZ2lzdHJ5IHN1cHBvcnRzIHNldmVyYWwgY29udHJhY3RcbiAgICogdmVyc2lvbnMgcHVibGlzaGVkIHNpZGUgYnkgc2lkZSwgd2hpY2ggaXMgaG93IGEgcHJvdmlkZXIgc2hpcHMgYSBicmVha2luZyBgMi4wLjBgIHdpdGhvdXQgc3RyYW5kaW5nXG4gICAqIGNvbnN1bWVycyBzdGlsbCBwaW5uZWQgdG8gYF4xYC5cbiAgICpcbiAgICogRXZlcnkgZGVjbGFyYXRpb24gaGVyZSBpcyBwdWJsaXNoZWQgQkVGT1JFIHRoZSBgb2JzaWRpYW4tZGV2LXV0aWxzOnBsdWdpbi1sb2FkZWRgIGJyb2FkY2FzdCwgd2hpY2ggaXNcbiAgICogd2hhdCBsZXRzIGEgbGlzdGVuZXIgY2FsbCB0aGVzZSBBUElzIHRoZSBtb21lbnQgaXQgaGVhcnMgdGhhdCBldmVudC5cbiAgICpcbiAgICogQHJldHVybnMgVGhlIEFQSSBkZWNsYXJhdGlvbnMuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0UGx1Z2luQXBpcygpOiBQbHVnaW5BcGlEZWNsYXJhdGlvbltdIHtcbiAgICByZXR1cm4gW107XG4gIH1cblxuICAvKipcbiAgICogUHJvdmlkZXMgdGhlIHBsdWdpbnMgdGhpcyBvbmUgcmVmdXNlcywgb3Igd2FybnMgYWJvdXQsIHJ1bm5pbmcgYmVzaWRlLlxuICAgKlxuICAgKiBPdmVycmlkZSBpbiBzdWJjbGFzcyB0byBkZWNsYXJlIGFuIG92ZXJsYXAuIFRoZSBkZWZhdWx0IGRlY2xhcmVzIG5vbmUuXG4gICAqXG4gICAqIEEgYEJsb2NrYCBjb25mbGljdCBpcyB0aGUgbWlycm9yIGltYWdlIG9mIGEgZGVwZW5kZW5jeTogd2hpbGUgYSBjb25mbGljdGluZyBwbHVnaW4gaXMgZW5hYmxlZCBhdCBhXG4gICAqIGNvbmZsaWN0aW5nIHZlcnNpb24sIHtAbGluayBvbmxvYWRJbXBsfSBkb2VzIG5vdCBydW4gYXQgYWxsIGFuZCB0aGUgcGx1Z2luIHJlZ2lzdGVycyBub3RoaW5nLiBEZWNsYXJlXG4gICAqIGl0IHdoZW4gYm90aCBwbHVnaW5zIGFjdGluZyBvbiB0aGUgc2FtZSBvcGVyYXRpb24gZGFtYWdlcyB0aGUgdmF1bHQgXHUyMDE0IHRoZXJlIGlzIG5vIHJlbGlhYmxlIHdheSB0byB3aW5cbiAgICogdGhhdCByYWNlLCBiZWNhdXNlIHdoaWNoZXZlciBwbHVnaW4gbG9hZGVkIGZpcnN0IGtlZXBzIGEgaGFuZCBvbiB0aGUgd2hlZWwsIHNvIHJlZnVzaW5nIGRldGVybWluaXN0aWNhbGx5XG4gICAqIGJlYXRzIGNvbXBldGluZyB1bnByZWRpY3RhYmx5LiBBIGBXYXJuYCBjb25mbGljdCBkZWNsYXJlcyBhbiBvdmVybGFwIHRoYXQgaXMgbWVyZWx5IGFubm95aW5nLCBzdWNoIGFzIGFcbiAgICogZHVwbGljYXRlZCBjb21tYW5kOiBib3RoIHBsdWdpbnMga2VlcCBydW5uaW5nIGFuZCB0aGUgdXNlciBpcyB0b2xkLlxuICAgKlxuICAgKiBVbmxpa2UgYSBkZXBlbmRlbmN5LCBhIGNvbmZsaWN0aW5nIHBsdWdpbiBuZWVkIG5vdCBwdWJsaXNoIGFueXRoaW5nIFx1MjAxNCBpdCBpcyBkZXRlY3RlZCBieSByZWFkaW5nIGl0c1xuICAgKiBpbnN0YWxsZWQgdmVyc2lvbiwgd2hpY2ggaXMgdGhlIG9ubHkgdGhpbmcgYWJvdXQgYW5vdGhlciBwbHVnaW4gdGhhdCByZWFkcyB0aGUgc2FtZSByZWdhcmRsZXNzIG9mIGxvYWRcbiAgICogb3JkZXIuXG4gICAqXG4gICAqIEByZXR1cm5zIFRoZSBkZWNsYXJlZCBjb25mbGljdHMuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0UGx1Z2luQ29uZmxpY3RzKCk6IFBsdWdpbkNvbmZsaWN0W10ge1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQcm92aWRlcyB0aGUgcGx1Z2lucyB0aGlzIG9uZSBjYW5ub3Qgd29yayB3aXRob3V0LlxuICAgKlxuICAgKiBPdmVycmlkZSBpbiBzdWJjbGFzcyB0byBkZWNsYXJlIGEgbWFuZGF0b3J5IGRlcGVuZGVuY3kuIFRoZSBkZWZhdWx0IGRlY2xhcmVzIG5vbmUsIGFuZCBzdWNoIGEgcGx1Z2luXG4gICAqIGxvYWRzIGV4YWN0bHkgYXMgaXQgYWx3YXlzIGhhcy5cbiAgICpcbiAgICogQSBkZWNsYXJlZCBkZXBlbmRlbmN5IGlzIE1BTkRBVE9SWSwgdW5saWtlIHRoZSBvZmZlciBgUGx1Z2luU3VnZ2VzdGlvbkNvbXBvbmVudGAgbWFrZXM6IHdoaWxlIG9uZSBpc1xuICAgKiBtaXNzaW5nLCBkaXNhYmxlZCwgb3IgdG9vIG9sZCwge0BsaW5rIG9ubG9hZEltcGx9IGRvZXMgbm90IHJ1biBhdCBhbGwgYW5kIHRoZSBwbHVnaW4gcmVnaXN0ZXJzIG5vdGhpbmdcbiAgICogXHUyMDE0IG5vIGNvbW1hbmRzLCBubyBoYW5kbGVycywgbm8gcGF0Y2hlcy4gSXQgc3RheXMgZW5hYmxlZCBpbiBPYnNpZGlhbidzIGxpc3QgcmF0aGVyIHRoYW4gZGlzYWJsaW5nXG4gICAqIGl0c2VsZiwgYmVjYXVzZSB0aGUgZW5hYmxlZCBzZXQgaXMgdGhlIHVzZXIncyB0byBjaGFuZ2UsIGFuZCBpdCBleHBsYWlucyBpdHNlbGYgdGhyb3VnaCBhIG5vdGljZSBhbmQgYVxuICAgKiBzZXR0aW5ncyBiYW5uZXIgdGhhdCBpbnN0YWxscyB0aGUgbWlzc2luZyBwbHVnaW4gaW4gb25lIGNsaWNrLiBUaGUgbG9hZCBjb21wbGV0ZXMgdGhlIG1vbWVudCB0aGVcbiAgICogZGVwZW5kZW5jeSBhcnJpdmVzLCB3aXRoIG5vIHJlc3RhcnQuXG4gICAqXG4gICAqIEEgZGVwZW5kZW5jeSBtdXN0IHB1Ymxpc2ggYW4gQVBJIHRocm91Z2ggYHB1Ymxpc2hQbHVnaW5BcGlgLCB3aGljaCBpcyB3aGF0IG1ha2VzIGl0cyBwcmVzZW5jZSxcbiAgICogYWJzZW5jZSwgdmVyc2lvbiBhbmQgZGVwYXJ0dXJlIGFsbCBvYnNlcnZhYmxlIHRocm91Z2ggb25lIG1lY2hhbmlzbS4gQSBwbHVnaW4gd2l0aCBub3RoaW5nIHRvIGV4cG9zZVxuICAgKiBjYW4gcHVibGlzaCBhbiBlbXB0eSBBUEkgcHVyZWx5IHNvIGl0IGNhbiBiZSBkZXBlbmRlZCB1cG9uLlxuICAgKlxuICAgKiBAcmV0dXJucyBUaGUgZGVjbGFyZWQgZGVwZW5kZW5jaWVzLlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldFBsdWdpbkRlcGVuZGVuY2llcygpOiBQbHVnaW5EZXBlbmRlbmN5W10ge1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDYWxsZWQgZHVyaW5nIHtAbGluayBvbmxvYWR9IHRvIHdpcmUgcGx1Z2luLXNwZWNpZmljIGNoaWxkIGNvbXBvbmVudHMuXG4gICAqXG4gICAqIE92ZXJyaWRlIGluIHN1YmNsYXNzIHRvIGFkZCBjaGlsZCBjb21wb25lbnRzIHZpYSB7QGxpbmsgYWRkQ2hpbGR9LiBUaGUgdW5pdmVyc2FsIGNvbXBvbmVudHMgYXJlXG4gICAqIGF2YWlsYWJsZSBoZXJlLiBDaGlsZHJlbiBhcmUgbG9hZGVkIHNlcXVlbnRpYWxseSBpbiB0aGUgb3JkZXIgdGhleSBhcmUgYWRkZWQgKGNoaWxkcmVuLWZpcnN0KS5cbiAgICpcbiAgICogQHJldHVybnMgQSB7QGxpbmsgUHJvbWlzZX0gdGhhdCByZXNvbHZlcyB3aGVuIHRoZSBzdWJjbGFzcyBsb2FkIGxvZ2ljIGlzIGNvbXBsZXRlLlxuICAgKi9cbiAgcHJvdGVjdGVkIG9ubG9hZEltcGwoKTogUHJvbWlzYWJsZTx2b2lkPiB7XG4gICAgcmV0dXJuIG5vb3BBc3luYygpO1xuICB9XG5cbiAgLyoqXG4gICAqIFN0b3JlcyBhIHVuaXZlcnNhbCBjb21wb25lbnQsIHVubG9hZGluZyB3aGljaGV2ZXIgY29tcG9uZW50IHRoZSBrZXkgaGVsZCBiZWZvcmUuXG4gICAqXG4gICAqIEtleWVkIGJ5IG5hbWUgcmF0aGVyIHRoYW4gaGFuZGVkIHRoZSBwcmV2aW91cyB2YWx1ZSBiZWNhdXNlIGBrZXlvZiB0aGlzYCBleGNsdWRlcyBwcml2YXRlXG4gICAqIG1lbWJlcnMsIHNvIHRoZSBjb21wb25lbnRzIGxpdmUgaW4gYSBzaW5nbGUge0BsaW5rIFBsdWdpbkJhc2VDb21wb25lbnRzfSBiYWcgd2hvc2Uga2V5cyBBUkVcbiAgICogaW5kZXhhYmxlLlxuICAgKlxuICAgKiBAdHlwZVBhcmFtIFRLZXkgLSBUaGUga2V5IG9mIHRoZSBjb21wb25lbnQgdG8gc3RvcmUuXG4gICAqIEBwYXJhbSBrZXkgLSBUaGUga2V5IG9mIHRoZSBjb21wb25lbnQgdG8gc3RvcmUuXG4gICAqIEBwYXJhbSB2YWx1ZSAtIFRoZSBjb21wb25lbnQgdG8gc3RvcmUuXG4gICAqL1xuICAvKipcbiAgICogQWRkcyBhIGNvbXBvbmVudCB0byB0aGUgdW5pdmVyc2FsIHRpZXIsIHdoaWNoIG91dGxpdmVzIGFueSBkZXBlbmRlbmN5LlxuICAgKlxuICAgKiBQcml2YXRlIG9uIHB1cnBvc2U6IG9ubHkgdGhpcyBjbGFzcyBkZWNpZGVzIHdoYXQgaXMgdW5pdmVyc2FsLiBBIHN1YmNsYXNzIGFkZGluZyBvbmUgb2YgaXRzIG93biBnb2VzXG4gICAqIHRocm91Z2gge0BsaW5rIGFkZENoaWxkfSBhbmQgbGFuZHMgaW4gdGhlIGdhdGVkIHRpZXIsIHdoZXJlIGl0IGJlbG9uZ3MuXG4gICAqXG4gICAqIEB0eXBlUGFyYW0gVENvbXBvbmVudCAtIFRoZSB0eXBlIG9mIGNvbXBvbmVudCB0byBhZGQuXG4gICAqIEBwYXJhbSBjb21wb25lbnQgLSBUaGUgY29tcG9uZW50IGluc3RhbmNlIHRvIGFkZC5cbiAgICogQHJldHVybnMgVGhlIGFkZGVkIGNvbXBvbmVudC5cbiAgICovXG4gIHByaXZhdGUgYWRkVW5pdmVyc2FsQ2hpbGQ8VENvbXBvbmVudCBleHRlbmRzIENvbXBvbmVudD4oY29tcG9uZW50OiBUQ29tcG9uZW50KTogVENvbXBvbmVudCB7XG4gICAgcmV0dXJuIHRoaXMudW5pdmVyc2FsV3JhcHBlckNvbXBvbmVudC5hZGRDaGlsZChjb21wb25lbnQpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFubm91bmNlcyBvbiBgYXBwLndvcmtzcGFjZWAgdGhhdCB0aGlzIHBsdWdpbiBpcyBsb2FkZWQgYW5kIGl0cyBBUElzIGFyZSBjYWxsYWJsZS5cbiAgICovXG4gIHByaXZhdGUgYnJvYWRjYXN0TG9hZGVkKCk6IHZvaWQge1xuICAgIHRoaXMubGlmZWN5Y2xlRXZlbnRQYXlsb2FkID0ge1xuICAgICAgYXBpVmVyc2lvbnM6IHRoaXMuZ2V0UGx1Z2luQXBpcygpLm1hcCgoZGVjbGFyYXRpb24pID0+IGRlY2xhcmF0aW9uLmFwaVZlcnNpb24pLFxuICAgICAgZGVwZW5kZW5jeVBsdWdpbklkczogdGhpcy5nZXRQbHVnaW5EZXBlbmRlbmNpZXMoKS5tYXAoKGRlcGVuZGVuY3kpID0+IGRlcGVuZGVuY3kucGx1Z2luSWQpLFxuICAgICAgcGx1Z2luSWQ6IHRoaXMubWFuaWZlc3QuaWQsXG4gICAgICBwbHVnaW5OYW1lOiB0aGlzLm1hbmlmZXN0Lm5hbWUsXG4gICAgICBwbHVnaW5WZXJzaW9uOiB0aGlzLm1hbmlmZXN0LnZlcnNpb25cbiAgICB9O1xuXG4gICAgdHJpZ2dlclBsdWdpbkxpZmVjeWNsZUV2ZW50KHtcbiAgICAgIGFwcDogdGhpcy5hcHAsXG4gICAgICBuYW1lOiBQTFVHSU5fTE9BREVEX0VWRU5UX05BTUUsXG4gICAgICBwYXlsb2FkOiB0aGlzLmxpZmVjeWNsZUV2ZW50UGF5bG9hZFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEFubm91bmNlcyBvbiBgYXBwLndvcmtzcGFjZWAgdGhhdCB0aGlzIHBsdWdpbidzIHN1cmZhY2UgaGFzIGdvbmUgYXdheS5cbiAgICpcbiAgICogU2lsZW50IHVubGVzcyBhIGxvYWRlZCBicm9hZGNhc3QgaXMgb3V0c3RhbmRpbmcsIHNvIHRoZSB0d28gZXZlbnRzIHN0YXkgcGFpcmVkOiBhIHBsdWdpbiB0aGF0IG5ldmVyXG4gICAqIGdvdCBwYXN0IGl0cyBkZXBlbmRlbmN5IGdhdGUgbmV2ZXIgYW5ub3VuY2VkIGl0c2VsZiwgYW5kIG11c3Qgbm90IGFubm91bmNlIGEgZGVwYXJ0dXJlIGVpdGhlci5cbiAgICovXG4gIHByaXZhdGUgYnJvYWRjYXN0VW5sb2FkZWQoKTogdm9pZCB7XG4gICAgY29uc3QgcGF5bG9hZCA9IHRoaXMubGlmZWN5Y2xlRXZlbnRQYXlsb2FkO1xuICAgIGlmICghcGF5bG9hZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMubGlmZWN5Y2xlRXZlbnRQYXlsb2FkID0gbnVsbDtcbiAgICB0cmlnZ2VyUGx1Z2luTGlmZWN5Y2xlRXZlbnQoe1xuICAgICAgYXBwOiB0aGlzLmFwcCxcbiAgICAgIG5hbWU6IFBMVUdJTl9VTkxPQURFRF9FVkVOVF9OQU1FLFxuICAgICAgcGF5bG9hZFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkcyBhbmQgbG9hZHMgdGhlIHN1YmNsYXNzJ3MgZmVhdHVyZSBzdXJmYWNlLCB0aGVuIHB1Ymxpc2hlcyBpdHMgQVBJcyBhbmQgYW5ub3VuY2VzIGl0c2VsZi5cbiAgICpcbiAgICogTk9UIGlkZW1wb3RlbnQsIGRlbGliZXJhdGVseS4gYFBsdWdpbkdhdGVDb21wb25lbnRgIG93bnMgdGhlIHVwL2Rvd24gc3RhdGUgbWFjaGluZSBhbmQgY2FsbHNcbiAgICogdGhpcyBvbmx5IG9uIGEgcmVhbCB0cmFuc2l0aW9uOyBhIHNlY29uZCBndWFyZCBoZXJlIHdvdWxkIGJlIGEgc2Vjb25kIGNvcHkgb2YgdGhhdCBzdGF0ZSwgd2hpY2ggaXMgdGhlXG4gICAqIGtpbmQgb2YgZHVwbGljYXRlIHRoYXQgZHJpZnRzLlxuICAgKlxuICAgKiBAcmV0dXJucyBBIHtAbGluayBQcm9taXNlfSB0aGF0IHJlc29sdmVzIG9uY2UgdGhlIHN1cmZhY2UgaXMgbG9hZGVkIGFuZCB0aGUgYnJvYWRjYXN0IGhhcyBiZWVuIG1hZGUuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGxvYWRGZWF0dXJlU3VyZmFjZSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAvLyBMb2FkZWQgZXhwbGljaXRseSBmb3IgdGhlIHNhbWUgcmVhc29uIHRoZSB1bml2ZXJzYWwgd3JhcHBlciBpczogYGFkZENoaWxkYCBsb2FkcyBhIGNoaWxkIG9ubHkgb25jZVxuICAgIC8vIEl0cyBwYXJlbnQgaXMgbG9hZGVkLCBhbmQgdGhlIHN1cmZhY2UgaGFzIHRvIGJlIGxpdmUgYmVmb3JlIGBvbmxvYWRJbXBsYCBzdGFydHMgYWRkaW5nIHRvIGl0LlxuICAgIGNvbnN0IGdhdGVkV3JhcHBlckNvbXBvbmVudCA9IHRoaXMuZ2F0ZWRXcmFwcGVyQ29tcG9uZW50O1xuICAgIHRoaXMudW5pdmVyc2FsV3JhcHBlckNvbXBvbmVudC5hZGRDaGlsZChnYXRlZFdyYXBwZXJDb21wb25lbnQpO1xuICAgIGdhdGVkV3JhcHBlckNvbXBvbmVudC5sb2FkKCk7XG5cbiAgICBhd2FpdCB0aGlzLm9ubG9hZEltcGwoKTtcbiAgICBhd2FpdCBnYXRlZFdyYXBwZXJDb21wb25lbnQubG9hZFdpdGhQcm9taXNlcygpO1xuXG4gICAgZm9yIChjb25zdCBkZWNsYXJhdGlvbiBvZiB0aGlzLmdldFBsdWdpbkFwaXMoKSkge1xuICAgICAgcHVibGlzaFBsdWdpbkFwaSh7XG4gICAgICAgIC4uLmRlY2xhcmF0aW9uLFxuICAgICAgICAvLyBSZXZva2VkIHdpdGggdGhlIFNVUkZBQ0UsIG5vdCB3aXRoIHRoZSBwbHVnaW46IGEgcGx1Z2luIHdob3NlIGRlcGVuZGVuY3kgZ29lcyBhd2F5IGtlZXBzIHJ1bm5pbmdcbiAgICAgICAgLy8gSXRzIHVuaXZlcnNhbCBjb21wb25lbnRzLCBhbmQgYSBjb25zdW1lciBtdXN0IG5vdCBiZSBsZWZ0IGhvbGRpbmcgYSBoYW5kbGUgaW50byB0aGUgaGFsZiBvZiBpdFxuICAgICAgICAvLyBUaGF0IHdhcyBqdXN0IHRvcm4gZG93bi5cbiAgICAgICAgY29tcG9uZW50OiBnYXRlZFdyYXBwZXJDb21wb25lbnQsXG4gICAgICAgIHBsdWdpbjogdGhpc1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgdGhpcy5icm9hZGNhc3RMb2FkZWQoKTtcbiAgfVxuXG4gIHByaXZhdGUgc2V0Q29tcG9uZW50PFRLZXkgZXh0ZW5kcyBrZXlvZiBQbHVnaW5CYXNlQ29tcG9uZW50cz4oa2V5OiBUS2V5LCB2YWx1ZTogTm9uTnVsbGFibGU8UGx1Z2luQmFzZUNvbXBvbmVudHNbVEtleV0+KTogdm9pZCB7XG4gICAgY29uc3Qgb2xkQ29tcG9uZW50ID0gdGhpcy5jb21wb25lbnRzW2tleV07XG4gICAgaWYgKG9sZENvbXBvbmVudCkge1xuICAgICAgdGhpcy5yZW1vdmVDaGlsZChvbGRDb21wb25lbnQpO1xuICAgIH1cbiAgICB0aGlzLmNvbXBvbmVudHNba2V5XSA9IHZhbHVlO1xuICB9XG5cbiAgLyoqXG4gICAqIFRlYXJzIHRoZSBzdWJjbGFzcydzIGZlYXR1cmUgc3VyZmFjZSBkb3duLCBsZWF2aW5nIHRoZSB1bml2ZXJzYWwgY29tcG9uZW50cyBydW5uaW5nLlxuICAgKi9cbiAgcHJpdmF0ZSB1bmxvYWRGZWF0dXJlU3VyZmFjZSgpOiB2b2lkIHtcbiAgICBjb25zdCBnYXRlZFdyYXBwZXJDb21wb25lbnQgPSB0aGlzLmdhdGVkV3JhcHBlckNvbXBvbmVudDtcblxuICAgIC8vIFJlcGxhY2VkIEJFRk9SRSB0aGUgb2xkIG9uZSBpcyB1bmxvYWRlZCwgc28gYW55dGhpbmcgdGhhdCByZXN1bWVzIG1pZC10ZWFyZG93biBhbmQgY2FsbHMgYGFkZENoaWxkYFxuICAgIC8vIFBhcmtzIGl0cyBjaGlsZCBvbiB0aGUgZnJlc2ggc3VyZmFjZSByYXRoZXIgdGhhbiBvbiB0aGUgb25lIGJlaW5nIHRvcm4gZG93biBcdTIwMTQgd2hlcmUgYENvbXBvbmVudEV4YFxuICAgIC8vIFdvdWxkIHJlZnVzZSBpdCBvdXRyaWdodCwgc2luY2UgaXQgcmVmdXNlcyBjaGlsZHJlbiBhZGRlZCB0byBhbiBhbHJlYWR5LXVubG9hZGVkIGNvbXBvbmVudC5cbiAgICB0aGlzLmdhdGVkV3JhcHBlckNvbXBvbmVudCA9IG5ldyBDb21wb25lbnRFeCgpO1xuICAgIHRoaXMudW5pdmVyc2FsV3JhcHBlckNvbXBvbmVudC5yZW1vdmVDaGlsZChnYXRlZFdyYXBwZXJDb21wb25lbnQpO1xuXG4gICAgdGhpcy5icm9hZGNhc3RVbmxvYWRlZCgpO1xuICB9XG59XG5cbi8qKlxuICogUmVsb2FkcyB0aGUgc3BlY2lmaWVkIHBsdWdpbiBieSBkaXNhYmxpbmcgYW5kIHRoZW4gcmUtZW5hYmxpbmcgaXQuXG4gKlxuICogQHBhcmFtIHBsdWdpbiAtIFRoZSBwbHVnaW4gdG8gcmVsb2FkLlxuICogQHJldHVybnMgQSB7QGxpbmsgUHJvbWlzZX0gdGhhdCByZXNvbHZlcyB3aGVuIHRoZSBwbHVnaW4gaXMgcmVsb2FkZWQuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByZWxvYWRQbHVnaW4ocGx1Z2luOiBQbHVnaW4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgcGx1Z2lucyA9IHBsdWdpbi5hcHAucGx1Z2lucztcbiAgY29uc3QgcGx1Z2luSWQgPSBwbHVnaW4ubWFuaWZlc3QuaWQ7XG4gIGF3YWl0IHBsdWdpbnMuZGlzYWJsZVBsdWdpbihwbHVnaW5JZCk7XG4gIGF3YWl0IHBsdWdpbnMuZW5hYmxlUGx1Z2luKHBsdWdpbklkKTtcbn1cblxuLyoqXG4gKiBEaXNwbGF5cyBhbiBlcnJvciBtZXNzYWdlIGFzIGEgbm90aWNlLCBsb2dzIGl0IHRvIHRoZSBjb25zb2xlLCBhbmQgZGlzYWJsZXMgdGhlIHNwZWNpZmllZCBwbHVnaW4uXG4gKlxuICogQHBhcmFtIHBsdWdpbiAtIFRoZSBwbHVnaW4gdG8gZGlzYWJsZS5cbiAqIEBwYXJhbSBtZXNzYWdlIC0gVGhlIGVycm9yIG1lc3NhZ2UgdG8gZGlzcGxheSBhbmQgbG9nLlxuICogQHJldHVybnMgQSB7QGxpbmsgUHJvbWlzZX0gdGhhdCByZXNvbHZlcyB3aGVuIHRoZSBwbHVnaW4gaXMgZGlzYWJsZWQuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBzaG93RXJyb3JBbmREaXNhYmxlUGx1Z2luKHBsdWdpbjogUGx1Z2luLCBtZXNzYWdlOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgcGx1Z2luTm90aWNlQ29tcG9uZW50ID0gbmV3IFBsdWdpbk5vdGljZUNvbXBvbmVudCh7XG4gICAgYXBwOiBwbHVnaW4uYXBwLFxuICAgIHBsdWdpbk5hbWU6IHBsdWdpbi5tYW5pZmVzdC5uYW1lXG4gIH0pO1xuICBwbHVnaW5Ob3RpY2VDb21wb25lbnQuc2hvd05vdGljZShtZXNzYWdlKTtcbiAgcHJpbnRFcnJvcihuZXcgRXJyb3IobWVzc2FnZSkpO1xuICBhd2FpdCBwbHVnaW4uYXBwLnBsdWdpbnMuZGlzYWJsZVBsdWdpbihwbHVnaW4ubWFuaWZlc3QuaWQpO1xufVxuIl0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7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