@infrab4a/connect-angular 3.10.1 → 3.10.2

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 (83) hide show
  1. package/angular-connect.module.d.ts +20 -20
  2. package/angular-elastic-search.module.d.ts +9 -9
  3. package/angular-firebase-auth.module.d.ts +10 -10
  4. package/angular-firestore.module.d.ts +15 -15
  5. package/angular-hasura-graphql.module.d.ts +16 -16
  6. package/bundles/infrab4a-connect-angular.umd.js +2548 -2554
  7. package/bundles/infrab4a-connect-angular.umd.js.map +1 -1
  8. package/consts/backend-url.const.d.ts +1 -1
  9. package/consts/category-structure.d.ts +1 -1
  10. package/consts/default-shop.const.d.ts +1 -1
  11. package/consts/es-config.const.d.ts +1 -1
  12. package/consts/hasura-options.const.d.ts +1 -1
  13. package/consts/index.d.ts +5 -5
  14. package/esm2015/angular-connect.module.js +63 -63
  15. package/esm2015/angular-elastic-search.module.js +34 -34
  16. package/esm2015/angular-firebase-auth.module.js +113 -113
  17. package/esm2015/angular-firestore.module.js +394 -394
  18. package/esm2015/angular-hasura-graphql.module.js +172 -172
  19. package/esm2015/consts/backend-url.const.js +1 -1
  20. package/esm2015/consts/category-structure.js +2 -2
  21. package/esm2015/consts/default-shop.const.js +2 -2
  22. package/esm2015/consts/es-config.const.js +2 -2
  23. package/esm2015/consts/hasura-options.const.js +2 -2
  24. package/esm2015/consts/index.js +6 -6
  25. package/esm2015/index.js +6 -6
  26. package/esm2015/infrab4a-connect-angular.js +4 -4
  27. package/esm2015/services/auth.service.js +42 -42
  28. package/esm2015/services/cart.service.js +281 -281
  29. package/esm2015/services/catalog/adapters/category-structure.adapter.js +2 -2
  30. package/esm2015/services/catalog/adapters/index.js +4 -4
  31. package/esm2015/services/catalog/adapters/new-category-structure.adapter.js +51 -51
  32. package/esm2015/services/catalog/adapters/old-category-structure.adapter.js +27 -27
  33. package/esm2015/services/catalog/catalog.service.js +96 -94
  34. package/esm2015/services/catalog/category.service.js +56 -61
  35. package/esm2015/services/catalog/enums/index.js +2 -2
  36. package/esm2015/services/catalog/enums/product-sorts.enum.js +11 -11
  37. package/esm2015/services/catalog/index.js +6 -6
  38. package/esm2015/services/catalog/models/category-with-tree.model.js +10 -10
  39. package/esm2015/services/catalog/models/index.js +2 -2
  40. package/esm2015/services/catalog/types/index.js +2 -2
  41. package/esm2015/services/catalog/types/product-sort.type.js +2 -2
  42. package/esm2015/services/checkout-subscription.service.js +53 -53
  43. package/esm2015/services/checkout.service.js +70 -70
  44. package/esm2015/services/coupon.service.js +244 -240
  45. package/esm2015/services/home-shop.service.js +116 -116
  46. package/esm2015/services/index.js +10 -10
  47. package/esm2015/services/order.service.js +32 -32
  48. package/esm2015/services/shipping.service.js +98 -98
  49. package/esm2015/services/types/index.js +3 -3
  50. package/esm2015/services/types/required-checkout-data.type.js +2 -2
  51. package/esm2015/services/types/required-checkout-subscription-data.type.js +2 -2
  52. package/esm2015/services/types/shipping-methods.type.js +2 -2
  53. package/fesm2015/infrab4a-connect-angular.js +1804 -1803
  54. package/fesm2015/infrab4a-connect-angular.js.map +1 -1
  55. package/index.d.ts +5 -5
  56. package/infrab4a-connect-angular.d.ts +5 -5
  57. package/package.json +1 -1
  58. package/services/auth.service.d.ts +19 -19
  59. package/services/cart.service.d.ts +42 -42
  60. package/services/catalog/adapters/category-structure.adapter.d.ts +4 -4
  61. package/services/catalog/adapters/index.d.ts +3 -3
  62. package/services/catalog/adapters/new-category-structure.adapter.d.ts +14 -14
  63. package/services/catalog/adapters/old-category-structure.adapter.d.ts +10 -10
  64. package/services/catalog/catalog.service.d.ts +54 -54
  65. package/services/catalog/category.service.d.ts +15 -15
  66. package/services/catalog/enums/index.d.ts +1 -1
  67. package/services/catalog/enums/product-sorts.enum.d.ts +9 -9
  68. package/services/catalog/index.d.ts +5 -5
  69. package/services/catalog/models/category-with-tree.model.d.ts +4 -4
  70. package/services/catalog/models/index.d.ts +1 -1
  71. package/services/catalog/types/index.d.ts +1 -1
  72. package/services/catalog/types/product-sort.type.d.ts +2 -2
  73. package/services/checkout-subscription.service.d.ts +18 -18
  74. package/services/checkout.service.d.ts +23 -23
  75. package/services/coupon.service.d.ts +28 -28
  76. package/services/home-shop.service.d.ts +25 -25
  77. package/services/index.d.ts +9 -9
  78. package/services/order.service.d.ts +13 -13
  79. package/services/shipping.service.d.ts +19 -19
  80. package/services/types/index.d.ts +2 -2
  81. package/services/types/required-checkout-data.type.d.ts +2 -2
  82. package/services/types/required-checkout-subscription-data.type.d.ts +2 -2
  83. package/services/types/shipping-methods.type.d.ts +12 -12
@@ -1,240 +1,244 @@
1
- import { __awaiter } from "tslib";
2
- import { Inject, Injectable } from '@angular/core';
3
- import { CheckoutTypes, CouponTypes, Exclusivities, Shops, Where, } from '@infrab4a/connect';
4
- import { from, of } from 'rxjs';
5
- import { concatMap, map } from 'rxjs/operators';
6
- import { DEFAULT_SHOP } from '../consts';
7
- import * as i0 from "@angular/core";
8
- import * as i1 from "@infrab4a/connect";
9
- export class CouponService {
10
- constructor(couponRepository, defaultShop, orderRepository, categoryRepository) {
11
- this.couponRepository = couponRepository;
12
- this.defaultShop = defaultShop;
13
- this.orderRepository = orderRepository;
14
- this.categoryRepository = categoryRepository;
15
- this.emailIsFromCollaborator = (userEmail) => !!(userEmail === null || userEmail === void 0 ? void 0 : userEmail.match(/@b4a.com.br/g));
16
- }
17
- checkCoupon(nickname, checkoutType, checkout, plan) {
18
- return from(this.couponRepository
19
- .find({
20
- filters: {
21
- nickname: { operator: Where.EQUALS, value: nickname },
22
- active: { operator: Where.EQUALS, value: true },
23
- },
24
- })
25
- .then((result) => result.data[0])).pipe(concatMap((coupon) => this.couponValidation(coupon, checkoutType)), concatMap((couponValid) => this.couponRulesValidation(couponValid, checkoutType, checkout, plan)), map((couponValidated) => couponValidated));
26
- }
27
- couponValidation(coupon, checkoutType) {
28
- return __awaiter(this, void 0, void 0, function* () {
29
- if (!coupon)
30
- throw 'Cupom inválido.';
31
- if ((coupon === null || coupon === void 0 ? void 0 : coupon.beginAt) && (coupon === null || coupon === void 0 ? void 0 : coupon.beginAt.getTime()) > new Date().getTime())
32
- throw 'Cupom inválido.';
33
- if ((coupon === null || coupon === void 0 ? void 0 : coupon.expiresIn) && (coupon === null || coupon === void 0 ? void 0 : coupon.expiresIn.getTime()) < new Date().getTime())
34
- throw 'Cupom expirado.';
35
- const isInShop = coupon.shopAvailability === Shops.ALL || coupon.shopAvailability === this.defaultShop;
36
- if (!isInShop)
37
- throw 'Cupom inválido para loja.';
38
- const isCheckoutType = coupon.checkoutType === CheckoutTypes.ALL || coupon.checkoutType === checkoutType;
39
- if (!isCheckoutType)
40
- throw 'Cupom inválido. Erro de checkout.';
41
- return coupon;
42
- });
43
- }
44
- couponRulesValidation(coupon, checkoutType, checkout, plan) {
45
- return __awaiter(this, void 0, void 0, function* () {
46
- if (checkoutType == CheckoutTypes.SUBSCRIPTION) {
47
- if (coupon.plan && coupon.plan.toUpperCase() !== plan.toUpperCase())
48
- throw 'Cupom inválido para sua assinatura.';
49
- return coupon;
50
- }
51
- const validUser = this.coupomUserValidation(coupon, checkout === null || checkout === void 0 ? void 0 : checkout.user);
52
- if (!validUser)
53
- throw 'Usuário não elegível.';
54
- const orders = yield this.getOrdersWithCoupon(coupon);
55
- const ordersWithUser = this.countOrdersWithUser(orders, checkout.user.email);
56
- const couponUseLimits = this.getCouponUseLimits(coupon, checkoutType, checkout.user);
57
- if (couponUseLimits.limitedPerUser && ordersWithUser > 0)
58
- throw 'Limite de uso por usuário atingido.';
59
- if (!couponUseLimits.unlimited && couponUseLimits.total && orders.length >= couponUseLimits.total)
60
- throw 'Limite de uso atingido.';
61
- const hasProductCategories = yield this.hasProductCategories(coupon, checkout);
62
- if (!hasProductCategories)
63
- throw 'Seu carrinho não possui produtos elegíveis para desconto.';
64
- const hasMinSubTotal = yield this.hasMinSubTotal(coupon, checkout);
65
- if (!hasMinSubTotal)
66
- throw `Valor mínimo de ${Intl.NumberFormat('pt-BR', { style: 'currency', currency: 'BRL' }).format(coupon.minSubTotalValue)} não atingido`;
67
- return coupon;
68
- });
69
- }
70
- calcDiscountSubscription(coupon, checkout) {
71
- let discount = 0;
72
- if (coupon.discount.subscription.type == CouponTypes.ABSOLUTE)
73
- discount = coupon.discount.subscription.value;
74
- else
75
- discount = checkout.subscriptionPlan.recurrencePrice * (coupon.discount.subscription.value / 100);
76
- return of(discount);
77
- }
78
- calcDiscountShopping(coupon, checkout) {
79
- return __awaiter(this, void 0, void 0, function* () {
80
- let discount = 0;
81
- if (checkout.user.isSubscriber && coupon.discount.subscriber.value) {
82
- discount = yield this.calcDiscountByType(coupon.discount.subscriber.type, coupon.discount.subscriber.value, coupon.productsCategories, checkout);
83
- }
84
- else {
85
- discount = yield this.calcDiscountByType(coupon.discount.non_subscriber.type, coupon.discount.non_subscriber.value, coupon.productsCategories, checkout);
86
- }
87
- return discount;
88
- });
89
- }
90
- calcDiscountByType(type, value, categories, checkout) {
91
- return __awaiter(this, void 0, void 0, function* () {
92
- let discount = 0;
93
- let lineItensDiscount = yield this.getLineItensEligebleForDiscount(categories, checkout);
94
- const subTotal = this.calcCheckoutSubtotal(lineItensDiscount, checkout.user, checkout.shop);
95
- if (type == CouponTypes.ABSOLUTE) {
96
- discount = value > subTotal ? subTotal : value;
97
- }
98
- else {
99
- discount = subTotal * (value / 100);
100
- }
101
- return discount;
102
- });
103
- }
104
- hasMinSubTotal(coupon, checkout) {
105
- return __awaiter(this, void 0, void 0, function* () {
106
- if (!coupon.minSubTotalValue)
107
- return true;
108
- let lineItensDiscount = yield this.getLineItensEligebleForDiscount(coupon.productsCategories, checkout);
109
- const subTotal = this.calcCheckoutSubtotal(lineItensDiscount, checkout.user, checkout.shop);
110
- if (coupon.minSubTotalValue <= subTotal)
111
- return true;
112
- return false;
113
- });
114
- }
115
- hasProductCategories(coupon, checkout) {
116
- var _a;
117
- return __awaiter(this, void 0, void 0, function* () {
118
- if (!coupon.productsCategories || !coupon.productsCategories.length) {
119
- return true;
120
- }
121
- const couponCategories = yield this.getCouponCategoriesId(coupon.productsCategories);
122
- const hasCategories = (_a = checkout.lineItems) === null || _a === void 0 ? void 0 : _a.filter((i) => {
123
- var _a;
124
- if (!i.categories || !((_a = i.categories) === null || _a === void 0 ? void 0 : _a.length))
125
- return true;
126
- return i.categories.some((c) => couponCategories.some((cat) => cat == c));
127
- });
128
- return hasCategories.length ? true : false;
129
- });
130
- }
131
- coupomUserValidation(coupon, user) {
132
- if (!user || coupon.exclusivityType.includes(Exclusivities.ALL_USERS))
133
- return true;
134
- let userTypes = [];
135
- if (coupon.exclusivityType.includes(Exclusivities.COLLABORATORS) && this.emailIsFromCollaborator(user.email))
136
- userTypes.push(Exclusivities.COLLABORATORS);
137
- if (coupon.exclusivityType.includes(Exclusivities.SPECIFIC_USER) && coupon.userExclusiveEmail.includes(user.email))
138
- userTypes.push(Exclusivities.SPECIFIC_USER);
139
- if (coupon.exclusivityType.includes(Exclusivities.ACTIVE_SUBSCRIBER) &&
140
- user.isSubscriber &&
141
- user.subscriptionPlan != '')
142
- userTypes.push(Exclusivities.ACTIVE_SUBSCRIBER);
143
- if (user.isSubscriber &&
144
- user.subscriptionPlan == '' &&
145
- coupon.exclusivityType.includes(Exclusivities.INACTIVE_SUBSCRIBER))
146
- userTypes.push(Exclusivities.INACTIVE_SUBSCRIBER);
147
- if (coupon.exclusivityType.includes(Exclusivities.NON_SUBSCRIBER) && !user.isSubscriber)
148
- userTypes.push(Exclusivities.NON_SUBSCRIBER);
149
- return coupon.exclusivityType.some((r) => userTypes.includes(r));
150
- }
151
- getCouponCategoriesId(productsCategories) {
152
- return __awaiter(this, void 0, void 0, function* () {
153
- const couponCategories = [];
154
- for (let index = 0; index < productsCategories.length; index++) {
155
- const category = yield this.categoryRepository.get({
156
- id: productsCategories[index],
157
- });
158
- if (category) {
159
- const children = yield this.categoryRepository.getChildren(parseInt(productsCategories[index]));
160
- couponCategories.push(category.id, ...children.map((c) => c.id.toString()));
161
- }
162
- }
163
- return [...new Set(couponCategories)];
164
- });
165
- }
166
- getLineItensEligebleForDiscount(productsCategories, checkout) {
167
- var _a;
168
- return __awaiter(this, void 0, void 0, function* () {
169
- let lineItensDiscount = [];
170
- const couponCategories = yield this.getCouponCategoriesId(productsCategories);
171
- if (productsCategories && productsCategories.length) {
172
- lineItensDiscount = (_a = checkout.lineItems) === null || _a === void 0 ? void 0 : _a.filter((i) => {
173
- var _a;
174
- if ((_a = i.categories) === null || _a === void 0 ? void 0 : _a.length) {
175
- return i.categories.some((c) => couponCategories.some((cat) => cat == c));
176
- }
177
- return true;
178
- });
179
- }
180
- else {
181
- lineItensDiscount = checkout.lineItems;
182
- }
183
- return lineItensDiscount;
184
- });
185
- }
186
- calcCheckoutSubtotal(lineItens, user, shop) {
187
- return ((lineItens === null || lineItens === void 0 ? void 0 : lineItens.reduce((acc, curr) => {
188
- var _a, _b;
189
- return (user === null || user === void 0 ? void 0 : user.isSubscriber) && ((_a = curr.price[shop]) === null || _a === void 0 ? void 0 : _a.subscriberPrice)
190
- ? acc + ((_b = curr.price[shop]) === null || _b === void 0 ? void 0 : _b.subscriberPrice) * curr.quantity
191
- : acc + curr.pricePaid * curr.quantity;
192
- }, 0)) || 0);
193
- }
194
- getOrdersWithCoupon(coupon) {
195
- return __awaiter(this, void 0, void 0, function* () {
196
- return yield this.orderRepository
197
- .find({
198
- filters: {
199
- coupon: { id: coupon.id },
200
- payment: { status: 'paid' },
201
- },
202
- })
203
- .then((result) => result.data);
204
- });
205
- }
206
- countOrdersWithUser(orders, email) {
207
- return orders.filter((o) => o.user.email == email).length;
208
- }
209
- getCouponUseLimits(coupon, checkoutType, user) {
210
- let couponUseLimits;
211
- if (checkoutType == CheckoutTypes.ECOMMERCE || checkoutType == CheckoutTypes.ALL) {
212
- couponUseLimits = user && user.isSubscriber ? coupon.useLimits.subscriber : coupon.useLimits.non_subscriber;
213
- }
214
- else {
215
- couponUseLimits = coupon.useLimits.subscription;
216
- }
217
- return couponUseLimits;
218
- }
219
- }
220
- CouponService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0, type: CouponService, deps: [{ token: 'CouponRepository' }, { token: DEFAULT_SHOP }, { token: 'OrderRepository' }, { token: 'CategoryRepository' }], target: i0.ɵɵFactoryTarget.Injectable });
221
- CouponService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0, type: CouponService, providedIn: 'root' });
222
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0, type: CouponService, decorators: [{
223
- type: Injectable,
224
- args: [{
225
- providedIn: 'root',
226
- }]
227
- }], ctorParameters: function () { return [{ type: undefined, decorators: [{
228
- type: Inject,
229
- args: ['CouponRepository']
230
- }] }, { type: i1.Shops, decorators: [{
231
- type: Inject,
232
- args: [DEFAULT_SHOP]
233
- }] }, { type: undefined, decorators: [{
234
- type: Inject,
235
- args: ['OrderRepository']
236
- }] }, { type: undefined, decorators: [{
237
- type: Inject,
238
- args: ['CategoryRepository']
239
- }] }]; } });
240
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY291cG9uLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9jb25uZWN0LWFuZ3VsYXIvc3JjL3NlcnZpY2VzL2NvdXBvbi5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQTtBQUNsRCxPQUFPLEVBS0wsYUFBYSxFQUdiLFdBQVcsRUFDWCxhQUFhLEVBSWIsS0FBSyxFQUVMLEtBQUssR0FDTixNQUFNLG1CQUFtQixDQUFBO0FBQzFCLE9BQU8sRUFBRSxJQUFJLEVBQWMsRUFBRSxFQUFFLE1BQU0sTUFBTSxDQUFBO0FBQzNDLE9BQU8sRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLE1BQU0sZ0JBQWdCLENBQUE7QUFDL0MsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLFdBQVcsQ0FBQTs7O0FBS3hDLE1BQU0sT0FBTyxhQUFhO0lBQ3hCLFlBQytDLGdCQUFrQyxFQUN4QyxXQUFrQixFQUNiLGVBQWdDLEVBQzdCLGtCQUFzQztRQUh4QyxxQkFBZ0IsR0FBaEIsZ0JBQWdCLENBQWtCO1FBQ3hDLGdCQUFXLEdBQVgsV0FBVyxDQUFPO1FBQ2Isb0JBQWUsR0FBZixlQUFlLENBQWlCO1FBQzdCLHVCQUFrQixHQUFsQixrQkFBa0IsQ0FBb0I7UUFvTi9FLDRCQUF1QixHQUFHLENBQUMsU0FBaUIsRUFBVyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUEsU0FBUyxhQUFULFNBQVMsdUJBQVQsU0FBUyxDQUFFLEtBQUssQ0FBQyxjQUFjLENBQUMsQ0FBQSxDQUFBO0lBbk5qRyxDQUFDO0lBRUosV0FBVyxDQUNULFFBQWdCLEVBQ2hCLFlBQTJCLEVBQzNCLFFBQTJCLEVBQzNCLElBQVk7UUFFWixPQUFPLElBQUksQ0FDVCxJQUFJLENBQUMsZ0JBQWdCO2FBQ2xCLElBQUksQ0FBQztZQUNKLE9BQU8sRUFBRTtnQkFDUCxR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LGFBQWEsQ0FBQyxHQUFHLEVBQUU7WUFDaEYsZUFBZSxHQUFHLElBQUksSUFBSSxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxjQUFjLENBQUE7U0FDNUc7YUFBTTtZQUNMLGVBQWUsR0FBRyxNQUFNLENBQUMsU0FBUyxDQUFDLFlBQVksQ0FBQTtTQUNoRDtRQUVELE9BQU8sZUFBZSxDQUFBO0lBQ3hCLENBQUM7OzJHQXBSVSxhQUFhLGtCQUVkLGtCQUFrQixhQUNsQixZQUFZLGFBQ1osaUJBQWlCLGFBQ2pCLG9CQUFvQjsrR0FMbkIsYUFBYSxjQUZaLE1BQU07NEZBRVAsYUFBYTtrQkFIekIsVUFBVTttQkFBQztvQkFDVixVQUFVLEVBQUUsTUFBTTtpQkFDbkI7OzBCQUdJLE1BQU07MkJBQUMsa0JBQWtCOzswQkFDekIsTUFBTTsyQkFBQyxZQUFZOzswQkFDbkIsTUFBTTsyQkFBQyxpQkFBaUI7OzBCQUN4QixNQUFNOzJCQUFDLG9CQUFvQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdCwgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnXHJcbmltcG9ydCB7XHJcbiAgQ2F0ZWdvcnksXHJcbiAgQ2F0ZWdvcnlSZXBvc2l0b3J5LFxyXG4gIENoZWNrb3V0LFxyXG4gIENoZWNrb3V0U3Vic2NyaXB0aW9uLFxyXG4gIENoZWNrb3V0VHlwZXMsXHJcbiAgQ291cG9uLFxyXG4gIENvdXBvblJlcG9zaXRvcnksXHJcbiAgQ291cG9uVHlwZXMsXHJcbiAgRXhjbHVzaXZpdGllcyxcclxuICBMaW5lSXRlbSxcclxuICBPcmRlcixcclxuICBPcmRlclJlcG9zaXRvcnksXHJcbiAgU2hvcHMsXHJcbiAgVXNlcixcclxuICBXaGVyZSxcclxufSBmcm9tICdAaW5mcmFiNGEvY29ubmVjdCdcclxuaW1wb3J0IHsgZnJvbSwgT2JzZXJ2YWJsZSwgb2YgfSBmcm9tICdyeGpzJ1xyXG5pbXBvcnQgeyBjb25jYXRNYXAsIG1hcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJ1xyXG5pbXBvcnQgeyBERUZBVUxUX1NIT1AgfSBmcm9tICcuLi9jb25zdHMnXHJcblxyXG5ASW5qZWN0YWJsZSh7XHJcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgQ291cG9uU2VydmljZSB7XHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICBASW5qZWN0KCdDb3Vwb25SZXBvc2l0b3J5JykgcHJpdmF0ZSByZWFkb25seSBjb3Vwb25SZXBvc2l0b3J5OiBDb3Vwb25SZXBvc2l0b3J5LFxyXG4gICAgQEluamVjdChERUZBVUxUX1NIT1ApIHByaXZhdGUgcmVhZG9ubHkgZGVmYXVsdFNob3A6IFNob3BzLFxyXG4gICAgQEluamVjdCgnT3JkZXJSZXBvc2l0b3J5JykgcHJpdmF0ZSByZWFkb25seSBvcmRlclJlcG9zaXRvcnk6IE9yZGVyUmVwb3NpdG9yeSxcclxuICAgIEBJbmplY3QoJ0NhdGVnb3J5UmVwb3NpdG9yeScpIHByaXZhdGUgcmVhZG9ubHkgY2F0ZWdvcnlSZXBvc2l0b3J5OiBDYXRlZ29yeVJlcG9zaXRvcnksXHJcbiAgKSB7fVxyXG5cclxuICBjaGVja0NvdXBvbihcclxuICAgIG5pY2tuYW1lOiBzdHJpbmcsXHJcbiAgICBjaGVja291dFR5cGU6IENoZWNrb3V0VHlwZXMsXHJcbiAgICBjaGVja291dDogUGFydGlhbDxDaGVja291dD4sXHJcbiAgICBwbGFuOiBzdHJpbmcsXHJcbiAgKTogT2JzZXJ2YWJsZTxDb3Vwb24+IHtcclxuICAgIHJldHVybiBmcm9tKFxyXG4gICAgICB0aGlzLmNvdXBvblJlcG9zaXRvcnlcclxuICAgICAgICAuZmluZCh7XHJcbiAgICAgICAgICBmaWx0ZXJzOiB7XHJcbiAgICAgICAgICAgIG5pY2tuYW1lOiB7IG9wZXJhdG9yOiBXaGVyZS5FUVVBTFMsIHZhbHVlOiBuaWNrbmFtZSB9LFxyXG4gICAgICAgICAgICBhY3RpdmU6IHsgb3BlcmF0b3I6IFdoZXJlLkVRVUFMUywgdmFsdWU6IHRydWUgfSxcclxuICAgICAgICAgIH0sXHJcbiAgICAgICAgfSlcclxuICAgICAgICAudGhlbigocmVzdWx0KSA9PiByZXN1bHQuZGF0YVswXSksXHJcbiAgICApLnBpcGUoXHJcbiAgICAgIGNvbmNhdE1hcCgoY291cG9uKSA9PiB0aGlzLmNvdXBvblZhbGlkYXRpb24oY291cG9uLCBjaGVja291dFR5cGUpKSxcclxuICAgICAgY29uY2F0TWFwKChjb3Vwb25WYWxpZDogQ291cG9uKSA9PiB0aGlzLmNvdXBvblJ1bGVzVmFsaWRhdGlvbihjb3Vwb25WYWxpZCwgY2hlY2tvdXRUeXBlLCBjaGVja291dCwgcGxhbikpLFxyXG4gICAgICBtYXAoKGNvdXBvblZhbGlkYXRlZDogQ291cG9uKSA9PiBjb3Vwb25WYWxpZGF0ZWQgYXMgQ291cG9uKSxcclxuICAgIClcclxuICB9XHJcblxyXG4gIHByaXZhdGUgYXN5bmMgY291cG9uVmFsaWRhdGlvbihjb3Vwb246IENvdXBvbiwgY2hlY2tvdXRUeXBlOiBDaGVja291dFR5cGVzKSB7XHJcbiAgICBpZiAoIWNvdXBvbikgdGhyb3cgJ0N1cG9tIGludsOhbGlkby4nXHJcblxyXG4gICAgaWYgKGNvdXBvbj8uYmVnaW5BdCAmJiBjb3Vwb24/LmJlZ2luQXQuZ2V0VGltZSgpID4gbmV3IERhdGUoKS5nZXRUaW1lKCkpIHRocm93ICdDdXBvbSBpbnbDoWxpZG8uJ1xyXG5cclxuICAgIGlmIChjb3Vwb24/LmV4cGlyZXNJbiAmJiBjb3Vwb24/LmV4cGlyZXNJbi5nZXRUaW1lKCkgPCBuZXcgRGF0ZSgpLmdldFRpbWUoKSkgdGhyb3cgJ0N1cG9tIGV4cGlyYWRvLidcclxuXHJcbiAgICBjb25zdCBpc0luU2hvcCA9IGNvdXBvbi5zaG9wQXZhaWxhYmlsaXR5ID09PSBTaG9wcy5BTEwgfHwgY291cG9uLnNob3BBdmFpbGFiaWxpdHkgPT09IHRoaXMuZGVmYXVsdFNob3BcclxuXHJcbiAgICBpZiAoIWlzSW5TaG9wKSB0aHJvdyAnQ3Vwb20gaW52w6FsaWRvIHBhcmEgbG9qYS4nXHJcblxyXG4gICAgY29uc3QgaXNDaGVja291dFR5cGUgPSBjb3Vwb24uY2hlY2tvdXRUeXBlID09PSBDaGVja291dFR5cGVzLkFMTCB8fCBjb3Vwb24uY2hlY2tvdXRUeXBlID09PSBjaGVja291dFR5cGVcclxuXHJcbiAgICBpZiAoIWlzQ2hlY2tvdXRUeXBlKSB0aHJvdyAnQ3Vwb20gaW52w6FsaWRvLiBFcnJvIGRlIGNoZWNrb3V0LidcclxuXHJcbiAgICByZXR1cm4gY291cG9uXHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGFzeW5jIGNvdXBvblJ1bGVzVmFsaWRhdGlvbihcclxuICAgIGNvdXBvbjogQ291cG9uLFxyXG4gICAgY2hlY2tvdXRUeXBlOiBDaGVja291dFR5cGVzLFxyXG4gICAgY2hlY2tvdXQ6IFBhcnRpYWw8Q2hlY2tvdXQ+LFxyXG4gICAgcGxhbjogc3RyaW5nLFxyXG4gICkge1xyXG4gICAgaWYgKGNoZWNrb3V0VHlwZSA9PSBDaGVja291dFR5cGVzLlNVQlNDUklQVElPTikge1xyXG4gICAgICBpZiAoY291cG9uLnBsYW4gJiYgY291cG9uLnBsYW4udG9VcHBlckNhc2UoKSAhPT0gcGxhbi50b1VwcGVyQ2FzZSgpKSB0aHJvdyAnQ3Vwb20gaW52w6FsaWRvIHBhcmEgc3VhIGFzc2luYXR1cmEuJ1xyXG5cclxuICAgICAgcmV0dXJuIGNvdXBvblxyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IHZhbGlkVXNlciA9IHRoaXMuY291cG9tVXNlclZhbGlkYXRpb24oY291cG9uLCBjaGVja291dD8udXNlcilcclxuXHJcbiAgICBpZiAoIXZhbGlkVXNlcikgdGhyb3cgJ1VzdcOhcmlvIG7Do28gZWxlZ8OtdmVsLidcclxuXHJcbiAgICBjb25zdCBvcmRlcnMgPSBhd2FpdCB0aGlzLmdldE9yZGVyc1dpdGhDb3Vwb24oY291cG9uKVxyXG5cclxuICAgIGNvbnN0IG9yZGVyc1dpdGhVc2VyID0gdGhpcy5jb3VudE9yZGVyc1dpdGhVc2VyKG9yZGVycywgY2hlY2tvdXQudXNlci5lbWFpbClcclxuXHJcbiAgICBjb25zdCBjb3Vwb25Vc2VMaW1pdHMgPSB0aGlzLmdldENvdXBvblVzZUxpbWl0cyhjb3Vwb24sIGNoZWNrb3V0VHlwZSwgY2hlY2tvdXQudXNlcilcclxuXHJcbiAgICBpZiAoY291cG9uVXNlTGltaXRzLmxpbWl0ZWRQZXJVc2VyICYmIG9yZGVyc1dpdGhVc2VyID4gMCkgdGhyb3cgJ0xpbWl0ZSBkZSB1c28gcG9yIHVzdcOhcmlvIGF0aW5naWRvLidcclxuXHJcbiAgICBpZiAoIWNvdXBvblVzZUxpbWl0cy51bmxpbWl0ZWQgJiYgY291cG9uVXNlTGltaXRzLnRvdGFsICYmIG9yZGVycy5sZW5ndGggPj0gY291cG9uVXNlTGltaXRzLnRvdGFsKVxyXG4gICAgICB0aHJvdyAnTGltaXRlIGRlIHVzbyBhdGluZ2lkby4nXHJcblxyXG4gICAgY29uc3QgaGFzUHJvZHVjdENhdGVnb3JpZXMgPSBhd2FpdCB0aGlzLmhhc1Byb2R1Y3RDYXRlZ29yaWVzKGNvdXBvbiwgY2hlY2tvdXQpXHJcblxyXG4gICAgaWYgKCFoYXNQcm9kdWN0Q2F0ZWdvcmllcykgdGhyb3cgJ1NldSBjYXJyaW5obyBuw6NvIHBvc3N1aSBwcm9kdXRvcyBlbGVnw612ZWlzIHBhcmEgZGVzY29udG8uJ1xyXG5cclxuICAgIGNvbnN0IGhhc01pblN1YlRvdGFsID0gYXdhaXQgdGhpcy5oYXNNaW5TdWJUb3RhbChjb3Vwb24sIGNoZWNrb3V0KVxyXG5cclxuICAgIGlmICghaGFzTWluU3ViVG90YWwpXHJcbiAgICAgIHRocm93IGBWYWxvciBtw61uaW1vIGRlICR7SW50bC5OdW1iZXJGb3JtYXQoJ3B0LUJSJywgeyBzdHlsZTogJ2N1cnJlbmN5JywgY3VycmVuY3k6ICdCUkwnIH0pLmZvcm1hdChcclxuICAgICAgICBjb3Vwb24ubWluU3ViVG90YWxWYWx1ZSxcclxuICAgICAgKX0gbsOjbyBhdGluZ2lkb2BcclxuXHJcbiAgICByZXR1cm4gY291cG9uXHJcbiAgfVxyXG5cclxuICBwdWJsaWMgY2FsY0Rpc2NvdW50U3Vic2NyaXB0aW9uKGNvdXBvbjogQ291cG9uLCBjaGVja291dDogUGFydGlhbDxDaGVja291dFN1YnNjcmlwdGlvbj4pOiBPYnNlcnZhYmxlPG51bWJlcj4ge1xyXG4gICAgbGV0IGRpc2NvdW50ID0gMFxyXG5cclxuICAgIGlmIChjb3Vwb24uZGlzY291bnQuc3Vic2NyaXB0aW9uLnR5cGUgPT0gQ291cG9uVHlwZXMuQUJTT0xVVEUpIGRpc2NvdW50ID0gY291cG9uLmRpc2NvdW50LnN1YnNjcmlwdGlvbi52YWx1ZVxyXG4gICAgZWxzZSBkaXNjb3VudCA9IGNoZWNrb3V0LnN1YnNjcmlwdGlvblBsYW4ucmVjdXJyZW5jZVByaWNlICogKGNvdXBvbi5kaXNjb3VudC5zdWJzY3JpcHRpb24udmFsdWUgLyAxMDApXHJcblxyXG4gICAgcmV0dXJuIG9mKGRpc2NvdW50KVxyXG4gIH1cclxuXHJcbiAgcHVibGljIGFzeW5jIGNhbGNEaXNjb3VudFNob3BwaW5nKGNvdXBvbjogQ291cG9uLCBjaGVja291dDogUGFydGlhbDxDaGVja291dD4pOiBQcm9taXNlPG51bWJlcj4ge1xyXG4gICAgbGV0IGRpc2NvdW50ID0gMFxyXG5cclxuICAgIGlmIChjaGVja291dC51c2VyLmlzU3Vic2NyaWJlciAmJiBjb3Vwb24uZGlzY291bnQuc3Vic2NyaWJlci52YWx1ZSkge1xyXG4gICAgICBkaXNjb3VudCA9IGF3YWl0IHRoaXMuY2FsY0Rpc2NvdW50QnlUeXBlKFxyXG4gICAgICAgIGNvdXBvbi5kaXNjb3VudC5zdWJzY3JpYmVyLnR5cGUsXHJcbiAgICAgICAgY291cG9uLmRpc2NvdW50LnN1YnNjcmliZXIudmFsdWUsXHJcbiAgICAgICAgY291cG9uLnByb2R1Y3RzQ2F0ZWdvcmllcyxcclxuICAgICAgICBjaGVja291dCxcclxuICAgICAgKVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgZGlzY291bnQgPSBhd2FpdCB0aGlzLmNhbGNEaXNjb3VudEJ5VHlwZShcclxuICAgICAgICBjb3Vwb24uZGlzY291bnQubm9uX3N1YnNjcmliZXIudHlwZSxcclxuICAgICAgICBjb3Vwb24uZGlzY291bnQubm9uX3N1YnNjcmliZXIudmFsdWUsXHJcbiAgICAgICAgY291cG9uLnByb2R1Y3RzQ2F0ZWdvcmllcyxcclxuICAgICAgICBjaGVja291dCxcclxuICAgICAgKVxyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBkaXNjb3VudFxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBhc3luYyBjYWxjRGlzY291bnRCeVR5cGUoXHJcbiAgICB0eXBlOiBDb3Vwb25UeXBlcyxcclxuICAgIHZhbHVlOiBudW1iZXIsXHJcbiAgICBjYXRlZ29yaWVzLFxyXG4gICAgY2hlY2tvdXQ6IFBhcnRpYWw8Q2hlY2tvdXQ+LFxyXG4gICk6IFByb21pc2U8bnVtYmVyPiB7XHJcbiAgICBsZXQgZGlzY291bnQgPSAwXHJcblxyXG4gICAgbGV0IGxpbmVJdGVuc0Rpc2NvdW50ID0gYXdhaXQgdGhpcy5nZXRMaW5lSXRlbnNFbGlnZWJsZUZvckRpc2NvdW50KGNhdGVnb3JpZXMsIGNoZWNrb3V0KVxyXG5cclxuICAgIGNvbnN0IHN1YlRvdGFsID0gdGhpcy5jYWxjQ2hlY2tvdXRTdWJ0b3RhbChsaW5lSXRlbnNEaXNjb3VudCwgY2hlY2tvdXQudXNlciwgY2hlY2tvdXQuc2hvcClcclxuXHJcbiAgICBpZiAodHlwZSA9PSBDb3Vwb25UeXBlcy5BQlNPTFVURSkge1xyXG4gICAgICBkaXNjb3VudCA9IHZhbHVlID4gc3ViVG90YWwgPyBzdWJUb3RhbCA6IHZhbHVlXHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBkaXNjb3VudCA9IHN1YlRvdGFsICogKHZhbHVlIC8gMTAwKVxyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBkaXNjb3VudFxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBhc3luYyBoYXNNaW5TdWJUb3RhbChjb3Vwb246IENvdXBvbiwgY2hlY2tvdXQ6IFBhcnRpYWw8Q2hlY2tvdXQ+KTogUHJvbWlzZTxib29sZWFuPiB7XHJcbiAgICBpZiAoIWNvdXBvbi5taW5TdWJUb3RhbFZhbHVlKSByZXR1cm4gdHJ1ZVxyXG5cclxuICAgIGxldCBsaW5lSXRlbnNEaXNjb3VudCA9IGF3YWl0IHRoaXMuZ2V0TGluZUl0ZW5zRWxpZ2VibGVGb3JEaXNjb3VudChjb3Vwb24ucHJvZHVjdHNDYXRlZ29yaWVzLCBjaGVja291dClcclxuXHJcbiAgICBjb25zdCBzdWJUb3RhbCA9IHRoaXMuY2FsY0NoZWNrb3V0U3VidG90YWwobGluZUl0ZW5zRGlzY291bnQsIGNoZWNrb3V0LnVzZXIsIGNoZWNrb3V0LnNob3ApXHJcblxyXG4gICAgaWYgKGNvdXBvbi5taW5TdWJUb3RhbFZhbHVlIDw9IHN1YlRvdGFsKSByZXR1cm4gdHJ1ZVxyXG5cclxuICAgIHJldHVybiBmYWxzZVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBhc3luYyBoYXNQcm9kdWN0Q2F0ZWdvcmllcyhjb3Vwb246IENvdXBvbiwgY2hlY2tvdXQ6IFBhcnRpYWw8Q2hlY2tvdXQ+KTogUHJvbWlzZTxib29sZWFuPiB7XHJcbiAgICBpZiAoIWNvdXBvbi5wcm9kdWN0c0NhdGVnb3JpZXMgfHwgIWNvdXBvbi5wcm9kdWN0c0NhdGVnb3JpZXMubGVuZ3RoKSB7XHJcbiAgICAgIHJldHVybiB0cnVlXHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgY291cG9uQ2F0ZWdvcmllcyA9IGF3YWl0IHRoaXMuZ2V0Q291cG9uQ2F0ZWdvcmllc0lkKGNvdXBvbi5wcm9kdWN0c0NhdGVnb3JpZXMpXHJcblxyXG4gICAgY29uc3QgaGFzQ2F0ZWdvcmllcyA9IGNoZWNrb3V0LmxpbmVJdGVtcz8uZmlsdGVyKChpKSA9PiB7XHJcbiAgICAgIGlmICghaS5jYXRlZ29yaWVzIHx8ICFpLmNhdGVnb3JpZXM/Lmxlbmd0aCkgcmV0dXJuIHRydWVcclxuICAgICAgcmV0dXJuIGkuY2F0ZWdvcmllcy5zb21lKChjKSA9PiBjb3Vwb25DYXRlZ29yaWVzLnNvbWUoKGNhdCkgPT4gY2F0ID09IGMpKVxyXG4gICAgfSlcclxuXHJcbiAgICByZXR1cm4gaGFzQ2F0ZWdvcmllcy5sZW5ndGggPyB0cnVlIDogZmFsc2VcclxuICB9XHJcblxyXG4gIHByaXZhdGUgY291cG9tVXNlclZhbGlkYXRpb24oY291cG9uOiBDb3Vwb24sIHVzZXI6IFVzZXIpIHtcclxuICAgIGlmICghdXNlciB8fCBjb3Vwb24uZXhjbHVzaXZpdHlUeXBlLmluY2x1ZGVzKEV4Y2x1c2l2aXRpZXMuQUxMX1VTRVJTKSkgcmV0dXJuIHRydWVcclxuXHJcbiAgICBsZXQgdXNlclR5cGVzID0gW11cclxuXHJcbiAgICBpZiAoY291cG9uLmV4Y2x1c2l2aXR5VHlwZS5pbmNsdWRlcyhFeGNsdXNpdml0aWVzLkNPTExBQk9SQVRPUlMpICYmIHRoaXMuZW1haWxJc0Zyb21Db2xsYWJvcmF0b3IodXNlci5lbWFpbCkpXHJcbiAgICAgIHVzZXJUeXBlcy5wdXNoKEV4Y2x1c2l2aXRpZXMuQ09MTEFCT1JBVE9SUylcclxuXHJcbiAgICBpZiAoY291cG9uLmV4Y2x1c2l2aXR5VHlwZS5pbmNsdWRlcyhFeGNsdXNpdml0aWVzLlNQRUNJRklDX1VTRVIpICYmIGNvdXBvbi51c2VyRXhjbHVzaXZlRW1haWwuaW5jbHVkZXModXNlci5lbWFpbCkpXHJcbiAgICAgIHVzZXJUeXBlcy5wdXNoKEV4Y2x1c2l2aXRpZXMuU1BFQ0lGSUNfVVNFUilcclxuXHJcbiAgICBpZiAoXHJcbiAgICAgIGNvdXBvbi5leGNsdXNpdml0eVR5cGUuaW5jbHVkZXMoRXhjbHVzaXZpdGllcy5BQ1RJVkVfU1VCU0NSSUJFUikgJiZcclxuICAgICAgdXNlci5pc1N1YnNjcmliZXIgJiZcclxuICAgICAgdXNlci5zdWJzY3JpcHRpb25QbGFuICE9ICcnXHJcbiAgICApXHJcbiAgICAgIHVzZXJUeXBlcy5wdXNoKEV4Y2x1c2l2aXRpZXMuQUNUSVZFX1NVQlNDUklCRVIpXHJcblxyXG4gICAgaWYgKFxyXG4gICAgICB1c2VyLmlzU3Vic2NyaWJlciAmJlxyXG4gICAgICB1c2VyLnN1YnNjcmlwdGlvblBsYW4gPT0gJycgJiZcclxuICAgICAgY291cG9uLmV4Y2x1c2l2aXR5VHlwZS5pbmNsdWRlcyhFeGNsdXNpdml0aWVzLklOQUNUSVZFX1NVQlNDUklCRVIpXHJcbiAgICApXHJcbiAgICAgIHVzZXJUeXBlcy5wdXNoKEV4Y2x1c2l2aXRpZXMuSU5BQ1RJVkVfU1VCU0NSSUJFUilcclxuXHJcbiAgICBpZiAoY291cG9uLmV4Y2x1c2l2aXR5VHlwZS5pbmNsdWRlcyhFeGNsdXNpdml0aWVzLk5PTl9TVUJTQ1JJQkVSKSAmJiAhdXNlci5pc1N1YnNjcmliZXIpXHJcbiAgICAgIHVzZXJUeXBlcy5wdXNoKEV4Y2x1c2l2aXRpZXMuTk9OX1NVQlNDUklCRVIpXHJcblxyXG4gICAgcmV0dXJuIGNvdXBvbi5leGNsdXNpdml0eVR5cGUuc29tZSgocikgPT4gdXNlclR5cGVzLmluY2x1ZGVzKHIpKVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBhc3luYyBnZXRDb3Vwb25DYXRlZ29yaWVzSWQocHJvZHVjdHNDYXRlZ29yaWVzOiBzdHJpbmdbXSk6IFByb21pc2U8QXJyYXk8U3RyaW5nPj4ge1xyXG4gICAgY29uc3QgY291cG9uQ2F0ZWdvcmllczogQXJyYXk8U3RyaW5nPiA9IFtdXHJcblxyXG4gICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IHByb2R1Y3RzQ2F0ZWdvcmllcy5sZW5ndGg7IGluZGV4KyspIHtcclxuICAgICAgY29uc3QgY2F0ZWdvcnk6IENhdGVnb3J5ICYgeyBmaXJlc3RvcmVJZD86IHN0cmluZyB9ID0gYXdhaXQgdGhpcy5jYXRlZ29yeVJlcG9zaXRvcnkuZ2V0KHtcclxuICAgICAgICBpZDogcHJvZHVjdHNDYXRlZ29yaWVzW2luZGV4XSxcclxuICAgICAgfSlcclxuXHJcbiAgICAgIGlmIChjYXRlZ29yeSkge1xyXG4gICAgICAgIGNvbnN0IGNoaWxkcmVuID0gYXdhaXQgdGhpcy5jYXRlZ29yeVJlcG9zaXRvcnkuZ2V0Q2hpbGRyZW4ocGFyc2VJbnQocHJvZHVjdHNDYXRlZ29yaWVzW2luZGV4XSkpXHJcblxyXG4gICAgICAgIGNvdXBvbkNhdGVnb3JpZXMucHVzaChjYXRlZ29yeS5pZCwgLi4uY2hpbGRyZW4ubWFwKChjKSA9PiBjLmlkLnRvU3RyaW5nKCkpKVxyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIFsuLi5uZXcgU2V0KGNvdXBvbkNhdGVnb3JpZXMpXVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBlbWFpbElzRnJvbUNvbGxhYm9yYXRvciA9ICh1c2VyRW1haWw6IHN0cmluZyk6IGJvb2xlYW4gPT4gISF1c2VyRW1haWw/Lm1hdGNoKC9AYjRhLmNvbS5ici9nKVxyXG5cclxuICBwcml2YXRlIGFzeW5jIGdldExpbmVJdGVuc0VsaWdlYmxlRm9yRGlzY291bnQoXHJcbiAgICBwcm9kdWN0c0NhdGVnb3JpZXM6IHN0cmluZ1tdLFxyXG4gICAgY2hlY2tvdXQ6IFBhcnRpYWw8Q2hlY2tvdXQ+LFxyXG4gICk6IFByb21pc2U8TGluZUl0ZW1bXT4ge1xyXG4gICAgbGV0IGxpbmVJdGVuc0Rpc2NvdW50ID0gW11cclxuICAgIGNvbnN0IGNvdXBvbkNhdGVnb3JpZXMgPSBhd2FpdCB0aGlzLmdldENvdXBvbkNhdGVnb3JpZXNJZChwcm9kdWN0c0NhdGVnb3JpZXMpXHJcblxyXG4gICAgaWYgKHByb2R1Y3RzQ2F0ZWdvcmllcyAmJiBwcm9kdWN0c0NhdGVnb3JpZXMubGVuZ3RoKSB7XHJcbiAgICAgIGxpbmVJdGVuc0Rpc2NvdW50ID0gY2hlY2tvdXQubGluZUl0ZW1zPy5maWx0ZXIoKGkpID0+IHtcclxuICAgICAgICBpZiAoaS5jYXRlZ29yaWVzPy5sZW5ndGgpIHtcclxuICAgICAgICAgIHJldHVybiBpLmNhdGVnb3JpZXMuc29tZSgoYykgPT4gY291cG9uQ2F0ZWdvcmllcy5zb21lKChjYXQpID0+IGNhdCA9PSBjKSlcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHRydWVcclxuICAgICAgfSlcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGxpbmVJdGVuc0Rpc2NvdW50ID0gY2hlY2tvdXQubGluZUl0ZW1zXHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIGxpbmVJdGVuc0Rpc2NvdW50XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGNhbGNDaGVja291dFN1YnRvdGFsKGxpbmVJdGVuczogTGluZUl0ZW1bXSwgdXNlcjogVXNlciwgc2hvcDogc3RyaW5nKTogbnVtYmVyIHtcclxuICAgIHJldHVybiAoXHJcbiAgICAgIGxpbmVJdGVucz8ucmVkdWNlKFxyXG4gICAgICAgIChhY2MsIGN1cnIpID0+XHJcbiAgICAgICAgICB1c2VyPy5pc1N1YnNjcmliZXIgJiYgY3Vyci5wcmljZVtzaG9wXT8uc3Vic2NyaWJlclByaWNlXHJcbiAgICAgICAgICAgID8gYWNjICsgY3Vyci5wcmljZVtzaG9wXT8uc3Vic2NyaWJlclByaWNlICogY3Vyci5xdWFudGl0eVxyXG4gICAgICAgICAgICA6IGFjYyArIGN1cnIucHJpY2VQYWlkICogY3Vyci5xdWFudGl0eSxcclxuICAgICAgICAwLFxyXG4gICAgICApIHx8IDBcclxuICAgIClcclxuICB9XHJcblxyXG4gIHByaXZhdGUgYXN5bmMgZ2V0T3JkZXJzV2l0aENvdXBvbihjb3Vwb246IENvdXBvbik6IFByb21pc2U8T3JkZXJbXT4ge1xyXG4gICAgcmV0dXJuIGF3YWl0IHRoaXMub3JkZXJSZXBvc2l0b3J5XHJcbiAgICAgIC5maW5kKHtcclxuICAgICAgICBmaWx0ZXJzOiB7XHJcbiAgICAgICAgICBjb3Vwb246IHsgaWQ6IGNvdXBvbi5pZCB9LFxyXG4gICAgICAgICAgcGF5bWVudDogeyBzdGF0dXM6ICdwYWlkJyB9LFxyXG4gICAgICAgIH0sXHJcbiAgICAgIH0pXHJcbiAgICAgIC50aGVuKChyZXN1bHQpID0+IHJlc3VsdC5kYXRhKVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBjb3VudE9yZGVyc1dpdGhVc2VyKG9yZGVyczogT3JkZXJbXSwgZW1haWw6IHN0cmluZyk6IG51bWJlciB7XHJcbiAgICByZXR1cm4gb3JkZXJzLmZpbHRlcigobykgPT4gby51c2VyLmVtYWlsID09IGVtYWlsKS5sZW5ndGhcclxuICB9XHJcblxyXG4gIHByaXZhdGUgZ2V0Q291cG9uVXNlTGltaXRzKGNvdXBvbjogQ291cG9uLCBjaGVja291dFR5cGU6IENoZWNrb3V0VHlwZXMsIHVzZXI6IFVzZXIpIHtcclxuICAgIGxldCBjb3Vwb25Vc2VMaW1pdHM6IHsgdW5saW1pdGVkPzogYm9vbGVhbjsgdG90YWw/OiBudW1iZXI7IGxpbWl0ZWRQZXJVc2VyPzogYm9vbGVhbiB9XHJcbiAgICBpZiAoY2hlY2tvdXRUeXBlID09IENoZWNrb3V0VHlwZXMuRUNPTU1FUkNFIHx8IGNoZWNrb3V0VHlwZSA9PSBDaGVja291dFR5cGVzLkFMTCkge1xyXG4gICAgICBjb3Vwb25Vc2VMaW1pdHMgPSB1c2VyICYmIHVzZXIuaXNTdWJzY3JpYmVyID8gY291cG9uLnVzZUxpbWl0cy5zdWJzY3JpYmVyIDogY291cG9uLnVzZUxpbWl0cy5ub25fc3Vic2NyaWJlclxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgY291cG9uVXNlTGltaXRzID0gY291cG9uLnVzZUxpbWl0cy5zdWJzY3JpcHRpb25cclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gY291cG9uVXNlTGltaXRzXHJcbiAgfVxyXG59XHJcbiJdfQ==
1
+ import { __awaiter } from "tslib";
2
+ import { Inject, Injectable } from '@angular/core';
3
+ import { CheckoutTypes, CouponTypes, Exclusivities, Shops, Where, } from '@infrab4a/connect';
4
+ import { from, of } from 'rxjs';
5
+ import { concatMap, map } from 'rxjs/operators';
6
+ import { DEFAULT_SHOP } from '../consts';
7
+ import * as i0 from "@angular/core";
8
+ import * as i1 from "@infrab4a/connect";
9
+ export class CouponService {
10
+ constructor(couponRepository, defaultShop, orderRepository, categoryRepository) {
11
+ this.couponRepository = couponRepository;
12
+ this.defaultShop = defaultShop;
13
+ this.orderRepository = orderRepository;
14
+ this.categoryRepository = categoryRepository;
15
+ this.emailIsFromCollaborator = (userEmail) => !!(userEmail === null || userEmail === void 0 ? void 0 : userEmail.match(/@b4a.com.br/g));
16
+ }
17
+ checkCoupon(nickname, checkoutType, checkout, plan) {
18
+ return from(this.couponRepository
19
+ .find({
20
+ filters: {
21
+ nickname: { operator: Where.EQUALS, value: nickname },
22
+ active: { operator: Where.EQUALS, value: true },
23
+ },
24
+ })
25
+ .then((result) => result.data[0])).pipe(concatMap((coupon) => this.couponValidation(coupon, checkoutType)), concatMap((couponValid) => this.couponRulesValidation(couponValid, checkoutType, checkout, plan)), map((couponValidated) => couponValidated));
26
+ }
27
+ couponValidation(coupon, checkoutType) {
28
+ return __awaiter(this, void 0, void 0, function* () {
29
+ if (!coupon)
30
+ throw 'Cupom inválido.';
31
+ if ((coupon === null || coupon === void 0 ? void 0 : coupon.beginAt) && (coupon === null || coupon === void 0 ? void 0 : coupon.beginAt.getTime()) > new Date().getTime())
32
+ throw 'Cupom inválido.';
33
+ if ((coupon === null || coupon === void 0 ? void 0 : coupon.expiresIn) && (coupon === null || coupon === void 0 ? void 0 : coupon.expiresIn.getTime()) < new Date().getTime())
34
+ throw 'Cupom expirado.';
35
+ const isInShop = coupon.shopAvailability === Shops.ALL || coupon.shopAvailability === this.defaultShop;
36
+ if (!isInShop)
37
+ throw 'Cupom inválido para loja.';
38
+ const isCheckoutType = coupon.checkoutType === CheckoutTypes.ALL || coupon.checkoutType === checkoutType;
39
+ if (!isCheckoutType)
40
+ throw 'Cupom inválido. Erro de checkout.';
41
+ return coupon;
42
+ });
43
+ }
44
+ couponRulesValidation(coupon, checkoutType, checkout, plan) {
45
+ return __awaiter(this, void 0, void 0, function* () {
46
+ if (checkoutType == CheckoutTypes.SUBSCRIPTION) {
47
+ if (coupon.plan && coupon.plan.toUpperCase() !== plan.toUpperCase())
48
+ throw 'Cupom inválido para sua assinatura.';
49
+ return coupon;
50
+ }
51
+ const validUser = this.coupomUserValidation(coupon, checkout === null || checkout === void 0 ? void 0 : checkout.user);
52
+ if (!validUser)
53
+ throw 'Usuário não elegível.';
54
+ const couponUseLimits = this.getCouponUseLimits(coupon, checkoutType, checkout.user);
55
+ if (!couponUseLimits.unlimited || couponUseLimits.limitedPerUser) {
56
+ const orders = yield this.getOrdersWithCoupon(coupon);
57
+ if (!couponUseLimits.unlimited && couponUseLimits.total && orders.length >= couponUseLimits.total)
58
+ throw 'Limite de uso atingido.';
59
+ if (couponUseLimits.limitedPerUser) {
60
+ const ordersWithUser = this.countOrdersWithUser(orders, checkout.user.email);
61
+ if (ordersWithUser > 0)
62
+ throw 'Limite de uso por usuário atingido.';
63
+ }
64
+ }
65
+ const hasProductCategories = yield this.hasProductCategories(coupon, checkout);
66
+ if (!hasProductCategories)
67
+ throw 'Seu carrinho não possui produtos elegíveis para desconto.';
68
+ const hasMinSubTotal = yield this.hasMinSubTotal(coupon, checkout);
69
+ if (!hasMinSubTotal)
70
+ throw `Valor mínimo de ${Intl.NumberFormat('pt-BR', { style: 'currency', currency: 'BRL' }).format(coupon.minSubTotalValue)} não atingido`;
71
+ return coupon;
72
+ });
73
+ }
74
+ calcDiscountSubscription(coupon, checkout) {
75
+ let discount = 0;
76
+ if (coupon.discount.subscription.type == CouponTypes.ABSOLUTE)
77
+ discount = coupon.discount.subscription.value;
78
+ else
79
+ discount = checkout.subscriptionPlan.recurrencePrice * (coupon.discount.subscription.value / 100);
80
+ return of(discount);
81
+ }
82
+ calcDiscountShopping(coupon, checkout) {
83
+ return __awaiter(this, void 0, void 0, function* () {
84
+ let discount = 0;
85
+ if (checkout.user.isSubscriber && coupon.discount.subscriber.value) {
86
+ discount = yield this.calcDiscountByType(coupon.discount.subscriber.type, coupon.discount.subscriber.value, coupon.productsCategories, checkout);
87
+ }
88
+ else {
89
+ discount = yield this.calcDiscountByType(coupon.discount.non_subscriber.type, coupon.discount.non_subscriber.value, coupon.productsCategories, checkout);
90
+ }
91
+ return discount;
92
+ });
93
+ }
94
+ calcDiscountByType(type, value, categories, checkout) {
95
+ return __awaiter(this, void 0, void 0, function* () {
96
+ let discount = 0;
97
+ let lineItensDiscount = yield this.getLineItensEligebleForDiscount(categories, checkout);
98
+ const subTotal = this.calcCheckoutSubtotal(lineItensDiscount, checkout.user, checkout.shop);
99
+ if (type == CouponTypes.ABSOLUTE) {
100
+ discount = value > subTotal ? subTotal : value;
101
+ }
102
+ else {
103
+ discount = subTotal * (value / 100);
104
+ }
105
+ return discount;
106
+ });
107
+ }
108
+ hasMinSubTotal(coupon, checkout) {
109
+ return __awaiter(this, void 0, void 0, function* () {
110
+ if (!coupon.minSubTotalValue)
111
+ return true;
112
+ let lineItensDiscount = yield this.getLineItensEligebleForDiscount(coupon.productsCategories, checkout);
113
+ const subTotal = this.calcCheckoutSubtotal(lineItensDiscount, checkout.user, checkout.shop);
114
+ if (coupon.minSubTotalValue <= subTotal)
115
+ return true;
116
+ return false;
117
+ });
118
+ }
119
+ hasProductCategories(coupon, checkout) {
120
+ var _a;
121
+ return __awaiter(this, void 0, void 0, function* () {
122
+ if (!coupon.productsCategories || !coupon.productsCategories.length) {
123
+ return true;
124
+ }
125
+ const couponCategories = yield this.getCouponCategoriesId(coupon.productsCategories);
126
+ const hasCategories = (_a = checkout.lineItems) === null || _a === void 0 ? void 0 : _a.filter((i) => {
127
+ var _a;
128
+ if (!i.categories || !((_a = i.categories) === null || _a === void 0 ? void 0 : _a.length))
129
+ return true;
130
+ return i.categories.some((c) => couponCategories.some((cat) => cat == c));
131
+ });
132
+ return hasCategories.length ? true : false;
133
+ });
134
+ }
135
+ coupomUserValidation(coupon, user) {
136
+ if (!user || coupon.exclusivityType.includes(Exclusivities.ALL_USERS))
137
+ return true;
138
+ let userTypes = [];
139
+ if (coupon.exclusivityType.includes(Exclusivities.COLLABORATORS) && this.emailIsFromCollaborator(user.email))
140
+ userTypes.push(Exclusivities.COLLABORATORS);
141
+ if (coupon.exclusivityType.includes(Exclusivities.SPECIFIC_USER) && coupon.userExclusiveEmail.includes(user.email))
142
+ userTypes.push(Exclusivities.SPECIFIC_USER);
143
+ if (coupon.exclusivityType.includes(Exclusivities.ACTIVE_SUBSCRIBER) &&
144
+ user.isSubscriber &&
145
+ user.subscriptionPlan != '')
146
+ userTypes.push(Exclusivities.ACTIVE_SUBSCRIBER);
147
+ if (user.isSubscriber &&
148
+ user.subscriptionPlan == '' &&
149
+ coupon.exclusivityType.includes(Exclusivities.INACTIVE_SUBSCRIBER))
150
+ userTypes.push(Exclusivities.INACTIVE_SUBSCRIBER);
151
+ if (coupon.exclusivityType.includes(Exclusivities.NON_SUBSCRIBER) && !user.isSubscriber)
152
+ userTypes.push(Exclusivities.NON_SUBSCRIBER);
153
+ return coupon.exclusivityType.some((r) => userTypes.includes(r));
154
+ }
155
+ getCouponCategoriesId(productsCategories) {
156
+ return __awaiter(this, void 0, void 0, function* () {
157
+ const couponCategories = [];
158
+ for (let index = 0; index < productsCategories.length; index++) {
159
+ const category = yield this.categoryRepository.get({
160
+ id: productsCategories[index],
161
+ });
162
+ if (category) {
163
+ const children = yield this.categoryRepository.getChildren(parseInt(productsCategories[index]));
164
+ couponCategories.push(category.id, ...children.map((c) => c.id.toString()));
165
+ }
166
+ }
167
+ return [...new Set(couponCategories)];
168
+ });
169
+ }
170
+ getLineItensEligebleForDiscount(productsCategories, checkout) {
171
+ var _a;
172
+ return __awaiter(this, void 0, void 0, function* () {
173
+ let lineItensDiscount = [];
174
+ const couponCategories = yield this.getCouponCategoriesId(productsCategories);
175
+ if (productsCategories && productsCategories.length) {
176
+ lineItensDiscount = (_a = checkout.lineItems) === null || _a === void 0 ? void 0 : _a.filter((i) => {
177
+ var _a;
178
+ if ((_a = i.categories) === null || _a === void 0 ? void 0 : _a.length) {
179
+ return i.categories.some((c) => couponCategories.some((cat) => cat == c));
180
+ }
181
+ return true;
182
+ });
183
+ }
184
+ else {
185
+ lineItensDiscount = checkout.lineItems;
186
+ }
187
+ return lineItensDiscount;
188
+ });
189
+ }
190
+ calcCheckoutSubtotal(lineItens, user, shop) {
191
+ return ((lineItens === null || lineItens === void 0 ? void 0 : lineItens.reduce((acc, curr) => {
192
+ var _a, _b;
193
+ return (user === null || user === void 0 ? void 0 : user.isSubscriber) && ((_a = curr.price[shop]) === null || _a === void 0 ? void 0 : _a.subscriberPrice)
194
+ ? acc + ((_b = curr.price[shop]) === null || _b === void 0 ? void 0 : _b.subscriberPrice) * curr.quantity
195
+ : acc + curr.pricePaid * curr.quantity;
196
+ }, 0)) || 0);
197
+ }
198
+ getOrdersWithCoupon(coupon) {
199
+ return __awaiter(this, void 0, void 0, function* () {
200
+ return yield this.orderRepository
201
+ .find({
202
+ filters: {
203
+ coupon: { id: coupon.id },
204
+ payment: { status: 'paid' },
205
+ },
206
+ })
207
+ .then((result) => result.data);
208
+ });
209
+ }
210
+ countOrdersWithUser(orders, email) {
211
+ return orders.filter((o) => o.user.email == email).length;
212
+ }
213
+ getCouponUseLimits(coupon, checkoutType, user) {
214
+ let couponUseLimits;
215
+ if (checkoutType == CheckoutTypes.ECOMMERCE || checkoutType == CheckoutTypes.ALL) {
216
+ couponUseLimits = user && user.isSubscriber ? coupon.useLimits.subscriber : coupon.useLimits.non_subscriber;
217
+ }
218
+ else {
219
+ couponUseLimits = coupon.useLimits.subscription;
220
+ }
221
+ return couponUseLimits;
222
+ }
223
+ }
224
+ CouponService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0, type: CouponService, deps: [{ token: 'CouponRepository' }, { token: DEFAULT_SHOP }, { token: 'OrderRepository' }, { token: 'CategoryRepository' }], target: i0.ɵɵFactoryTarget.Injectable });
225
+ CouponService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0, type: CouponService, providedIn: 'root' });
226
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0, type: CouponService, decorators: [{
227
+ type: Injectable,
228
+ args: [{
229
+ providedIn: 'root',
230
+ }]
231
+ }], ctorParameters: function () { return [{ type: undefined, decorators: [{
232
+ type: Inject,
233
+ args: ['CouponRepository']
234
+ }] }, { type: i1.Shops, decorators: [{
235
+ type: Inject,
236
+ args: [DEFAULT_SHOP]
237
+ }] }, { type: undefined, decorators: [{
238
+ type: Inject,
239
+ args: ['OrderRepository']
240
+ }] }, { type: undefined, decorators: [{
241
+ type: Inject,
242
+ args: ['CategoryRepository']
243
+ }] }]; } });
244
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY291cG9uLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9jb25uZWN0LWFuZ3VsYXIvc3JjL3NlcnZpY2VzL2NvdXBvbi5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQTtBQUNsRCxPQUFPLEVBS0wsYUFBYSxFQUdiLFdBQVcsRUFDWCxhQUFhLEVBSWIsS0FBSyxFQUVMLEtBQUssR0FDTixNQUFNLG1CQUFtQixDQUFBO0FBQzFCLE9BQU8sRUFBRSxJQUFJLEVBQWMsRUFBRSxFQUFFLE1BQU0sTUFBTSxDQUFBO0FBQzNDLE9BQU8sRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLE1BQU0sZ0JBQWdCLENBQUE7QUFDL0MsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLFdBQVcsQ0FBQTs7O0FBS3hDLE1BQU0sT0FBTyxhQUFhO0lBQ3hCLFlBQytDLGdCQUFrQyxFQUN4QyxXQUFrQixFQUNiLGVBQWdDLEVBQzdCLGtCQUFzQztRQUh4QyxxQkFBZ0IsR0FBaEIsZ0JBQWdCLENBQWtCO1FBQ3hDLGdCQUFXLEdBQVgsV0FBVyxDQUFPO1FBQ2Isb0JBQWUsR0FBZixlQUFlLENBQWlCO1FBQzdCLHVCQUFrQixHQUFsQixrQkFBa0IsQ0FBb0I7UUF3Ti9FLDRCQUF1QixHQUFHLENBQUMsU0FBaUIsRUFBVyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUEsU0FBUyxhQUFULFNBQVMsdUJBQVQsU0FBUyxDQUFFLEtBQUssQ0FBQyxjQUFjLENBQUMsQ0FBQSxDQUFBO0lBdk5qRyxDQUFDO0lBRUosV0FBVyxDQUNULFFBQWdCLEVBQ2hCLFlBQTJCLEVBQzNCLFFBQTJCLEVBQzNCLElBQVk7UUFFWixPQUFPLElBQUksQ0FDVCxJQUFJLENBQUMsZ0JBQWdCO2FBQ2xCLElBQUksQ0FBQztZQUNKLE9BQU8sRUFBRTtnQkFDUCxR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LEVBQUUsSUFBVTtRQUNoRixJQUFJLGVBQWtGLENBQUE7UUFDdEYsSUFBSSxZQUFZLElBQUksYUFBYSxDQUFDLFNBQVMsSUFBSSxZQUFZLElBQUksYUFBYSxDQUFDLEdBQUcsRUFBRTtZQUNoRixlQUFlLEdBQUcsSUFBSSxJQUFJLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLGNBQWMsQ0FBQTtTQUM1RzthQUFNO1lBQ0wsZUFBZSxHQUFHLE1BQU0sQ0FBQyxTQUFTLENBQUMsWUFBWSxDQUFBO1NBQ2hEO1FBRUQsT0FBTyxlQUFlLENBQUE7SUFDeEIsQ0FBQzs7MkdBeFJVLGFBQWEsa0JBRWQsa0JBQWtCLGFBQ2xCLFlBQVksYUFDWixpQkFBaUIsYUFDakIsb0JBQW9COytHQUxuQixhQUFhLGNBRlosTUFBTTs0RkFFUCxhQUFhO2tCQUh6QixVQUFVO21CQUFDO29CQUNWLFVBQVUsRUFBRSxNQUFNO2lCQUNuQjs7MEJBR0ksTUFBTTsyQkFBQyxrQkFBa0I7OzBCQUN6QixNQUFNOzJCQUFDLFlBQVk7OzBCQUNuQixNQUFNOzJCQUFDLGlCQUFpQjs7MEJBQ3hCLE1BQU07MkJBQUMsb0JBQW9CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0LCBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSdcbmltcG9ydCB7XG4gIENhdGVnb3J5LFxuICBDYXRlZ29yeVJlcG9zaXRvcnksXG4gIENoZWNrb3V0LFxuICBDaGVja291dFN1YnNjcmlwdGlvbixcbiAgQ2hlY2tvdXRUeXBlcyxcbiAgQ291cG9uLFxuICBDb3Vwb25SZXBvc2l0b3J5LFxuICBDb3Vwb25UeXBlcyxcbiAgRXhjbHVzaXZpdGllcyxcbiAgTGluZUl0ZW0sXG4gIE9yZGVyLFxuICBPcmRlclJlcG9zaXRvcnksXG4gIFNob3BzLFxuICBVc2VyLFxuICBXaGVyZSxcbn0gZnJvbSAnQGluZnJhYjRhL2Nvbm5lY3QnXG5pbXBvcnQgeyBmcm9tLCBPYnNlcnZhYmxlLCBvZiB9IGZyb20gJ3J4anMnXG5pbXBvcnQgeyBjb25jYXRNYXAsIG1hcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJ1xuaW1wb3J0IHsgREVGQVVMVF9TSE9QIH0gZnJvbSAnLi4vY29uc3RzJ1xuXG5ASW5qZWN0YWJsZSh7XG4gIHByb3ZpZGVkSW46ICdyb290Jyxcbn0pXG5leHBvcnQgY2xhc3MgQ291cG9uU2VydmljZSB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIEBJbmplY3QoJ0NvdXBvblJlcG9zaXRvcnknKSBwcml2YXRlIHJlYWRvbmx5IGNvdXBvblJlcG9zaXRvcnk6IENvdXBvblJlcG9zaXRvcnksXG4gICAgQEluamVjdChERUZBVUxUX1NIT1ApIHByaXZhdGUgcmVhZG9ubHkgZGVmYXVsdFNob3A6IFNob3BzLFxuICAgIEBJbmplY3QoJ09yZGVyUmVwb3NpdG9yeScpIHByaXZhdGUgcmVhZG9ubHkgb3JkZXJSZXBvc2l0b3J5OiBPcmRlclJlcG9zaXRvcnksXG4gICAgQEluamVjdCgnQ2F0ZWdvcnlSZXBvc2l0b3J5JykgcHJpdmF0ZSByZWFkb25seSBjYXRlZ29yeVJlcG9zaXRvcnk6IENhdGVnb3J5UmVwb3NpdG9yeSxcbiAgKSB7fVxuXG4gIGNoZWNrQ291cG9uKFxuICAgIG5pY2tuYW1lOiBzdHJpbmcsXG4gICAgY2hlY2tvdXRUeXBlOiBDaGVja291dFR5cGVzLFxuICAgIGNoZWNrb3V0OiBQYXJ0aWFsPENoZWNrb3V0PixcbiAgICBwbGFuOiBzdHJpbmcsXG4gICk6IE9ic2VydmFibGU8Q291cG9uPiB7XG4gICAgcmV0dXJuIGZyb20oXG4gICAgICB0aGlzLmNvdXBvblJlcG9zaXRvcnlcbiAgICAgICAgLmZpbmQoe1xuICAgICAgICAgIGZpbHRlcnM6IHtcbiAgICAgICAgICAgIG5pY2tuYW1lOiB7IG9wZXJhdG9yOiBXaGVyZS5FUVVBTFMsIHZhbHVlOiBuaWNrbmFtZSB9LFxuICAgICAgICAgICAgYWN0aXZlOiB7IG9wZXJhdG9yOiBXaGVyZS5FUVVBTFMsIHZhbHVlOiB0cnVlIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4oKHJlc3VsdCkgPT4gcmVzdWx0LmRhdGFbMF0pLFxuICAgICkucGlwZShcbiAgICAgIGNvbmNhdE1hcCgoY291cG9uKSA9PiB0aGlzLmNvdXBvblZhbGlkYXRpb24oY291cG9uLCBjaGVja291dFR5cGUpKSxcbiAgICAgIGNvbmNhdE1hcCgoY291cG9uVmFsaWQ6IENvdXBvbikgPT4gdGhpcy5jb3Vwb25SdWxlc1ZhbGlkYXRpb24oY291cG9uVmFsaWQsIGNoZWNrb3V0VHlwZSwgY2hlY2tvdXQsIHBsYW4pKSxcbiAgICAgIG1hcCgoY291cG9uVmFsaWRhdGVkOiBDb3Vwb24pID0+IGNvdXBvblZhbGlkYXRlZCBhcyBDb3Vwb24pLFxuICAgIClcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgY291cG9uVmFsaWRhdGlvbihjb3Vwb246IENvdXBvbiwgY2hlY2tvdXRUeXBlOiBDaGVja291dFR5cGVzKSB7XG4gICAgaWYgKCFjb3Vwb24pIHRocm93ICdDdXBvbSBpbnbDoWxpZG8uJ1xuXG4gICAgaWYgKGNvdXBvbj8uYmVnaW5BdCAmJiBjb3Vwb24/LmJlZ2luQXQuZ2V0VGltZSgpID4gbmV3IERhdGUoKS5nZXRUaW1lKCkpIHRocm93ICdDdXBvbSBpbnbDoWxpZG8uJ1xuXG4gICAgaWYgKGNvdXBvbj8uZXhwaXJlc0luICYmIGNvdXBvbj8uZXhwaXJlc0luLmdldFRpbWUoKSA8IG5ldyBEYXRlKCkuZ2V0VGltZSgpKSB0aHJvdyAnQ3Vwb20gZXhwaXJhZG8uJ1xuXG4gICAgY29uc3QgaXNJblNob3AgPSBjb3Vwb24uc2hvcEF2YWlsYWJpbGl0eSA9PT0gU2hvcHMuQUxMIHx8IGNvdXBvbi5zaG9wQXZhaWxhYmlsaXR5ID09PSB0aGlzLmRlZmF1bHRTaG9wXG5cbiAgICBpZiAoIWlzSW5TaG9wKSB0aHJvdyAnQ3Vwb20gaW52w6FsaWRvIHBhcmEgbG9qYS4nXG5cbiAgICBjb25zdCBpc0NoZWNrb3V0VHlwZSA9IGNvdXBvbi5jaGVja291dFR5cGUgPT09IENoZWNrb3V0VHlwZXMuQUxMIHx8IGNvdXBvbi5jaGVja291dFR5cGUgPT09IGNoZWNrb3V0VHlwZVxuXG4gICAgaWYgKCFpc0NoZWNrb3V0VHlwZSkgdGhyb3cgJ0N1cG9tIGludsOhbGlkby4gRXJybyBkZSBjaGVja291dC4nXG5cbiAgICByZXR1cm4gY291cG9uXG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGNvdXBvblJ1bGVzVmFsaWRhdGlvbihcbiAgICBjb3Vwb246IENvdXBvbixcbiAgICBjaGVja291dFR5cGU6IENoZWNrb3V0VHlwZXMsXG4gICAgY2hlY2tvdXQ6IFBhcnRpYWw8Q2hlY2tvdXQ+LFxuICAgIHBsYW46IHN0cmluZyxcbiAgKSB7XG4gICAgaWYgKGNoZWNrb3V0VHlwZSA9PSBDaGVja291dFR5cGVzLlNVQlNDUklQVElPTikge1xuICAgICAgaWYgKGNvdXBvbi5wbGFuICYmIGNvdXBvbi5wbGFuLnRvVXBwZXJDYXNlKCkgIT09IHBsYW4udG9VcHBlckNhc2UoKSkgdGhyb3cgJ0N1cG9tIGludsOhbGlkbyBwYXJhIHN1YSBhc3NpbmF0dXJhLidcblxuICAgICAgcmV0dXJuIGNvdXBvblxuICAgIH1cblxuICAgIGNvbnN0IHZhbGlkVXNlciA9IHRoaXMuY291cG9tVXNlclZhbGlkYXRpb24oY291cG9uLCBjaGVja291dD8udXNlcilcblxuICAgIGlmICghdmFsaWRVc2VyKSB0aHJvdyAnVXN1w6FyaW8gbsOjbyBlbGVnw612ZWwuJ1xuXG4gICAgY29uc3QgY291cG9uVXNlTGltaXRzID0gdGhpcy5nZXRDb3Vwb25Vc2VMaW1pdHMoY291cG9uLCBjaGVja291dFR5cGUsIGNoZWNrb3V0LnVzZXIpXG5cbiAgICBpZiAoIWNvdXBvblVzZUxpbWl0cy51bmxpbWl0ZWQgfHwgY291cG9uVXNlTGltaXRzLmxpbWl0ZWRQZXJVc2VyKSB7XG4gICAgICBjb25zdCBvcmRlcnMgPSBhd2FpdCB0aGlzLmdldE9yZGVyc1dpdGhDb3Vwb24oY291cG9uKVxuXG4gICAgICBpZiAoIWNvdXBvblVzZUxpbWl0cy51bmxpbWl0ZWQgJiYgY291cG9uVXNlTGltaXRzLnRvdGFsICYmIG9yZGVycy5sZW5ndGggPj0gY291cG9uVXNlTGltaXRzLnRvdGFsKVxuICAgICAgICB0aHJvdyAnTGltaXRlIGRlIHVzbyBhdGluZ2lkby4nXG5cbiAgICAgIGlmIChjb3Vwb25Vc2VMaW1pdHMubGltaXRlZFBlclVzZXIpIHtcbiAgICAgICAgY29uc3Qgb3JkZXJzV2l0aFVzZXIgPSB0aGlzLmNvdW50T3JkZXJzV2l0aFVzZXIob3JkZXJzLCBjaGVja291dC51c2VyLmVtYWlsKVxuXG4gICAgICAgIGlmIChvcmRlcnNXaXRoVXNlciA+IDApIHRocm93ICdMaW1pdGUgZGUgdXNvIHBvciB1c3XDoXJpbyBhdGluZ2lkby4nXG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgaGFzUHJvZHVjdENhdGVnb3JpZXMgPSBhd2FpdCB0aGlzLmhhc1Byb2R1Y3RDYXRlZ29yaWVzKGNvdXBvbiwgY2hlY2tvdXQpXG5cbiAgICBpZiAoIWhhc1Byb2R1Y3RDYXRlZ29yaWVzKSB0aHJvdyAnU2V1IGNhcnJpbmhvIG7Do28gcG9zc3VpIHByb2R1dG9zIGVsZWfDrXZlaXMgcGFyYSBkZXNjb250by4nXG5cbiAgICBjb25zdCBoYXNNaW5TdWJUb3RhbCA9IGF3YWl0IHRoaXMuaGFzTWluU3ViVG90YWwoY291cG9uLCBjaGVja291dClcblxuICAgIGlmICghaGFzTWluU3ViVG90YWwpXG4gICAgICB0aHJvdyBgVmFsb3IgbcOtbmltbyBkZSAke0ludGwuTnVtYmVyRm9ybWF0KCdwdC1CUicsIHsgc3R5bGU6ICdjdXJyZW5jeScsIGN1cnJlbmN5OiAnQlJMJyB9KS5mb3JtYXQoXG4gICAgICAgIGNvdXBvbi5taW5TdWJUb3RhbFZhbHVlLFxuICAgICAgKX0gbsOjbyBhdGluZ2lkb2BcblxuICAgIHJldHVybiBjb3Vwb25cbiAgfVxuXG4gIHB1YmxpYyBjYWxjRGlzY291bnRTdWJzY3JpcHRpb24oY291cG9uOiBDb3Vwb24sIGNoZWNrb3V0OiBQYXJ0aWFsPENoZWNrb3V0U3Vic2NyaXB0aW9uPik6IE9ic2VydmFibGU8bnVtYmVyPiB7XG4gICAgbGV0IGRpc2NvdW50ID0gMFxuXG4gICAgaWYgKGNvdXBvbi5kaXNjb3VudC5zdWJzY3JpcHRpb24udHlwZSA9PSBDb3Vwb25UeXBlcy5BQlNPTFVURSkgZGlzY291bnQgPSBjb3Vwb24uZGlzY291bnQuc3Vic2NyaXB0aW9uLnZhbHVlXG4gICAgZWxzZSBkaXNjb3VudCA9IGNoZWNrb3V0LnN1YnNjcmlwdGlvblBsYW4ucmVjdXJyZW5jZVByaWNlICogKGNvdXBvbi5kaXNjb3VudC5zdWJzY3JpcHRpb24udmFsdWUgLyAxMDApXG5cbiAgICByZXR1cm4gb2YoZGlzY291bnQpXG4gIH1cblxuICBwdWJsaWMgYXN5bmMgY2FsY0Rpc2NvdW50U2hvcHBpbmcoY291cG9uOiBDb3Vwb24sIGNoZWNrb3V0OiBQYXJ0aWFsPENoZWNrb3V0Pik6IFByb21pc2U8bnVtYmVyPiB7XG4gICAgbGV0IGRpc2NvdW50ID0gMFxuXG4gICAgaWYgKGNoZWNrb3V0LnVzZXIuaXNTdWJzY3JpYmVyICYmIGNvdXBvbi5kaXNjb3VudC5zdWJzY3JpYmVyLnZhbHVlKSB7XG4gICAgICBkaXNjb3VudCA9IGF3YWl0IHRoaXMuY2FsY0Rpc2NvdW50QnlUeXBlKFxuICAgICAgICBjb3Vwb24uZGlzY291bnQuc3Vic2NyaWJlci50eXBlLFxuICAgICAgICBjb3Vwb24uZGlzY291bnQuc3Vic2NyaWJlci52YWx1ZSxcbiAgICAgICAgY291cG9uLnByb2R1Y3RzQ2F0ZWdvcmllcyxcbiAgICAgICAgY2hlY2tvdXQsXG4gICAgICApXG4gICAgfSBlbHNlIHtcbiAgICAgIGRpc2NvdW50ID0gYXdhaXQgdGhpcy5jYWxjRGlzY291bnRCeVR5cGUoXG4gICAgICAgIGNvdXBvbi5kaXNjb3VudC5ub25fc3Vic2NyaWJlci50eXBlLFxuICAgICAgICBjb3Vwb24uZGlzY291bnQubm9uX3N1YnNjcmliZXIudmFsdWUsXG4gICAgICAgIGNvdXBvbi5wcm9kdWN0c0NhdGVnb3JpZXMsXG4gICAgICAgIGNoZWNrb3V0LFxuICAgICAgKVxuICAgIH1cblxuICAgIHJldHVybiBkaXNjb3VudFxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBjYWxjRGlzY291bnRCeVR5cGUoXG4gICAgdHlwZTogQ291cG9uVHlwZXMsXG4gICAgdmFsdWU6IG51bWJlcixcbiAgICBjYXRlZ29yaWVzLFxuICAgIGNoZWNrb3V0OiBQYXJ0aWFsPENoZWNrb3V0PixcbiAgKTogUHJvbWlzZTxudW1iZXI+IHtcbiAgICBsZXQgZGlzY291bnQgPSAwXG5cbiAgICBsZXQgbGluZUl0ZW5zRGlzY291bnQgPSBhd2FpdCB0aGlzLmdldExpbmVJdGVuc0VsaWdlYmxlRm9yRGlzY291bnQoY2F0ZWdvcmllcywgY2hlY2tvdXQpXG5cbiAgICBjb25zdCBzdWJUb3RhbCA9IHRoaXMuY2FsY0NoZWNrb3V0U3VidG90YWwobGluZUl0ZW5zRGlzY291bnQsIGNoZWNrb3V0LnVzZXIsIGNoZWNrb3V0LnNob3ApXG5cbiAgICBpZiAodHlwZSA9PSBDb3Vwb25UeXBlcy5BQlNPTFVURSkge1xuICAgICAgZGlzY291bnQgPSB2YWx1ZSA+IHN1YlRvdGFsID8gc3ViVG90YWwgOiB2YWx1ZVxuICAgIH0gZWxzZSB7XG4gICAgICBkaXNjb3VudCA9IHN1YlRvdGFsICogKHZhbHVlIC8gMTAwKVxuICAgIH1cblxuICAgIHJldHVybiBkaXNjb3VudFxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBoYXNNaW5TdWJUb3RhbChjb3Vwb246IENvdXBvbiwgY2hlY2tvdXQ6IFBhcnRpYWw8Q2hlY2tvdXQ+KTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgaWYgKCFjb3Vwb24ubWluU3ViVG90YWxWYWx1ZSkgcmV0dXJuIHRydWVcblxuICAgIGxldCBsaW5lSXRlbnNEaXNjb3VudCA9IGF3YWl0IHRoaXMuZ2V0TGluZUl0ZW5zRWxpZ2VibGVGb3JEaXNjb3VudChjb3Vwb24ucHJvZHVjdHNDYXRlZ29yaWVzLCBjaGVja291dClcblxuICAgIGNvbnN0IHN1YlRvdGFsID0gdGhpcy5jYWxjQ2hlY2tvdXRTdWJ0b3RhbChsaW5lSXRlbnNEaXNjb3VudCwgY2hlY2tvdXQudXNlciwgY2hlY2tvdXQuc2hvcClcblxuICAgIGlmIChjb3Vwb24ubWluU3ViVG90YWxWYWx1ZSA8PSBzdWJUb3RhbCkgcmV0dXJuIHRydWVcblxuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBoYXNQcm9kdWN0Q2F0ZWdvcmllcyhjb3Vwb246IENvdXBvbiwgY2hlY2tvdXQ6IFBhcnRpYWw8Q2hlY2tvdXQ+KTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgaWYgKCFjb3Vwb24ucHJvZHVjdHNDYXRlZ29yaWVzIHx8ICFjb3Vwb24ucHJvZHVjdHNDYXRlZ29yaWVzLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIHRydWVcbiAgICB9XG5cbiAgICBjb25zdCBjb3Vwb25DYXRlZ29yaWVzID0gYXdhaXQgdGhpcy5nZXRDb3Vwb25DYXRlZ29yaWVzSWQoY291cG9uLnByb2R1Y3RzQ2F0ZWdvcmllcylcblxuICAgIGNvbnN0IGhhc0NhdGVnb3JpZXMgPSBjaGVja291dC5saW5lSXRlbXM/LmZpbHRlcigoaSkgPT4ge1xuICAgICAgaWYgKCFpLmNhdGVnb3JpZXMgfHwgIWkuY2F0ZWdvcmllcz8ubGVuZ3RoKSByZXR1cm4gdHJ1ZVxuICAgICAgcmV0dXJuIGkuY2F0ZWdvcmllcy5zb21lKChjKSA9PiBjb3Vwb25DYXRlZ29yaWVzLnNvbWUoKGNhdCkgPT4gY2F0ID09IGMpKVxuICAgIH0pXG5cbiAgICByZXR1cm4gaGFzQ2F0ZWdvcmllcy5sZW5ndGggPyB0cnVlIDogZmFsc2VcbiAgfVxuXG4gIHByaXZhdGUgY291cG9tVXNlclZhbGlkYXRpb24oY291cG9uOiBDb3Vwb24sIHVzZXI6IFVzZXIpIHtcbiAgICBpZiAoIXVzZXIgfHwgY291cG9uLmV4Y2x1c2l2aXR5VHlwZS5pbmNsdWRlcyhFeGNsdXNpdml0aWVzLkFMTF9VU0VSUykpIHJldHVybiB0cnVlXG5cbiAgICBsZXQgdXNlclR5cGVzID0gW11cblxuICAgIGlmIChjb3Vwb24uZXhjbHVzaXZpdHlUeXBlLmluY2x1ZGVzKEV4Y2x1c2l2aXRpZXMuQ09MTEFCT1JBVE9SUykgJiYgdGhpcy5lbWFpbElzRnJvbUNvbGxhYm9yYXRvcih1c2VyLmVtYWlsKSlcbiAgICAgIHVzZXJUeXBlcy5wdXNoKEV4Y2x1c2l2aXRpZXMuQ09MTEFCT1JBVE9SUylcblxuICAgIGlmIChjb3Vwb24uZXhjbHVzaXZpdHlUeXBlLmluY2x1ZGVzKEV4Y2x1c2l2aXRpZXMuU1BFQ0lGSUNfVVNFUikgJiYgY291cG9uLnVzZXJFeGNsdXNpdmVFbWFpbC5pbmNsdWRlcyh1c2VyLmVtYWlsKSlcbiAgICAgIHVzZXJUeXBlcy5wdXNoKEV4Y2x1c2l2aXRpZXMuU1BFQ0lGSUNfVVNFUilcblxuICAgIGlmIChcbiAgICAgIGNvdXBvbi5leGNsdXNpdml0eVR5cGUuaW5jbHVkZXMoRXhjbHVzaXZpdGllcy5BQ1RJVkVfU1VCU0NSSUJFUikgJiZcbiAgICAgIHVzZXIuaXNTdWJzY3JpYmVyICYmXG4gICAgICB1c2VyLnN1YnNjcmlwdGlvblBsYW4gIT0gJydcbiAgICApXG4gICAgICB1c2VyVHlwZXMucHVzaChFeGNsdXNpdml0aWVzLkFDVElWRV9TVUJTQ1JJQkVSKVxuXG4gICAgaWYgKFxuICAgICAgdXNlci5pc1N1YnNjcmliZXIgJiZcbiAgICAgIHVzZXIuc3Vic2NyaXB0aW9uUGxhbiA9PSAnJyAmJlxuICAgICAgY291cG9uLmV4Y2x1c2l2aXR5VHlwZS5pbmNsdWRlcyhFeGNsdXNpdml0aWVzLklOQUNUSVZFX1NVQlNDUklCRVIpXG4gICAgKVxuICAgICAgdXNlclR5cGVzLnB1c2goRXhjbHVzaXZpdGllcy5JTkFDVElWRV9TVUJTQ1JJQkVSKVxuXG4gICAgaWYgKGNvdXBvbi5leGNsdXNpdml0eVR5cGUuaW5jbHVkZXMoRXhjbHVzaXZpdGllcy5OT05fU1VCU0NSSUJFUikgJiYgIXVzZXIuaXNTdWJzY3JpYmVyKVxuICAgICAgdXNlclR5cGVzLnB1c2goRXhjbHVzaXZpdGllcy5OT05fU1VCU0NSSUJFUilcblxuICAgIHJldHVybiBjb3Vwb24uZXhjbHVzaXZpdHlUeXBlLnNvbWUoKHIpID0+IHVzZXJUeXBlcy5pbmNsdWRlcyhyKSlcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgZ2V0Q291cG9uQ2F0ZWdvcmllc0lkKHByb2R1Y3RzQ2F0ZWdvcmllczogc3RyaW5nW10pOiBQcm9taXNlPEFycmF5PFN0cmluZz4+IHtcbiAgICBjb25zdCBjb3Vwb25DYXRlZ29yaWVzOiBBcnJheTxTdHJpbmc+ID0gW11cblxuICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBwcm9kdWN0c0NhdGVnb3JpZXMubGVuZ3RoOyBpbmRleCsrKSB7XG4gICAgICBjb25zdCBjYXRlZ29yeTogQ2F0ZWdvcnkgJiB7IGZpcmVzdG9yZUlkPzogc3RyaW5nIH0gPSBhd2FpdCB0aGlzLmNhdGVnb3J5UmVwb3NpdG9yeS5nZXQoe1xuICAgICAgICBpZDogcHJvZHVjdHNDYXRlZ29yaWVzW2luZGV4XSxcbiAgICAgIH0pXG5cbiAgICAgIGlmIChjYXRlZ29yeSkge1xuICAgICAgICBjb25zdCBjaGlsZHJlbiA9IGF3YWl0IHRoaXMuY2F0ZWdvcnlSZXBvc2l0b3J5LmdldENoaWxkcmVuKHBhcnNlSW50KHByb2R1Y3RzQ2F0ZWdvcmllc1tpbmRleF0pKVxuXG4gICAgICAgIGNvdXBvbkNhdGVnb3JpZXMucHVzaChjYXRlZ29yeS5pZCwgLi4uY2hpbGRyZW4ubWFwKChjKSA9PiBjLmlkLnRvU3RyaW5nKCkpKVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBbLi4ubmV3IFNldChjb3Vwb25DYXRlZ29yaWVzKV1cbiAgfVxuXG4gIHByaXZhdGUgZW1haWxJc0Zyb21Db2xsYWJvcmF0b3IgPSAodXNlckVtYWlsOiBzdHJpbmcpOiBib29sZWFuID0+ICEhdXNlckVtYWlsPy5tYXRjaCgvQGI0YS5jb20uYnIvZylcblxuICBwcml2YXRlIGFzeW5jIGdldExpbmVJdGVuc0VsaWdlYmxlRm9yRGlzY291bnQoXG4gICAgcHJvZHVjdHNDYXRlZ29yaWVzOiBzdHJpbmdbXSxcbiAgICBjaGVja291dDogUGFydGlhbDxDaGVja291dD4sXG4gICk6IFByb21pc2U8TGluZUl0ZW1bXT4ge1xuICAgIGxldCBsaW5lSXRlbnNEaXNjb3VudCA9IFtdXG4gICAgY29uc3QgY291cG9uQ2F0ZWdvcmllcyA9IGF3YWl0IHRoaXMuZ2V0Q291cG9uQ2F0ZWdvcmllc0lkKHByb2R1Y3RzQ2F0ZWdvcmllcylcblxuICAgIGlmIChwcm9kdWN0c0NhdGVnb3JpZXMgJiYgcHJvZHVjdHNDYXRlZ29yaWVzLmxlbmd0aCkge1xuICAgICAgbGluZUl0ZW5zRGlzY291bnQgPSBjaGVja291dC5saW5lSXRlbXM/LmZpbHRlcigoaSkgPT4ge1xuICAgICAgICBpZiAoaS5jYXRlZ29yaWVzPy5sZW5ndGgpIHtcbiAgICAgICAgICByZXR1cm4gaS5jYXRlZ29yaWVzLnNvbWUoKGMpID0+IGNvdXBvbkNhdGVnb3JpZXMuc29tZSgoY2F0KSA9PiBjYXQgPT0gYykpXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWVcbiAgICAgIH0pXG4gICAgfSBlbHNlIHtcbiAgICAgIGxpbmVJdGVuc0Rpc2NvdW50ID0gY2hlY2tvdXQubGluZUl0ZW1zXG4gICAgfVxuXG4gICAgcmV0dXJuIGxpbmVJdGVuc0Rpc2NvdW50XG4gIH1cblxuICBwcml2YXRlIGNhbGNDaGVja291dFN1YnRvdGFsKGxpbmVJdGVuczogTGluZUl0ZW1bXSwgdXNlcjogVXNlciwgc2hvcDogc3RyaW5nKTogbnVtYmVyIHtcbiAgICByZXR1cm4gKFxuICAgICAgbGluZUl0ZW5zPy5yZWR1Y2UoXG4gICAgICAgIChhY2MsIGN1cnIpID0+XG4gICAgICAgICAgdXNlcj8uaXNTdWJzY3JpYmVyICYmIGN1cnIucHJpY2Vbc2hvcF0/LnN1YnNjcmliZXJQcmljZVxuICAgICAgICAgICAgPyBhY2MgKyBjdXJyLnByaWNlW3Nob3BdPy5zdWJzY3JpYmVyUHJpY2UgKiBjdXJyLnF1YW50aXR5XG4gICAgICAgICAgICA6IGFjYyArIGN1cnIucHJpY2VQYWlkICogY3Vyci5xdWFudGl0eSxcbiAgICAgICAgMCxcbiAgICAgICkgfHwgMFxuICAgIClcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgZ2V0T3JkZXJzV2l0aENvdXBvbihjb3Vwb246IENvdXBvbik6IFByb21pc2U8T3JkZXJbXT4ge1xuICAgIHJldHVybiBhd2FpdCB0aGlzLm9yZGVyUmVwb3NpdG9yeVxuICAgICAgLmZpbmQoe1xuICAgICAgICBmaWx0ZXJzOiB7XG4gICAgICAgICAgY291cG9uOiB7IGlkOiBjb3Vwb24uaWQgfSxcbiAgICAgICAgICBwYXltZW50OiB7IHN0YXR1czogJ3BhaWQnIH0sXG4gICAgICAgIH0sXG4gICAgICB9KVxuICAgICAgLnRoZW4oKHJlc3VsdCkgPT4gcmVzdWx0LmRhdGEpXG4gIH1cblxuICBwcml2YXRlIGNvdW50T3JkZXJzV2l0aFVzZXIob3JkZXJzOiBPcmRlcltdLCBlbWFpbDogc3RyaW5nKTogbnVtYmVyIHtcbiAgICByZXR1cm4gb3JkZXJzLmZpbHRlcigobykgPT4gby51c2VyLmVtYWlsID09IGVtYWlsKS5sZW5ndGhcbiAgfVxuXG4gIHByaXZhdGUgZ2V0Q291cG9uVXNlTGltaXRzKGNvdXBvbjogQ291cG9uLCBjaGVja291dFR5cGU6IENoZWNrb3V0VHlwZXMsIHVzZXI6IFVzZXIpIHtcbiAgICBsZXQgY291cG9uVXNlTGltaXRzOiB7IHVubGltaXRlZD86IGJvb2xlYW47IHRvdGFsPzogbnVtYmVyOyBsaW1pdGVkUGVyVXNlcj86IGJvb2xlYW4gfVxuICAgIGlmIChjaGVja291dFR5cGUgPT0gQ2hlY2tvdXRUeXBlcy5FQ09NTUVSQ0UgfHwgY2hlY2tvdXRUeXBlID09IENoZWNrb3V0VHlwZXMuQUxMKSB7XG4gICAgICBjb3Vwb25Vc2VMaW1pdHMgPSB1c2VyICYmIHVzZXIuaXNTdWJzY3JpYmVyID8gY291cG9uLnVzZUxpbWl0cy5zdWJzY3JpYmVyIDogY291cG9uLnVzZUxpbWl0cy5ub25fc3Vic2NyaWJlclxuICAgIH0gZWxzZSB7XG4gICAgICBjb3Vwb25Vc2VMaW1pdHMgPSBjb3Vwb24udXNlTGltaXRzLnN1YnNjcmlwdGlvblxuICAgIH1cblxuICAgIHJldHVybiBjb3Vwb25Vc2VMaW1pdHNcbiAgfVxufVxuIl19