ng-miam 6.4.13 → 7.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (208) hide show
  1. package/bundles/ng-miam.umd.js +8539 -10855
  2. package/bundles/ng-miam.umd.js.map +1 -1
  3. package/bundles/ng-miam.umd.min.js +2 -2
  4. package/bundles/ng-miam.umd.min.js.map +1 -1
  5. package/esm2015/lib/_components/abstracts/event-tracer.component.js +3 -2
  6. package/esm2015/lib/_components/accordion/accordion.component.js +75 -0
  7. package/esm2015/lib/_components/components.module.js +27 -21
  8. package/esm2015/lib/_components/counter-input/counter-input.component.js +86 -76
  9. package/esm2015/lib/_components/icon/icon.component.js +1 -1
  10. package/esm2015/lib/_components/index.js +5 -5
  11. package/esm2015/lib/_components/like-button/like-button.component.js +1 -1
  12. package/esm2015/lib/_components/list-input/list-input.component.js +5 -5
  13. package/esm2015/lib/_components/loader/loader.component.js +1 -1
  14. package/esm2015/lib/_components/meals-planner-link/meals-planner-link.component.js +3 -3
  15. package/esm2015/lib/_components/modal/modal.component.js +155 -137
  16. package/esm2015/lib/_components/product-card/product-card.component.js +333 -0
  17. package/esm2015/lib/_components/products-picker/products-picker.component.js +155 -0
  18. package/esm2015/lib/_components/progress-tracker/progress-tracker.component.js +1 -1
  19. package/esm2015/lib/_components/recipe-filters/recipe-filters.component.js +166 -217
  20. package/esm2015/lib/_components/recipe-pricing/recipe-pricing.component.js +55 -35
  21. package/esm2015/lib/_components/slider-tabs/slider-tabs.component.js +84 -0
  22. package/esm2015/lib/_components/sponsor-blocks/sponsor-image-and-text-block/sponsor-image-and-text-block.component.js +1 -1
  23. package/esm2015/lib/_components/sponsor-blocks/sponsor-text-and-image-block/sponsor-text-and-image-block.component.js +1 -1
  24. package/esm2015/lib/_components/tabs/tabs.component.js +48 -88
  25. package/esm2015/lib/_components/toaster/toaster.component.js +48 -84
  26. package/esm2015/lib/_components/tooltipable-content/tooltipable-content.component.js +1 -1
  27. package/esm2015/lib/_models/basket-entry.js +33 -49
  28. package/esm2015/lib/_models/basket-preview-line.js +5 -5
  29. package/esm2015/lib/_models/basket.js +15 -12
  30. package/esm2015/lib/_models/item.js +2 -2
  31. package/esm2015/lib/_models/recipe.js +2 -15
  32. package/esm2015/lib/_models/user.js +1 -1
  33. package/esm2015/lib/_services/analytics.service.js +24 -5
  34. package/esm2015/lib/_services/baskets-synchronizing/baskets-comparator.service.js +1 -10
  35. package/esm2015/lib/_services/baskets-synchronizing/baskets-synchronizer.service.js +15 -15
  36. package/esm2015/lib/_services/baskets.service.js +478 -60
  37. package/esm2015/lib/_services/context.service.js +22 -35
  38. package/esm2015/lib/_services/index.js +3 -5
  39. package/esm2015/lib/_services/interceptor.service.js +2 -2
  40. package/esm2015/lib/_services/items.service.js +27 -4
  41. package/esm2015/lib/_services/recipe-details.service.js +198 -0
  42. package/esm2015/lib/_services/recipe-likes.service.js +1 -1
  43. package/esm2015/lib/_services/recipes.service.js +24 -53
  44. package/esm2015/lib/_services/scrolling.service.js +17 -0
  45. package/esm2015/lib/_services/toaster.service.js +4 -5
  46. package/esm2015/lib/_services/user.service.js +2 -2
  47. package/esm2015/lib/_types/basket-action-type.enum.js +11 -0
  48. package/esm2015/lib/_types/basket-action.js +2 -0
  49. package/esm2015/lib/_types/basket-stats.js +2 -0
  50. package/esm2015/lib/_types/builded/miam-interface.js +1 -1
  51. package/esm2015/lib/_types/event-trace.js +5 -0
  52. package/esm2015/lib/_types/items-comparator.js +1 -10
  53. package/esm2015/lib/_types/recipe-filters.js +1 -1
  54. package/esm2015/lib/_types/toaster.js +1 -1
  55. package/esm2015/lib/_utils/directives/index.js +2 -1
  56. package/esm2015/lib/_utils/directives/reach-top.directive.js +33 -0
  57. package/esm2015/lib/_utils/pipes/readable-float-number/readable-float-number.pipe.js +8 -2
  58. package/esm2015/lib/_utils/utils.module.js +12 -8
  59. package/esm2015/lib/_web-components/basket-preview/basket-preview-block/basket-preview-block.component.js +140 -118
  60. package/esm2015/lib/_web-components/basket-preview/basket-preview-disabled/basket-preview-disabled.component.js +2 -2
  61. package/esm2015/lib/_web-components/basket-preview/basket-preview-line/basket-preview-line.component.js +125 -444
  62. package/esm2015/lib/_web-components/basket-preview/replace-item/replace-item.component.js +211 -108
  63. package/esm2015/lib/_web-components/index.js +1 -4
  64. package/esm2015/lib/_web-components/list-scan/basket-preview/basket-preview.component.js +11 -14
  65. package/esm2015/lib/_web-components/list-scan/files-inputs/files-inputs.component.js +13 -13
  66. package/esm2015/lib/_web-components/list-scan/ingredients-list/ingredients-list.component.js +6 -6
  67. package/esm2015/lib/_web-components/list-scan/list-scan.component.js +10 -10
  68. package/esm2015/lib/_web-components/list-scan/overlay-button/overlay-button.component.js +23 -11
  69. package/esm2015/lib/_web-components/meals-planner/meals-planner-basket-confirmation/meals-planner-basket-confirmation.component.js +1 -1
  70. package/esm2015/lib/_web-components/meals-planner/meals-planner-catalog/meals-planner-catalog.component.js +1 -1
  71. package/esm2015/lib/_web-components/meals-planner/meals-planner-form/meals-planner-form.component.js +7 -7
  72. package/esm2015/lib/_web-components/meals-planner/meals-planner-result/meals-planner-result.component.js +5 -5
  73. package/esm2015/lib/_web-components/meals-planner/meals-planner.component.js +16 -20
  74. package/esm2015/lib/_web-components/planner-side-menu/planner-side-menu.component.js +4 -53
  75. package/esm2015/lib/_web-components/recipe-cards/add-recipe-card/add-recipe-card.component.js +1 -1
  76. package/esm2015/lib/_web-components/recipe-cards/index.js +1 -3
  77. package/esm2015/lib/_web-components/recipe-cards/recipe-card/recipe-card.component.js +326 -404
  78. package/esm2015/lib/_web-components/recipe-cards/recipe-card-cta/recipe-card-cta.component.js +50 -146
  79. package/esm2015/lib/_web-components/recipe-cards/recipe-cards.module.js +3 -15
  80. package/esm2015/lib/_web-components/recipe-catalog/catalog-article-card/catalog-article-card.component.js +1 -1
  81. package/esm2015/lib/_web-components/recipe-catalog/catalog-category/catalog-category.component.js +35 -29
  82. package/esm2015/lib/_web-components/recipe-catalog/catalog-header/catalog-header.component.js +1 -1
  83. package/esm2015/lib/_web-components/recipe-catalog/catalog-list/catalog-list.component.js +27 -31
  84. package/esm2015/lib/_web-components/recipe-catalog/recipe-catalog.component.js +98 -100
  85. package/esm2015/lib/_web-components/recipe-creation/recipe-form/recipe-form.component.js +2 -2
  86. package/esm2015/lib/_web-components/recipe-creation/recipe-stepper/recipe-stepper.component.js +7 -7
  87. package/esm2015/lib/_web-components/recipe-creation/tags-creator/tags-creator.component.js +4 -4
  88. package/esm2015/lib/_web-components/recipe-creation/tags-selector/tags-selector.component.js +8 -8
  89. package/esm2015/lib/_web-components/recipe-details/recipe-addon/recipe-addon.component.js +7 -3
  90. package/esm2015/lib/_web-components/recipe-details/recipe-details-infos/recipe-details-infos.component.js +57 -358
  91. package/esm2015/lib/_web-components/recipe-details/recipe-details-ingredients/recipe-details-ingredients.component.js +59 -122
  92. package/esm2015/lib/_web-components/recipe-details/recipe-details-steps/recipe-details-steps.component.js +51 -72
  93. package/esm2015/lib/_web-components/recipe-details/recipe-details.component.js +313 -363
  94. package/esm2015/lib/_web-components/recipe-details/recipe-details.module.js +8 -4
  95. package/esm2015/lib/_web-components/recipe-details/sponsor-storytelling/sponsor-storytelling.component.js +1 -1
  96. package/esm2015/lib/_web-components/recipe-helper/recipe-helper.component.js +89 -113
  97. package/esm2015/lib/_web-components/recipe-modal/recipe-modal.component.js +78 -69
  98. package/esm2015/lib/_web-components/recipe-tags/recipe-tags.component.js +5 -5
  99. package/esm2015/lib/_web-components/toaster-stack/toaster-stack.component.js +8 -4
  100. package/esm2015/lib/_web-components/web-components.module.js +3 -19
  101. package/esm2015/lib/ng-miam.module.js +5 -7
  102. package/fesm2015/ng-miam.js +5165 -6973
  103. package/fesm2015/ng-miam.js.map +1 -1
  104. package/lib/_components/abstracts/event-tracer.component.d.ts +2 -1
  105. package/lib/_components/accordion/accordion.component.d.ts +23 -0
  106. package/lib/_components/components.module.d.ts +38 -36
  107. package/lib/_components/counter-input/counter-input.component.d.ts +12 -14
  108. package/lib/_components/index.d.ts +4 -4
  109. package/lib/_components/modal/modal.component.d.ts +18 -18
  110. package/lib/_components/product-card/product-card.component.d.ts +40 -0
  111. package/lib/_components/products-picker/products-picker.component.d.ts +17 -0
  112. package/lib/_components/recipe-pricing/recipe-pricing.component.d.ts +12 -8
  113. package/lib/_components/slider-tabs/slider-tabs.component.d.ts +16 -0
  114. package/lib/_components/tabs/tabs.component.d.ts +11 -11
  115. package/lib/_components/toaster/toaster.component.d.ts +4 -2
  116. package/lib/_models/basket-entry.d.ts +16 -20
  117. package/lib/_models/basket-preview-line.d.ts +1 -0
  118. package/lib/_models/basket.d.ts +12 -5
  119. package/lib/_models/item.d.ts +1 -1
  120. package/lib/_models/recipe.d.ts +0 -5
  121. package/lib/_models/user.d.ts +0 -1
  122. package/lib/_services/analytics.service.d.ts +8 -22
  123. package/lib/_services/baskets-synchronizing/baskets-comparator.service.d.ts +0 -5
  124. package/lib/_services/baskets-synchronizing/baskets-synchronizer.service.d.ts +3 -6
  125. package/lib/_services/baskets.service.d.ts +137 -18
  126. package/lib/_services/context.service.d.ts +2 -4
  127. package/lib/_services/index.d.ts +2 -4
  128. package/lib/_services/items.service.d.ts +9 -2
  129. package/lib/_services/recipe-details.service.d.ts +84 -0
  130. package/lib/_services/recipe-likes.service.d.ts +2 -1
  131. package/lib/_services/recipes.service.d.ts +10 -14
  132. package/lib/_services/scrolling.service.d.ts +8 -0
  133. package/lib/_services/toaster.service.d.ts +1 -1
  134. package/lib/_types/basket-action-type.enum.d.ts +9 -0
  135. package/lib/_types/basket-action.d.ts +14 -0
  136. package/lib/_types/basket-stats.d.ts +5 -0
  137. package/lib/_types/builded/miam-interface.d.ts +16 -25
  138. package/lib/_types/event-trace.d.ts +22 -0
  139. package/lib/_types/items-comparator.d.ts +0 -5
  140. package/lib/_types/recipe-filters.d.ts +0 -2
  141. package/lib/_types/toaster.d.ts +1 -1
  142. package/lib/_utils/directives/index.d.ts +1 -0
  143. package/lib/_utils/directives/reach-top.directive.d.ts +13 -0
  144. package/lib/_utils/pipes/readable-float-number/readable-float-number.pipe.d.ts +1 -1
  145. package/lib/_utils/utils.module.d.ts +2 -2
  146. package/lib/_web-components/basket-preview/basket-preview-block/basket-preview-block.component.d.ts +9 -8
  147. package/lib/_web-components/basket-preview/basket-preview-line/basket-preview-line.component.d.ts +11 -9
  148. package/lib/_web-components/basket-preview/replace-item/replace-item.component.d.ts +27 -20
  149. package/lib/_web-components/index.d.ts +0 -3
  150. package/lib/_web-components/list-scan/basket-preview/basket-preview.component.d.ts +1 -2
  151. package/lib/_web-components/list-scan/files-inputs/files-inputs.component.d.ts +6 -5
  152. package/lib/_web-components/list-scan/ingredients-list/ingredients-list.component.d.ts +3 -3
  153. package/lib/_web-components/list-scan/list-scan.component.d.ts +3 -3
  154. package/lib/_web-components/list-scan/overlay-button/overlay-button.component.d.ts +8 -6
  155. package/lib/_web-components/meals-planner/meals-planner.component.d.ts +2 -3
  156. package/lib/_web-components/recipe-cards/index.d.ts +0 -2
  157. package/lib/_web-components/recipe-cards/recipe-card/recipe-card.component.d.ts +58 -17
  158. package/lib/_web-components/recipe-cards/recipe-card-cta/recipe-card-cta.component.d.ts +5 -12
  159. package/lib/_web-components/recipe-cards/recipe-cards.module.d.ts +7 -9
  160. package/lib/_web-components/recipe-catalog/catalog-category/catalog-category.component.d.ts +8 -6
  161. package/lib/_web-components/recipe-catalog/catalog-list/catalog-list.component.d.ts +7 -4
  162. package/lib/_web-components/recipe-catalog/recipe-catalog.component.d.ts +2 -3
  163. package/lib/_web-components/recipe-details/recipe-addon/recipe-addon.component.d.ts +5 -2
  164. package/lib/_web-components/recipe-details/recipe-details-infos/recipe-details-infos.component.d.ts +6 -18
  165. package/lib/_web-components/recipe-details/recipe-details-ingredients/recipe-details-ingredients.component.d.ts +6 -13
  166. package/lib/_web-components/recipe-details/recipe-details-steps/recipe-details-steps.component.d.ts +2 -10
  167. package/lib/_web-components/recipe-details/recipe-details.component.d.ts +29 -36
  168. package/lib/_web-components/recipe-details/recipe-details.module.d.ts +2 -1
  169. package/lib/_web-components/recipe-helper/recipe-helper.component.d.ts +2 -6
  170. package/lib/_web-components/recipe-modal/recipe-modal.component.d.ts +11 -9
  171. package/lib/_web-components/toaster-stack/toaster-stack.component.d.ts +5 -2
  172. package/lib/_web-components/web-components.module.d.ts +23 -29
  173. package/miam-style.css +1 -1
  174. package/package.json +1 -1
  175. package/esm2015/lib/_components/abstracts/abstract-recipe-card.component.js +0 -130
  176. package/esm2015/lib/_components/skeleton/skeleton.component.js +0 -70
  177. package/esm2015/lib/_components/tabs/tab-body.component.js +0 -30
  178. package/esm2015/lib/_components/tabs/tab-item.component.js +0 -36
  179. package/esm2015/lib/_components/tabs/tab-label.component.js +0 -30
  180. package/esm2015/lib/_models/groceries-entry.js +0 -42
  181. package/esm2015/lib/_models/groceries-list.js +0 -36
  182. package/esm2015/lib/_services/counter.service.js +0 -20
  183. package/esm2015/lib/_services/groceries-entries.service.js +0 -21
  184. package/esm2015/lib/_services/groceries-lists.service.js +0 -240
  185. package/esm2015/lib/_services/recipe-events.service.js +0 -63
  186. package/esm2015/lib/_types/skeleton.enum.js +0 -7
  187. package/esm2015/lib/_web-components/drawer/drawer.component.js +0 -273
  188. package/esm2015/lib/_web-components/pos-card/pos-card.component.js +0 -207
  189. package/esm2015/lib/_web-components/pos-selection/pos-selection.component.js +0 -283
  190. package/esm2015/lib/_web-components/recipe-cards/catalog-recipe-card/catalog-recipe-card.component.js +0 -632
  191. package/esm2015/lib/_web-components/recipe-cards/suggestion-card/suggestion-card.component.js +0 -144
  192. package/lib/_components/abstracts/abstract-recipe-card.component.d.ts +0 -49
  193. package/lib/_components/skeleton/skeleton.component.d.ts +0 -11
  194. package/lib/_components/tabs/tab-body.component.d.ts +0 -8
  195. package/lib/_components/tabs/tab-item.component.d.ts +0 -11
  196. package/lib/_components/tabs/tab-label.component.d.ts +0 -8
  197. package/lib/_models/groceries-entry.d.ts +0 -20
  198. package/lib/_models/groceries-list.d.ts +0 -30
  199. package/lib/_services/counter.service.d.ts +0 -10
  200. package/lib/_services/groceries-entries.service.d.ts +0 -10
  201. package/lib/_services/groceries-lists.service.d.ts +0 -68
  202. package/lib/_services/recipe-events.service.d.ts +0 -23
  203. package/lib/_types/skeleton.enum.d.ts +0 -5
  204. package/lib/_web-components/drawer/drawer.component.d.ts +0 -37
  205. package/lib/_web-components/pos-card/pos-card.component.d.ts +0 -24
  206. package/lib/_web-components/pos-selection/pos-selection.component.d.ts +0 -38
  207. package/lib/_web-components/recipe-cards/catalog-recipe-card/catalog-recipe-card.component.d.ts +0 -49
  208. package/lib/_web-components/recipe-cards/suggestion-card/suggestion-card.component.d.ts +0 -42
@@ -1,36 +1,40 @@
1
1
  import { HttpClient } from '@angular/common/http';
2
2
  import { Injectable } from '@angular/core';
3
- import { unionBy, flatten } from 'lodash-es';
3
+ import { flatten, unionBy } from 'lodash-es';
4
4
  import { Service } from 'ngx-jsonapi';
5
- import { BehaviorSubject, combineLatest, forkJoin, of } from 'rxjs';
6
- import { skipWhile, switchMap, tap, map, take } from 'rxjs/operators';
7
- import { Basket } from '../_models/basket';
8
- import { BasketPreviewLine } from '../_models/basket-preview-line';
5
+ import { BehaviorSubject, forkJoin, of } from 'rxjs';
6
+ import { debounceTime, map, skipWhile, switchMap, take, tap } from 'rxjs/operators';
7
+ import { Basket, BasketPreviewLine } from '../_models';
8
+ import { BasketActionType } from '../_types/basket-action-type.enum';
9
+ import { MessageType } from '../_types/message-type.enum';
9
10
  import { environment as e } from '../environments/environment';
10
11
  import { AnalyticsService } from './analytics.service';
11
12
  import { BasketEntriesService } from './basket-entries.service';
12
- import { GroceriesEntriesService } from './groceries-entries.service';
13
- import { GroceriesListsService } from './groceries-lists.service';
14
13
  import { PointOfSalesService } from './point-of-sales.service';
15
14
  import { RecipesService } from './recipes.service';
15
+ import { ToasterService } from './toaster.service';
16
+ import { UserService } from './user.service';
16
17
  import * as i0 from "@angular/core";
17
18
  import * as i1 from "@angular/common/http";
18
19
  import * as i2 from "./basket-entries.service";
19
- import * as i3 from "./groceries-lists.service";
20
- import * as i4 from "./groceries-entries.service";
21
- import * as i5 from "./point-of-sales.service";
22
- import * as i6 from "./recipes.service";
23
- import * as i7 from "./analytics.service";
20
+ import * as i3 from "./point-of-sales.service";
21
+ import * as i4 from "./recipes.service";
22
+ import * as i5 from "./analytics.service";
23
+ import * as i6 from "./user.service";
24
+ import * as i7 from "./toaster.service";
25
+ const BASKET_SPARSE_FIELDS = {
26
+ baskets: ['total-price', 'pricebook-key', 'recipes-infos', 'completion']
27
+ };
24
28
  export class BasketsService extends Service {
25
- constructor(http, basketEntriesService, listsService, groceriesEntriesService, posService, recipesService, analyticsService) {
29
+ constructor(http, basketEntriesService, posService, recipesService, analyticsService, usersService, toasterService) {
26
30
  super();
27
31
  this.http = http;
28
32
  this.basketEntriesService = basketEntriesService;
29
- this.listsService = listsService;
30
- this.groceriesEntriesService = groceriesEntriesService;
31
33
  this.posService = posService;
32
34
  this.recipesService = recipesService;
33
35
  this.analyticsService = analyticsService;
36
+ this.usersService = usersService;
37
+ this.toasterService = toasterService;
34
38
  this.resource = Basket;
35
39
  this.type = 'baskets';
36
40
  this._basket$ = new BehaviorSubject(null);
@@ -39,9 +43,18 @@ export class BasketsService extends Service {
39
43
  this.basketIsFetching = false;
40
44
  this.basketPreviewIsCalculating = false;
41
45
  this.basketInitCalled = false;
46
+ this.basketActionsQueue = new BehaviorSubject([]);
42
47
  this._entries$ = new BehaviorSubject([]);
48
+ this.actionsBeingProcessed = new BehaviorSubject([]);
49
+ this.actionsBeingOverriden = [];
50
+ this.subscriptions = [];
43
51
  this.register();
52
+ this.subscriptions.push(this.basketActionsQueue.pipe(debounceTime(200), skipWhile(actions => actions.length === 0 || this.actionsBeingProcessed.value.length > 0), tap(() => this.emptyActionsQueue())).subscribe());
53
+ if (this.recipesService.confirmationToaster) {
54
+ this.showRecipeAddedToaster();
55
+ }
44
56
  }
57
+ /** ************************************************************ GETTERS ************************************************************ **/
45
58
  /**
46
59
  * We want basket$ to be a singleton that always returns the same basket, so it is fetched only when necessary.
47
60
  * At any point in time the basket can be fetched via the initBasket function (if we want to fetch it on startup to save time later)
@@ -65,19 +78,82 @@ export class BasketsService extends Service {
65
78
  }
66
79
  return this._basketPreview$;
67
80
  }
68
- // Fetch related baskets, filtering on a point of sale
69
- fetchForListAndPos(listId, posId) {
70
- if (!listId || !posId) {
71
- return of(null);
72
- }
73
- let url = [e.miamAPI, 'api/v1/groceries-lists', listId, 'baskets'].join('/');
74
- url = `${url}?filter[point_of_sale_id]=${posId}`;
75
- return this.http.get(url).pipe(skipWhile((resp) => resp.is_loading), map((resp) => {
76
- const baskets = this.newCollection();
77
- baskets.fill(resp);
78
- return baskets.data[0];
81
+ /**
82
+ * To use when needing to be sure that basket was fetched before doing an action that doesn't need to stay subscribed to basket$
83
+ * This method is meant to be an equivalent of basket$.value but asynchronous
84
+ */
85
+ get waitForBasket() {
86
+ return this.basket$.pipe(skipWhile(b => !b), take(1));
87
+ }
88
+ /** ************************************** QUEUE UTILS TO LOCK MORE ACTIONS OR DISPLAY LOADERS ************************************** **/
89
+ // Util method to avoid repeating too much for the next 6 methods
90
+ subjectContainsRecipeId(subject, type, recipeId) {
91
+ return subject.pipe(map(value => value.some(a => a.type === type && a.params.recipeId === recipeId)));
92
+ }
93
+ // Util method to avoid repeating too much for the next 6 methods
94
+ subjectContainsIngredientId(subject, type, ingredientId) {
95
+ return subject.pipe(map(value => value.some(a => a.type === type && a.params.ingredientId === ingredientId)));
96
+ }
97
+ recipeWillBeAdded(recipeId) {
98
+ return this.subjectContainsRecipeId(this.basketActionsQueue, BasketActionType.ADD_RECIPE, recipeId);
99
+ }
100
+ recipeWillBeRemoved(recipeId) {
101
+ return this.subjectContainsRecipeId(this.basketActionsQueue, BasketActionType.REMOVE_RECIPE, recipeId);
102
+ }
103
+ recipeWillBeUpdated(recipeId) {
104
+ return this.subjectContainsRecipeId(this.basketActionsQueue, BasketActionType.UPDATE_RECIPE, recipeId);
105
+ }
106
+ recipeIsBeingAdded(recipeId) {
107
+ return this.subjectContainsRecipeId(this.actionsBeingProcessed, BasketActionType.ADD_RECIPE, recipeId);
108
+ }
109
+ recipeIsBeingRemoved(recipeId) {
110
+ return this.subjectContainsRecipeId(this.actionsBeingProcessed, BasketActionType.REMOVE_RECIPE, recipeId);
111
+ }
112
+ recipeIsBeingUpdated(recipeId) {
113
+ return this.subjectContainsRecipeId(this.actionsBeingProcessed, BasketActionType.UPDATE_RECIPE, recipeId);
114
+ }
115
+ ingredientWillBeAdded(ingredientId) {
116
+ return this.subjectContainsIngredientId(this.basketActionsQueue, BasketActionType.ADD_PRODUCT, ingredientId);
117
+ }
118
+ ingredientWillBeRemoved(ingredientId) {
119
+ return this.subjectContainsIngredientId(this.basketActionsQueue, BasketActionType.REMOVE_PRODUCT, ingredientId);
120
+ }
121
+ recipesWillBeAdded() {
122
+ return this.basketActionsQueue.pipe(map(queue => queue.some(a => a.type === BasketActionType.ADD_RECIPE)));
123
+ }
124
+ recipesWillBeRemoved() {
125
+ return this.basketActionsQueue.pipe(map(queue => queue.some(a => a.type === BasketActionType.REMOVE_RECIPE)));
126
+ }
127
+ recipesWillBeUpdated() {
128
+ return this.basketActionsQueue.pipe(map(queue => queue.some(a => a.type === BasketActionType.UPDATE_RECIPE)));
129
+ }
130
+ productsWillBeAdded() {
131
+ return this.basketActionsQueue.pipe(map(queue => queue.filter(a => a.type === BasketActionType.ADD_PRODUCT).length));
132
+ }
133
+ /** ************************************************************* UTILS ************************************************************* **/
134
+ // Check if the recipeId is in the Basket's recipes-infos
135
+ recipeIsInBasket(recipeId) {
136
+ return this.basket$.pipe(skipWhile(b => !b), map(basket => basket.hasRecipe(recipeId)));
137
+ }
138
+ guestsForRecipe(recipeId) {
139
+ var _a;
140
+ return (_a = this.basket$.value) === null || _a === void 0 ? void 0 : _a.guestsForRecipe(recipeId);
141
+ }
142
+ showRecipeAddedToaster() {
143
+ let previousNumberOfProductToAdd = 0;
144
+ this.subscriptions.push(this.productsWillBeAdded().pipe(skipWhile(number => previousNumberOfProductToAdd === number)).subscribe(number => {
145
+ if (previousNumberOfProductToAdd > number) {
146
+ const article = previousNumberOfProductToAdd - number === 1 ? 'article ajouté' : 'articles ajoutés';
147
+ const msg = `${previousNumberOfProductToAdd - number} ${article} à votre panier`;
148
+ this.toasterService.show(MessageType.Success, msg, '', false);
149
+ }
150
+ previousNumberOfProductToAdd = number;
79
151
  }));
80
152
  }
153
+ /** ***************************************************** LOAD / RELOAD / RESET ***************************************************** **/
154
+ reloadBasket() {
155
+ return this.refreshCurrentBasket().pipe(take(1));
156
+ }
81
157
  initBasket() {
82
158
  if (!this.basketInitCalled) {
83
159
  this.basketInitCalled = true;
@@ -85,21 +161,39 @@ export class BasketsService extends Service {
85
161
  this.loadPreview().subscribe();
86
162
  }
87
163
  }
88
- reloadBasket() {
89
- return this.loadBasket().pipe(take(1));
164
+ refreshCurrentBasket() {
165
+ return this.posService.pos$.pipe(skipWhile(pos => !pos), take(1), switchMap(pos => {
166
+ console.log('[Miam] refreshing basket');
167
+ const cachedBasketId = localStorage.getItem('_miam/basketId');
168
+ const baseRoute = 'current?point_of_sale_id=' + pos.id;
169
+ const endpoint = ((cachedBasketId === null || cachedBasketId === void 0 ? void 0 : cachedBasketId.toString().match(/^[0-9]+$/)) ? baseRoute + '&merge_with=' + cachedBasketId : baseRoute) +
170
+ `&fields[baskets]=${BASKET_SPARSE_FIELDS.baskets.join(',')}`;
171
+ // Cancel last subscription before starting another one
172
+ if (this.currentSubscription) {
173
+ this.currentSubscription.unsubscribe();
174
+ }
175
+ this.currentSubscription = this.get(endpoint).pipe(skipWhile(basket => basket.is_loading), switchMap(basket => this.updateLocalBasket(basket))).subscribe();
176
+ return this._basket$;
177
+ }));
90
178
  }
179
+ resetBasket(eventTrace = { originPath: '', props: {} }) {
180
+ console.log('[Miam] resetting basket');
181
+ this.analyticsService.sendEventWhenReady(this.analyticsService.EVENT_RECIPE_RESET, eventTrace.originPath, eventTrace.props);
182
+ return this.posService.pos$.pipe(skipWhile(pos => !pos), take(1), switchMap(pos => this.waitForBasket.pipe(tap(basket => this.analyticsService.sendEventsOfResetBasket(basket, eventTrace)), switchMap(() => this.get(`reset?point_of_sale_id=${pos.id}&fields[baskets]=${BASKET_SPARSE_FIELDS.baskets.join(',')}`).pipe(skipWhile(basket => basket.is_loading), switchMap(basket => this.updateLocalBasket(basket)))))));
183
+ }
184
+ /** ********************************************************* CONFIRM BASKET ********************************************************* **/
91
185
  // Set basket as confirmed, and returns only once the new current list is returned
92
186
  confirmBasket(totalPrice) {
93
187
  let confirmedBasket;
94
188
  console.log(`[Miam] Confirm basket ${JSON.stringify(confirmedBasket)}`);
95
- return this.basket$.pipe(skipWhile(b => !b), take(1), tap(basket => {
189
+ return this.waitForBasket.pipe(tap(basket => {
96
190
  if (basket.totalPrice > 0) {
97
191
  this.analyticsService.sendEventWhenReady(this.analyticsService.EVENT_PAYMENT_CONFIRMED, null, this.eventProps(basket, totalPrice));
98
192
  }
99
193
  }), switchMap(basket => {
100
194
  console.log('[Miam] Save basket with confirmed=true');
101
195
  basket.attributes.confirmed = true;
102
- return basket.save();
196
+ return basket.save({ fields: { baskets: [...BASKET_SPARSE_FIELDS.baskets, ...['token']] } });
103
197
  }), switchMap((resp) => {
104
198
  confirmedBasket = this.new();
105
199
  confirmedBasket.fill(resp);
@@ -108,7 +202,7 @@ export class BasketsService extends Service {
108
202
  this.analyticsService.sendEventWhenReady(this.analyticsService.EVENT_BASKET_CONFIRMED, null, this.eventProps(confirmedBasket, totalPrice));
109
203
  }
110
204
  this._basket$.next(undefined);
111
- return this.listsService.resetList();
205
+ return this.resetBasket();
112
206
  }), switchMap(() => this._basket$), skipWhile(b => !b), map(() => confirmedBasket));
113
207
  }
114
208
  eventProps(basket, totalPrice) {
@@ -121,11 +215,12 @@ export class BasketsService extends Service {
121
215
  total_amount: totalPrice
122
216
  };
123
217
  }
218
+ /** ******************************************************* ACTIONS ON ENTRIES ******************************************************* **/
124
219
  basketEntries() {
125
220
  return this._entries$;
126
221
  }
127
222
  activeBasketEntries() {
128
- return this.basketEntries().pipe(map((entries) => entries.filter(entry => entry.groceriesEntryStatus === 'active')));
223
+ return this.basketEntries().pipe(map((entries) => entries.filter(entry => entry.status === 'active')));
129
224
  }
130
225
  // Decrease quantity on a list of basket entries
131
226
  // If the quantity goes below 1, the corresponding groceries entry's status gets deleted
@@ -146,39 +241,363 @@ export class BasketsService extends Service {
146
241
  }
147
242
  else {
148
243
  basketEntry.quantity = 1;
149
- basketEntry.groceriesEntry.status = 'deleted';
150
- return forkJoin([basketEntry.save(), basketEntry.groceriesEntry.save()]);
244
+ basketEntry.status = 'deleted';
245
+ return forkJoin([basketEntry.save(), basketEntry.save()]);
151
246
  }
152
247
  });
153
- return forkJoin(saveObservables).pipe(switchMap(() => this.listsService.refreshCurrentList()), take(1));
248
+ return forkJoin(saveObservables).pipe(switchMap(() => this.refreshCurrentBasket()), take(1));
154
249
  }
155
- loadBasket() {
156
- return combineLatest([this.listsService.list$, this.posService.pos$]).pipe(skipWhile(results => !results[0] || !results[1]), switchMap(results => this.fetchForListAndPos(results[0].id, results[1].id)), tap(basket => {
157
- this._basket$.next(basket);
158
- this.basketIsFetching = false;
250
+ /**
251
+ * Fetches the BasketEntry for an ingredient if it exists
252
+ * Returns a fake BasketEntry with id = -1 if it doesn't exist
253
+ */
254
+ basketEntryFromIngredient(ingredientId) {
255
+ return this.waitForBasket.pipe(switchMap(basket => {
256
+ const url = `${e.miamAPI}/api/v1/baskets/${basket.id}/basket-entries/from-ingredient?ingredient_id=${ingredientId}`;
257
+ return this.http.get(url, { params: { include: ['selected-item'] } });
258
+ }), skipWhile(result => result.is_loading || !result), map(res => {
259
+ const entry = this.basketEntriesService.new();
260
+ entry.fill(res);
261
+ return entry;
159
262
  }));
160
263
  }
264
+ /** *********************************************************** PRICEBOOK *********************************************************** **/
161
265
  // will patch basket with given pricebookName
162
266
  // Api will look for prices (pos items) corresponding to this pricebook key
163
267
  // fall case to a default pricebook
164
268
  updatePricebook(pricebookName) {
165
- return this.basket$.pipe(skipWhile(b => !b), take(1), switchMap(basket => {
269
+ return this.waitForBasket.pipe(switchMap(basket => {
166
270
  if (basket.pricebookKey === pricebookName) {
167
271
  console.log(`[Miam] same pricebook ${JSON.stringify(pricebookName)}`);
168
- return of(basket);
272
+ return of();
169
273
  }
170
274
  console.log(`[Miam] update pricebook to ${JSON.stringify(pricebookName)}`);
171
275
  basket.pricebookKey = pricebookName;
172
- return basket.save().pipe(map((resp) => {
173
- const updatedBasket = this.new();
174
- updatedBasket.fill(resp);
175
- this._basket$.next(updatedBasket);
176
- return updatedBasket;
276
+ return basket.save({ fields: BASKET_SPARSE_FIELDS }).pipe(switchMap((resp) => {
277
+ this.fillBasket(resp);
278
+ return this.loadPreview();
279
+ }));
280
+ }));
281
+ }
282
+ /** ******************************************************** ADD FROM PICTURE ******************************************************** **/
283
+ addEntriesFromPicture(file, include = [], disableIngredientsMatching = false) {
284
+ return this.waitForBasket.pipe(switchMap(basket => {
285
+ const url = `${e.miamAPI}/api/v1/baskets/${basket.id}/add_entries_from_picture` +
286
+ `?fields[baskets]=${BASKET_SPARSE_FIELDS.baskets.join(',')}${(disableIngredientsMatching ? '&disable_matching=true' : '')}`;
287
+ const formData = new FormData();
288
+ formData.append('picture', file);
289
+ formData.append('include', include.join(','));
290
+ return this.http.patch(url, formData).pipe(map((response) => this.fillBasket(response)));
291
+ }));
292
+ }
293
+ /** **************************************************** ADD ACTIONS TO THE QUEUE **************************************************** **/
294
+ /**
295
+ * Adds recipes to the basket action to queue.
296
+ *
297
+ * @param recipeIds - The array of recipe IDs to add.
298
+ * @param guests - The number of guests.
299
+ * @param eventTrace - The event trace.
300
+ * @param withIngredients - Whether to include ingredients. Default is true.
301
+ * @return This function does not return anything.
302
+ */
303
+ addRecipesToBasket(recipeIds, guests, eventTrace, withIngredients = true) {
304
+ const toAdd = this.basketActionsQueue.value;
305
+ recipeIds.forEach(recipeId => toAdd.push({
306
+ type: withIngredients ? BasketActionType.ADD_RECIPE : BasketActionType.ADD_RECIPE_LIGHT,
307
+ params: { recipeId, eventTrace, guests }
308
+ }));
309
+ this.basketActionsQueue.next(toAdd);
310
+ }
311
+ removeRecipesFromBasket(recipeIds, eventTrace) {
312
+ const toRemove = this.basketActionsQueue.value;
313
+ recipeIds.forEach(recipeId => toRemove.push({
314
+ type: BasketActionType.REMOVE_RECIPE,
315
+ params: { recipeId, eventTrace }
316
+ }));
317
+ this.basketActionsQueue.next(toRemove);
318
+ }
319
+ updateRecipesInBasket(recipeIds, guests, eventTrace) {
320
+ const toUpdate = this.basketActionsQueue.value;
321
+ recipeIds.forEach(recipeId => toUpdate.push({
322
+ type: BasketActionType.UPDATE_RECIPE,
323
+ params: { recipeId, eventTrace, guests }
324
+ }));
325
+ this.basketActionsQueue.next(toUpdate);
326
+ }
327
+ addIngredientsToBasket(recipeId, ingredientIdsAndEntries, eventTrace) {
328
+ const toAdd = this.basketActionsQueue.value;
329
+ ingredientIdsAndEntries.forEach(ingredientIdAndEntry => toAdd.push({
330
+ type: BasketActionType.ADD_PRODUCT,
331
+ params: { recipeId, ingredientId: ingredientIdAndEntry.ingredientId, basketEntry: ingredientIdAndEntry.entry, eventTrace }
332
+ }));
333
+ this.basketActionsQueue.next(toAdd);
334
+ }
335
+ removeIngredientsFromBasket(basketEntry, recipeId, ingredientIds, eventTrace) {
336
+ const toRemove = this.basketActionsQueue.value;
337
+ ingredientIds.forEach(ingredientId => toRemove.push({
338
+ type: BasketActionType.REMOVE_PRODUCT,
339
+ params: { basketEntry, recipeId, ingredientId, eventTrace }
340
+ }));
341
+ this.basketActionsQueue.next(toRemove);
342
+ }
343
+ changeProductQuantity(basketEntry, recipeId, newQuantity, eventTrace) {
344
+ const toUpdate = this.basketActionsQueue.value;
345
+ toUpdate.push({
346
+ type: BasketActionType.UPDATE_PRODUCT,
347
+ params: { basketEntry, recipeId, newQuantity, eventTrace }
348
+ });
349
+ this.basketActionsQueue.next(toUpdate);
350
+ }
351
+ /** *************************************************** PROCESS THE ACTIONS QUEUE *************************************************** **/
352
+ emptyActionsQueue() {
353
+ if (this.basketActionsQueue.value.length > 0) {
354
+ const actionsToProcess = this.nextActionsBatch();
355
+ this.actionsBeingProcessed.next([...actionsToProcess]);
356
+ if (actionsToProcess.length > 0) {
357
+ this.processActionsBatch(actionsToProcess).subscribe(() => {
358
+ this.actionsBeingProcessed.next([]);
359
+ this.basketActionsQueue.next(this.basketActionsQueue.value.filter(i => !actionsToProcess.includes(i) && !this.actionsBeingOverriden.includes(i)));
360
+ this.actionsBeingOverriden = [];
361
+ });
362
+ }
363
+ }
364
+ }
365
+ /**
366
+ * If multiple actions of the same type are next to each other in the queue, we want to process them as a batch.
367
+ * @returns the next batch of actions to process
368
+ */
369
+ nextActionsBatch() {
370
+ var _a;
371
+ const batch = [];
372
+ let i = 0;
373
+ let currentAction = this.basketActionsQueue.value[i];
374
+ let shouldForceStop = false;
375
+ while (((_a = this.basketActionsQueue.value[i]) === null || _a === void 0 ? void 0 : _a.type) === (currentAction === null || currentAction === void 0 ? void 0 : currentAction.type) && !shouldForceStop) {
376
+ currentAction = this.basketActionsQueue.value[i];
377
+ shouldForceStop = this.addActionToBatchOrStopProcessingBatch(batch, currentAction);
378
+ i++;
379
+ }
380
+ return batch;
381
+ }
382
+ /**
383
+ * @returns true if the batch should stop processing
384
+ */
385
+ addActionToBatchOrStopProcessingBatch(batch, currentAction) {
386
+ const recipeIndex = this.checkForActionToOverride(batch, currentAction);
387
+ if (recipeIndex !== -1) {
388
+ this.actionsBeingOverriden.push(batch[recipeIndex]);
389
+ batch[recipeIndex] = currentAction;
390
+ }
391
+ else {
392
+ if (this.shouldForceStopBatch(batch, currentAction)) {
393
+ return true;
394
+ }
395
+ else {
396
+ batch.push(currentAction);
397
+ }
398
+ }
399
+ return false;
400
+ }
401
+ shouldForceStopBatch(batch, currentAction) {
402
+ // If the current batch is an UPDATE batch, we can't update multiple recipes with differents guests values at the same time
403
+ // so in this case we stop the batch before the UPDATE with a different guests value
404
+ return (currentAction.type === BasketActionType.UPDATE_RECIPE &&
405
+ batch.length > 0 &&
406
+ !batch.some(a => a.params.guests === currentAction.params.guests)) ||
407
+ // If the current batch is an product add/remove batch, we can't add or remove products from different recipes at the same time
408
+ // so in this case we stop the batch before the add/remove with a different recipe
409
+ ((currentAction.type === BasketActionType.ADD_PRODUCT || currentAction.type === BasketActionType.REMOVE_PRODUCT) &&
410
+ batch.length > 0 &&
411
+ !batch.some(a => a.params.recipeId === currentAction.params.recipeId));
412
+ }
413
+ /**
414
+ * Check for actions for which overriding would have the same result as processing both in order
415
+ */
416
+ checkForActionToOverride(batch, currentAction) {
417
+ if (currentAction.type === BasketActionType.UPDATE_RECIPE &&
418
+ batch.length > 0 &&
419
+ !batch.some(a => a.params.recipeId !== currentAction.params.recipeId)) {
420
+ return batch.findIndex(a => a.params.recipeId === currentAction.params.recipeId);
421
+ // if there are only the same recipeId as the currentAction in the batch and we are updating this recipe's guests
422
+ // we can safely override the action in the batch
423
+ }
424
+ else if (currentAction.type === BasketActionType.UPDATE_PRODUCT) {
425
+ return batch.findIndex(a => a.params.basketEntry.id === currentAction.params.basketEntry.id);
426
+ // If the currentAction modifies the same basketEntry as a previous one in the batch, it overrides it
427
+ }
428
+ else if (![BasketActionType.ADD_PRODUCT, BasketActionType.REMOVE_PRODUCT, BasketActionType.UPDATE_RECIPE].includes(currentAction.type)) {
429
+ return batch.findIndex(a => a.params.recipeId === currentAction.params.recipeId);
430
+ // If the currentAction modifies the same recipe as a previous one in the batch, it overrides it
431
+ }
432
+ else {
433
+ return batch.findIndex(a => a.params.ingredientId === currentAction.params.ingredientId &&
434
+ a.params.recipeId === currentAction.params.recipeId);
435
+ // If the currentAction modifies the same ingredient for the same recipe as a previous one in the batch, it overrides it
436
+ }
437
+ }
438
+ processActionsBatch(actionsToProcess) {
439
+ switch (actionsToProcess[0].type) {
440
+ case BasketActionType.ADD_RECIPE:
441
+ return this.addRecipes(actionsToProcess);
442
+ case BasketActionType.ADD_RECIPE_LIGHT:
443
+ return this.addRecipesWithoutIngredients(actionsToProcess);
444
+ case BasketActionType.REMOVE_RECIPE:
445
+ return this.removeRecipes(actionsToProcess);
446
+ case BasketActionType.UPDATE_RECIPE:
447
+ return this.updateRecipesGuests(actionsToProcess);
448
+ case BasketActionType.ADD_PRODUCT:
449
+ return this.addItemsForIngredients(actionsToProcess);
450
+ case BasketActionType.REMOVE_PRODUCT:
451
+ return this.removeItemsForIngredients(actionsToProcess);
452
+ case BasketActionType.UPDATE_PRODUCT:
453
+ return this.changeBasketEntriesQuantities(actionsToProcess);
454
+ default:
455
+ return of();
456
+ }
457
+ }
458
+ /** ****************************************************** PROCESS THE ACTIONS ****************************************************** **/
459
+ /**
460
+ * Adds recipes to the basket HTTP request.
461
+ *
462
+ * @param recipesToAdd - The recipes to add to the basket.
463
+ * @param withIngredients - (optional) Whether to include ingredients in the request. Default is true.
464
+ * @return An observable that emits void when the request is completed.
465
+ */
466
+ addRecipes(recipesToAdd, withIngredients = true) {
467
+ return this.waitForBasket.pipe(switchMap(basket => {
468
+ const url = `${e.miamAPI}/api/v1/baskets/${basket.id}/recipes` +
469
+ `?fields[baskets]=${BASKET_SPARSE_FIELDS.baskets.join(',')}${withIngredients ? '' : '&light_mode=true'}`;
470
+ const body = { data: recipesToAdd.map(r => ({ recipe_id: r.params.recipeId, guests: r.params.guests })) };
471
+ this.analyticsService.sendAddRecipesEvents(recipesToAdd);
472
+ return this.http.post(url, body).pipe(skipWhile((b) => b.is_loading), switchMap(b => {
473
+ var _a;
474
+ if ((_a = b === null || b === void 0 ? void 0 : b.data) === null || _a === void 0 ? void 0 : _a.id) {
475
+ this.fillBasket(b);
476
+ return this.loadPreview();
477
+ }
478
+ return of();
479
+ }));
480
+ }));
481
+ }
482
+ addRecipesWithoutIngredients(recipesToAdd) {
483
+ return this.addRecipes(recipesToAdd, false);
484
+ }
485
+ removeRecipes(recipesToRemove) {
486
+ return this.waitForBasket.pipe(switchMap(basket => {
487
+ const url = `${e.miamAPI}/api/v1/baskets/${basket.id}/recipes?recipe_ids[]=` +
488
+ recipesToRemove.map(r => r.params.recipeId).join('&recipe_ids[]=') + `&fields[baskets]=${BASKET_SPARSE_FIELDS.baskets.join(',')}`;
489
+ this.analyticsService.sendRemoveRecipesEvents(recipesToRemove);
490
+ return this.http.delete(url).pipe(skipWhile((b) => b.is_loading), switchMap(b => {
491
+ var _a;
492
+ if ((_a = b === null || b === void 0 ? void 0 : b.data) === null || _a === void 0 ? void 0 : _a.id) {
493
+ this.fillBasket(b);
494
+ return this.loadPreview();
495
+ }
496
+ return of();
177
497
  }));
178
498
  }));
179
499
  }
500
+ updateRecipesGuests(recipesToUpdate) {
501
+ return this.waitForBasket.pipe(switchMap(basket => {
502
+ const url = `${e.miamAPI}/api/v1/baskets/${basket.id}/recipes_guests?guests=${recipesToUpdate[0].params.guests}&recipe_ids[]=` +
503
+ recipesToUpdate.map(r => r.params.recipeId).join('&recipe_ids[]=') + `&fields[baskets]=${BASKET_SPARSE_FIELDS.baskets.join(',')}`;
504
+ this.analyticsService.sendUpdateGuestsEvents(recipesToUpdate);
505
+ return this.http.patch(url, {}).pipe(skipWhile((b) => !b || b.is_loading), switchMap(b => {
506
+ var _a;
507
+ if ((_a = b === null || b === void 0 ? void 0 : b.data) === null || _a === void 0 ? void 0 : _a.id) {
508
+ this.fillBasket(b);
509
+ return this.loadPreview();
510
+ }
511
+ return of();
512
+ }));
513
+ }));
514
+ }
515
+ /**
516
+ * @param ingredientsToAdd
517
+ */
518
+ addItemsForIngredients(ingredientsToAdd) {
519
+ return this.waitForBasket.pipe(skipWhile(basket => basket.is_loading), switchMap(basket => {
520
+ const requests = ingredientsToAdd.map(action => {
521
+ const modifiedGuests = this.guestsForRecipe(action.params.recipeId);
522
+ const url = `${e.miamAPI}/api/v1/baskets/${basket.id}/basket-entries/${action.params.basketEntry.id}/add-ingredient` +
523
+ `?ingredient_id=${action.params.ingredientId}&selected_item_id=${action.params.basketEntry.selectedItem.id}` +
524
+ `&guests=${modifiedGuests}`;
525
+ return this.http.patch(url, {});
526
+ });
527
+ return forkJoin(requests);
528
+ }), switchMap(() => this.reloadBasket()), switchMap(() => of(null)) // Just to keep the return type as Observable<void> to match with the other methods
529
+ );
530
+ }
531
+ /**
532
+ * Removes the specified ingredients from the basket HTTP request.
533
+ *
534
+ * @param ingredientsToRemove - The list of ingredients to remove from the basket.
535
+ * @return An observable that emits when the ingredients are successfully removed.
536
+ */
537
+ removeItemsForIngredients(ingredientsToRemove) {
538
+ return this.waitForBasket.pipe(skipWhile(basket => basket.is_loading), switchMap(basket => {
539
+ const requests = ingredientsToRemove.map(action => {
540
+ const modifiedGuests = this.guestsForRecipe(action.params.recipeId);
541
+ const url = e.miamAPI + '/api/v1/baskets/' + basket.id +
542
+ '/basket-entries/' + action.params.basketEntry.id +
543
+ '/remove-ingredient?ingredient_id=' + action.params.ingredientId +
544
+ '&selected_item_id=' + action.params.basketEntry.selectedItem.id +
545
+ '&guests=' + modifiedGuests;
546
+ return this.http.patch(url, {});
547
+ });
548
+ return forkJoin(requests);
549
+ }), switchMap(() => this.reloadBasket()), switchMap(() => of(null)) // Just to keep the return type as Observable<void> to match with the other methods
550
+ );
551
+ }
552
+ /**
553
+ * Removes the specified ingredients from the basket HTTP request.
554
+ *
555
+ * @param ingredientsToRemove - The list of ingredients to remove from the basket.
556
+ * @return An observable that emits when the ingredients are successfully removed.
557
+ */
558
+ changeBasketEntriesQuantities(quantitiesToChange) {
559
+ const requests = quantitiesToChange.map(action => {
560
+ action.params.basketEntry.quantity = action.params.newQuantity;
561
+ return action.params.basketEntry.save();
562
+ });
563
+ return forkJoin(requests).pipe(switchMap(() => this.reloadBasket()), switchMap(() => of(null)) // Just to keep the return type as Observable<void> to match with the other methods
564
+ );
565
+ }
566
+ /** ****************************************************** UPDATING THE BASKET ****************************************************** **/
567
+ /**
568
+ * Update _basket$ content & save basketId in the localStorage if the user is not loggued in so we can mergeWith when they log in
569
+ */
570
+ updateLocalBasket(basket) {
571
+ if (this.usersService.isLogged$.value) {
572
+ localStorage.removeItem('_miam/basketId');
573
+ }
574
+ else {
575
+ localStorage.setItem('_miam/basketId', basket.id);
576
+ }
577
+ this._basket$.next(basket);
578
+ return this.loadPreview().pipe(tap(() => this.basketIsFetching = false));
579
+ }
580
+ /**
581
+ * save() returns an object that isn't a resource so methods aren't attached, so we have to do a little trick
582
+ * @param res result of the save
583
+ * @returns correct Basket with the right attributes & methods
584
+ */
585
+ fillBasket(res) {
586
+ const basket = this.new();
587
+ basket.fill(res);
588
+ this._basket$.next(basket);
589
+ return basket;
590
+ }
591
+ /** ********************************************************** INITIAL LOAD ********************************************************** **/
592
+ /**
593
+ * Initialise the basket loading when the pos is initialised or modified
594
+ * @returns _basket$
595
+ */
596
+ loadBasket() {
597
+ return this.posService.pos$.pipe(skipWhile(pos => !pos), switchMap(() => this.refreshCurrentBasket()));
598
+ }
180
599
  loadPreview() {
181
- return this.basket$.pipe(skipWhile(b => !b), switchMap(() => this.recipesService.loadRecipes()), switchMap(recipes => {
600
+ return this.basket$.pipe(skipWhile(b => !b), take(1), switchMap(basket => this.recipesService.loadRecipes(basket.recipeInfos)), switchMap((recipes) => {
182
601
  const basket = this._basket$.value;
183
602
  return this.fetchBasketEntries(basket).pipe(map(entries => {
184
603
  const lineEntries = this.groupBasketEntries(recipes, entries);
@@ -186,20 +605,18 @@ export class BasketsService extends Service {
186
605
  this._basketPreview$.next(lines);
187
606
  this.basketPreviewIsCalculating = false;
188
607
  this.basketStats$.next(this.buildStats(lines));
189
- return lines;
190
608
  }));
191
609
  }));
192
610
  }
193
611
  fetchBasketEntries(basket) {
194
612
  if (!basket || !basket.completion || basket.completion.total < 1) {
195
613
  this._entries$.next([]);
196
- return this._entries$;
614
+ return this._entries$.pipe(take(1));
197
615
  }
198
616
  const pagesCount = Math.ceil(basket.completion.total / BasketsService.entriesPerPages);
199
617
  return forkJoin(Array(pagesCount).fill(0).map((v, i) => this.fetchBasketEntriesPage(basket, i + 1))).pipe(map((collections) => {
200
618
  // eslint-disable-next-line @typescript-eslint/no-unsafe-call
201
619
  const entries = flatten(collections.map(col => col.data));
202
- entries.forEach((entry) => entry.setItemsSelection());
203
620
  this._entries$.next(entries);
204
621
  return this._entries$.value;
205
622
  }));
@@ -219,8 +636,8 @@ export class BasketsService extends Service {
219
636
  };
220
637
  }
221
638
  fetchBasketEntriesPage(basket, page) {
222
- let url = [e.miamAPI, 'api/v1/baskets', basket.id, 'basket-entries'].join('/');
223
- url = `${url}?include=groceries-entry,items&page[number]=${page}&page[size]=${BasketsService.entriesPerPages}`;
639
+ let url = `${e.miamAPI}/api/v1/baskets/${basket.id}/basket-entries`;
640
+ url = `${url}?include=items&include=selected-item&page[number]=${page}&page[size]=${BasketsService.entriesPerPages}`;
224
641
  return this.http.get(url).pipe(skipWhile((resp) => resp.is_loading), map((resp) => {
225
642
  const basketEntries = this.basketEntriesService.newCollection();
226
643
  basketEntries.fill(resp);
@@ -236,22 +653,22 @@ export class BasketsService extends Service {
236
653
  const selectedItem = entry.attributes['basket-entries-items'].find(item => item.item_id === entry.attributes['selected-item-id']);
237
654
  const qty = entry.attributes.quantity;
238
655
  const unitPrice = parseFloat(selectedItem['unit-price']);
239
- const numberOfRecipesForEntry = entry.attributes['recipe-ids'].length || 1;
656
+ const numberOfRecipesForEntry = entry.recipesIds.length || 1;
240
657
  recipePrice += (qty * unitPrice) / numberOfRecipesForEntry;
241
658
  });
242
659
  const pricePerGuest = recipePrice / guests;
243
660
  return BasketPreviewLine.fromRecipe(recipe, itemsCount, pricePerGuest, recipePrice, lineEntries[idx]);
244
- }).sort((a, b) => recipes.findIndex(r => r.id === a.id) - recipes.findIndex(r => r.id === b.id));
661
+ }).sort((a, b) => recipes.findIndex(r => r.id === b.id) - recipes.findIndex(r => r.id === a.id));
245
662
  }
246
663
  groupBasketEntries(recipes, entries) {
247
664
  return recipes.map(recipe => {
248
- const lineEntries = { found: [], notFound: [], oftenDeleted: [], removed: [] };
665
+ const lineEntries = { found: [], notFound: [], oftenDeleted: [], removed: [], all: [] };
249
666
  entries
250
- .filter(entry => entry.attributes['recipe-ids'].includes(parseInt(recipe.id, 10)))
667
+ .filter(entry => entry.recipesIds.includes(parseInt(recipe.id, 10)))
251
668
  .forEach(entry => {
252
669
  const available = entry.attributes['selected-item-id'];
253
670
  if (available) {
254
- switch (entry.attributes['groceries-entry-status']) {
671
+ switch (entry.status) {
255
672
  case 'often_deleted': {
256
673
  lineEntries.oftenDeleted.push(entry);
257
674
  break;
@@ -269,18 +686,19 @@ export class BasketsService extends Service {
269
686
  else {
270
687
  lineEntries.notFound.push(entry);
271
688
  }
689
+ lineEntries.all.push(entry);
272
690
  });
273
691
  return lineEntries;
274
692
  });
275
693
  }
276
694
  }
277
695
  BasketsService.entriesPerPages = 30;
278
- BasketsService.ɵfac = function BasketsService_Factory(t) { return new (t || BasketsService)(i0.ɵɵinject(i1.HttpClient), i0.ɵɵinject(i2.BasketEntriesService), i0.ɵɵinject(i3.GroceriesListsService), i0.ɵɵinject(i4.GroceriesEntriesService), i0.ɵɵinject(i5.PointOfSalesService), i0.ɵɵinject(i6.RecipesService), i0.ɵɵinject(i7.AnalyticsService)); };
696
+ BasketsService.ɵfac = function BasketsService_Factory(t) { return new (t || BasketsService)(i0.ɵɵinject(i1.HttpClient), i0.ɵɵinject(i2.BasketEntriesService), i0.ɵɵinject(i3.PointOfSalesService), i0.ɵɵinject(i4.RecipesService), i0.ɵɵinject(i5.AnalyticsService), i0.ɵɵinject(i6.UserService), i0.ɵɵinject(i7.ToasterService)); };
279
697
  BasketsService.ɵprov = i0.ɵɵdefineInjectable({ token: BasketsService, factory: BasketsService.ɵfac, providedIn: 'root' });
280
698
  /*@__PURE__*/ (function () { i0.ɵsetClassMetadata(BasketsService, [{
281
699
  type: Injectable,
282
700
  args: [{
283
701
  providedIn: 'root'
284
702
  }]
285
- }], function () { return [{ type: i1.HttpClient }, { type: i2.BasketEntriesService }, { type: i3.GroceriesListsService }, { type: i4.GroceriesEntriesService }, { type: i5.PointOfSalesService }, { type: i6.RecipesService }, { type: i7.AnalyticsService }]; }, null); })();
286
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFza2V0cy5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6Ii9idWlsZHMvbWlhbS9uZy1taWFtLXNkay9wcm9qZWN0cy9uZy1taWFtL3NyYy8iLCJzb3VyY2VzIjpbImxpYi9fc2VydmljZXMvYmFza2V0cy5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUNsRCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNDLE9BQU8sRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQzdDLE9BQU8sRUFBRSxPQUFPLEVBQXdDLE1BQU0sYUFBYSxDQUFDO0FBQzVFLE9BQU8sRUFBYyxlQUFlLEVBQUUsYUFBYSxFQUFFLFFBQVEsRUFBRSxFQUFFLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDaEYsT0FBTyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUN0RSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFFM0MsT0FBTyxFQUFFLGlCQUFpQixFQUFlLE1BQU0sZ0NBQWdDLENBQUM7QUFJaEYsT0FBTyxFQUFFLFdBQVcsSUFBSSxDQUFDLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUMvRCxPQUFPLEVBQUUsZ0JBQWdCLEVBQW9CLE1BQU0scUJBQXFCLENBQUM7QUFDekUsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDaEUsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDdEUsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDbEUsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDL0QsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFN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OzRCQUNQLFdBQVcsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDOzRCQUM5QixNQUFNO3lCQUNQO3FCQUNGO2lCQUNGO3FCQUFNO29CQUNMLFdBQVcsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO2lCQUNsQztZQUNILENBQUMsQ0FBQyxDQUFDO1lBQ0wsT0FBTyxXQUFXLENBQUM7UUFDckIsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDOztBQXJVTSw4QkFBZSxHQUFHLEVBQUUsQ0FBQzs0RUFEakIsY0FBYztzREFBZCxjQUFjLFdBQWQsY0FBYyxtQkFGYixNQUFNO2tEQUVQLGNBQWM7Y0FIMUIsVUFBVTtlQUFDO2dCQUNWLFVBQVUsRUFBRSxNQUFNO2FBQ25CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSHR0cENsaWVudCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcbmltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IHVuaW9uQnksIGZsYXR0ZW4gfSBmcm9tICdsb2Rhc2gtZXMnO1xuaW1wb3J0IHsgU2VydmljZSwgRG9jdW1lbnRDb2xsZWN0aW9uLCBEb2N1bWVudFJlc291cmNlIH0gZnJvbSAnbmd4LWpzb25hcGknO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgQmVoYXZpb3JTdWJqZWN0LCBjb21iaW5lTGF0ZXN0LCBmb3JrSm9pbiwgb2YgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IHNraXBXaGlsZSwgc3dpdGNoTWFwLCB0YXAsIG1hcCwgdGFrZSB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IEJhc2tldCB9IGZyb20gJy4uL19tb2RlbHMvYmFza2V0JztcbmltcG9ydCB7IEJhc2tldEVudHJ5IH0gZnJvbSAnLi4vX21vZGVscy9iYXNrZXQtZW50cnknO1xuaW1wb3J0IHsgQmFza2V0UHJldmlld0xpbmUsIExpbmVFbnRyaWVzIH0gZnJvbSAnLi4vX21vZGVscy9iYXNrZXQtcHJldmlldy1saW5lJztcbmltcG9ydCB7IEdyb2Nlcmllc0VudHJ5IH0gZnJvbSAnLi4vX21vZGVscy9ncm9jZXJpZXMtZW50cnknO1xuaW1wb3J0IHsgUmVjaXBlIH0gZnJvbSAnLi4vX21vZGVscy9yZWNpcGUnO1xuaW1wb3J0IHsgQ29tcGFyYWJsZVByb2R1Y3QgfSBmcm9tICcuLi9fdHlwZXMvYnVpbGRlZC9jb21wYXJhYmxlLXByb2R1Y3QnO1xuaW1wb3J0IHsgZW52aXJvbm1lbnQgYXMgZSB9IGZyb20gJy4uL2Vudmlyb25tZW50cy9lbnZpcm9ubWVudCc7XG5pbXBvcnQgeyBBbmFseXRpY3NTZXJ2aWNlLCBDdXN0b21Qcm9wZXJ0aWVzIH0gZnJvbSAnLi9hbmFseXRpY3Muc2VydmljZSc7XG5pbXBvcnQgeyBCYXNrZXRFbnRyaWVzU2VydmljZSB9IGZyb20gJy4vYmFza2V0LWVudHJpZXMuc2VydmljZSc7XG5pbXBvcnQgeyBHcm9jZXJpZXNFbnRyaWVzU2VydmljZSB9IGZyb20gJy4vZ3JvY2VyaWVzLWVudHJpZXMuc2VydmljZSc7XG5pbXBvcnQgeyBHcm9jZXJpZXNMaXN0c1NlcnZpY2UgfSBmcm9tICcuL2dyb2Nlcmllcy1saXN0cy5zZXJ2aWNlJztcbmltcG9ydCB7IFBvaW50T2ZTYWxlc1NlcnZpY2UgfSBmcm9tICcuL3BvaW50LW9mLXNhbGVzLnNlcnZpY2UnO1xuaW1wb3J0IHsgUmVjaXBlc1NlcnZpY2UgfSBmcm9tICcuL3JlY2lwZXMuc2VydmljZSc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQmFza2V0U3RhdHMge1xuICB0b3RhbFByaWNlOiBudW1iZXI7XG4gIHJlY2lwZXNDb3VudDogbnVtYmVyO1xuICBlbnRyaWVzQ291bnQ6IG51bWJlcjtcbn1cblxuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCdcbn0pXG5leHBvcnQgY2xhc3MgQmFza2V0c1NlcnZpY2UgZXh0ZW5kcyBTZXJ2aWNlPEJhc2tldD4ge1xuICBzdGF0aWMgZW50cmllc1BlclBhZ2VzID0gMzA7XG5cbiAgcmVzb3VyY2UgPSBCYXNrZXQ7XG4gIHR5cGUgPSAnYmFza2V0cyc7XG4gIF9iYXNrZXQkID0gbmV3IEJlaGF2aW9yU3ViamVjdDxCYXNrZXQ+KG51bGwpO1xuICBfYmFza2V0UHJldmlldyQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PEJhc2tldFByZXZpZXdMaW5lW10+KG51bGwpO1xuICBiYXNrZXRTdGF0cyQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PEJhc2tldFN0YXRzPihudWxsKTtcbiAgYmFza2V0SXNGZXRjaGluZyA9IGZhbHNlO1xuICBiYXNrZXRQcmV2aWV3SXNDYWxjdWxhdGluZyA9IGZhbHNlO1xuICBiYXNrZXRJbml0Q2FsbGVkID0gZmFsc2U7XG5cbiAgcHJpdmF0ZSBfZW50cmllcyQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PEJhc2tldEVudHJ5W10+KFtdKTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIGh0dHA6IEh0dHBDbGllbnQsXG4gICAgcHJpdmF0ZSBiYXNrZXRFbnRyaWVzU2VydmljZTogQmFza2V0RW50cmllc1NlcnZpY2UsXG4gICAgcHJpdmF0ZSBsaXN0c1NlcnZpY2U6IEdyb2Nlcmllc0xpc3RzU2VydmljZSxcbiAgICBwcml2YXRlIGdyb2Nlcmllc0VudHJpZXNTZXJ2aWNlOiBHcm9jZXJpZXNFbnRyaWVzU2VydmljZSxcbiAgICBwcml2YXRlIHBvc1NlcnZpY2U6IFBvaW50T2ZTYWxlc1NlcnZpY2UsXG4gICAgcHJpdmF0ZSByZWNpcGVzU2VydmljZTogUmVjaXBlc1NlcnZpY2UsXG4gICAgcHJpdmF0ZSBhbmFseXRpY3NTZXJ2aWNlOiBBbmFseXRpY3NTZXJ2aWNlXG4gICkge1xuICAgIHN1cGVyKCk7XG4gICAgdGhpcy5yZWdpc3RlcigpO1xuICB9XG5cbiAgLyoqXG4gICAqIFdlIHdhbnQgYmFza2V0JCB0byBiZSBhIHNpbmdsZXRvbiB0aGF0IGFsd2F5cyByZXR1cm5zIHRoZSBzYW1lIGJhc2tldCwgc28gaXQgaXMgZmV0Y2hlZCBvbmx5IHdoZW4gbmVjZXNzYXJ5LlxuICAgKiBBdCBhbnkgcG9pbnQgaW4gdGltZSB0aGUgYmFza2V0IGNhbiBiZSBmZXRjaGVkIHZpYSB0aGUgaW5pdEJhc2tldCBmdW5jdGlvbiAoaWYgd2Ugd2FudCB0byBmZXRjaCBpdCBvbiBzdGFydHVwIHRvIHNhdmUgdGltZSBsYXRlcilcbiAgICogQnV0IGlmIGluaXRCYXNrZXQgaXMgbm90IGNhbGxlZCwgdGhlIGJhc2tldCB3aWxsIG9ubHkgYmUgZmV0Y2hlZCB0aGUgMXN0IHRpbWUgaXQgaXMgbmVlZGVkLlxuICAgKi9cbiAgZ2V0IGJhc2tldCQoKTogQmVoYXZpb3JTdWJqZWN0PEJhc2tldD4ge1xuICAgIGlmICghdGhpcy5fYmFza2V0JC52YWx1ZSAmJiAhdGhpcy5iYXNrZXRJc0ZldGNoaW5nKSB7XG4gICAgICB0aGlzLmJhc2tldElzRmV0Y2hpbmcgPSB0cnVlO1xuICAgICAgdGhpcy5pbml0QmFza2V0KCk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9iYXNrZXQkO1xuICB9XG5cbiAgLyoqXG4gICAqIGJhc2tldFByZXZpZXckIHNob3VsZCBhbHNvIGJlIGEgc2luZ2xldG9uLCBhbmQgYXMgd2VsbCBhcyBiYXNrZXQkIGl0IHdpbGwgYmUgY2FsY3VsYXRlZCBmb3IgdGhlIGZpcnN0IHRpbWUgb25seSB3aGVuIG5lY2Vzc2FyeVxuICAgKiBvciBpZiBsb2FkUHJldmlldyBpcyBjYWxsZWQgYmVmb3JlXG4gICAqL1xuICBnZXQgYmFza2V0UHJldmlldyQoKTogQmVoYXZpb3JTdWJqZWN0PEJhc2tldFByZXZpZXdMaW5lW10+IHtcbiAgICBpZiAoIXRoaXMuX2Jhc2tldFByZXZpZXckLnZhbHVlICYmICF0aGlzLmJhc2tldFByZXZpZXdJc0NhbGN1bGF0aW5nKSB7XG4gICAgICB0aGlzLmJhc2tldFByZXZpZXdJc0NhbGN1bGF0aW5nID0gdHJ1ZTtcbiAgICAgIHRoaXMuaW5pdEJhc2tldCgpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fYmFza2V0UHJldmlldyQ7XG4gIH1cblxuICAvLyBGZXRjaCByZWxhdGVkIGJhc2tldHMsIGZpbHRlcmluZyBvbiBhIHBvaW50IG9mIHNhbGVcbiAgZmV0Y2hGb3JMaXN0QW5kUG9zKGxpc3RJZDogc3RyaW5nLCBwb3NJZDogc3RyaW5nKTogT2JzZXJ2YWJsZTxCYXNrZXQ+IHtcbiAgICBpZiAoIWxpc3RJZCB8fCAhcG9zSWQpIHtcbiAgICAgIHJldHVybiAob2YobnVsbCkgYXMgT2JzZXJ2YWJsZTxCYXNrZXQ+KTtcbiAgICB9XG4gICAgbGV0IHVybCA9IFtlLm1pYW1BUEksICdhcGkvdjEvZ3JvY2VyaWVzLWxpc3RzJywgbGlzdElkLCAnYmFza2V0cyddLmpvaW4oJy8nKTtcbiAgICB1cmwgPSBgJHt1cmx9P2ZpbHRlcltwb2ludF9vZl9zYWxlX2lkXT0ke3Bvc0lkfWA7XG5cbiAgICByZXR1cm4gdGhpcy5odHRwLmdldCh1cmwpLnBpcGUoXG4gICAgICBza2lwV2hpbGUoKHJlc3A6IERvY3VtZW50Q29sbGVjdGlvbjxCYXNrZXQ+KSA9PiByZXNwLmlzX2xvYWRpbmcpLFxuICAgICAgbWFwKChyZXNwOiBEb2N1bWVudENvbGxlY3Rpb248QmFza2V0PikgPT4ge1xuICAgICAgICBjb25zdCBiYXNrZXRzID0gdGhpcy5uZXdDb2xsZWN0aW9uKCk7XG4gICAgICAgIGJhc2tldHMuZmlsbChyZXNwKTtcbiAgICAgICAgcmV0dXJuIGJhc2tldHMuZGF0YVswXTtcbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIGluaXRCYXNrZXQoKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmJhc2tldEluaXRDYWxsZWQpIHtcbiAgICAgIHRoaXMuYmFza2V0SW5pdENhbGxlZCA9IHRydWU7XG4gICAgICB0aGlzLmxvYWRCYXNrZXQoKS5zdWJzY3JpYmUoKTtcbiAgICAgIHRoaXMubG9hZFByZXZpZXcoKS5zdWJzY3JpYmUoKTtcbiAgICB9XG4gIH1cblxuICByZWxvYWRCYXNrZXQoKTogT2JzZXJ2YWJsZTxCYXNrZXQ+IHtcbiAgICByZXR1cm4gdGhpcy5sb2FkQmFza2V0KCkucGlwZSh0YWtlKDEpKTtcbiAgfVxuXG4gIC8vIFNldCBiYXNrZXQgYXMgY29uZmlybWVkLCBhbmQgcmV0dXJucyBvbmx5IG9uY2UgdGhlIG5ldyBjdXJyZW50IGxpc3QgaXMgcmV0dXJuZWRcbiAgY29uZmlybUJhc2tldCh0b3RhbFByaWNlOiBudW1iZXIgfCBzdHJpbmcpOiBPYnNlcnZhYmxlPEJhc2tldD4ge1xuICAgIGxldCBjb25maXJtZWRCYXNrZXQ6IEJhc2tldDtcbiAgICBjb25zb2xlLmxvZyhgW01pYW1dIENvbmZpcm0gYmFza2V0ICR7SlNPTi5zdHJpbmdpZnkoY29uZmlybWVkQmFza2V0KX1gKTtcbiAgICByZXR1cm4gdGhpcy5iYXNrZXQkLnBpcGUoXG4gICAgICBza2lwV2hpbGUoYiA9PiAhYiksXG4gICAgICB0YWtlKDEpLFxuICAgICAgdGFwKGJhc2tldCA9PiB7XG4gICAgICAgIGlmIChiYXNrZXQudG90YWxQcmljZSA+IDApIHtcbiAgICAgICAgICB0aGlzLmFuYWx5dGljc1NlcnZpY2Uuc2VuZEV2ZW50V2hlblJlYWR5KFxuICAgICAgICAgICAgdGhpcy5hbmFseXRpY3NTZXJ2aWNlLkVWRU5UX1BBWU1FTlRfQ09ORklSTUVELCBudWxsLCB0aGlzLmV2ZW50UHJvcHMoYmFza2V0LCB0b3RhbFByaWNlKVxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH0pLFxuICAgICAgc3dpdGNoTWFwKGJhc2tldCA9PiB7XG4gICAgICAgIGNvbnNvbGUubG9nKCdbTWlhbV0gU2F2ZSBiYXNrZXQgd2l0aCBjb25maXJtZWQ9dHJ1ZScpO1xuICAgICAgICBiYXNrZXQuYXR0cmlidXRlcy5jb25maXJtZWQgPSB0cnVlO1xuICAgICAgICByZXR1cm4gYmFza2V0LnNhdmUoKTtcbiAgICAgIH0pLFxuICAgICAgc3dpdGNoTWFwKChyZXNwOiBEb2N1bWVudFJlc291cmNlPEJhc2tldD4pID0+IHtcbiAgICAgICAgY29uZmlybWVkQmFza2V0ID0gdGhpcy5uZXcoKTtcbiAgICAgICAgY29uZmlybWVkQmFza2V0LmZpbGwocmVzcCk7XG4gICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgIGBbTWlhbV0gc2VuZCBwdXNoIGFuYWx5dGljcyBldmVudCBpZiA+IDA6ICR7SlNPTi5zdHJpbmdpZnkoY29uZmlybWVkQmFza2V0LnRvdGFsUHJpY2UpfSAke0pTT04uc3RyaW5naWZ5KGNvbmZpcm1lZEJhc2tldCl9YFxuICAgICAgICApO1xuICAgICAgICBpZiAoY29uZmlybWVkQmFza2V0LnRvdGFsUHJpY2UgPiAwICYmIGNvbmZpcm1lZEJhc2tldC50b2tlbikge1xuICAgICAgICAgIHRoaXMuYW5hbHl0aWNzU2VydmljZS5zZW5kRXZlbnRXaGVuUmVhZHkoXG4gICAgICAgICAgICB0aGlzLmFuYWx5dGljc1NlcnZpY2UuRVZFTlRfQkFTS0VUX0NPTkZJUk1FRCwgbnVsbCwgdGhpcy5ldmVudFByb3BzKGNvbmZpcm1lZEJhc2tldCwgdG90YWxQcmljZSlcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2Jhc2tldCQubmV4dCh1bmRlZmluZWQpO1xuICAgICAgICByZXR1cm4gdGhpcy5saXN0c1NlcnZpY2UucmVzZXRMaXN0KCk7XG4gICAgICB9KSxcbiAgICAgIHN3aXRjaE1hcCgoKSA9PiB0aGlzLl9iYXNrZXQkXG4gICAgICApLFxuICAgICAgc2tpcFdoaWxlKGIgPT4gIWIpLFxuICAgICAgbWFwKCgpID0+IGNvbmZpcm1lZEJhc2tldClcbiAgICApO1xuICB9XG5cbiAgZXZlbnRQcm9wcyhiYXNrZXQ6IEJhc2tldCwgdG90YWxQcmljZTogbnVtYmVyIHwgc3RyaW5nKTogQ3VzdG9tUHJvcGVydGllcyB7XG4gICAgcmV0dXJuIHtcbiAgICAgIC8vIGlmIHlvdSBoYXZlIGEgYmFza2V0IHlvdSBoYXZlIGEgcG9zLi4uXG4gICAgICBwb3NfaWQ6IHRoaXMucG9zU2VydmljZS5wb3MkLmdldFZhbHVlKCkuaWQsXG4gICAgICBwb3NfbmFtZTogdGhpcy5wb3NTZXJ2aWNlLnBvcyQuZ2V0VmFsdWUoKS5hdHRyaWJ1dGVzLm5hbWUsXG4gICAgICBiYXNrZXRfaWQ6IGJhc2tldC5pZCxcbiAgICAgIG1pYW1fYW1vdW50OiBiYXNrZXQudG90YWxQcmljZSxcbiAgICAgIHRvdGFsX2Ftb3VudDogdG90YWxQcmljZVxuICAgIH07XG4gIH1cblxuICBiYXNrZXRFbnRyaWVzKCk6IE9ic2VydmFibGU8QmFza2V0RW50cnlbXT4ge1xuICAgIHJldHVybiB0aGlzLl9lbnRyaWVzJDtcbiAgfVxuXG4gIGFjdGl2ZUJhc2tldEVudHJpZXMoKTogT2JzZXJ2YWJsZTxCYXNrZXRFbnRyeVtdPiB7XG4gICAgcmV0dXJuIHRoaXMuYmFza2V0RW50cmllcygpLnBpcGUoXG4gICAgICBtYXAoKGVudHJpZXM6IEJhc2tldEVudHJ5W10pID0+IGVudHJpZXMuZmlsdGVyKGVudHJ5ID0+IGVudHJ5Lmdyb2Nlcmllc0VudHJ5U3RhdHVzID09PSAnYWN0aXZlJykpXG4gICAgKTtcbiAgfVxuXG4gIC8vIERlY3JlYXNlIHF1YW50aXR5IG9uIGEgbGlzdCBvZiBiYXNrZXQgZW50cmllc1xuICAvLyBJZiB0aGUgcXVhbnRpdHkgZ29lcyBiZWxvdyAxLCB0aGUgY29ycmVzcG9uZGluZyBncm9jZXJpZXMgZW50cnkncyBzdGF0dXMgZ2V0cyBkZWxldGVkXG4gIC8vIFJlbG9hZCBiYXNrZXQgYWZ0ZXIgYWxsIG9iamVjdHMgYXJlIHNhdmVkXG4gIHJlbW92ZUJhc2tldEVudHJpZXMoZW50cmllc1RvUmVtb3ZlOiBDb21wYXJhYmxlUHJvZHVjdFtdKTogT2JzZXJ2YWJsZTxhbnk+IHtcbiAgICBpZiAoIXRoaXMuX2VudHJpZXMkLnZhbHVlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3Qgc2F2ZU9ic2VydmFibGVzOiBPYnNlcnZhYmxlPGFueT5bXSA9IGVudHJpZXNUb1JlbW92ZS5tYXAoZW50cnlUb1JlbW92ZSA9PiB7XG4gICAgICBjb25zdCBiYXNrZXRFbnRyeSA9IHRoaXMuX2VudHJpZXMkLnZhbHVlLmZpbmQoYmUgPT4gYmUuaWQgPT09IGVudHJ5VG9SZW1vdmUuaWQpO1xuICAgICAgaWYgKCFiYXNrZXRFbnRyeSB8fCAhZW50cnlUb1JlbW92ZS5xdWFudGl0eSkge1xuICAgICAgICByZXR1cm4gb2YobnVsbCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGZpbmFsQ291bnQgPSBiYXNrZXRFbnRyeS5xdWFudGl0eSAtIGVudHJ5VG9SZW1vdmUucXVhbnRpdHk7XG4gICAgICBpZiAoZmluYWxDb3VudCA+PSAxKSB7XG4gICAgICAgIGJhc2tldEVudHJ5LnF1YW50aXR5ID0gZmluYWxDb3VudDtcbiAgICAgICAgcmV0dXJuIGJhc2tldEVudHJ5LnNhdmUoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGJhc2tldEVudHJ5LnF1YW50aXR5ID0gMTtcbiAgICAgICAgYmFza2V0RW50cnkuZ3JvY2VyaWVzRW50cnkuc3RhdHVzID0gJ2RlbGV0ZWQnO1xuICAgICAgICByZXR1cm4gZm9ya0pvaW4oW2Jhc2tldEVudHJ5LnNhdmUoKSwgYmFza2V0RW50cnkuZ3JvY2VyaWVzRW50cnkuc2F2ZSgpXSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gZm9ya0pvaW4oc2F2ZU9ic2VydmFibGVzKS5waXBlKFxuICAgICAgc3dpdGNoTWFwKCgpID0+IHRoaXMubGlzdHNTZXJ2aWNlLnJlZnJlc2hDdXJyZW50TGlzdCgpKSxcbiAgICAgIHRha2UoMSlcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBsb2FkQmFza2V0KCk6IE9ic2VydmFibGU8QmFza2V0PiB7XG4gICAgcmV0dXJuIGNvbWJpbmVMYXRlc3QoW3RoaXMubGlzdHNTZXJ2aWNlLmxpc3QkLCB0aGlzLnBvc1NlcnZpY2UucG9zJF0pLnBpcGUoXG4gICAgICBza2lwV2hpbGUocmVzdWx0cyA9PiAgIXJlc3VsdHNbMF0gfHwgIXJlc3VsdHNbMV0pLFxuICAgICAgc3dpdGNoTWFwKHJlc3VsdHMgPT4gdGhpcy5mZXRjaEZvckxpc3RBbmRQb3MocmVzdWx0c1swXS5pZCwgcmVzdWx0c1sxXS5pZCkpLFxuICAgICAgdGFwKGJhc2tldCA9PiB7XG4gICAgICAgIHRoaXMuX2Jhc2tldCQubmV4dChiYXNrZXQpO1xuICAgICAgICB0aGlzLmJhc2tldElzRmV0Y2hpbmcgPSBmYWxzZTtcbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIC8vIHdpbGwgcGF0Y2ggYmFza2V0IHdpdGggZ2l2ZW4gcHJpY2Vib29rTmFtZVxuICAvLyBBcGkgd2lsbCBsb29rIGZvciBwcmljZXMgKHBvcyBpdGVtcykgY29ycmVzcG9uZGluZyB0byB0aGlzIHByaWNlYm9vayBrZXlcbiAgLy8gZmFsbCBjYXNlIHRvIGEgZGVmYXVsdCBwcmljZWJvb2tcbiAgdXBkYXRlUHJpY2Vib29rKHByaWNlYm9va05hbWU6IHN0cmluZyk6IE9ic2VydmFibGU8QmFza2V0PiB7XG4gICAgcmV0dXJuIHRoaXMuYmFza2V0JC5waXBlKFxuICAgICAgc2tpcFdoaWxlKGIgPT4gIWIpLFxuICAgICAgdGFrZSgxKSxcbiAgICAgIHN3aXRjaE1hcChiYXNrZXQgPT4ge1xuICAgICAgICBpZiAoYmFza2V0LnByaWNlYm9va0tleSA9PT0gcHJpY2Vib29rTmFtZSkge1xuICAgICAgICAgIGNvbnNvbGUubG9nKGBbTWlhbV0gc2FtZSBwcmljZWJvb2sgJHtKU09OLnN0cmluZ2lmeShwcmljZWJvb2tOYW1lKX1gKTtcbiAgICAgICAgICByZXR1cm4gb2YoYmFza2V0KTtcbiAgICAgICAgfVxuICAgICAgICBjb25zb2xlLmxvZyhgW01pYW1dIHVwZGF0ZSBwcmljZWJvb2sgdG8gJHtKU09OLnN0cmluZ2lmeShwcmljZWJvb2tOYW1lKX1gKTtcbiAgICAgICAgYmFza2V0LnByaWNlYm9va0tleSA9IHByaWNlYm9va05hbWU7XG4gICAgICAgIHJldHVybiBiYXNrZXQuc2F2ZSgpLnBpcGUobWFwKChyZXNwOiBEb2N1bWVudFJlc291cmNlPEJhc2tldD4pID0+IHtcbiAgICAgICAgICBjb25zdCB1cGRhdGVkQmFza2V0ID0gdGhpcy5uZXcoKTtcbiAgICAgICAgICB1cGRhdGVkQmFza2V0LmZpbGwocmVzcCk7XG4gICAgICAgICAgdGhpcy5fYmFza2V0JC5uZXh0KHVwZGF0ZWRCYXNrZXQpO1xuICAgICAgICAgIHJldHVybiB1cGRhdGVkQmFza2V0O1xuICAgICAgICB9KSk7XG4gICAgICB9KVxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIGxvYWRQcmV2aWV3KCk6IE9ic2VydmFibGU8QmFza2V0UHJldmlld0xpbmVbXT4ge1xuICAgIHJldHVybiB0aGlzLmJhc2tldCQucGlwZShcbiAgICAgIHNraXBXaGlsZShiID0+ICFiKSxcbiAgICAgIHN3aXRjaE1hcCgoKSA9PiB0aGlzLnJlY2lwZXNTZXJ2aWNlLmxvYWRSZWNpcGVzKCkpLFxuICAgICAgc3dpdGNoTWFwKHJlY2lwZXMgPT4ge1xuICAgICAgICBjb25zdCBiYXNrZXQ6IEJhc2tldCA9IHRoaXMuX2Jhc2tldCQudmFsdWU7XG4gICAgICAgIHJldHVybiB0aGlzLmZldGNoQmFza2V0RW50cmllcyhiYXNrZXQpLnBpcGUoXG4gICAgICAgICAgbWFwKGVudHJpZXMgPT4ge1xuICAgICAgICAgICAgY29uc3QgbGluZUVudHJpZXMgPSB0aGlzLmdyb3VwQmFza2V0RW50cmllcyhyZWNpcGVzLCBlbnRyaWVzKTtcbiAgICAgICAgICAgIGNvbnN0IGxpbmVzID0gdGhpcy5yZWNpcGVzQW5kTGluZUVudHJpZXNUb0Jhc2tldFByZXZpZXdMaW5lKHJlY2lwZXMsIGxpbmVFbnRyaWVzKTtcbiAgICAgICAgICAgIHRoaXMuX2Jhc2tldFByZXZpZXckLm5leHQobGluZXMpO1xuICAgICAgICAgICAgdGhpcy5iYXNrZXRQcmV2aWV3SXNDYWxjdWxhdGluZyA9IGZhbHNlO1xuICAgICAgICAgICAgdGhpcy5iYXNrZXRTdGF0cyQubmV4dCh0aGlzLmJ1aWxkU3RhdHMobGluZXMpKTtcbiAgICAgICAgICAgIHJldHVybiBsaW5lcztcbiAgICAgICAgICB9KVxuICAgICAgICApO1xuICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBmZXRjaEJhc2tldEVudHJpZXMoYmFza2V0OiBCYXNrZXQpOiBPYnNlcnZhYmxlPEJhc2tldEVudHJ5W10+IHtcbiAgICBpZiAoIWJhc2tldCB8fCAhYmFza2V0LmNvbXBsZXRpb24gfHwgYmFza2V0LmNvbXBsZXRpb24udG90YWwgPCAxKSB7XG4gICAgICB0aGlzLl9lbnRyaWVzJC5uZXh0KFtdKTtcbiAgICAgIHJldHVybiB0aGlzLl9lbnRyaWVzJDtcbiAgICB9XG5cbiAgICBjb25zdCBwYWdlc0NvdW50ID0gTWF0aC5jZWlsKGJhc2tldC5jb21wbGV0aW9uLnRvdGFsIC8gQmFza2V0c1NlcnZpY2UuZW50cmllc1BlclBhZ2VzKTtcbiAgICByZXR1cm4gZm9ya0pvaW4oQXJyYXkocGFnZXNDb3VudCkuZmlsbCgwKS5tYXAoKHYsIGkpID0+IHRoaXMuZmV0Y2hCYXNrZXRFbnRyaWVzUGFnZShiYXNrZXQsIGkgKyAxKSkpLnBpcGUoXG4gICAgICBtYXAoKGNvbGxlY3Rpb25zOiBEb2N1bWVudENvbGxlY3Rpb248QmFza2V0RW50cnk+W10pID0+IHtcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnNhZmUtY2FsbFxuICAgICAgICBjb25zdCBlbnRyaWVzID0gKGZsYXR0ZW4oY29sbGVjdGlvbnMubWFwKGNvbCA9PiBjb2wuZGF0YSkpIGFzIEJhc2tldEVudHJ5W10pO1xuICAgICAgICBlbnRyaWVzLmZvckVhY2goKGVudHJ5OiBCYXNrZXRFbnRyeSkgPT4gZW50cnkuc2V0SXRlbXNTZWxlY3Rpb24oKSk7XG4gICAgICAgIHRoaXMuX2VudHJpZXMkLm5leHQoZW50cmllcyk7XG4gICAgICAgIHJldHVybiB0aGlzLl9lbnRyaWVzJC52YWx1ZTtcbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgYnVpbGRTdGF0cyhsaW5lczogQmFza2V0UHJldmlld0xpbmVbXSk6IEJhc2tldFN0YXRzIHtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVuc2FmZS1hc3NpZ25tZW50LCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW5zYWZlLWNhbGxcbiAgICBjb25zdCBlbnRyaWVzRm91bmQ6IEJhc2tldEVudHJ5W10gPSB1bmlvbkJ5KC4uLiBsaW5lcy5tYXAobGluZSA9PiBsaW5lLmVudHJpZXMuZm91bmQpLCAnaWQnKTtcblxuICAgIGNvbnN0IHRvdGFsUHJpY2UgPSBlbnRyaWVzRm91bmQucmVkdWNlKCh0b3RhbCwgZW50cnkpID0+IHtcbiAgICAgIGNvbnN0IGl0ZW0gPSBlbnRyeS5hdHRyaWJ1dGVzWydiYXNrZXQtZW50cmllcy1pdGVtcyddLmZpbmQoaSA9PiBpLml0ZW1faWQgPT09IGVudHJ5LmF0dHJpYnV0ZXNbJ3NlbGVjdGVkLWl0ZW0taWQnXSk7XG4gICAgICB0b3RhbCArPSAgKGVudHJ5LmF0dHJpYnV0ZXMucXVhbnRpdHkgfHwgMCkgKiBwYXJzZUZsb2F0KGl0ZW1bJ3VuaXQtcHJpY2UnXSk7XG4gICAgICByZXR1cm4gdG90YWw7XG4gICAgfSwgMCApO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHJlY2lwZXNDb3VudDogbGluZXMubGVuZ3RoLFxuICAgICAgZW50cmllc0NvdW50OiBlbnRyaWVzRm91bmQubGVuZ3RoLFxuICAgICAgdG90YWxQcmljZVxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIGZldGNoQmFza2V0RW50cmllc1BhZ2UoYmFza2V0OiBCYXNrZXQsIHBhZ2U6IG51bWJlcik6IE9ic2VydmFibGU8RG9jdW1lbnRDb2xsZWN0aW9uPEJhc2tldEVudHJ5Pj4ge1xuICAgIGxldCB1cmwgPSBbZS5taWFtQVBJLCAnYXBpL3YxL2Jhc2tldHMnLCBiYXNrZXQuaWQsICdiYXNrZXQtZW50cmllcyddLmpvaW4oJy8nKTtcbiAgICB1cmwgPSBgJHt1cmx9P2luY2x1ZGU9Z3JvY2VyaWVzLWVudHJ5LGl0ZW1zJnBhZ2VbbnVtYmVyXT0ke3BhZ2V9JnBhZ2Vbc2l6ZV09JHtCYXNrZXRzU2VydmljZS5lbnRyaWVzUGVyUGFnZXN9YDtcblxuICAgIHJldHVybiB0aGlzLmh0dHAuZ2V0KHVybCkucGlwZShcbiAgICAgIHNraXBXaGlsZSgocmVzcDogRG9jdW1lbnRDb2xsZWN0aW9uPEJhc2tldEVudHJ5PikgPT4gcmVzcC5pc19sb2FkaW5nKSxcbiAgICAgIG1hcCgocmVzcDogRG9jdW1lbnRDb2xsZWN0aW9uPEJhc2tldEVudHJ5PikgPT4ge1xuICAgICAgICBjb25zdCBiYXNrZXRFbnRyaWVzID0gdGhpcy5iYXNrZXRFbnRyaWVzU2VydmljZS5uZXdDb2xsZWN0aW9uKCk7XG4gICAgICAgIGJhc2tldEVudHJpZXMuZmlsbChyZXNwKTtcbiAgICAgICAgcmV0dXJuIGJhc2tldEVudHJpZXM7XG4gICAgICB9KVxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIHJlY2lwZXNBbmRMaW5lRW50cmllc1RvQmFza2V0UHJldmlld0xpbmUocmVjaXBlczogUmVjaXBlW10sIGxpbmVFbnRyaWVzOiBMaW5lRW50cmllc1tdKTogQmFza2V0UHJldmlld0xpbmVbXSB7XG4gICAgcmV0dXJuIHJlY2lwZXMubWFwKChyZWNpcGUsIGlkeCkgPT4ge1xuICAgICAgY29uc3QgaXRlbXNDb3VudCA9IGxpbmVFbnRyaWVzW2lkeF0uZm91bmQubGVuZ3RoO1xuICAgICAgbGV0IHJlY2lwZVByaWNlID0gMC4wO1xuICAgICAgY29uc3QgZ3Vlc3RzID0gcmVjaXBlLm1vZGlmaWVkR3Vlc3RzIHx8IHBhcnNlSW50KHJlY2lwZS5ndWVzdHMsIDEwKTtcblxuICAgICAgbGluZUVudHJpZXNbaWR4XS5mb3VuZC5mb3JFYWNoKGVudHJ5ID0+IHtcbiAgICAgICAgY29uc3Qgc2VsZWN0ZWRJdGVtID0gZW50cnkuYXR0cmlidXRlc1snYmFza2V0LWVudHJpZXMtaXRlbXMnXS5maW5kKGl0ZW0gPT4gaXRlbS5pdGVtX2lkID09PSBlbnRyeS5hdHRyaWJ1dGVzWydzZWxlY3RlZC1pdGVtLWlkJ10pO1xuICAgICAgICBjb25zdCBxdHkgPSBlbnRyeS5hdHRyaWJ1dGVzLnF1YW50aXR5O1xuICAgICAgICBjb25zdCB1bml0UHJpY2UgPSBwYXJzZUZsb2F0KHNlbGVjdGVkSXRlbVsndW5pdC1wcmljZSddKTtcbiAgICAgICAgY29uc3QgbnVtYmVyT2ZSZWNpcGVzRm9yRW50cnkgPSBlbnRyeS5hdHRyaWJ1dGVzWydyZWNpcGUtaWRzJ10ubGVuZ3RoIHx8IDE7XG5cbiAgICAgICAgcmVjaXBlUHJpY2UgKz0gKHF0eSAqIHVuaXRQcmljZSkgLyBudW1iZXJPZlJlY2lwZXNGb3JFbnRyeTtcbiAgICAgIH0pO1xuICAgICAgY29uc3QgcHJpY2VQZXJHdWVzdCA9IHJlY2lwZVByaWNlIC8gZ3Vlc3RzO1xuXG4gICAgICByZXR1cm4gQmFza2V0UHJldmlld0xpbmUuZnJvbVJlY2lwZShyZWNpcGUsIGl0ZW1zQ291bnQsIHByaWNlUGVyR3Vlc3QsIHJlY2lwZVByaWNlLCBsaW5lRW50cmllc1tpZHhdKTtcbiAgICB9KS5zb3J0KChhLCBiKSA9PiByZWNpcGVzLmZpbmRJbmRleChyID0+IHIuaWQgPT09IGEuaWQpIC0gcmVjaXBlcy5maW5kSW5kZXgociA9PiByLmlkID09PSBiLmlkKSk7XG4gIH1cblxuICBwcml2YXRlIGdyb3VwQmFza2V0RW50cmllcyhyZWNpcGVzOiBSZWNpcGVbXSwgZW50cmllczogQmFza2V0RW50cnlbXSk6IExpbmVFbnRyaWVzW10ge1xuICAgIHJldHVybiByZWNpcGVzLm1hcChyZWNpcGUgPT4ge1xuICAgICAgY29uc3QgbGluZUVudHJpZXMgPSB7IGZvdW5kOiBbXSwgbm90Rm91bmQ6IFtdLCBvZnRlbkRlbGV0ZWQ6IFtdLCByZW1vdmVkOiBbXSB9IGFzIExpbmVFbnRyaWVzO1xuICAgICAgZW50cmllc1xuICAgICAgICAuZmlsdGVyKGVudHJ5ID0+IGVudHJ5LmF0dHJpYnV0ZXNbJ3JlY2lwZS1pZHMnXS5pbmNsdWRlcyhwYXJzZUludChyZWNpcGUuaWQsIDEwKSkpXG4gICAgICAgIC5mb3JFYWNoKGVudHJ5ID0+IHtcbiAgICAgICAgICBjb25zdCBhdmFpbGFibGUgPSBlbnRyeS5hdHRyaWJ1dGVzWydzZWxlY3RlZC1pdGVtLWlkJ107XG4gICAgICAgICAgaWYgKGF2YWlsYWJsZSkge1xuICAgICAgICAgICAgc3dpdGNoIChlbnRyeS5hdHRyaWJ1dGVzWydncm9jZXJpZXMtZW50cnktc3RhdHVzJ10pIHtcbiAgICAgICAgICAgICAgY2FzZSAnb2Z0ZW5fZGVsZXRlZCc6IHtcbiAgICAgICAgICAgICAgICBsaW5lRW50cmllcy5vZnRlbkRlbGV0ZWQucHVzaChlbnRyeSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgY2FzZSAnZGVsZXRlZCc6IHtcbiAgICAgICAgICAgICAgICBsaW5lRW50cmllcy5yZW1vdmVkLnB1c2goZW50cnkpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGRlZmF1bHQ6IHtcbiAgICAgICAgICAgICAgICBsaW5lRW50cmllcy5mb3VuZC5wdXNoKGVudHJ5KTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBsaW5lRW50cmllcy5ub3RGb3VuZC5wdXNoKGVudHJ5KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgcmV0dXJuIGxpbmVFbnRyaWVzO1xuICAgIH0pO1xuICB9XG59XG4iXX0=
703
+ }], function () { return [{ type: i1.HttpClient }, { type: i2.BasketEntriesService }, { type: i3.PointOfSalesService }, { type: i4.RecipesService }, { type: i5.AnalyticsService }, { type: i6.UserService }, { type: i7.ToasterService }]; }, null); })();
704
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFza2V0cy5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6Ii9idWlsZHMvbWlhbS9uZy1taWFtLXNkay9wcm9qZWN0cy9uZy1taWFtL3NyYy8iLCJzb3VyY2VzIjpbImxpYi9fc2VydmljZXMvYmFza2V0cy5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUNsRCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNDLE9BQU8sRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQzdDLE9BQU8sRUFBd0MsT0FBTyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQzVFLE9BQU8sRUFBRSxlQUFlLEVBQUUsUUFBUSxFQUFjLEVBQUUsRUFBZ0IsTUFBTSxNQUFNLENBQUM7QUFDL0UsT0FBTyxFQUFFLFlBQVksRUFBRSxHQUFHLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsR0FBRyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDcEYsT0FBTyxFQUFFLE1BQU0sRUFBZSxpQkFBaUIsRUFBdUIsTUFBTSxZQUFZLENBQUM7QUFFekYsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFJckUsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQzFELE9BQU8sRUFBRSxXQUFXLElBQUksQ0FBQyxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDL0QsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDdkQsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDaEUsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDL0QsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ25ELE9BQU8sRUFBRSxjQUFjLEVB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QUksU0FBUyxFQUFFO29CQUNiLFFBQVEsS0FBSyxDQUFDLE1BQU0sRUFBRTt3QkFDcEIsS0FBSyxlQUFlLENBQUMsQ0FBQzs0QkFDcEIsV0FBVyxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7NEJBQ3JDLE1BQU07eUJBQ1A7d0JBQ0QsS0FBSyxTQUFTLENBQUMsQ0FBQzs0QkFDZCxXQUFXLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQzs0QkFDaEMsTUFBTTt5QkFDUDt3QkFDRCxPQUFPLENBQUMsQ0FBQzs0QkFDUCxXQUFXLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQzs0QkFDOUIsTUFBTTt5QkFDUDtxQkFDRjtpQkFDRjtxQkFBTTtvQkFDTCxXQUFXLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztpQkFDbEM7Z0JBQ0QsV0FBVyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDOUIsQ0FBQyxDQUFDLENBQUM7WUFDTCxPQUFPLFdBQVcsQ0FBQztRQUNyQixDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7O0FBejJCTSw4QkFBZSxHQUFHLEVBQUUsQ0FBQzs0RUFEakIsY0FBYztzREFBZCxjQUFjLFdBQWQsY0FBYyxtQkFGYixNQUFNO2tEQUVQLGNBQWM7Y0FIMUIsVUFBVTtlQUFDO2dCQUNWLFVBQVUsRUFBRSxNQUFNO2FBQ25CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSHR0cENsaWVudCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcbmltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IGZsYXR0ZW4sIHVuaW9uQnkgfSBmcm9tICdsb2Rhc2gtZXMnO1xuaW1wb3J0IHsgRG9jdW1lbnRDb2xsZWN0aW9uLCBEb2N1bWVudFJlc291cmNlLCBTZXJ2aWNlIH0gZnJvbSAnbmd4LWpzb25hcGknO1xuaW1wb3J0IHsgQmVoYXZpb3JTdWJqZWN0LCBmb3JrSm9pbiwgT2JzZXJ2YWJsZSwgb2YsIFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgZGVib3VuY2VUaW1lLCBtYXAsIHNraXBXaGlsZSwgc3dpdGNoTWFwLCB0YWtlLCB0YXAgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBCYXNrZXQsIEJhc2tldEVudHJ5LCBCYXNrZXRQcmV2aWV3TGluZSwgTGluZUVudHJpZXMsIFJlY2lwZSB9IGZyb20gJy4uL19tb2RlbHMnO1xuaW1wb3J0IHsgQmFza2V0QWN0aW9uIH0gZnJvbSAnLi4vX3R5cGVzL2Jhc2tldC1hY3Rpb24nO1xuaW1wb3J0IHsgQmFza2V0QWN0aW9uVHlwZSB9IGZyb20gJy4uL190eXBlcy9iYXNrZXQtYWN0aW9uLXR5cGUuZW51bSc7XG5pbXBvcnQgeyBCYXNrZXRTdGF0cyB9IGZyb20gJy4uL190eXBlcy9iYXNrZXQtc3RhdHMnO1xuaW1wb3J0IHsgQ29tcGFyYWJsZVByb2R1Y3QgfSBmcm9tICcuLi9fdHlwZXMvYnVpbGRlZC9jb21wYXJhYmxlLXByb2R1Y3QnO1xuaW1wb3J0IHsgQ3VzdG9tUHJvcGVydGllcywgRXZlbnRUcmFjZSB9IGZyb20gJy4uL190eXBlcy9ldmVudC10cmFjZSc7XG5pbXBvcnQgeyBNZXNzYWdlVHlwZSB9IGZyb20gJy4uL190eXBlcy9tZXNzYWdlLXR5cGUuZW51bSc7XG5pbXBvcnQgeyBlbnZpcm9ubWVudCBhcyBlIH0gZnJvbSAnLi4vZW52aXJvbm1lbnRzL2Vudmlyb25tZW50JztcbmltcG9ydCB7IEFuYWx5dGljc1NlcnZpY2UgfSBmcm9tICcuL2FuYWx5dGljcy5zZXJ2aWNlJztcbmltcG9ydCB7IEJhc2tldEVudHJpZXNTZXJ2aWNlIH0gZnJvbSAnLi9iYXNrZXQtZW50cmllcy5zZXJ2aWNlJztcbmltcG9ydCB7IFBvaW50T2ZTYWxlc1NlcnZpY2UgfSBmcm9tICcuL3BvaW50LW9mLXNhbGVzLnNlcnZpY2UnO1xuaW1wb3J0IHsgUmVjaXBlc1NlcnZpY2UgfSBmcm9tICcuL3JlY2lwZXMuc2VydmljZSc7XG5pbXBvcnQgeyBUb2FzdGVyU2VydmljZSB9IGZyb20gJy4vdG9hc3Rlci5zZXJ2aWNlJztcbmltcG9ydCB7IFVzZXJTZXJ2aWNlIH0gZnJvbSAnLi91c2VyLnNlcnZpY2UnO1xuXG5jb25zdCBCQVNLRVRfU1BBUlNFX0ZJRUxEUyA9IHtcbiAgYmFza2V0czogWyd0b3RhbC1wcmljZScsICdwcmljZWJvb2sta2V5JywgJ3JlY2lwZXMtaW5mb3MnLCAnY29tcGxldGlvbiddXG59O1xuXG5cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnXG59KVxuZXhwb3J0IGNsYXNzIEJhc2tldHNTZXJ2aWNlIGV4dGVuZHMgU2VydmljZTxCYXNrZXQ+IHtcbiAgc3RhdGljIGVudHJpZXNQZXJQYWdlcyA9IDMwO1xuXG4gIHJlc291cmNlID0gQmFza2V0O1xuICB0eXBlID0gJ2Jhc2tldHMnO1xuICBfYmFza2V0JCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8QmFza2V0PihudWxsKTtcbiAgX2Jhc2tldFByZXZpZXckID0gbmV3IEJlaGF2aW9yU3ViamVjdDxCYXNrZXRQcmV2aWV3TGluZVtdPihudWxsKTtcbiAgYmFza2V0U3RhdHMkID0gbmV3IEJlaGF2aW9yU3ViamVjdDxCYXNrZXRTdGF0cz4obnVsbCk7XG4gIGJhc2tldElzRmV0Y2hpbmcgPSBmYWxzZTtcbiAgYmFza2V0UHJldmlld0lzQ2FsY3VsYXRpbmcgPSBmYWxzZTtcbiAgYmFza2V0SW5pdENhbGxlZCA9IGZhbHNlO1xuXG4gIHByaXZhdGUgYmFza2V0QWN0aW9uc1F1ZXVlID0gbmV3IEJlaGF2aW9yU3ViamVjdDxCYXNrZXRBY3Rpb25bXT4oW10pO1xuICBwcml2YXRlIGN1cnJlbnRTdWJzY3JpcHRpb246IFN1YnNjcmlwdGlvbjtcbiAgcHJpdmF0ZSBfZW50cmllcyQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PEJhc2tldEVudHJ5W10+KFtdKTtcbiAgcHJpdmF0ZSBhY3Rpb25zQmVpbmdQcm9jZXNzZWQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PEJhc2tldEFjdGlvbltdPihbXSk7XG4gIHByaXZhdGUgYWN0aW9uc0JlaW5nT3ZlcnJpZGVuOiBCYXNrZXRBY3Rpb25bXSA9IFtdO1xuICBwcml2YXRlIHN1YnNjcmlwdGlvbnM6IFN1YnNjcmlwdGlvbltdID0gW107XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBodHRwOiBIdHRwQ2xpZW50LFxuICAgIHByaXZhdGUgYmFza2V0RW50cmllc1NlcnZpY2U6IEJhc2tldEVudHJpZXNTZXJ2aWNlLFxuICAgIHByaXZhdGUgcG9zU2VydmljZTogUG9pbnRPZlNhbGVzU2VydmljZSxcbiAgICBwcml2YXRlIHJlY2lwZXNTZXJ2aWNlOiBSZWNpcGVzU2VydmljZSxcbiAgICBwcml2YXRlIGFuYWx5dGljc1NlcnZpY2U6IEFuYWx5dGljc1NlcnZpY2UsXG4gICAgcHJpdmF0ZSB1c2Vyc1NlcnZpY2U6IFVzZXJTZXJ2aWNlLFxuICAgIHByaXZhdGUgdG9hc3RlclNlcnZpY2U6IFRvYXN0ZXJTZXJ2aWNlXG4gICkge1xuICAgIHN1cGVyKCk7XG4gICAgdGhpcy5yZWdpc3RlcigpO1xuICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5wdXNoKFxuICAgICAgdGhpcy5iYXNrZXRBY3Rpb25zUXVldWUucGlwZShcbiAgICAgICAgZGVib3VuY2VUaW1lKDIwMCksXG4gICAgICAgIHNraXBXaGlsZShhY3Rpb25zID0+IGFjdGlvbnMubGVuZ3RoID09PSAwIHx8IHRoaXMuYWN0aW9uc0JlaW5nUHJvY2Vzc2VkLnZhbHVlLmxlbmd0aCA+IDApLFxuICAgICAgICB0YXAoKCkgPT4gdGhpcy5lbXB0eUFjdGlvbnNRdWV1ZSgpKVxuICAgICAgKS5zdWJzY3JpYmUoKVxuICAgICk7XG4gICAgaWYgKHRoaXMucmVjaXBlc1NlcnZpY2UuY29uZmlybWF0aW9uVG9hc3Rlcikge1xuICAgICAgdGhpcy5zaG93UmVjaXBlQWRkZWRUb2FzdGVyKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiBHRVRURVJTICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiAqKi9cblxuICAvKipcbiAgICogV2Ugd2FudCBiYXNrZXQkIHRvIGJlIGEgc2luZ2xldG9uIHRoYXQgYWx3YXlzIHJldHVybnMgdGhlIHNhbWUgYmFza2V0LCBzbyBpdCBpcyBmZXRjaGVkIG9ubHkgd2hlbiBuZWNlc3NhcnkuXG4gICAqIEF0IGFueSBwb2ludCBpbiB0aW1lIHRoZSBiYXNrZXQgY2FuIGJlIGZldGNoZWQgdmlhIHRoZSBpbml0QmFza2V0IGZ1bmN0aW9uIChpZiB3ZSB3YW50IHRvIGZldGNoIGl0IG9uIHN0YXJ0dXAgdG8gc2F2ZSB0aW1lIGxhdGVyKVxuICAgKiBCdXQgaWYgaW5pdEJhc2tldCBpcyBub3QgY2FsbGVkLCB0aGUgYmFza2V0IHdpbGwgb25seSBiZSBmZXRjaGVkIHRoZSAxc3QgdGltZSBpdCBpcyBuZWVkZWQuXG4gICAqL1xuICBnZXQgYmFza2V0JCgpOiBCZWhhdmlvclN1YmplY3Q8QmFza2V0PiB7XG4gICAgaWYgKCF0aGlzLl9iYXNrZXQkLnZhbHVlICYmICF0aGlzLmJhc2tldElzRmV0Y2hpbmcpIHtcbiAgICAgIHRoaXMuYmFza2V0SXNGZXRjaGluZyA9IHRydWU7XG4gICAgICB0aGlzLmluaXRCYXNrZXQoKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX2Jhc2tldCQ7XG4gIH1cblxuICAvKipcbiAgICogYmFza2V0UHJldmlldyQgc2hvdWxkIGFsc28gYmUgYSBzaW5nbGV0b24sIGFuZCBhcyB3ZWxsIGFzIGJhc2tldCQgaXQgd2lsbCBiZSBjYWxjdWxhdGVkIGZvciB0aGUgZmlyc3QgdGltZSBvbmx5IHdoZW4gbmVjZXNzYXJ5XG4gICAqIG9yIGlmIGxvYWRQcmV2aWV3IGlzIGNhbGxlZCBiZWZvcmVcbiAgICovXG4gIGdldCBiYXNrZXRQcmV2aWV3JCgpOiBCZWhhdmlvclN1YmplY3Q8QmFza2V0UHJldmlld0xpbmVbXT4ge1xuICAgIGlmICghdGhpcy5fYmFza2V0UHJldmlldyQudmFsdWUgJiYgIXRoaXMuYmFza2V0UHJldmlld0lzQ2FsY3VsYXRpbmcpIHtcbiAgICAgIHRoaXMuYmFza2V0UHJldmlld0lzQ2FsY3VsYXRpbmcgPSB0cnVlO1xuICAgICAgdGhpcy5pbml0QmFza2V0KCk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9iYXNrZXRQcmV2aWV3JDtcbiAgfVxuXG4gIC8qKlxuICAgKiBUbyB1c2Ugd2hlbiBuZWVkaW5nIHRvIGJlIHN1cmUgdGhhdCBiYXNrZXQgd2FzIGZldGNoZWQgYmVmb3JlIGRvaW5nIGFuIGFjdGlvbiB0aGF0IGRvZXNuJ3QgbmVlZCB0byBzdGF5IHN1YnNjcmliZWQgdG8gYmFza2V0JFxuICAgKiBUaGlzIG1ldGhvZCBpcyBtZWFudCB0byBiZSBhbiBlcXVpdmFsZW50IG9mIGJhc2tldCQudmFsdWUgYnV0IGFzeW5jaHJvbm91c1xuICAgKi9cbiAgZ2V0IHdhaXRGb3JCYXNrZXQoKTogT2JzZXJ2YWJsZTxCYXNrZXQ+IHtcbiAgICByZXR1cm4gdGhpcy5iYXNrZXQkLnBpcGUoXG4gICAgICBza2lwV2hpbGUoYiA9PiAhYiksXG4gICAgICB0YWtlKDEpXG4gICAgKTtcbiAgfVxuXG4gIC8qKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiBRVUVVRSBVVElMUyBUTyBMT0NLIE1PUkUgQUNUSU9OUyBPUiBESVNQTEFZIExPQURFUlMgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKiovXG5cbiAgLy8gVXRpbCBtZXRob2QgdG8gYXZvaWQgcmVwZWF0aW5nIHRvbyBtdWNoIGZvciB0aGUgbmV4dCA2IG1ldGhvZHNcbiAgcHJpdmF0ZSBzdWJqZWN0Q29udGFpbnNSZWNpcGVJZChzdWJqZWN0OiBCZWhhdmlvclN1YmplY3Q8QmFza2V0QWN0aW9uW10+LCB0eXBlOiBCYXNrZXRBY3Rpb25UeXBlLCByZWNpcGVJZDogc3RyaW5nKTogT2JzZXJ2YWJsZTxib29sZWFuPiB7XG4gICAgcmV0dXJuIHN1YmplY3QucGlwZShtYXAodmFsdWUgPT4gdmFsdWUuc29tZShhID0+IGEudHlwZSA9PT0gdHlwZSAmJiBhLnBhcmFtcy5yZWNpcGVJZCA9PT0gcmVjaXBlSWQpKSk7XG4gIH1cblxuICAvLyBVdGlsIG1ldGhvZCB0byBhdm9pZCByZXBlYXRpbmcgdG9vIG11Y2ggZm9yIHRoZSBuZXh0IDYgbWV0aG9kc1xuICBwcml2YXRlIHN1YmplY3RDb250YWluc0luZ3JlZGllbnRJZChcbiAgICBzdWJqZWN0OiBCZWhhdmlvclN1YmplY3Q8QmFza2V0QWN0aW9uW10+LCB0eXBlOiBCYXNrZXRBY3Rpb25UeXBlLCBpbmdyZWRpZW50SWQ6IHN0cmluZ1xuICApOiBPYnNlcnZhYmxlPGJvb2xlYW4+IHtcbiAgICByZXR1cm4gc3ViamVjdC5waXBlKG1hcCh2YWx1ZSA9PiB2YWx1ZS5zb21lKGEgPT4gYS50eXBlID09PSB0eXBlICYmIGEucGFyYW1zLmluZ3JlZGllbnRJZCA9PT0gaW5ncmVkaWVudElkKSkpO1xuICB9XG5cbiAgcmVjaXBlV2lsbEJlQWRkZWQocmVjaXBlSWQ6IHN0cmluZyk6IE9ic2VydmFibGU8Ym9vbGVhbj4ge1xuICAgIHJldHVybiB0aGlzLnN1YmplY3RDb250YWluc1JlY2lwZUlkKHRoaXMuYmFza2V0QWN0aW9uc1F1ZXVlLCBCYXNrZXRBY3Rpb25UeXBlLkFERF9SRUNJUEUsIHJlY2lwZUlkKTtcbiAgfVxuXG4gIHJlY2lwZVdpbGxCZVJlbW92ZWQocmVjaXBlSWQ6IHN0cmluZyk6IE9ic2VydmFibGU8Ym9vbGVhbj4ge1xuICAgIHJldHVybiB0aGlzLnN1YmplY3RDb250YWluc1JlY2lwZUlkKHRoaXMuYmFza2V0QWN0aW9uc1F1ZXVlLCBCYXNrZXRBY3Rpb25UeXBlLlJFTU9WRV9SRUNJUEUsIHJlY2lwZUlkKTtcbiAgfVxuXG4gIHJlY2lwZVdpbGxCZVVwZGF0ZWQocmVjaXBlSWQ6IHN0cmluZyk6IE9ic2VydmFibGU8Ym9vbGVhbj4ge1xuICAgIHJldHVybiB0aGlzLnN1YmplY3RDb250YWluc1JlY2lwZUlkKHRoaXMuYmFza2V0QWN0aW9uc1F1ZXVlLCBCYXNrZXRBY3Rpb25UeXBlLlVQREFURV9SRUNJUEUsIHJlY2lwZUlkKTtcbiAgfVxuXG4gIHJlY2lwZUlzQmVpbmdBZGRlZChyZWNpcGVJZDogc3RyaW5nKTogT2JzZXJ2YWJsZTxib29sZWFuPiB7XG4gICAgcmV0dXJuIHRoaXMuc3ViamVjdENvbnRhaW5zUmVjaXBlSWQodGhpcy5hY3Rpb25zQmVpbmdQcm9jZXNzZWQsIEJhc2tldEFjdGlvblR5cGUuQUREX1JFQ0lQRSwgcmVjaXBlSWQpO1xuICB9XG5cbiAgcmVjaXBlSXNCZWluZ1JlbW92ZWQocmVjaXBlSWQ6IHN0cmluZyk6IE9ic2VydmFibGU8Ym9vbGVhbj4ge1xuICAgIHJldHVybiB0aGlzLnN1YmplY3RDb250YWluc1JlY2lwZUlkKHRoaXMuYWN0aW9uc0JlaW5nUHJvY2Vzc2VkLCBCYXNrZXRBY3Rpb25UeXBlLlJFTU9WRV9SRUNJUEUsIHJlY2lwZUlkKTtcbiAgfVxuXG4gIHJlY2lwZUlzQmVpbmdVcGRhdGVkKHJlY2lwZUlkOiBzdHJpbmcpOiBPYnNlcnZhYmxlPGJvb2xlYW4+IHtcbiAgICByZXR1cm4gdGhpcy5zdWJqZWN0Q29udGFpbnNSZWNpcGVJZCh0aGlzLmFjdGlvbnNCZWluZ1Byb2Nlc3NlZCwgQmFza2V0QWN0aW9uVHlwZS5VUERBVEVfUkVDSVBFLCByZWNpcGVJZCk7XG4gIH1cblxuICBpbmdyZWRpZW50V2lsbEJlQWRkZWQoaW5ncmVkaWVudElkOiBzdHJpbmcpOiBPYnNlcnZhYmxlPGJvb2xlYW4+IHtcbiAgICByZXR1cm4gdGhpcy5zdWJqZWN0Q29udGFpbnNJbmdyZWRpZW50SWQodGhpcy5iYXNrZXRBY3Rpb25zUXVldWUsIEJhc2tldEFjdGlvblR5cGUuQUREX1BST0RVQ1QsIGluZ3JlZGllbnRJZCk7XG4gIH1cblxuICBpbmdyZWRpZW50V2lsbEJlUmVtb3ZlZChpbmdyZWRpZW50SWQ6IHN0cmluZyk6IE9ic2VydmFibGU8Ym9vbGVhbj4ge1xuICAgIHJldHVybiB0aGlzLnN1YmplY3RDb250YWluc0luZ3JlZGllbnRJZCh0aGlzLmJhc2tldEFjdGlvbnNRdWV1ZSwgQmFza2V0QWN0aW9uVHlwZS5SRU1PVkVfUFJPRFVDVCwgaW5ncmVkaWVudElkKTtcbiAgfVxuXG4gIHJlY2lwZXNXaWxsQmVBZGRlZCgpOiBPYnNlcnZhYmxlPGJvb2xlYW4+IHtcbiAgICByZXR1cm4gdGhpcy5iYXNrZXRBY3Rpb25zUXVldWUucGlwZShtYXAocXVldWUgPT4gcXVldWUuc29tZShhID0+IGEudHlwZSA9PT0gQmFza2V0QWN0aW9uVHlwZS5BRERfUkVDSVBFKSkpO1xuICB9XG5cbiAgcmVjaXBlc1dpbGxCZVJlbW92ZWQoKTogT2JzZXJ2YWJsZTxib29sZWFuPiB7XG4gICAgcmV0dXJuIHRoaXMuYmFza2V0QWN0aW9uc1F1ZXVlLnBpcGUobWFwKHF1ZXVlID0+IHF1ZXVlLnNvbWUoYSA9PiBhLnR5cGUgPT09IEJhc2tldEFjdGlvblR5cGUuUkVNT1ZFX1JFQ0lQRSkpKTtcbiAgfVxuXG4gIHJlY2lwZXNXaWxsQmVVcGRhdGVkKCk6IE9ic2VydmFibGU8Ym9vbGVhbj4ge1xuICAgIHJldHVybiB0aGlzLmJhc2tldEFjdGlvbnNRdWV1ZS5waXBlKG1hcChxdWV1ZSA9PiBxdWV1ZS5zb21lKGEgPT4gYS50eXBlID09PSBCYXNrZXRBY3Rpb25UeXBlLlVQREFURV9SRUNJUEUpKSk7XG4gIH1cblxuICBwcm9kdWN0c1dpbGxCZUFkZGVkKCk6IE9ic2VydmFibGU8bnVtYmVyPiB7XG4gICAgcmV0dXJuIHRoaXMuYmFza2V0QWN0aW9uc1F1ZXVlLnBpcGUobWFwKHF1ZXVlID0+IHF1ZXVlLmZpbHRlcihhID0+IGEudHlwZSA9PT0gQmFza2V0QWN0aW9uVHlwZS5BRERfUFJPRFVDVCkubGVuZ3RoKSk7XG4gIH1cblxuICAvKiogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiBVVElMUyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICoqL1xuXG4gIC8vIENoZWNrIGlmIHRoZSByZWNpcGVJZCBpcyBpbiB0aGUgQmFza2V0J3MgcmVjaXBlcy1pbmZvc1xuICByZWNpcGVJc0luQmFza2V0KHJlY2lwZUlkOiBzdHJpbmcpOiBPYnNlcnZhYmxlPGJvb2xlYW4+IHtcbiAgICByZXR1cm4gdGhpcy5iYXNrZXQkLnBpcGUoXG4gICAgICBza2lwV2hpbGUoYiA9PiAhYiksXG4gICAgICBtYXAoYmFza2V0ID0+IGJhc2tldC5oYXNSZWNpcGUocmVjaXBlSWQpKVxuICAgICk7XG4gIH1cblxuICBndWVzdHNGb3JSZWNpcGUocmVjaXBlSWQ6IHN0cmluZyk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuYmFza2V0JC52YWx1ZT8uZ3Vlc3RzRm9yUmVjaXBlKHJlY2lwZUlkKTtcbiAgfVxuXG4gIHByaXZhdGUgc2hvd1JlY2lwZUFkZGVkVG9hc3RlcigpOiB2b2lkIHtcbiAgICBsZXQgcHJldmlvdXNOdW1iZXJPZlByb2R1Y3RUb0FkZCA9IDA7XG4gICAgdGhpcy5zdWJzY3JpcHRpb25zLnB1c2goXG4gICAgICB0aGlzLnByb2R1Y3RzV2lsbEJlQWRkZWQoKS5waXBlKFxuICAgICAgICBza2lwV2hpbGUobnVtYmVyID0+IHByZXZpb3VzTnVtYmVyT2ZQcm9kdWN0VG9BZGQgPT09IG51bWJlcilcbiAgICAgICkuc3Vic2NyaWJlKG51bWJlciA9PiB7XG4gICAgICAgIGlmICggcHJldmlvdXNOdW1iZXJPZlByb2R1Y3RUb0FkZCA+IG51bWJlcikge1xuICAgICAgICAgIGNvbnN0IGFydGljbGUgPSBwcmV2aW91c051bWJlck9mUHJvZHVjdFRvQWRkIC0gbnVtYmVyID09PSAxID8gJ2FydGljbGUgYWpvdXTDqScgOiAnYXJ0aWNsZXMgYWpvdXTDqXMnO1xuICAgICAgICAgIGNvbnN0IG1zZyA9IGAke3ByZXZpb3VzTnVtYmVyT2ZQcm9kdWN0VG9BZGQgLSBudW1iZXJ9ICR7YXJ0aWNsZX0gw6Agdm90cmUgcGFuaWVyYDtcbiAgICAgICAgICB0aGlzLnRvYXN0ZXJTZXJ2aWNlLnNob3coTWVzc2FnZVR5cGUuU3VjY2VzcywgbXNnLCAnJywgZmFsc2UpO1xuICAgICAgICB9XG4gICAgICAgIHByZXZpb3VzTnVtYmVyT2ZQcm9kdWN0VG9BZGQgPSBudW1iZXI7XG4gICAgICB9KVxuICAgICk7XG4gIH1cblxuICAvKiogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogTE9BRCAvIFJFTE9BRCAvIFJFU0VUICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICoqL1xuXG4gIHJlbG9hZEJhc2tldCgpOiBPYnNlcnZhYmxlPEJhc2tldD4ge1xuICAgIHJldHVybiB0aGlzLnJlZnJlc2hDdXJyZW50QmFza2V0KCkucGlwZSh0YWtlKDEpKTtcbiAgfVxuXG4gIGluaXRCYXNrZXQoKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmJhc2tldEluaXRDYWxsZWQpIHtcbiAgICAgIHRoaXMuYmFza2V0SW5pdENhbGxlZCA9IHRydWU7XG4gICAgICB0aGlzLmxvYWRCYXNrZXQoKS5zdWJzY3JpYmUoKTtcbiAgICAgIHRoaXMubG9hZFByZXZpZXcoKS5zdWJzY3JpYmUoKTtcbiAgICB9XG4gIH1cblxuICByZWZyZXNoQ3VycmVudEJhc2tldCgpOiBPYnNlcnZhYmxlPEJhc2tldD4ge1xuICAgIHJldHVybiB0aGlzLnBvc1NlcnZpY2UucG9zJC5waXBlKFxuICAgICAgc2tpcFdoaWxlKHBvcyA9PiAhcG9zKSxcbiAgICAgIHRha2UoMSksXG4gICAgICBzd2l0Y2hNYXAocG9zID0+IHtcbiAgICAgICAgY29uc29sZS5sb2coJ1tNaWFtXSByZWZyZXNoaW5nIGJhc2tldCcpO1xuICAgICAgICBjb25zdCBjYWNoZWRCYXNrZXRJZCA9IGxvY2FsU3RvcmFnZS5nZXRJdGVtKCdfbWlhbS9iYXNrZXRJZCcpO1xuICAgICAgICBjb25zdCBiYXNlUm91dGUgPSAnY3VycmVudD9wb2ludF9vZl9zYWxlX2lkPScgKyBwb3MuaWQ7XG4gICAgICAgIGNvbnN0IGVuZHBvaW50ID0gKGNhY2hlZEJhc2tldElkPy50b1N0cmluZygpLm1hdGNoKC9eWzAtOV0rJC8pID8gYmFzZVJvdXRlICsgJyZtZXJnZV93aXRoPScgKyBjYWNoZWRCYXNrZXRJZCA6IGJhc2VSb3V0ZSkgK1xuICAgICAgICAgIGAmZmllbGRzW2Jhc2tldHNdPSR7QkFTS0VUX1NQQVJTRV9GSUVMRFMuYmFza2V0cy5qb2luKCcsJyl9YDtcbiAgICAgICAgLy8gQ2FuY2VsIGxhc3Qgc3Vic2NyaXB0aW9uIGJlZm9yZSBzdGFydGluZyBhbm90aGVyIG9uZVxuICAgICAgICBpZiAodGhpcy5jdXJyZW50U3Vic2NyaXB0aW9uKSB7XG4gICAgICAgICAgdGhpcy5jdXJyZW50U3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jdXJyZW50U3Vic2NyaXB0aW9uID0gdGhpcy5nZXQoZW5kcG9pbnQpLnBpcGUoXG4gICAgICAgICAgc2tpcFdoaWxlKGJhc2tldCA9PiBiYXNrZXQuaXNfbG9hZGluZyksXG4gICAgICAgICAgc3dpdGNoTWFwKGJhc2tldCA9PiB0aGlzLnVwZGF0ZUxvY2FsQmFza2V0KGJhc2tldCkpXG4gICAgICAgICkuc3Vic2NyaWJlKCk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuX2Jhc2tldCQ7XG4gICAgICB9KVxuICAgICk7XG4gIH1cblxuICByZXNldEJhc2tldChldmVudFRyYWNlOiBFdmVudFRyYWNlID0geyBvcmlnaW5QYXRoOiAnJywgcHJvcHM6IHt9IH0pOiBPYnNlcnZhYmxlPHZvaWQ+IHtcbiAgICBjb25zb2xlLmxvZygnW01pYW1dIHJlc2V0dGluZyBiYXNrZXQnKTtcbiAgICB0aGlzLmFuYWx5dGljc1NlcnZpY2Uuc2VuZEV2ZW50V2hlblJlYWR5KHRoaXMuYW5hbHl0aWNzU2VydmljZS5FVkVOVF9SRUNJUEVfUkVTRVQsIGV2ZW50VHJhY2Uub3JpZ2luUGF0aCwgZXZlbnRUcmFjZS5wcm9wcyk7XG4gICAgcmV0dXJuIHRoaXMucG9zU2VydmljZS5wb3MkLnBpcGUoXG4gICAgICBza2lwV2hpbGUocG9zID0+ICFwb3MpLFxuICAgICAgdGFrZSgxKSxcbiAgICAgIHN3aXRjaE1hcChwb3MgPT4gdGhpcy53YWl0Rm9yQmFza2V0LnBpcGUoXG4gICAgICAgIHRhcChiYXNrZXQgPT4gdGhpcy5hbmFseXRpY3NTZXJ2aWNlLnNlbmRFdmVudHNPZlJlc2V0QmFza2V0KGJhc2tldCwgZXZlbnRUcmFjZSkpLFxuICAgICAgICBzd2l0Y2hNYXAoKCkgPT4gdGhpcy5nZXQoYHJlc2V0P3BvaW50X29mX3NhbGVfaWQ9JHtwb3MuaWR9JmZpZWxkc1tiYXNrZXRzXT0ke0JBU0tFVF9TUEFSU0VfRklFTERTLmJhc2tldHMuam9pbignLCcpfWApLnBpcGUoXG4gICAgICAgICAgc2tpcFdoaWxlKGJhc2tldCA9PiBiYXNrZXQuaXNfbG9hZGluZyksXG4gICAgICAgICAgc3dpdGNoTWFwKGJhc2tldCA9PiB0aGlzLnVwZGF0ZUxvY2FsQmFza2V0KGJhc2tldCkpXG4gICAgICAgICkpXG4gICAgICApKVxuICAgICk7XG4gIH1cblxuICAvKiogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqIENPTkZJUk0gQkFTS0VUICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiAqKi9cblxuICAvLyBTZXQgYmFza2V0IGFzIGNvbmZpcm1lZCwgYW5kIHJldHVybnMgb25seSBvbmNlIHRoZSBuZXcgY3VycmVudCBsaXN0IGlzIHJldHVybmVkXG4gIGNvbmZpcm1CYXNrZXQodG90YWxQcmljZTogbnVtYmVyIHwgc3RyaW5nKTogT2JzZXJ2YWJsZTxCYXNrZXQ+IHtcbiAgICBsZXQgY29uZmlybWVkQmFza2V0OiBCYXNrZXQ7XG4gICAgY29uc29sZS5sb2coYFtNaWFtXSBDb25maXJtIGJhc2tldCAke0pTT04uc3RyaW5naWZ5KGNvbmZpcm1lZEJhc2tldCl9YCk7XG4gICAgcmV0dXJuIHRoaXMud2FpdEZvckJhc2tldC5waXBlKFxuICAgICAgdGFwKGJhc2tldCA9PiB7XG4gICAgICAgIGlmIChiYXNrZXQudG90YWxQcmljZSA+IDApIHtcbiAgICAgICAgICB0aGlzLmFuYWx5dGljc1NlcnZpY2Uuc2VuZEV2ZW50V2hlblJlYWR5KFxuICAgICAgICAgICAgdGhpcy5hbmFseXRpY3NTZXJ2aWNlLkVWRU5UX1BBWU1FTlRfQ09ORklSTUVELCBudWxsLCB0aGlzLmV2ZW50UHJvcHMoYmFza2V0LCB0b3RhbFByaWNlKVxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH0pLFxuICAgICAgc3dpdGNoTWFwKGJhc2tldCA9PiB7XG4gICAgICAgIGNvbnNvbGUubG9nKCdbTWlhbV0gU2F2ZSBiYXNrZXQgd2l0aCBjb25maXJtZWQ9dHJ1ZScpO1xuICAgICAgICBiYXNrZXQuYXR0cmlidXRlcy5jb25maXJtZWQgPSB0cnVlO1xuICAgICAgICByZXR1cm4gYmFza2V0LnNhdmUoeyBmaWVsZHM6IHsgYmFza2V0czogWy4uLkJBU0tFVF9TUEFSU0VfRklFTERTLmJhc2tldHMsIC4uLlsndG9rZW4nXV0gfSB9KTtcbiAgICAgIH0pLFxuICAgICAgc3dpdGNoTWFwKChyZXNwOiBEb2N1bWVudFJlc291cmNlPEJhc2tldD4pID0+IHtcbiAgICAgICAgY29uZmlybWVkQmFza2V0ID0gdGhpcy5uZXcoKTtcbiAgICAgICAgY29uZmlybWVkQmFza2V0LmZpbGwocmVzcCk7XG4gICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgIGBbTWlhbV0gc2VuZCBwdXNoIGFuYWx5dGljcyBldmVudCBpZiA+IDA6ICR7SlNPTi5zdHJpbmdpZnkoY29uZmlybWVkQmFza2V0LnRvdGFsUHJpY2UpfSAke0pTT04uc3RyaW5naWZ5KGNvbmZpcm1lZEJhc2tldCl9YFxuICAgICAgICApO1xuICAgICAgICBpZiAoY29uZmlybWVkQmFza2V0LnRvdGFsUHJpY2UgPiAwICYmIGNvbmZpcm1lZEJhc2tldC50b2tlbikge1xuICAgICAgICAgIHRoaXMuYW5hbHl0aWNzU2VydmljZS5zZW5kRXZlbnRXaGVuUmVhZHkoXG4gICAgICAgICAgICB0aGlzLmFuYWx5dGljc1NlcnZpY2UuRVZFTlRfQkFTS0VUX0NPTkZJUk1FRCwgbnVsbCwgdGhpcy5ldmVudFByb3BzKGNvbmZpcm1lZEJhc2tldCwgdG90YWxQcmljZSlcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2Jhc2tldCQubmV4dCh1bmRlZmluZWQpO1xuICAgICAgICByZXR1cm4gdGhpcy5yZXNldEJhc2tldCgpO1xuICAgICAgfSksXG4gICAgICBzd2l0Y2hNYXAoKCkgPT4gdGhpcy5fYmFza2V0JFxuICAgICAgKSxcbiAgICAgIHNraXBXaGlsZShiID0+ICFiKSxcbiAgICAgIG1hcCgoKSA9PiBjb25maXJtZWRCYXNrZXQpXG4gICAgKTtcbiAgfVxuXG4gIGV2ZW50UHJvcHMoYmFza2V0OiBCYXNrZXQsIHRvdGFsUHJpY2U6IG51bWJlciB8IHN0cmluZyk6IEN1c3RvbVByb3BlcnRpZXMge1xuICAgIHJldHVybiB7XG4gICAgICAvLyBpZiB5b3UgaGF2ZSBhIGJhc2tldCB5b3UgaGF2ZSBhIHBvcy4uLlxuICAgICAgcG9zX2lkOiB0aGlzLnBvc1NlcnZpY2UucG9zJC5nZXRWYWx1ZSgpLmlkLFxuICAgICAgcG9zX25hbWU6IHRoaXMucG9zU2VydmljZS5wb3MkLmdldFZhbHVlKCkuYXR0cmlidXRlcy5uYW1lLFxuICAgICAgYmFza2V0X2lkOiBiYXNrZXQuaWQsXG4gICAgICBtaWFtX2Ftb3VudDogYmFza2V0LnRvdGFsUHJpY2UsXG4gICAgICB0b3RhbF9hbW91bnQ6IHRvdGFsUHJpY2VcbiAgICB9O1xuICB9XG5cbiAgLyoqICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogQUNUSU9OUyBPTiBFTlRSSUVTICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKiovXG5cbiAgYmFza2V0RW50cmllcygpOiBPYnNlcnZhYmxlPEJhc2tldEVudHJ5W10+IHtcbiAgICByZXR1cm4gdGhpcy5fZW50cmllcyQ7XG4gIH1cblxuICBhY3RpdmVCYXNrZXRFbnRyaWVzKCk6IE9ic2VydmFibGU8QmFza2V0RW50cnlbXT4ge1xuICAgIHJldHVybiB0aGlzLmJhc2tldEVudHJpZXMoKS5waXBlKFxuICAgICAgbWFwKChlbnRyaWVzOiBCYXNrZXRFbnRyeVtdKSA9PiBlbnRyaWVzLmZpbHRlcihlbnRyeSA9PiBlbnRyeS5zdGF0dXMgPT09ICdhY3RpdmUnKSlcbiAgICApO1xuICB9XG5cbiAgLy8gRGVjcmVhc2UgcXVhbnRpdHkgb24gYSBsaXN0IG9mIGJhc2tldCBlbnRyaWVzXG4gIC8vIElmIHRoZSBxdWFudGl0eSBnb2VzIGJlbG93IDEsIHRoZSBjb3JyZXNwb25kaW5nIGdyb2NlcmllcyBlbnRyeSdzIHN0YXR1cyBnZXRzIGRlbGV0ZWRcbiAgLy8gUmVsb2FkIGJhc2tldCBhZnRlciBhbGwgb2JqZWN0cyBhcmUgc2F2ZWRcbiAgcmVtb3ZlQmFza2V0RW50cmllcyhlbnRyaWVzVG9SZW1vdmU6IENvbXBhcmFibGVQcm9kdWN0W10pOiBPYnNlcnZhYmxlPGFueT4ge1xuICAgIGlmICghdGhpcy5fZW50cmllcyQudmFsdWUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBzYXZlT2JzZXJ2YWJsZXM6IE9ic2VydmFibGU8YW55PltdID0gZW50cmllc1RvUmVtb3ZlLm1hcChlbnRyeVRvUmVtb3ZlID0+IHtcbiAgICAgIGNvbnN0IGJhc2tldEVudHJ5ID0gdGhpcy5fZW50cmllcyQudmFsdWUuZmluZChiZSA9PiBiZS5pZCA9PT0gZW50cnlUb1JlbW92ZS5pZCk7XG4gICAgICBpZiAoIWJhc2tldEVudHJ5IHx8ICFlbnRyeVRvUmVtb3ZlLnF1YW50aXR5KSB7XG4gICAgICAgIHJldHVybiBvZihudWxsKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgZmluYWxDb3VudCA9IGJhc2tldEVudHJ5LnF1YW50aXR5IC0gZW50cnlUb1JlbW92ZS5xdWFudGl0eTtcbiAgICAgIGlmIChmaW5hbENvdW50ID49IDEpIHtcbiAgICAgICAgYmFza2V0RW50cnkucXVhbnRpdHkgPSBmaW5hbENvdW50O1xuICAgICAgICByZXR1cm4gYmFza2V0RW50cnkuc2F2ZSgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYmFza2V0RW50cnkucXVhbnRpdHkgPSAxO1xuICAgICAgICBiYXNrZXRFbnRyeS5zdGF0dXMgPSAnZGVsZXRlZCc7XG4gICAgICAgIHJldHVybiBmb3JrSm9pbihbYmFza2V0RW50cnkuc2F2ZSgpLCBiYXNrZXRFbnRyeS5zYXZlKCldKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHJldHVybiBmb3JrSm9pbihzYXZlT2JzZXJ2YWJsZXMpLnBpcGUoXG4gICAgICBzd2l0Y2hNYXAoKCkgPT4gdGhpcy5yZWZyZXNoQ3VycmVudEJhc2tldCgpKSxcbiAgICAgIHRha2UoMSlcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEZldGNoZXMgdGhlIEJhc2tldEVudHJ5IGZvciBhbiBpbmdyZWRpZW50IGlmIGl0IGV4aXN0c1xuICAgKiBSZXR1cm5zIGEgZmFrZSBCYXNrZXRFbnRyeSB3aXRoIGlkID0gLTEgaWYgaXQgZG9lc24ndCBleGlzdFxuICAgKi9cbiAgYmFza2V0RW50cnlGcm9tSW5ncmVkaWVudChpbmdyZWRpZW50SWQ6IHN0cmluZyk6IE9ic2VydmFibGU8QmFza2V0RW50cnk+IHtcbiAgICByZXR1cm4gdGhpcy53YWl0Rm9yQmFza2V0LnBpcGUoXG4gICAgICBzd2l0Y2hNYXAoYmFza2V0ID0+IHtcbiAgICAgICAgY29uc3QgdXJsID0gYCR7ZS5taWFtQVBJfS9hcGkvdjEvYmFza2V0cy8ke2Jhc2tldC5pZH0vYmFza2V0LWVudHJpZXMvZnJvbS1pbmdyZWRpZW50P2luZ3JlZGllbnRfaWQ9JHtpbmdyZWRpZW50SWR9YDtcbiAgICAgICAgcmV0dXJuIHRoaXMuaHR0cC5nZXQodXJsLCB7IHBhcmFtczogeyBpbmNsdWRlOiBbJ3NlbGVjdGVkLWl0ZW0nXSB9IH0pIGFzIE9ic2VydmFibGU8RG9jdW1lbnRSZXNvdXJjZTxCYXNrZXRFbnRyeT4+O1xuICAgICAgfSksXG4gICAgICBza2lwV2hpbGUocmVzdWx0ID0+IHJlc3VsdC5pc19sb2FkaW5nIHx8ICFyZXN1bHQpLFxuICAgICAgbWFwKHJlcyA9PiB7XG4gICAgICAgIGNvbnN0IGVudHJ5ID0gdGhpcy5iYXNrZXRFbnRyaWVzU2VydmljZS5uZXcoKTtcbiAgICAgICAgZW50cnkuZmlsbChyZXMpO1xuICAgICAgICByZXR1cm4gZW50cnk7XG4gICAgICB9KVxuICAgICk7XG4gIH1cblxuICAvKiogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogUFJJQ0VCT09LICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICoqL1xuXG4gIC8vIHdpbGwgcGF0Y2ggYmFza2V0IHdpdGggZ2l2ZW4gcHJpY2Vib29rTmFtZVxuICAvLyBBcGkgd2lsbCBsb29rIGZvciBwcmljZXMgKHBvcyBpdGVtcykgY29ycmVzcG9uZGluZyB0byB0aGlzIHByaWNlYm9vayBrZXlcbiAgLy8gZmFsbCBjYXNlIHRvIGEgZGVmYXVsdCBwcmljZWJvb2tcbiAgdXBkYXRlUHJpY2Vib29rKHByaWNlYm9va05hbWU6IHN0cmluZyk6IE9ic2VydmFibGU8dm9pZD4ge1xuICAgIHJldHVybiB0aGlzLndhaXRGb3JCYXNrZXQucGlwZShcbiAgICAgIHN3aXRjaE1hcChiYXNrZXQgPT4ge1xuICAgICAgICBpZiAoYmFza2V0LnByaWNlYm9va0tleSA9PT0gcHJpY2Vib29rTmFtZSkge1xuICAgICAgICAgIGNvbnNvbGUubG9nKGBbTWlhbV0gc2FtZSBwcmljZWJvb2sgJHtKU09OLnN0cmluZ2lmeShwcmljZWJvb2tOYW1lKX1gKTtcbiAgICAgICAgICByZXR1cm4gb2Y8dm9pZD4oKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zb2xlLmxvZyhgW01pYW1dIHVwZGF0ZSBwcmljZWJvb2sgdG8gJHtKU09OLnN0cmluZ2lmeShwcmljZWJvb2tOYW1lKX1gKTtcbiAgICAgICAgYmFza2V0LnByaWNlYm9va0tleSA9IHByaWNlYm9va05hbWU7XG4gICAgICAgIHJldHVybiBiYXNrZXQuc2F2ZSh7IGZpZWxkczogQkFTS0VUX1NQQVJTRV9GSUVMRFMgfSkucGlwZShcbiAgICAgICAgICBzd2l0Y2hNYXAoKHJlc3A6IERvY3VtZW50UmVzb3VyY2U8QmFza2V0PikgPT4ge1xuICAgICAgICAgICAgdGhpcy5maWxsQmFza2V0KHJlc3ApO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMubG9hZFByZXZpZXcoKTtcbiAgICAgICAgICB9KVxuICAgICAgICApO1xuICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgLyoqICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqIEFERCBGUk9NIFBJQ1RVUkUgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKiovXG5cbiAgYWRkRW50cmllc0Zyb21QaWN0dXJlKGZpbGU6IEZpbGUsIGluY2x1ZGUgPSBbXSwgZGlzYWJsZUluZ3JlZGllbnRzTWF0Y2hpbmcgPSBmYWxzZSk6IE9ic2VydmFibGU8QmFza2V0PiB7XG4gICAgcmV0dXJuIHRoaXMud2FpdEZvckJhc2tldC5waXBlKFxuICAgICAgc3dpdGNoTWFwKGJhc2tldCA9PiB7XG4gICAgICAgIGNvbnN0IHVybCA9IGAke2UubWlhbUFQSX0vYXBpL3YxL2Jhc2tldHMvJHtiYXNrZXQuaWR9L2FkZF9lbnRyaWVzX2Zyb21fcGljdHVyZWAgK1xuICAgICAgICAgIGA/ZmllbGRzW2Jhc2tldHNdPSR7QkFTS0VUX1NQQVJTRV9GSUVMRFMuYmFza2V0cy5qb2luKCcsJyl9JHsoZGlzYWJsZUluZ3JlZGllbnRzTWF0Y2hpbmcgPyAnJmRpc2FibGVfbWF0Y2hpbmc9dHJ1ZScgOiAnJyl9YDtcbiAgICAgICAgY29uc3QgZm9ybURhdGE6IEZvcm1EYXRhID0gbmV3IEZvcm1EYXRhKCk7XG4gICAgICAgIGZvcm1EYXRhLmFwcGVuZCgncGljdHVyZScsIGZpbGUpO1xuICAgICAgICBmb3JtRGF0YS5hcHBlbmQoJ2luY2x1ZGUnLCBpbmNsdWRlLmpvaW4oJywnKSk7XG4gICAgICAgIHJldHVybiB0aGlzLmh0dHAucGF0Y2godXJsLCBmb3JtRGF0YSkucGlwZShtYXAoKHJlc3BvbnNlOiBEb2N1bWVudFJlc291cmNlPEJhc2tldD4pID0+IHRoaXMuZmlsbEJhc2tldChyZXNwb25zZSkpKTtcbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIC8qKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqIEFERCBBQ1RJT05TIFRPIFRIRSBRVUVVRSAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICoqL1xuXG4gIC8qKlxuICAgKiBBZGRzIHJlY2lwZXMgdG8gdGhlIGJhc2tldCBhY3Rpb24gdG8gcXVldWUuXG4gICAqXG4gICAqIEBwYXJhbSByZWNpcGVJZHMgLSBUaGUgYXJyYXkgb2YgcmVjaXBlIElEcyB0byBhZGQuXG4gICAqIEBwYXJhbSBndWVzdHMgLSBUaGUgbnVtYmVyIG9mIGd1ZXN0cy5cbiAgICogQHBhcmFtIGV2ZW50VHJhY2UgLSBUaGUgZXZlbnQgdHJhY2UuXG4gICAqIEBwYXJhbSB3aXRoSW5ncmVkaWVudHMgLSBXaGV0aGVyIHRvIGluY2x1ZGUgaW5ncmVkaWVudHMuIERlZmF1bHQgaXMgdHJ1ZS5cbiAgICogQHJldHVybiBUaGlzIGZ1bmN0aW9uIGRvZXMgbm90IHJldHVybiBhbnl0aGluZy5cbiAgICovXG4gIGFkZFJlY2lwZXNUb0Jhc2tldChyZWNpcGVJZHM6IHN0cmluZ1tdLCBndWVzdHM6IG51bWJlciwgZXZlbnRUcmFjZTogRXZlbnRUcmFjZSwgd2l0aEluZ3JlZGllbnRzID0gdHJ1ZSk6IHZvaWQge1xuICAgIGNvbnN0IHRvQWRkID0gdGhpcy5iYXNrZXRBY3Rpb25zUXVldWUudmFsdWU7XG4gICAgcmVjaXBlSWRzLmZvckVhY2gocmVjaXBlSWQgPT5cbiAgICAgIHRvQWRkLnB1c2goe1xuICAgICAgICB0eXBlOiB3aXRoSW5ncmVkaWVudHMgPyBCYXNrZXRBY3Rpb25UeXBlLkFERF9SRUNJUEUgOiBCYXNrZXRBY3Rpb25UeXBlLkFERF9SRUNJUEVfTElHSFQsXG4gICAgICAgIHBhcmFtczogeyByZWNpcGVJZCwgZXZlbnRUcmFjZSwgZ3Vlc3RzIH1cbiAgICAgIH0pXG4gICAgKTtcbiAgICB0aGlzLmJhc2tldEFjdGlvbnNRdWV1ZS5uZXh0KHRvQWRkKTtcbiAgfVxuXG4gIHJlbW92ZVJlY2lwZXNGcm9tQmFza2V0KHJlY2lwZUlkczogc3RyaW5nW10sIGV2ZW50VHJhY2U6IEV2ZW50VHJhY2UpOiB2b2lkIHtcbiAgICBjb25zdCB0b1JlbW92ZSA9IHRoaXMuYmFza2V0QWN0aW9uc1F1ZXVlLnZhbHVlO1xuICAgIHJlY2lwZUlkcy5mb3JFYWNoKHJlY2lwZUlkID0+XG4gICAgICB0b1JlbW92ZS5wdXNoKHtcbiAgICAgICAgdHlwZTogQmFza2V0QWN0aW9uVHlwZS5SRU1PVkVfUkVDSVBFLFxuICAgICAgICBwYXJhbXM6IHsgcmVjaXBlSWQsIGV2ZW50VHJhY2UgfVxuICAgICAgfSlcbiAgICApO1xuICAgIHRoaXMuYmFza2V0QWN0aW9uc1F1ZXVlLm5leHQodG9SZW1vdmUpO1xuICB9XG5cbiAgdXBkYXRlUmVjaXBlc0luQmFza2V0KHJlY2lwZUlkczogc3RyaW5nW10sIGd1ZXN0czogbnVtYmVyLCBldmVudFRyYWNlOiBFdmVudFRyYWNlKTogdm9pZCB7XG4gICAgY29uc3QgdG9VcGRhdGUgPSB0aGlzLmJhc2tldEFjdGlvbnNRdWV1ZS52YWx1ZTtcbiAgICByZWNpcGVJZHMuZm9yRWFjaChyZWNpcGVJZCA9PlxuICAgICAgdG9VcGRhdGUucHVzaCh7XG4gICAgICAgIHR5cGU6IEJhc2tldEFjdGlvblR5cGUuVVBEQVRFX1JFQ0lQRSxcbiAgICAgICAgcGFyYW1zOiB7IHJlY2lwZUlkLCBldmVudFRyYWNlLCBndWVzdHMgfVxuICAgICAgfSlcbiAgICApO1xuICAgIHRoaXMuYmFza2V0QWN0aW9uc1F1ZXVlLm5leHQodG9VcGRhdGUpO1xuICB9XG5cbiAgYWRkSW5ncmVkaWVudHNUb0Jhc2tldChyZWNpcGVJZDogc3RyaW5nLCBpbmdyZWRpZW50SWRzQW5kRW50cmllczogeyBpbmdyZWRpZW50SWQ6IHN0cmluZzsgZW50cnk6IEJhc2tldEVudHJ5IH1bXSxcbiAgICBldmVudFRyYWNlOiBFdmVudFRyYWNlKTogdm9pZCB7XG4gICAgY29uc3QgdG9BZGQgPSB0aGlzLmJhc2tldEFjdGlvbnNRdWV1ZS52YWx1ZTtcbiAgICBpbmdyZWRpZW50SWRzQW5kRW50cmllcy5mb3JFYWNoKGluZ3JlZGllbnRJZEFuZEVudHJ5ID0+XG4gICAgICB0b0FkZC5wdXNoKHtcbiAgICAgICAgdHlwZTogQmFza2V0QWN0aW9uVHlwZS5BRERfUFJPRFVDVCxcbiAgICAgICAgcGFyYW1zOiB7IHJlY2lwZUlkLCBpbmdyZWRpZW50SWQ6IGluZ3JlZGllbnRJZEFuZEVudHJ5LmluZ3JlZGllbnRJZCwgYmFza2V0RW50cnk6IGluZ3JlZGllbnRJZEFuZEVudHJ5LmVudHJ5LCBldmVudFRyYWNlIH1cbiAgICAgIH0pXG4gICAgKTtcbiAgICB0aGlzLmJhc2tldEFjdGlvbnNRdWV1ZS5uZXh0KHRvQWRkKTtcbiAgfVxuXG4gIHJlbW92ZUluZ3JlZGllbnRzRnJvbUJhc2tldChiYXNrZXRFbnRyeTogQmFza2V0RW50cnksIHJlY2lwZUlkOiBzdHJpbmcsIGluZ3JlZGllbnRJZHM6IHN0cmluZ1tdLCBldmVudFRyYWNlOiBFdmVudFRyYWNlKTogdm9pZCB7XG4gICAgY29uc3QgdG9SZW1vdmUgPSB0aGlzLmJhc2tldEFjdGlvbnNRdWV1ZS52YWx1ZTtcbiAgICBpbmdyZWRpZW50SWRzLmZvckVhY2goaW5ncmVkaWVudElkID0+XG4gICAgICB0b1JlbW92ZS5wdXNoKHtcbiAgICAgICAgdHlwZTogQmFza2V0QWN0aW9uVHlwZS5SRU1PVkVfUFJPRFVDVCxcbiAgICAgICAgcGFyYW1zOiB7IGJhc2tldEVudHJ5LCByZWNpcGVJZCwgaW5ncmVkaWVudElkLCBldmVudFRyYWNlIH1cbiAgICAgIH0pXG4gICAgKTtcbiAgICB0aGlzLmJhc2tldEFjdGlvbnNRdWV1ZS5uZXh0KHRvUmVtb3ZlKTtcbiAgfVxuXG4gIGNoYW5nZVByb2R1Y3RRdWFudGl0eShiYXNrZXRFbnRyeTogQmFza2V0RW50cnksIHJlY2lwZUlkOiBzdHJpbmcsIG5ld1F1YW50aXR5OiBudW1iZXIsIGV2ZW50VHJhY2U6IEV2ZW50VHJhY2UpOiB2b2lkIHtcbiAgICBjb25zdCB0b1VwZGF0ZSA9IHRoaXMuYmFza2V0QWN0aW9uc1F1ZXVlLnZhbHVlO1xuICAgIHRvVXBkYXRlLnB1c2goe1xuICAgICAgdHlwZTogQmFza2V0QWN0aW9uVHlwZS5VUERBVEVfUFJPRFVDVCxcbiAgICAgIHBhcmFtczogeyBiYXNrZXRFbnRyeSwgcmVjaXBlSWQsIG5ld1F1YW50aXR5LCBldmVudFRyYWNlIH1cbiAgICB9KTtcbiAgICB0aGlzLmJhc2tldEFjdGlvbnNRdWV1ZS5uZXh0KHRvVXBkYXRlKTtcbiAgfVxuXG4gIC8qKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogUFJPQ0VTUyBUSEUgQUNUSU9OUyBRVUVVRSAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKiovXG5cbiAgcHJpdmF0ZSBlbXB0eUFjdGlvbnNRdWV1ZSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5iYXNrZXRBY3Rpb25zUXVldWUudmFsdWUubGVuZ3RoID4gMCkge1xuICAgICAgY29uc3QgYWN0aW9uc1RvUHJvY2VzcyA9IHRoaXMubmV4dEFjdGlvbnNCYXRjaCgpO1xuICAgICAgdGhpcy5hY3Rpb25zQmVpbmdQcm9jZXNzZWQubmV4dChbLi4uYWN0aW9uc1RvUHJvY2Vzc10pO1xuICAgICAgaWYgKGFjdGlvbnNUb1Byb2Nlc3MubGVuZ3RoID4gMCkge1xuICAgICAgICB0aGlzLnByb2Nlc3NBY3Rpb25zQmF0Y2goYWN0aW9uc1RvUHJvY2Vzcykuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgICB0aGlzLmFjdGlvbnNCZWluZ1Byb2Nlc3NlZC5uZXh0KFtdKTtcbiAgICAgICAgICB0aGlzLmJhc2tldEFjdGlvbnNRdWV1ZS5uZXh0KFxuICAgICAgICAgICAgdGhpcy5iYXNrZXRBY3Rpb25zUXVldWUudmFsdWUuZmlsdGVyKGkgPT4gIWFjdGlvbnNUb1Byb2Nlc3MuaW5jbHVkZXMoaSkgJiYgIXRoaXMuYWN0aW9uc0JlaW5nT3ZlcnJpZGVuLmluY2x1ZGVzKGkpKVxuICAgICAgICAgICk7XG4gICAgICAgICAgdGhpcy5hY3Rpb25zQmVpbmdPdmVycmlkZW4gPSBbXTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIElmIG11bHRpcGxlIGFjdGlvbnMgb2YgdGhlIHNhbWUgdHlwZSBhcmUgbmV4dCB0byBlYWNoIG90aGVyIGluIHRoZSBxdWV1ZSwgd2Ugd2FudCB0byBwcm9jZXNzIHRoZW0gYXMgYSBiYXRjaC5cbiAgICogQHJldHVybnMgdGhlIG5leHQgYmF0Y2ggb2YgYWN0aW9ucyB0byBwcm9jZXNzXG4gICAqL1xuICBwcml2YXRlIG5leHRBY3Rpb25zQmF0Y2goKTogQmFza2V0QWN0aW9uW10ge1xuICAgIGNvbnN0IGJhdGNoOiBCYXNrZXRBY3Rpb25bXSA9IFtdO1xuICAgIGxldCBpID0gMDtcbiAgICBsZXQgY3VycmVudEFjdGlvbiA9IHRoaXMuYmFza2V0QWN0aW9uc1F1ZXVlLnZhbHVlW2ldO1xuICAgIGxldCBzaG91bGRGb3JjZVN0b3AgPSBmYWxzZTtcbiAgICB3aGlsZSAodGhpcy5iYXNrZXRBY3Rpb25zUXVldWUudmFsdWVbaV0/LnR5cGUgPT09IGN1cnJlbnRBY3Rpb24/LnR5cGUgJiYgIXNob3VsZEZvcmNlU3RvcCkge1xuICAgICAgY3VycmVudEFjdGlvbiA9IHRoaXMuYmFza2V0QWN0aW9uc1F1ZXVlLnZhbHVlW2ldO1xuICAgICAgc2hvdWxkRm9yY2VTdG9wID0gdGhpcy5hZGRBY3Rpb25Ub0JhdGNoT3JTdG9wUHJvY2Vzc2luZ0JhdGNoKGJhdGNoLCBjdXJyZW50QWN0aW9uKTtcbiAgICAgIGkrKztcbiAgICB9XG4gICAgcmV0dXJuIGJhdGNoO1xuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm5zIHRydWUgaWYgdGhlIGJhdGNoIHNob3VsZCBzdG9wIHByb2Nlc3NpbmdcbiAgICovXG4gIHByaXZhdGUgYWRkQWN0aW9uVG9CYXRjaE9yU3RvcFByb2Nlc3NpbmdCYXRjaChiYXRjaDogQmFza2V0QWN0aW9uW10sIGN1cnJlbnRBY3Rpb246IEJhc2tldEFjdGlvbik6IGJvb2xlYW4ge1xuICAgIGNvbnN0IHJlY2lwZUluZGV4ID0gdGhpcy5jaGVja0ZvckFjdGlvblRvT3ZlcnJpZGUoYmF0Y2gsIGN1cnJlbnRBY3Rpb24pO1xuICAgIGlmIChyZWNpcGVJbmRleCAhPT0gLTEpIHtcbiAgICAgIHRoaXMuYWN0aW9uc0JlaW5nT3ZlcnJpZGVuLnB1c2goYmF0Y2hbcmVjaXBlSW5kZXhdKTtcbiAgICAgIGJhdGNoW3JlY2lwZUluZGV4XSA9IGN1cnJlbnRBY3Rpb247XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICh0aGlzLnNob3VsZEZvcmNlU3RvcEJhdGNoKGJhdGNoLCBjdXJyZW50QWN0aW9uKSkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGJhdGNoLnB1c2goY3VycmVudEFjdGlvbik7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHByaXZhdGUgc2hvdWxkRm9yY2VTdG9wQmF0Y2goYmF0Y2g6IEJhc2tldEFjdGlvbltdLCBjdXJyZW50QWN0aW9uOiBCYXNrZXRBY3Rpb24pOiBib29sZWFuIHtcbiAgICAvLyBJZiB0aGUgY3VycmVudCBiYXRjaCBpcyBhbiBVUERBVEUgYmF0Y2gsIHdlIGNhbid0IHVwZGF0ZSBtdWx0aXBsZSByZWNpcGVzIHdpdGggZGlmZmVyZW50cyBndWVzdHMgdmFsdWVzIGF0IHRoZSBzYW1lIHRpbWVcbiAgICAvLyBzbyBpbiB0aGlzIGNhc2Ugd2Ugc3RvcCB0aGUgYmF0Y2ggYmVmb3JlIHRoZSBVUERBVEUgd2l0aCBhIGRpZmZlcmVudCBndWVzdHMgdmFsdWVcbiAgICByZXR1cm4gKGN1cnJlbnRBY3Rpb24udHlwZSA9PT0gQmFza2V0QWN0aW9uVHlwZS5VUERBVEVfUkVDSVBFICYmXG4gICAgICAgIGJhdGNoLmxlbmd0aCA+IDAgJiZcbiAgICAgICAgIWJhdGNoLnNvbWUoYSA9PiBhLnBhcmFtcy5ndWVzdHMgPT09IGN1cnJlbnRBY3Rpb24ucGFyYW1zLmd1ZXN0cykpIHx8XG4gICAgICAvLyBJZiB0aGUgY3VycmVudCBiYXRjaCBpcyBhbiBwcm9kdWN0IGFkZC9yZW1vdmUgYmF0Y2gsIHdlIGNhbid0IGFkZCBvciByZW1vdmUgcHJvZHVjdHMgZnJvbSBkaWZmZXJlbnQgcmVjaXBlcyBhdCB0aGUgc2FtZSB0aW1lXG4gICAgICAvLyBzbyBpbiB0aGlzIGNhc2Ugd2Ugc3RvcCB0aGUgYmF0Y2ggYmVmb3JlIHRoZSBhZGQvcmVtb3ZlIHdpdGggYSBkaWZmZXJlbnQgcmVjaXBlXG4gICAgICAoKGN1cnJlbnRBY3Rpb24udHlwZSA9PT0gQmFza2V0QWN0aW9uVHlwZS5BRERfUFJPRFVDVCB8fCBjdXJyZW50QWN0aW9uLnR5cGUgPT09IEJhc2tldEFjdGlvblR5cGUuUkVNT1ZFX1BST0RVQ1QpICYmXG4gICAgICAgIGJhdGNoLmxlbmd0aCA+IDAgJiZcbiAgICAgICAgIWJhdGNoLnNvbWUoYSA9PiBhLnBhcmFtcy5yZWNpcGVJZCA9PT0gY3VycmVudEFjdGlvbi5wYXJhbXMucmVjaXBlSWQpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBmb3IgYWN0aW9ucyBmb3Igd2hpY2ggb3ZlcnJpZGluZyB3b3VsZCBoYXZlIHRoZSBzYW1lIHJlc3VsdCBhcyBwcm9jZXNzaW5nIGJvdGggaW4gb3JkZXJcbiAgICovXG4gIHByaXZhdGUgY2hlY2tGb3JBY3Rpb25Ub092ZXJyaWRlKGJhdGNoOiBCYXNrZXRBY3Rpb25bXSwgY3VycmVudEFjdGlvbjogQmFza2V0QWN0aW9uKTogbnVtYmVyIHtcbiAgICBpZiAoY3VycmVudEFjdGlvbi50eXBlID09PSBCYXNrZXRBY3Rpb25UeXBlLlVQREFURV9SRUNJUEUgJiZcbiAgICAgIGJhdGNoLmxlbmd0aCA+IDAgJiZcbiAgICAgICFiYXRjaC5zb21lKGEgPT4gYS5wYXJhbXMucmVjaXBlSWQgIT09IGN1cnJlbnRBY3Rpb24ucGFyYW1zLnJlY2lwZUlkKVxuICAgICkge1xuICAgICAgcmV0dXJuIGJhdGNoLmZpbmRJbmRleChhID0+IGEucGFyYW1zLnJlY2lwZUlkID09PSBjdXJyZW50QWN0aW9uLnBhcmFtcy5yZWNpcGVJZCk7XG4gICAgICAvLyBpZiB0aGVyZSBhcmUgb25seSB0aGUgc2FtZSByZWNpcGVJZCBhcyB0aGUgY3VycmVudEFjdGlvbiBpbiB0aGUgYmF0Y2ggYW5kIHdlIGFyZSB1cGRhdGluZyB0aGlzIHJlY2lwZSdzIGd1ZXN0c1xuICAgICAgLy8gd2UgY2FuIHNhZmVseSBvdmVycmlkZSB0aGUgYWN0aW9uIGluIHRoZSBiYXRjaFxuICAgIH0gZWxzZSBpZiAoY3VycmVudEFjdGlvbi50eXBlID09PSBCYXNrZXRBY3Rpb25UeXBlLlVQREFURV9QUk9EVUNUICkge1xuICAgICAgcmV0dXJuIGJhdGNoLmZpbmRJbmRleChhID0+IGEucGFyYW1zLmJhc2tldEVudHJ5LmlkID09PSBjdXJyZW50QWN0aW9uLnBhcmFtcy5iYXNrZXRFbnRyeS5pZCk7XG4gICAgICAvLyBJZiB0aGUgY3VycmVudEFjdGlvbiBtb2RpZmllcyB0aGUgc2FtZSBiYXNrZXRFbnRyeSBhcyBhIHByZXZpb3VzIG9uZSBpbiB0aGUgYmF0Y2gsIGl0IG92ZXJyaWRlcyBpdFxuICAgIH0gZWxzZSBpZiAoXG4gICAgICAhW0Jhc2tldEFjdGlvblR5cGUuQUREX1BST0RVQ1QsIEJhc2tldEFjdGlvblR5cGUuUkVNT1ZFX1BST0RVQ1QsIEJhc2tldEFjdGlvblR5cGUuVVBEQVRFX1JFQ0lQRV0uaW5jbHVkZXMoY3VycmVudEFjdGlvbi50eXBlKVxuICAgICkge1xuICAgICAgcmV0dXJuIGJhdGNoLmZpbmRJbmRleChhID0+IGEucGFyYW1zLnJlY2lwZUlkID09PSBjdXJyZW50QWN0aW9uLnBhcmFtcy5yZWNpcGVJZCk7XG4gICAgICAvLyBJZiB0aGUgY3VycmVudEFjdGlvbiBtb2RpZmllcyB0aGUgc2FtZSByZWNpcGUgYXMgYSBwcmV2aW91cyBvbmUgaW4gdGhlIGJhdGNoLCBpdCBvdmVycmlkZXMgaXRcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGJhdGNoLmZpbmRJbmRleChhID0+XG4gICAgICAgIGEucGFyYW1zLmluZ3JlZGllbnRJZCA9PT0gY3VycmVudEFjdGlvbi5wYXJhbXMuaW5ncmVkaWVudElkICYmXG4gICAgICAgIGEucGFyYW1zLnJlY2lwZUlkID09PSBjdXJyZW50QWN0aW9uLnBhcmFtcy5yZWNpcGVJZFxuICAgICAgKTtcbiAgICAgIC8vIElmIHRoZSBjdXJyZW50QWN0aW9uIG1vZGlmaWVzIHRoZSBzYW1lIGluZ3JlZGllbnQgZm9yIHRoZSBzYW1lIHJlY2lwZSBhcyBhIHByZXZpb3VzIG9uZSBpbiB0aGUgYmF0Y2gsIGl0IG92ZXJyaWRlcyBpdFxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgcHJvY2Vzc0FjdGlvbnNCYXRjaChhY3Rpb25zVG9Qcm9jZXNzOiBCYXNrZXRBY3Rpb25bXSk6IE9ic2VydmFibGU8dm9pZD4ge1xuICAgIHN3aXRjaCAoYWN0aW9uc1RvUHJvY2Vzc1swXS50eXBlKSB7XG4gICAgICBjYXNlIEJhc2tldEFjdGlvblR5cGUuQUREX1JFQ0lQRTpcbiAgICAgICAgcmV0dXJuIHRoaXMuYWRkUmVjaXBlcyhhY3Rpb25zVG9Qcm9jZXNzKTtcblxuICAgICAgY2FzZSBCYXNrZXRBY3Rpb25UeXBlLkFERF9SRUNJUEVfTElHSFQ6XG4gICAgICAgIHJldHVybiB0aGlzLmFkZFJlY2lwZXNXaXRob3V0SW5ncmVkaWVudHMoYWN0aW9uc1RvUHJvY2Vzcyk7XG5cbiAgICAgIGNhc2UgQmFza2V0QWN0aW9uVHlwZS5SRU1PVkVfUkVDSVBFOlxuICAgICAgICByZXR1cm4gdGhpcy5yZW1vdmVSZWNpcGVzKGFjdGlvbnNUb1Byb2Nlc3MpO1xuXG4gICAgICBjYXNlIEJhc2tldEFjdGlvblR5cGUuVVBEQVRFX1JFQ0lQRTpcbiAgICAgICAgcmV0dXJuIHRoaXMudXBkYXRlUmVjaXBlc0d1ZXN0cyhhY3Rpb25zVG9Qcm9jZXNzKTtcblxuICAgICAgY2FzZSBCYXNrZXRBY3Rpb25UeXBlLkFERF9QUk9EVUNUOlxuICAgICAgICByZXR1cm4gdGhpcy5hZGRJdGVtc0ZvckluZ3JlZGllbnRzKGFjdGlvbnNUb1Byb2Nlc3MpO1xuXG4gICAgICBjYXNlIEJhc2tldEFjdGlvblR5cGUuUkVNT1ZFX1BST0RVQ1Q6XG4gICAgICAgIHJldHVybiB0aGlzLnJlbW92ZUl0ZW1zRm9ySW5ncmVkaWVudHMoYWN0aW9uc1RvUHJvY2Vzcyk7XG5cbiAgICAgIGNhc2UgQmFza2V0QWN0aW9uVHlwZS5VUERBVEVfUFJPRFVDVDpcbiAgICAgICAgcmV0dXJuIHRoaXMuY2hhbmdlQmFza2V0RW50cmllc1F1YW50aXRpZXMoYWN0aW9uc1RvUHJvY2Vzcyk7XG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiBvZigpO1xuICAgIH1cbiAgfVxuXG4gIC8qKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogUFJPQ0VTUyBUSEUgQUNUSU9OUyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKiovXG5cbiAgLyoqXG4gICAqIEFkZHMgcmVjaXBlcyB0byB0aGUgYmFza2V0IEhUVFAgcmVxdWVzdC5cbiAgICpcbiAgICogQHBhcmFtIHJlY2lwZXNUb0FkZCAtIFRoZSByZWNpcGVzIHRvIGFkZCB0byB0aGUgYmFza2V0LlxuICAgKiBAcGFyYW0gd2l0aEluZ3JlZGllbnRzIC0gKG9wdGlvbmFsKSBXaGV0aGVyIHRvIGluY2x1ZGUgaW5ncmVkaWVudHMgaW4gdGhlIHJlcXVlc3QuIERlZmF1bHQgaXMgdHJ1ZS5cbiAgICogQHJldHVybiBBbiBvYnNlcnZhYmxlIHRoYXQgZW1pdHMgdm9pZCB3aGVuIHRoZSByZXF1ZXN0IGlzIGNvbXBsZXRlZC5cbiAgICovXG4gIHByaXZhdGUgYWRkUmVjaXBlcyhyZWNpcGVzVG9BZGQ6IEJhc2tldEFjdGlvbltdLCB3aXRoSW5ncmVkaWVudHMgPSB0cnVlKTogT2JzZXJ2YWJsZTx2b2lkPiB7XG4gICAgcmV0dXJuIHRoaXMud2FpdEZvckJhc2tldC5waXBlKFxuICAgICAgc3dpdGNoTWFwKGJhc2tldCA9PiB7XG4gICAgICAgIGNvbnN0IHVybCA9IGAke2UubWlhbUFQSX0vYXBpL3YxL2Jhc2tldHMvJHtiYXNrZXQuaWR9L3JlY2lwZXNgICtcbiAgICAgICAgYD9maWVsZHNbYmFza2V0c109JHtCQVNLRVRfU1BBUlNFX0ZJRUxEUy5iYXNrZXRzLmpvaW4oJywnKX0ke3dpdGhJbmdyZWRpZW50cyA/ICcnIDogJyZsaWdodF9tb2RlPXRydWUnfWA7XG4gICAgICAgIGNvbnN0IGJvZHkgPSB7IGRhdGE6IHJlY2lwZXNUb0FkZC5tYXAociA9PiAoeyByZWNpcGVfaWQ6IHIucGFyYW1zLnJlY2lwZUlkLCBndWVzdHM6IHIucGFyYW1zLmd1ZXN0cyB9KSkgfTtcbiAgICAgICAgdGhpcy5hbmFseXRpY3NTZXJ2aWNlLnNlbmRBZGRSZWNpcGVzRXZlbnRzKHJlY2lwZXNUb0FkZCk7XG4gICAgICAgIHJldHVybiB0aGlzLmh0dHAucG9zdCh1cmwsIGJvZHkpLnBpcGUoXG4gICAgICAgICAgc2tpcFdoaWxlKChiOiBEb2N1bWVudFJlc291cmNlPEJhc2tldD4pID0+IGIuaXNfbG9hZGluZyksXG4gICAgICAgICAgc3dpdGNoTWFwKGIgPT4ge1xuICAgICAgICAgICAgaWYgKGI/LmRhdGE/LmlkKSB7XG4gICAgICAgICAgICAgIHRoaXMuZmlsbEJhc2tldChiKTtcbiAgICAgICAgICAgICAgcmV0dXJuIHRoaXMubG9hZFByZXZpZXcoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIG9mPHZvaWQ+KCk7XG4gICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgYWRkUmVjaXBlc1dpdGhvdXRJbmdyZWRpZW50cyhyZWNpcGVzVG9BZGQ6IEJhc2tldEFjdGlvbltdKTogT2JzZXJ2YWJsZTx2b2lkPiB7XG4gICAgcmV0dXJuIHRoaXMuYWRkUmVjaXBlcyhyZWNpcGVzVG9BZGQsIGZhbHNlKTtcbiAgfVxuXG4gIHByaXZhdGUgcmVtb3ZlUmVjaXBlcyhyZWNpcGVzVG9SZW1vdmU6IEJhc2tldEFjdGlvbltdKTogT2JzZXJ2YWJsZTx2b2lkPiB7XG4gICAgcmV0dXJuIHRoaXMud2FpdEZvckJhc2tldC5waXBlKFxuICAgICAgc3dpdGNoTWFwKGJhc2tldCA9PiB7XG4gICAgICAgIGNvbnN0IHVybCA9IGAke2UubWlhbUFQSX0vYXBpL3YxL2Jhc2tldHMvJHtiYXNrZXQuaWR9L3JlY2lwZXM/cmVjaXBlX2lkc1tdPWAgK1xuICAgICAgICAgIHJlY2lwZXNUb1JlbW92ZS5tYXAociA9PiByLnBhcmFtcy5yZWNpcGVJZCkuam9pbignJnJlY2lwZV9pZHNbXT0nKSArIGAmZmllbGRzW2Jhc2tldHNdPSR7QkFTS0VUX1NQQVJTRV9GSUVMRFMuYmFza2V0cy5qb2luKCcsJyl9YDtcbiAgICAgICAgdGhpcy5hbmFseXRpY3NTZXJ2aWNlLnNlbmRSZW1vdmVSZWNpcGVzRXZlbnRzKHJlY2lwZXNUb1JlbW92ZSk7XG4gICAgICAgIHJldHVybiB0aGlzLmh0dHAuZGVsZXRlKHVybCkucGlwZShcbiAgICAgICAgICBza2lwV2hpbGUoKGI6IERvY3VtZW50UmVzb3VyY2U8QmFza2V0PikgPT4gYi5pc19sb2FkaW5nKSxcbiAgICAgICAgICBzd2l0Y2hNYXAoYiA9PiB7XG4gICAgICAgICAgICBpZiAoYj8uZGF0YT8uaWQpIHtcbiAgICAgICAgICAgICAgdGhpcy5maWxsQmFza2V0KGIpO1xuICAgICAgICAgICAgICByZXR1cm4gdGhpcy5sb2FkUHJldmlldygpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gb2Y8dm9pZD4oKTtcbiAgICAgICAgICB9KVxuICAgICAgICApO1xuICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSB1cGRhdGVSZWNpcGVzR3Vlc3RzKHJlY2lwZXNUb1VwZGF0ZTogQmFza2V0QWN0aW9uW10pOiBPYnNlcnZhYmxlPHZvaWQ+IHtcbiAgICByZXR1cm4gdGhpcy53YWl0Rm9yQmFza2V0LnBpcGUoXG4gICAgICBzd2l0Y2hNYXAoYmFza2V0ID0+IHtcbiAgICAgICAgY29uc3QgdXJsID0gYCR7ZS5taWFtQVBJfS9hcGkvdjEvYmFza2V0cy8ke2Jhc2tldC5pZH0vcmVjaXBlc19ndWVzdHM/Z3Vlc3RzPSR7cmVjaXBlc1RvVXBkYXRlWzBdLnBhcmFtcy5ndWVzdHN9JnJlY2lwZV9pZHNbXT1gICtcbiAgICAgICAgcmVjaXBlc1RvVXBkYXRlLm1hcChyID0+IHIucGFyYW1zLnJlY2lwZUlkKS5qb2luKCcmcmVjaXBlX2lkc1tdPScpICsgYCZmaWVsZHNbYmFza2V0c109JHtCQVNLRVRfU1BBUlNFX0ZJRUxEUy5iYXNrZXRzLmpvaW4oJywnKX1gO1xuICAgICAgICB0aGlzLmFuYWx5dGljc1NlcnZpY2Uuc2VuZFVwZGF0ZUd1ZXN0c0V2ZW50cyhyZWNpcGVzVG9VcGRhdGUpO1xuICAgICAgICByZXR1cm4gdGhpcy5odHRwLnBhdGNoKHVybCwge30pLnBpcGUoXG4gICAgICAgICAgc2tpcFdoaWxlKChiOiBEb2N1bWVudFJlc291cmNlPEJhc2tldD4pID0+ICFiIHx8IGIuaXNfbG9hZGluZyksXG4gICAgICAgICAgc3dpdGNoTWFwKGIgPT4ge1xuICAgICAgICAgICAgaWYgKGI/LmRhdGE/LmlkKSB7XG4gICAgICAgICAgICAgIHRoaXMuZmlsbEJhc2tldChiKTtcbiAgICAgICAgICAgICAgcmV0dXJuIHRoaXMubG9hZFByZXZpZXcoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIG9mPHZvaWQ+KCk7XG4gICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0gaW5ncmVkaWVudHNUb0FkZFxuICAgKi9cbiAgcHJpdmF0ZSBhZGRJdGVtc0ZvckluZ3JlZGllbnRzKGluZ3JlZGllbnRzVG9BZGQ6IEJhc2tldEFjdGlvbltdKTogT2JzZXJ2YWJsZTx2b2lkPiB7XG4gICAgcmV0dXJuIHRoaXMud2FpdEZvckJhc2tldC5waXBlKFxuICAgICAgc2tpcFdoaWxlKGJhc2tldCA9PiBiYXNrZXQuaXNfbG9hZGluZyksXG4gICAgICBzd2l0Y2hNYXAoYmFza2V0ID0+IHtcbiAgICAgICAgY29uc3QgcmVxdWVzdHMgPSBpbmdyZWRpZW50c1RvQWRkLm1hcChhY3Rpb24gPT4ge1xuICAgICAgICAgIGNvbnN0IG1vZGlmaWVkR3Vlc3RzID0gdGhpcy5ndWVzdHNGb3JSZWNpcGUoYWN0aW9uLnBhcmFtcy5yZWNpcGVJZCk7XG4gICAgICAgICAgY29uc3QgdXJsID0gYCR7ZS5taWFtQVBJfS9hcGkvdjEvYmFza2V0cy8ke2Jhc2tldC5pZH0vYmFza2V0LWVudHJpZXMvJHthY3Rpb24ucGFyYW1zLmJhc2tldEVudHJ5LmlkfS9hZGQtaW5ncmVkaWVudGAgK1xuICAgICAgICAgICAgYD9pbmdyZWRpZW50X2lkPSR7YWN0aW9uLnBhcmFtcy5pbmdyZWRpZW50SWR9JnNlbGVjdGVkX2l0ZW1faWQ9JHthY3Rpb24ucGFyYW1zLmJhc2tldEVudHJ5LnNlbGVjdGVkSXRlbS5pZH1gICtcbiAgICAgICAgICAgIGAmZ3Vlc3RzPSR7bW9kaWZpZWRHdWVzdHN9YDtcbiAgICAgICAgICByZXR1cm4gdGhpcy5odHRwLnBhdGNoKHVybCwge30pO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIGZvcmtKb2luKHJlcXVlc3RzKTtcbiAgICAgIH0pLFxuICAgICAgc3dpdGNoTWFwKCgpID0+IHRoaXMucmVsb2FkQmFza2V0KCkpLFxuICAgICAgc3dpdGNoTWFwKCgpID0+IG9mPHZvaWQ+KG51bGwpKSAvLyBKdXN0IHRvIGtlZXAgdGhlIHJldHVybiB0eXBlIGFzIE9ic2VydmFibGU8dm9pZD4gdG8gbWF0Y2ggd2l0aCB0aGUgb3RoZXIgbWV0aG9kc1xuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlcyB0aGUgc3BlY2lmaWVkIGluZ3JlZGllbnRzIGZyb20gdGhlIGJhc2tldCBIVFRQIHJlcXVlc3QuXG4gICAqXG4gICAqIEBwYXJhbSBpbmdyZWRpZW50c1RvUmVtb3ZlIC0gVGhlIGxpc3Qgb2YgaW5ncmVkaWVudHMgdG8gcmVtb3ZlIGZyb20gdGhlIGJhc2tldC5cbiAgICogQHJldHVybiBBbiBvYnNlcnZhYmxlIHRoYXQgZW1pdHMgd2hlbiB0aGUgaW5ncmVkaWVudHMgYXJlIHN1Y2Nlc3NmdWxseSByZW1vdmVkLlxuICAgKi9cbiAgcHJpdmF0ZSByZW1vdmVJdGVtc0ZvckluZ3JlZGllbnRzKGluZ3JlZGllbnRzVG9SZW1vdmU6IEJhc2tldEFjdGlvbltdKTogT2JzZXJ2YWJsZTx2b2lkPiB7XG4gICAgcmV0dXJuIHRoaXMud2FpdEZvckJhc2tldC5waXBlKFxuICAgICAgc2tpcFdoaWxlKGJhc2tldCA9PiBiYXNrZXQuaXNfbG9hZGluZyksXG4gICAgICBzd2l0Y2hNYXAoYmFza2V0ID0+IHtcbiAgICAgICAgY29uc3QgcmVxdWVzdHMgPSBpbmdyZWRpZW50c1RvUmVtb3ZlLm1hcChhY3Rpb24gPT4ge1xuICAgICAgICAgIGNvbnN0IG1vZGlmaWVkR3Vlc3RzID0gdGhpcy5ndWVzdHNGb3JSZWNpcGUoYWN0aW9uLnBhcmFtcy5yZWNpcGVJZCk7XG4gICAgICAgICAgY29uc3QgdXJsID0gZS5taWFtQVBJICsgJy9hcGkvdjEvYmFza2V0cy8nICsgYmFza2V0LmlkICtcbiAgICAgICAgICAgICcvYmFza2V0LWVudHJpZXMvJyArIGFjdGlvbi5wYXJhbXMuYmFza2V0RW50cnkuaWQgK1xuICAgICAgICAgICAgJy9yZW1vdmUtaW5ncmVkaWVudD9pbmdyZWRpZW50X2lkPScgKyBhY3Rpb24ucGFyYW1zLmluZ3JlZGllbnRJZCArXG4gICAgICAgICAgICAnJnNlbGVjdGVkX2l0ZW1faWQ9JyArIGFjdGlvbi5wYXJhbXMuYmFza2V0RW50cnkuc2VsZWN0ZWRJdGVtLmlkICtcbiAgICAgICAgICAgICcmZ3Vlc3RzPScgKyBtb2RpZmllZEd1ZXN0cztcbiAgICAgICAgICByZXR1cm4gdGhpcy5odHRwLnBhdGNoKHVybCwge30pO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIGZvcmtKb2luKHJlcXVlc3RzKTtcbiAgICAgIH0pLFxuICAgICAgc3dpdGNoTWFwKCgpID0+IHRoaXMucmVsb2FkQmFza2V0KCkpLFxuICAgICAgc3dpdGNoTWFwKCgpID0+IG9mPHZvaWQ+KG51bGwpKSAvLyBKdXN0IHRvIGtlZXAgdGhlIHJldHVybiB0eXBlIGFzIE9ic2VydmFibGU8dm9pZD4gdG8gbWF0Y2ggd2l0aCB0aGUgb3RoZXIgbWV0aG9kc1xuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlcyB0aGUgc3BlY2lmaWVkIGluZ3JlZGllbnRzIGZyb20gdGhlIGJhc2tldCBIVFRQIHJlcXVlc3QuXG4gICAqXG4gICAqIEBwYXJhbSBpbmdyZWRpZW50c1RvUmVtb3ZlIC0gVGhlIGxpc3Qgb2YgaW5ncmVkaWVudHMgdG8gcmVtb3ZlIGZyb20gdGhlIGJhc2tldC5cbiAgICogQHJldHVybiBBbiBvYnNlcnZhYmxlIHRoYXQgZW1pdHMgd2hlbiB0aGUgaW5ncmVkaWVudHMgYXJlIHN1Y2Nlc3NmdWxseSByZW1vdmVkLlxuICAgKi9cbiAgcHJpdmF0ZSBjaGFuZ2VCYXNrZXRFbnRyaWVzUXVhbnRpdGllcyhxdWFudGl0aWVzVG9DaGFuZ2U6IEJhc2tldEFjdGlvbltdKTogT2JzZXJ2YWJsZTx2b2lkPiB7XG4gICAgY29uc3QgcmVxdWVzdHMgPSBxdWFudGl0aWVzVG9DaGFuZ2UubWFwKGFjdGlvbiA9PiB7XG4gICAgICBhY3Rpb24ucGFyYW1zLmJhc2tldEVudHJ5LnF1YW50aXR5ID0gYWN0aW9uLnBhcmFtcy5uZXdRdWFudGl0eTtcbiAgICAgIHJldHVybiBhY3Rpb24ucGFyYW1zLmJhc2tldEVudHJ5LnNhdmUoKTtcbiAgICB9KTtcbiAgICByZXR1cm4gZm9ya0pvaW4ocmVxdWVzdHMpLnBpcGUoXG4gICAgICBzd2l0Y2hNYXAoKCkgPT4gdGhpcy5yZWxvYWRCYXNrZXQoKSksXG4gICAgICBzd2l0Y2hNYXAoKCkgPT4gb2Y8dm9pZD4obnVsbCkpIC8vIEp1c3QgdG8ga2VlcCB0aGUgcmV0dXJuIHR5cGUgYXMgT2JzZXJ2YWJsZTx2b2lkPiB0byBtYXRjaCB3aXRoIHRoZSBvdGhlciBtZXRob2RzXG4gICAgKTtcbiAgfVxuXG4gIC8qKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogVVBEQVRJTkcgVEhFIEJBU0tFVCAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKiovXG5cbiAgLyoqXG4gICAqIFVwZGF0ZSBfYmFza2V0JCBjb250ZW50ICYgc2F2ZSBiYXNrZXRJZCBpbiB0aGUgbG9jYWxTdG9yYWdlIGlmIHRoZSB1c2VyIGlzIG5vdCBsb2dndWVkIGluIHNvIHdlIGNhbiBtZXJnZVdpdGggd2hlbiB0aGV5IGxvZyBpblxuICAgKi9cbiAgcHJpdmF0ZSB1cGRhdGVMb2NhbEJhc2tldChiYXNrZXQ6IEJhc2tldCk6IE9ic2VydmFibGU8dm9pZD4ge1xuICAgIGlmICh0aGlzLnVzZXJzU2VydmljZS5pc0xvZ2dlZCQudmFsdWUpIHtcbiAgICAgIGxvY2FsU3RvcmFnZS5yZW1vdmVJdGVtKCdfbWlhbS9iYXNrZXRJZCcpO1xuICAgIH0gZWxzZSB7XG4gICAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbSgnX21pYW0vYmFza2V0SWQnLCBiYXNrZXQuaWQpO1xuICAgIH1cbiAgICB0aGlzLl9iYXNrZXQkLm5leHQoYmFza2V0KTtcbiAgICByZXR1cm4gdGhpcy5sb2FkUHJldmlldygpLnBpcGUodGFwKCgpID0+IHRoaXMuYmFza2V0SXNGZXRjaGluZyA9IGZhbHNlKSk7XG4gIH1cblxuICAvKipcbiAgICogc2F2ZSgpIHJldHVybnMgYW4gb2JqZWN0IHRoYXQgaXNuJ3QgYSByZXNvdXJjZSBzbyBtZXRob2RzIGFyZW4ndCBhdHRhY2hlZCwgc28gd2UgaGF2ZSB0byBkbyBhIGxpdHRsZSB0cmlja1xuICAgKiBAcGFyYW0gcmVzIHJlc3VsdCBvZiB0aGUgc2F2ZVxuICAgKiBAcmV0dXJucyBjb3JyZWN0IEJhc2tldCB3aXRoIHRoZSByaWdodCBhdHRyaWJ1dGVzICYgbWV0aG9kc1xuICAgKi9cbiAgcHJpdmF0ZSBmaWxsQmFza2V0KHJlczogRG9jdW1lbnRSZXNvdXJjZTxCYXNrZXQ+KTogQmFza2V0IHtcbiAgICBjb25zdCBiYXNrZXQgPSB0aGlzLm5ldygpO1xuICAgIGJhc2tldC5maWxsKHJlcyk7XG4gICAgdGhpcy5fYmFza2V0JC5uZXh0KGJhc2tldCk7XG4gICAgcmV0dXJuIGJhc2tldDtcbiAgfVxuXG4gIC8qKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqIElOSVRJQUwgTE9BRCAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICoqL1xuXG4gIC8qKlxuICAgKiBJbml0aWFsaXNlIHRoZSBiYXNrZXQgbG9hZGluZyB3aGVuIHRoZSBwb3MgaXMgaW5pdGlhbGlzZWQgb3IgbW9kaWZpZWRcbiAgICogQHJldHVybnMgX2Jhc2tldCRcbiAgICovXG4gIHByaXZhdGUgbG9hZEJhc2tldCgpOiBPYnNlcnZhYmxlPEJhc2tldD4ge1xuICAgIHJldHVybiB0aGlzLnBvc1NlcnZpY2UucG9zJC5waXBlKFxuICAgICAgc2tpcFdoaWxlKHBvcyA9PiAhcG9zKSxcbiAgICAgIHN3aXRjaE1hcCgoKSA9PiB0aGlzLnJlZnJlc2hDdXJyZW50QmFza2V0KCkpXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgbG9hZFByZXZpZXcoKTogT2JzZXJ2YWJsZTx2b2lkPiB7XG4gICAgcmV0dXJuIHRoaXMuYmFza2V0JC5waXBlKFxuICAgICAgc2tpcFdoaWxlKGIgPT4gIWIpLFxuICAgICAgdGFrZSgxKSxcbiAgICAgIHN3aXRjaE1hcChiYXNrZXQgPT4gdGhpcy5yZWNpcGVzU2VydmljZS5sb2FkUmVjaXBlcyhiYXNrZXQucmVjaXBlSW5mb3MpKSxcbiAgICAgIHN3aXRjaE1hcCgocmVjaXBlczogUmVjaXBlW10pID0+IHtcbiAgICAgICAgY29uc3QgYmFza2V0OiBCYXNrZXQgPSB0aGlzLl9iYXNrZXQkLnZhbHVlO1xuICAgICAgICByZXR1cm4gdGhpcy5mZXRjaEJhc2tldEVudHJpZXMoYmFza2V0KS5waXBlKFxuICAgICAgICAgIG1hcChlbnRyaWVzID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGxpbmVFbnRyaWVzID0gdGhpcy5ncm91cEJhc2tldEVudHJpZXMocmVjaXBlcywgZW50cmllcyk7XG4gICAgICAgICAgICBjb25zdCBsaW5lcyA9IHRoaXMucmVjaXBlc0FuZExpbmVFbnRyaWVzVG9CYXNrZXRQcmV2aWV3TGluZShyZWNpcGVzLCBsaW5lRW50cmllcyk7XG4gICAgICAgICAgICB0aGlzLl9iYXNrZXRQcmV2aWV3JC5uZXh0KGxpbmVzKTtcbiAgICAgICAgICAgIHRoaXMuYmFza2V0UHJldmlld0lzQ2FsY3VsYXRpbmcgPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMuYmFza2V0U3RhdHMkLm5leHQodGhpcy5idWlsZFN0YXRzKGxpbmVzKSk7XG4gICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgZmV0Y2hCYXNrZXRFbnRyaWVzKGJhc2tldDogQmFza2V0KTogT2JzZXJ2YWJsZTxCYXNrZXRFbnRyeVtdPiB7XG4gICAgaWYgKCFiYXNrZXQgfHwgIWJhc2tldC5jb21wbGV0aW9uIHx8IGJhc2tldC5jb21wbGV0aW9uLnRvdGFsIDwgMSkge1xuICAgICAgdGhpcy5fZW50cmllcyQubmV4dChbXSk7XG4gICAgICByZXR1cm4gdGhpcy5fZW50cmllcyQucGlwZSh0YWtlKDEpKTtcbiAgICB9XG5cbiAgICBjb25zdCBwYWdlc0NvdW50ID0gTWF0aC5jZWlsKGJhc2tldC5jb21wbGV0aW9uLnRvdGFsIC8gQmFza2V0c1NlcnZpY2UuZW50cmllc1BlclBhZ2VzKTtcbiAgICByZXR1cm4gZm9ya0pvaW4oQXJyYXkocGFnZXNDb3VudCkuZmlsbCgwKS5tYXAoKHYsIGkpID0+IHRoaXMuZmV0Y2hCYXNrZXRFbnRyaWVzUGFnZShiYXNrZXQsIGkgKyAxKSkpLnBpcGUoXG4gICAgICBtYXAoKGNvbGxlY3Rpb25zOiBEb2N1bWVudENvbGxlY3Rpb248QmFza2V0RW50cnk+W10pID0+IHtcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnNhZmUtY2FsbFxuICAgICAgICBjb25zdCBlbnRyaWVzID0gKGZsYXR0ZW4oY29sbGVjdGlvbnMubWFwKGNvbCA9PiBjb2wuZGF0YSkpIGFzIEJhc2tldEVudHJ5W10pO1xuICAgICAgICB0aGlzLl9lbnRyaWVzJC5uZXh0KGVudHJpZXMpO1xuICAgICAgICByZXR1cm4gdGhpcy5fZW50cmllcyQudmFsdWU7XG4gICAgICB9KVxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIGJ1aWxkU3RhdHMobGluZXM6IEJhc2tldFByZXZpZXdMaW5lW10pOiBCYXNrZXRTdGF0cyB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnNhZmUtYXNzaWdubWVudCwgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVuc2FmZS1jYWxsXG4gICAgY29uc3QgZW50cmllc0ZvdW5kOiBCYXNrZXRFbnRyeVtdID0gdW5pb25CeSguLi5saW5lcy5tYXAobGluZSA9PiBsaW5lLmVudHJpZXMuZm91bmQpLCAnaWQnKTtcblxuICAgIGNvbnN0IHRvdGFsUHJpY2UgPSBlbnRyaWVzRm91bmQucmVkdWNlKCh0b3RhbCwgZW50cnkpID0+IHtcbiAgICAgIGNvbnN0IGl0ZW0gPSBlbnRyeS5hdHRyaWJ1dGVzWydiYXNrZXQtZW50cmllcy1pdGVtcyddLmZpbmQoaSA9PiBpLml0ZW1faWQgPT09IGVudHJ5LmF0dHJpYnV0ZXNbJ3NlbGVjdGVkLWl0ZW0taWQnXSk7XG4gICAgICB0b3RhbCArPSAoZW50cnkuYXR0cmlidXRlcy5xdWFudGl0eSB8fCAwKSAqIHBhcnNlRmxvYXQoaXRlbVsndW5pdC1wcmljZSddKTtcbiAgICAgIHJldHVybiB0b3RhbDtcbiAgICB9LCAwKTtcblxuICAgIHJldHVybiB7XG4gICAgICByZWNpcGVzQ291bnQ6IGxpbmVzLmxlbmd0aCxcbiAgICAgIGVudHJpZXNDb3VudDogZW50cmllc0ZvdW5kLmxlbmd0aCxcbiAgICAgIHRvdGFsUHJpY2VcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBmZXRjaEJhc2tldEVudHJpZXNQYWdlKGJhc2tldDogQmFza2V0LCBwYWdlOiBudW1iZXIpOiBPYnNlcnZhYmxlPERvY3VtZW50Q29sbGVjdGlvbjxCYXNrZXRFbnRyeT4+IHtcbiAgICBsZXQgdXJsID0gYCR7ZS5taWFtQVBJfS9hcGkvdjEvYmFza2V0cy8ke2Jhc2tldC5pZH0vYmFza2V0LWVudHJpZXNgO1xuICAgIHVybCA9IGAke3VybH0/aW5jbHVkZT1pdGVtcyZpbmNsdWRlPXNlbGVjdGVkLWl0ZW0mcGFnZVtudW1iZXJdPSR7cGFnZX0mcGFnZVtzaXplXT0ke0Jhc2tldHNTZXJ2aWNlLmVudHJpZXNQZXJQYWdlc31gO1xuXG4gICAgcmV0dXJuIHRoaXMuaHR0cC5nZXQodXJsKS5waXBlKFxuICAgICAgc2tpcFdoaWxlKChyZXNwOiBEb2N1bWVudENvbGxlY3Rpb248QmFza2V0RW50cnk+KSA9PiByZXNwLmlzX2xvYWRpbmcpLFxuICAgICAgbWFwKChyZXNwOiBEb2N1bWVudENvbGxlY3Rpb248QmFza2V0RW50cnk+KSA9PiB7XG4gICAgICAgIGNvbnN0IGJhc2tldEVudHJpZXMgPSB0aGlzLmJhc2tldEVudHJpZXNTZXJ2aWNlLm5ld0NvbGxlY3Rpb24oKTtcbiAgICAgICAgYmFza2V0RW50cmllcy5maWxsKHJlc3ApO1xuICAgICAgICByZXR1cm4gYmFza2V0RW50cmllcztcbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgcmVjaXBlc0FuZExpbmVFbnRyaWVzVG9CYXNrZXRQcmV2aWV3TGluZShyZWNpcGVzOiBSZWNpcGVbXSwgbGluZUVudHJpZXM6IExpbmVFbnRyaWVzW10pOiBCYXNrZXRQcmV2aWV3TGluZVtdIHtcbiAgICByZXR1cm4gcmVjaXBlcy5tYXAoKHJlY2lwZSwgaWR4KSA9PiB7XG4gICAgICBjb25zdCBpdGVtc0NvdW50ID0gbGluZUVudHJpZXNbaWR4XS5mb3VuZC5sZW5ndGg7XG4gICAgICBsZXQgcmVjaXBlUHJpY2UgPSAwLjA7XG4gICAgICBjb25zdCBndWVzdHMgPSByZWNpcGUubW9kaWZpZWRHdWVzdHMgfHwgcGFyc2VJbnQocmVjaXBlLmd1ZXN0cywgMTApO1xuXG4gICAgICBsaW5lRW50cmllc1tpZHhdLmZvdW5kLmZvckVhY2goZW50cnkgPT4ge1xuICAgICAgICBjb25zdCBzZWxlY3RlZEl0ZW0gPSBlbnRyeS5hdHRyaWJ1dGVzWydiYXNrZXQtZW50cmllcy1pdGVtcyddLmZpbmQoaXRlbSA9PiBpdGVtLml0ZW1faWQgPT09IGVudHJ5LmF0dHJpYnV0ZXNbJ3NlbGVjdGVkLWl0ZW0taWQnXSk7XG4gICAgICAgIGNvbnN0IHF0eSA9IGVudHJ5LmF0dHJpYnV0ZXMucXVhbnRpdHk7XG4gICAgICAgIGNvbnN0IHVuaXRQcmljZSA9IHBhcnNlRmxvYXQoc2VsZWN0ZWRJdGVtWyd1bml0LXByaWNlJ10pO1xuICAgICAgICBjb25zdCBudW1iZXJPZlJlY2lwZXNGb3JFbnRyeSA9IGVudHJ5LnJlY2lwZXNJZHMubGVuZ3RoIHx8IDE7XG5cbiAgICAgICAgcmVjaXBlUHJpY2UgKz0gKHF0eSAqIHVuaXRQcmljZSkgLyBudW1iZXJPZlJlY2lwZXNGb3JFbnRyeTtcbiAgICAgIH0pO1xuICAgICAgY29uc3QgcHJpY2VQZXJHdWVzdCA9IHJlY2lwZVByaWNlIC8gZ3Vlc3RzO1xuXG4gICAgICByZXR1cm4gQmFza2V0UHJldmlld0xpbmUuZnJvbVJlY2lwZShyZWNpcGUsIGl0ZW1zQ291bnQsIHByaWNlUGVyR3Vlc3QsIHJlY2lwZVByaWNlLCBsaW5lRW50cmllc1tpZHhdKTtcbiAgICB9KS5zb3J0KChhLCBiKSA9PiByZWNpcGVzLmZpbmRJbmRleChyID0+IHIuaWQgPT09IGIuaWQpIC0gcmVjaXBlcy5maW5kSW5kZXgociA9PiByLmlkID09PSBhLmlkKSk7XG4gIH1cblxuICBwcml2YXRlIGdyb3VwQmFza2V0RW50cmllcyhyZWNpcGVzOiBSZWNpcGVbXSwgZW50cmllczogQmFza2V0RW50cnlbXSk6IExpbmVFbnRyaWVzW10ge1xuICAgIHJldHVybiByZWNpcGVzLm1hcChyZWNpcGUgPT4ge1xuICAgICAgY29uc3QgbGluZUVudHJpZXMgPSB7IGZvdW5kOiBbXSwgbm90Rm91bmQ6IFtdLCBvZnRlbkRlbGV0ZWQ6IFtdLCByZW1vdmVkOiBbXSwgYWxsOiBbXSB9IGFzIExpbmVFbnRyaWVzO1xuICAgICAgZW50cmllc1xuICAgICAgICAuZmlsdGVyKGVudHJ5ID0+IGVudHJ5LnJlY2lwZXNJZHMuaW5jbHVkZXMocGFyc2VJbnQocmVjaXBlLmlkLCAxMCkpKVxuICAgICAgICAuZm9yRWFjaChlbnRyeSA9PiB7XG4gICAgICAgICAgY29uc3QgYXZhaWxhYmxlID0gZW50cnkuYXR0cmlidXRlc1snc2VsZWN0ZWQtaXRlbS1pZCddO1xuICAgICAgICAgIGlmIChhdmFpbGFibGUpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoZW50cnkuc3RhdHVzKSB7XG4gICAgICAgICAgICAgIGNhc2UgJ29mdGVuX2RlbGV0ZWQnOiB7XG4gICAgICAgICAgICAgICAgbGluZUVudHJpZXMub2Z0ZW5EZWxldGVkLnB1c2goZW50cnkpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGNhc2UgJ2RlbGV0ZWQnOiB7XG4gICAgICAgICAgICAgICAgbGluZUVudHJpZXMucmVtb3ZlZC5wdXNoKGVudHJ5KTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBkZWZhdWx0OiB7XG4gICAgICAgICAgICAgICAgbGluZUVudHJpZXMuZm91bmQucHVzaChlbnRyeSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbGluZUVudHJpZXMubm90Rm91bmQucHVzaChlbnRyeSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGxpbmVFbnRyaWVzLmFsbC5wdXNoKGVudHJ5KTtcbiAgICAgICAgfSk7XG4gICAgICByZXR1cm4gbGluZUVudHJpZXM7XG4gICAgfSk7XG4gIH1cbn1cbiJdfQ==