@infrab4a/connect-angular 3.7.7 → 3.7.8-beta.1

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 (61) hide show
  1. package/angular-connect.module.d.ts +19 -19
  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 +2138 -2141
  7. package/bundles/infrab4a-connect-angular.umd.js.map +1 -1
  8. package/consts/backend-url.const.d.ts +1 -1
  9. package/consts/default-shop.const.d.ts +1 -1
  10. package/consts/es-config.const.d.ts +1 -1
  11. package/consts/hasura-options.const.d.ts +1 -1
  12. package/consts/index.d.ts +4 -4
  13. package/esm2015/angular-connect.module.js +52 -52
  14. package/esm2015/angular-elastic-search.module.js +38 -38
  15. package/esm2015/angular-firebase-auth.module.js +113 -113
  16. package/esm2015/angular-firestore.module.js +394 -394
  17. package/esm2015/angular-hasura-graphql.module.js +156 -156
  18. package/esm2015/consts/backend-url.const.js +1 -1
  19. package/esm2015/consts/default-shop.const.js +2 -2
  20. package/esm2015/consts/es-config.const.js +2 -2
  21. package/esm2015/consts/hasura-options.const.js +2 -2
  22. package/esm2015/consts/index.js +5 -5
  23. package/esm2015/index.js +6 -6
  24. package/esm2015/infrab4a-connect-angular.js +4 -4
  25. package/esm2015/services/auth.service.js +42 -42
  26. package/esm2015/services/cart.service.js +254 -258
  27. package/esm2015/services/checkout-subscription.service.js +53 -53
  28. package/esm2015/services/checkout.service.js +75 -75
  29. package/esm2015/services/coupon.service.js +249 -249
  30. package/esm2015/services/errors/group-invalid-coupon.error.js +8 -8
  31. package/esm2015/services/errors/index.js +3 -3
  32. package/esm2015/services/errors/invalid-coupon.error.js +8 -8
  33. package/esm2015/services/home-shop.service.js +116 -116
  34. package/esm2015/services/index.js +9 -9
  35. package/esm2015/services/order.service.js +32 -32
  36. package/esm2015/services/shipping.service.js +98 -98
  37. package/esm2015/services/types/index.js +3 -3
  38. package/esm2015/services/types/required-checkout-data.type.js +2 -2
  39. package/esm2015/services/types/required-checkout-subscription-data.type.js +2 -2
  40. package/esm2015/services/types/shipping-methods.type.js +2 -2
  41. package/fesm2015/infrab4a-connect-angular.js +1558 -1562
  42. package/fesm2015/infrab4a-connect-angular.js.map +1 -1
  43. package/index.d.ts +5 -5
  44. package/infrab4a-connect-angular.d.ts +5 -5
  45. package/package.json +1 -1
  46. package/services/auth.service.d.ts +19 -19
  47. package/services/cart.service.d.ts +40 -40
  48. package/services/checkout-subscription.service.d.ts +18 -18
  49. package/services/checkout.service.d.ts +23 -23
  50. package/services/coupon.service.d.ts +25 -25
  51. package/services/errors/group-invalid-coupon.error.d.ts +6 -6
  52. package/services/errors/index.d.ts +2 -2
  53. package/services/errors/invalid-coupon.error.d.ts +5 -5
  54. package/services/home-shop.service.d.ts +25 -25
  55. package/services/index.d.ts +8 -8
  56. package/services/order.service.d.ts +13 -13
  57. package/services/shipping.service.d.ts +19 -19
  58. package/services/types/index.d.ts +2 -2
  59. package/services/types/required-checkout-data.type.d.ts +2 -2
  60. package/services/types/required-checkout-subscription-data.type.d.ts +2 -2
  61. package/services/types/shipping-methods.type.d.ts +12 -12
@@ -1,249 +1,249 @@
1
- import { __awaiter } from "tslib";
2
- import { Inject, Injectable } from '@angular/core';
3
- import { CheckoutTypes, Coupon, CouponTypes, Exclusivities, Shops, Where, } from '@infrab4a/connect';
4
- import { from, of, throwError } from 'rxjs';
5
- import { concatMap, map } from 'rxjs/operators';
6
- import { DEFAULT_SHOP } from '../consts';
7
- import { InvalidCouponError } from './errors';
8
- import * as i0 from "@angular/core";
9
- import * as i1 from "@infrab4a/connect";
10
- export class CouponService {
11
- constructor(couponRepository, defaultShop, orderRepository, categoryRepository) {
12
- this.couponRepository = couponRepository;
13
- this.defaultShop = defaultShop;
14
- this.orderRepository = orderRepository;
15
- this.categoryRepository = categoryRepository;
16
- this.emailIsFromCollaborator = (userEmail) => !!(userEmail === null || userEmail === void 0 ? void 0 : userEmail.match(/@b4a.com.br/g));
17
- this.separateValidCoupons = (coupons, userEmail) => coupons
18
- .map((coupon) => {
19
- try {
20
- if (!(coupon instanceof Coupon))
21
- throw new InvalidCouponError('Cupom inválido.');
22
- if (this.isValidCoupon(coupon, userEmail))
23
- return coupon;
24
- }
25
- catch (error) {
26
- return error;
27
- }
28
- })
29
- .reduce((current, coupon) => (Object.assign(Object.assign({}, current), (coupon instanceof Coupon
30
- ? { valids: [...current.valids, coupon] }
31
- : { invalids: [...current.invalids, coupon] }))), {
32
- valids: [],
33
- invalids: [],
34
- });
35
- }
36
- checkCoupon(nickname, userEmail, checkoutType, plan, checkout, isSubscription) {
37
- return from(this.couponRepository.find({
38
- filters: {
39
- nickname: { operator: Where.EQUALS, value: nickname },
40
- active: { operator: Where.EQUALS, value: true },
41
- },
42
- })).pipe(concatMap((coupons) => this.checkCouponRules(coupons, checkoutType, plan, checkout, isSubscription)), concatMap((coupon) => this.checkCouponUseAndLimit(coupon, userEmail, checkout)), map((coupon) => this.isValidCoupon(coupon, userEmail)), map((coupon) => coupon));
43
- }
44
- checkCouponRules(coupons, checkoutType, plan, checkout, isSubscription) {
45
- // Caso não ache nenhum cupom, retorna erro
46
- if (coupons.count < 1) {
47
- return throwError('Cupom inválido.');
48
- }
49
- // Get Primeiro Cupom (o find do repository retorna um array)
50
- const coupon = coupons.data.shift();
51
- // Verifica se o cupom é aplicavel na loja
52
- const isInShop = coupon.shopAvailability === Shops.ALL || coupon.shopAvailability === this.defaultShop;
53
- // Cupon não aplicavel a loja retorna erro
54
- if (!isInShop)
55
- return throwError('Cupom inválido para loja.');
56
- // Verifica se o coupon é aplicado no checkout que está sendo realizado
57
- const isCheckoutType = coupon.checkoutType === CheckoutTypes.ALL || coupon.checkoutType === checkoutType;
58
- // Cupon não aplicavel ao checkout retorna erro
59
- if (!isCheckoutType)
60
- return throwError('Cupom inválido. Erro de checkout.');
61
- // Verifica se o cupom é ou pode ser aplicado para subscription
62
- if (checkoutType === CheckoutTypes.ALL || checkoutType === CheckoutTypes.SUBSCRIPTION) {
63
- // Se o cupom tiver um plano associado, verifica se é o mesmo plano do checkout da assinatura
64
- if (coupon.plan && coupon.plan.toUpperCase() !== plan.toUpperCase())
65
- return throwError('Cupom inválido para sua assinatura.');
66
- }
67
- if (isSubscription)
68
- return of(coupon);
69
- // Verifica se possui o valor minimo de compra para utilização do cupom
70
- const hasMinSubTotal = this.hasMinSubTotal(coupon, checkout);
71
- // Se não tem valor mínimo atingido, retorna erro
72
- if (!hasMinSubTotal)
73
- return throwError(`Valor mínimo de ${Intl.NumberFormat('pt-BR', { style: 'currency', currency: 'BRL' }).format(coupon.minSubTotalValue)} não atingido`);
74
- return of(coupon);
75
- }
76
- isValidCoupon(coupon, userEmail) {
77
- // Verifica a data de inicio de validade do cupom
78
- if ((coupon === null || coupon === void 0 ? void 0 : coupon.beginAt) > new Date())
79
- throw new InvalidCouponError('Cupom ainda não liberado.');
80
- // Verifica a data de validade do cupom
81
- if ((coupon === null || coupon === void 0 ? void 0 : coupon.expiresIn) < new Date())
82
- throw new InvalidCouponError('Cupom expirado.');
83
- return coupon;
84
- }
85
- checkCouponUseAndLimit(coupon, userEmail, checkout) {
86
- return __awaiter(this, void 0, void 0, function* () {
87
- const orders = yield this.orderRepository.find({
88
- filters: {
89
- coupon: { id: coupon.id },
90
- payment: { status: 'paid' },
91
- },
92
- });
93
- // orders que usuario ja fez com o cupom
94
- const ordersUserCoupon = orders.data.filter((o) => o.user.email == userEmail);
95
- // Verifica o limite de uso de cupom por usuario
96
- if (coupon.useLimitPerUser && ordersUserCoupon.length)
97
- throw new InvalidCouponError('Limite de uso por usuário atingido.');
98
- // Verifica o limite de uso geral por usuario
99
- if (coupon.useLimit && orders.data.length >= coupon.useLimit)
100
- throw new InvalidCouponError('Limite de uso atingido.');
101
- const validUser = this.userValidationAndSubscriptionStatus(coupon, checkout === null || checkout === void 0 ? void 0 : checkout.user);
102
- if (!validUser)
103
- throw new InvalidCouponError('Usuário não elegível.');
104
- const hasProductCategories = yield this.hasProductCategories(coupon, checkout);
105
- if (!hasProductCategories)
106
- throw 'Seu carrinho não possui produtos elegíveis para desconto.';
107
- return coupon;
108
- });
109
- }
110
- calcDiscountSubscription(coupon, checkout) {
111
- //
112
- let discount = 0;
113
- if (coupon.type === CouponTypes.ABSOLUTE)
114
- discount = coupon.discount;
115
- else if (coupon.type === CouponTypes.PERCENTAGE)
116
- discount = checkout.subscriptionPlan.recurrencePrice * (coupon.discount / 100);
117
- return of(discount);
118
- }
119
- calcDiscountShopping(coupon, checkout) {
120
- return __awaiter(this, void 0, void 0, function* () {
121
- let discount = 0;
122
- switch (coupon.type) {
123
- case CouponTypes.ABSOLUTE: {
124
- discount = coupon.discount;
125
- break;
126
- }
127
- case CouponTypes.PERCENTAGE: {
128
- discount = yield this.calcShoppingPercentageDiscount(coupon, checkout);
129
- break;
130
- }
131
- }
132
- return discount;
133
- });
134
- }
135
- calcShoppingPercentageDiscount(coupon, checkout) {
136
- var _a;
137
- return __awaiter(this, void 0, void 0, function* () {
138
- let discount = 0;
139
- const shop = checkout.shop;
140
- let lineItensDiscount = [];
141
- const couponCategories = yield this.getCouponCategoriesId(coupon);
142
- if (coupon.productsCategories && coupon.productsCategories.length) {
143
- lineItensDiscount = (_a = checkout.lineItems) === null || _a === void 0 ? void 0 : _a.filter((i) => {
144
- var _a;
145
- if ((_a = i.categories) === null || _a === void 0 ? void 0 : _a.length) {
146
- return i.categories.some((c) => couponCategories.some((cat) => cat.id == c || cat.firestoreId == c));
147
- }
148
- return true;
149
- });
150
- }
151
- else {
152
- lineItensDiscount = checkout.lineItems;
153
- }
154
- const subTotal = lineItensDiscount.reduce((acc, curr) => {
155
- var _a, _b, _c;
156
- return ((_a = checkout.user) === null || _a === void 0 ? void 0 : _a.isSubscriber) && ((_b = curr.price[shop]) === null || _b === void 0 ? void 0 : _b.subscriberPrice)
157
- ? acc + ((_c = curr.price[shop]) === null || _c === void 0 ? void 0 : _c.subscriberPrice) * curr.quantity
158
- : acc + curr.pricePaid * curr.quantity;
159
- }, 0) || 0;
160
- discount = subTotal * (coupon.discount / 100);
161
- return discount;
162
- });
163
- }
164
- hasMinSubTotal(coupon, checkout) {
165
- var _a;
166
- if (!coupon.minSubTotalValue)
167
- return true;
168
- const shop = checkout.shop;
169
- let subTotal = ((_a = checkout.lineItems) === null || _a === void 0 ? void 0 : _a.reduce((acc, curr) => {
170
- var _a, _b, _c;
171
- return ((_a = checkout.user) === null || _a === void 0 ? void 0 : _a.isSubscriber) && ((_b = curr.price[shop]) === null || _b === void 0 ? void 0 : _b.subscriberPrice)
172
- ? acc + ((_c = curr.price[shop]) === null || _c === void 0 ? void 0 : _c.subscriberPrice) * curr.quantity
173
- : acc + curr.pricePaid * curr.quantity;
174
- }, 0)) || 0;
175
- if (coupon.minSubTotalValue <= subTotal)
176
- return true;
177
- return false;
178
- }
179
- hasProductCategories(coupon, checkout) {
180
- var _a;
181
- return __awaiter(this, void 0, void 0, function* () {
182
- if (!coupon.productsCategories || !coupon.productsCategories.length) {
183
- return true;
184
- }
185
- const couponCategories = yield this.getCouponCategoriesId(coupon);
186
- const hasCategories = (_a = checkout.lineItems) === null || _a === void 0 ? void 0 : _a.filter((i) => {
187
- var _a;
188
- if (!i.categories || !((_a = i.categories) === null || _a === void 0 ? void 0 : _a.length))
189
- return true;
190
- return i.categories.some((c) => couponCategories.some((cat) => cat.id == c || cat.firestoreId == c));
191
- });
192
- return hasCategories.length ? true : false;
193
- });
194
- }
195
- userValidationAndSubscriptionStatus(coupon, user) {
196
- if (coupon.exclusivityType === Exclusivities.ALL_USERS)
197
- return true;
198
- if (!user)
199
- return true;
200
- // Verifica se o email do usuário é coorporativo
201
- if (!this.emailIsFromCollaborator(user.email) && coupon.exclusivityType === Exclusivities.COLLABORATORS)
202
- throw new InvalidCouponError('Você não é colaborador.');
203
- // Verifica se o email do usuário é associado ao cupom de uso por usuario
204
- if (coupon.exclusivityType === Exclusivities.SPECIFIC_USER && coupon.userExclusiveEmail !== user.email)
205
- throw new InvalidCouponError('Cupom não é válido para este usuário.');
206
- switch (coupon.exclusivityType) {
207
- case Exclusivities.ACTIVE_SUBSCRIBER:
208
- return user.isSubscriber ? true : false;
209
- case Exclusivities.INACTIVE_SUBSCRIBER:
210
- return user.isSubscriber ? false : true;
211
- case Exclusivities.NON_SUBSCRIBER:
212
- return user.isSubscriber ? false : true;
213
- }
214
- return true;
215
- }
216
- getCouponCategoriesId(coupon) {
217
- return __awaiter(this, void 0, void 0, function* () {
218
- let couponCategories = [];
219
- for (let index = 0; index < coupon.productsCategories.length; index++) {
220
- let c = yield this.categoryRepository.get({
221
- id: coupon.productsCategories[index],
222
- });
223
- couponCategories.push({ id: c.id, firestoreId: c.firestoreId });
224
- }
225
- return couponCategories;
226
- });
227
- }
228
- }
229
- 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 });
230
- CouponService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0, type: CouponService, providedIn: 'root' });
231
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0, type: CouponService, decorators: [{
232
- type: Injectable,
233
- args: [{
234
- providedIn: 'root',
235
- }]
236
- }], ctorParameters: function () { return [{ type: undefined, decorators: [{
237
- type: Inject,
238
- args: ['CouponRepository']
239
- }] }, { type: i1.Shops, decorators: [{
240
- type: Inject,
241
- args: [DEFAULT_SHOP]
242
- }] }, { type: undefined, decorators: [{
243
- type: Inject,
244
- args: ['OrderRepository']
245
- }] }, { type: undefined, decorators: [{
246
- type: Inject,
247
- args: ['CategoryRepository']
248
- }] }]; } });
249
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY291cG9uLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9jb25uZWN0LWFuZ3VsYXIvc3JjL3NlcnZpY2VzL2NvdXBvbi5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQTtBQUNsRCxPQUFPLEVBS0wsYUFBYSxFQUNiLE1BQU0sRUFFTixXQUFXLEVBQ1gsYUFBYSxFQUdiLEtBQUssRUFFTCxLQUFLLEdBQ04sTUFBTSxtQkFBbUIsQ0FBQTtBQUMxQixPQUFPLEVBQWMsSUFBSSxFQUFFLEVBQUUsRUFBRSxVQUFVLEVBQUUsTUFBTSxNQUFNLENBQUE7QUFDdkQsT0FBTyxFQUFFLFNBQVMsRUFBRSxHQUFHLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQTtBQUUvQyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sV0FBVyxDQUFBO0FBRXhDLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLFVBQVUsQ0FBQTs7O0FBSzdDLE1BQU0sT0FBTyxhQUFhO0lBQ3hCLFlBQytDLGdCQUFrQyxFQUN4QyxXQUFrQixFQUNiLGVBQWdDLEVBQzdCLGtCQUFzQztRQUh4QyxxQkFBZ0IsR0FBaEIsZ0JBQWdCLENBQWtCO1FBQ3hDLGdCQUFXLEdBQVgsV0FBVyxDQUFPO1FBQ2Isb0JBQWUsR0FBZixlQUFlLENBQWlCO1FBQzdCLHVCQUFrQixHQUFsQixrQkFBa0IsQ0FBb0I7UUEwQi9FLDRCQUF1QixHQUFHLENBQUMsU0FBaUIsRUFBVyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUEsU0FBUyxhQUFULFNBQVMsdUJBQVQsU0FBUyxDQUFFLEtBQUssQ0FBQyxjQUFjLENBQUMsQ0FBQSxDQUFBO1FBNk41Rix5QkFBb0IsR0FBRyxDQUM3QixPQUFpQixFQUNqQixTQUFpQixFQUNxQyxFQUFFLENBQ3hELE9BQU87YUFDSixHQUFHLENBQUMs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YUFDbEIsWUFBWSxhQUNaLGlCQUFpQixhQUNqQixvQkFBb0I7K0dBTG5CLGFBQWEsY0FGWixNQUFNOzRGQUVQLGFBQWE7a0JBSHpCLFVBQVU7bUJBQUM7b0JBQ1YsVUFBVSxFQUFFLE1BQU07aUJBQ25COzswQkFHSSxNQUFNOzJCQUFDLGtCQUFrQjs7MEJBQ3pCLE1BQU07MkJBQUMsWUFBWTs7MEJBQ25CLE1BQU07MkJBQUMsaUJBQWlCOzswQkFDeEIsTUFBTTsyQkFBQyxvQkFBb0IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3QsIEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJ1xyXG5pbXBvcnQge1xyXG4gIENhdGVnb3J5LFxyXG4gIENhdGVnb3J5UmVwb3NpdG9yeSxcclxuICBDaGVja291dCxcclxuICBDaGVja291dFN1YnNjcmlwdGlvbixcclxuICBDaGVja291dFR5cGVzLFxyXG4gIENvdXBvbixcclxuICBDb3Vwb25SZXBvc2l0b3J5LFxyXG4gIENvdXBvblR5cGVzLFxyXG4gIEV4Y2x1c2l2aXRpZXMsXHJcbiAgTGluZUl0ZW0sXHJcbiAgT3JkZXJSZXBvc2l0b3J5LFxyXG4gIFNob3BzLFxyXG4gIFVzZXIsXHJcbiAgV2hlcmUsXHJcbn0gZnJvbSAnQGluZnJhYjRhL2Nvbm5lY3QnXHJcbmltcG9ydCB7IE9ic2VydmFibGUsIGZyb20sIG9mLCB0aHJvd0Vycm9yIH0gZnJvbSAncnhqcydcclxuaW1wb3J0IHsgY29uY2F0TWFwLCBtYXAgfSBmcm9tICdyeGpzL29wZXJhdG9ycydcclxuXHJcbmltcG9ydCB7IERFRkFVTFRfU0hPUCB9IGZyb20gJy4uL2NvbnN0cydcclxuXHJcbmltcG9ydCB7IEludmFsaWRDb3Vwb25FcnJvciB9IGZyb20gJy4vZXJyb3JzJ1xyXG5cclxuQEluamVjdGFibGUoe1xyXG4gIHByb3ZpZGVkSW46ICdyb290JyxcclxufSlcclxuZXhwb3J0IGNsYXNzIENvdXBvblNlcnZpY2Uge1xyXG4gIGNvbnN0cnVjdG9yKFxyXG4gICAgQEluamVjdCgnQ291cG9uUmVwb3NpdG9yeScpIHByaXZhdGUgcmVhZG9ubHkgY291cG9uUmVwb3NpdG9yeTogQ291cG9uUmVwb3NpdG9yeSxcclxuICAgIEBJbmplY3QoREVGQVVMVF9TSE9QKSBwcml2YXRlIHJlYWRvbmx5IGRlZmF1bHRTaG9wOiBTaG9wcyxcclxuICAgIEBJbmplY3QoJ09yZGVyUmVwb3NpdG9yeScpIHByaXZhdGUgcmVhZG9ubHkgb3JkZXJSZXBvc2l0b3J5OiBPcmRlclJlcG9zaXRvcnksXHJcbiAgICBASW5qZWN0KCdDYXRlZ29yeVJlcG9zaXRvcnknKSBwcml2YXRlIHJlYWRvbmx5IGNhdGVnb3J5UmVwb3NpdG9yeTogQ2F0ZWdvcnlSZXBvc2l0b3J5LFxyXG4gICkge31cclxuXHJcbiAgY2hlY2tDb3Vwb24oXHJcbiAgICBuaWNrbmFtZTogc3RyaW5nLFxyXG4gICAgdXNlckVtYWlsOiBzdHJpbmcsXHJcbiAgICBjaGVja291dFR5cGU6IENoZWNrb3V0VHlwZXMsXHJcbiAgICBwbGFuPzogc3RyaW5nLFxyXG4gICAgY2hlY2tvdXQ/OiBQYXJ0aWFsPENoZWNrb3V0PixcclxuICAgIGlzU3Vic2NyaXB0aW9uPzogYm9vbGVhbixcclxuICApOiBPYnNlcnZhYmxlPENvdXBvbj4ge1xyXG4gICAgcmV0dXJuIGZyb20oXHJcbiAgICAgIHRoaXMuY291cG9uUmVwb3NpdG9yeS5maW5kKHtcclxuICAgICAgICBmaWx0ZXJzOiB7XHJcbiAgICAgICAgICBuaWNrbmFtZTogeyBvcGVyYXRvcjogV2hlcmUuRVFVQUxTLCB2YWx1ZTogbmlja25hbWUgfSxcclxuICAgICAgICAgIGFjdGl2ZTogeyBvcGVyYXRvcjogV2hlcmUuRVFVQUxTLCB2YWx1ZTogdHJ1ZSB9LFxyXG4gICAgICAgIH0sXHJcbiAgICAgIH0pLFxyXG4gICAgKS5waXBlKFxyXG4gICAgICBjb25jYXRNYXAoKGNvdXBvbnMpID0+IHRoaXMuY2hlY2tDb3Vwb25SdWxlcyhjb3Vwb25zLCBjaGVja291dFR5cGUsIHBsYW4sIGNoZWNrb3V0LCBpc1N1YnNjcmlwdGlvbikpLFxyXG4gICAgICBjb25jYXRNYXAoKGNvdXBvbjogQ291cG9uKSA9PiB0aGlzLmNoZWNrQ291cG9uVXNlQW5kTGltaXQoY291cG9uLCB1c2VyRW1haWwsIGNoZWNrb3V0KSksXHJcbiAgICAgIG1hcCgoY291cG9uOiBDb3Vwb24pID0+IHRoaXMuaXNWYWxpZENvdXBvbihjb3Vwb24sIHVzZXJFbWFpbCkpLFxyXG4gICAgICBtYXAoKGNvdXBvbjogQ291cG9uKSA9PiBjb3Vwb24pLFxyXG4gICAgKVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBlbWFpbElzRnJvbUNvbGxhYm9yYXRvciA9ICh1c2VyRW1haWw6IHN0cmluZyk6IGJvb2xlYW4gPT4gISF1c2VyRW1haWw/Lm1hdGNoKC9AYjRhLmNvbS5ici9nKVxyXG5cclxuICBwcml2YXRlIGNoZWNrQ291cG9uUnVsZXMoXHJcbiAgICBjb3Vwb25zLFxyXG4gICAgY2hlY2tvdXRUeXBlOiBDaGVja291dFR5cGVzLFxyXG4gICAgcGxhbj86IHN0cmluZyxcclxuICAgIGNoZWNrb3V0PzogUGFydGlhbDxDaGVja291dD4sXHJcbiAgICBpc1N1YnNjcmlwdGlvbj86IGJvb2xlYW4sXHJcbiAgKSB7XHJcbiAgICAvLyBDYXNvIG7Do28gYWNoZSBuZW5odW0gY3Vwb20sIHJldG9ybmEgZXJyb1xyXG4gICAgaWYgKGNvdXBvbnMuY291bnQgPCAxKSB7XHJcbiAgICAgIHJldHVybiB0aHJvd0Vycm9yKCdDdXBvbSBpbnbDoWxpZG8uJylcclxuICAgIH1cclxuXHJcbiAgICAvLyBHZXQgUHJpbWVpcm8gQ3Vwb20gKG8gZmluZCBkbyByZXBvc2l0b3J5IHJldG9ybmEgdW0gYXJyYXkpXHJcbiAgICBjb25zdCBjb3Vwb246IENvdXBvbiA9IGNvdXBvbnMuZGF0YS5zaGlmdCgpXHJcbiAgICAvLyBWZXJpZmljYSBzZSBvIGN1cG9tIMOpIGFwbGljYXZlbCBuYSBsb2phXHJcbiAgICBjb25zdCBpc0luU2hvcCA9IGNvdXBvbi5zaG9wQXZhaWxhYmlsaXR5ID09PSBTaG9wcy5BTEwgfHwgY291cG9uLnNob3BBdmFpbGFiaWxpdHkgPT09IHRoaXMuZGVmYXVsdFNob3BcclxuXHJcbiAgICAvLyBDdXBvbiBuw6NvIGFwbGljYXZlbCBhIGxvamEgcmV0b3JuYSBlcnJvXHJcbiAgICBpZiAoIWlzSW5TaG9wKSByZXR1cm4gdGhyb3dFcnJvcignQ3Vwb20gaW52w6FsaWRvIHBhcmEgbG9qYS4nKVxyXG5cclxuICAgIC8vIFZlcmlmaWNhIHNlIG8gY291cG9uIMOpIGFwbGljYWRvIG5vIGNoZWNrb3V0IHF1ZSBlc3TDoSBzZW5kbyByZWFsaXphZG9cclxuICAgIGNvbnN0IGlzQ2hlY2tvdXRUeXBlID0gY291cG9uLmNoZWNrb3V0VHlwZSA9PT0gQ2hlY2tvdXRUeXBlcy5BTEwgfHwgY291cG9uLmNoZWNrb3V0VHlwZSA9PT0gY2hlY2tvdXRUeXBlXHJcblxyXG4gICAgLy8gQ3Vwb24gbsOjbyBhcGxpY2F2ZWwgYW8gY2hlY2tvdXQgcmV0b3JuYSBlcnJvXHJcbiAgICBpZiAoIWlzQ2hlY2tvdXRUeXBlKSByZXR1cm4gdGhyb3dFcnJvcignQ3Vwb20gaW52w6FsaWRvLiBFcnJvIGRlIGNoZWNrb3V0LicpXHJcblxyXG4gICAgLy8gVmVyaWZpY2Egc2UgbyBjdXBvbSDDqSBvdSBwb2RlIHNlciBhcGxpY2FkbyBwYXJhIHN1YnNjcmlwdGlvblxyXG4gICAgaWYgKGNoZWNrb3V0VHlwZSA9PT0gQ2hlY2tvdXRUeXBlcy5BTEwgfHwgY2hlY2tvdXRUeXBlID09PSBDaGVja291dFR5cGVzLlNVQlNDUklQVElPTikge1xyXG4gICAgICAvLyBTZSBvIGN1cG9tIHRpdmVyIHVtIHBsYW5vIGFzc29jaWFkbywgdmVyaWZpY2Egc2Ugw6kgbyBtZXNtbyBwbGFubyBkbyBjaGVja291dCBkYSBhc3NpbmF0dXJhXHJcbiAgICAgIGlmIChjb3Vwb24ucGxhbiAmJiBjb3Vwb24ucGxhbi50b1VwcGVyQ2FzZSgpICE9PSBwbGFuLnRvVXBwZXJDYXNlKCkpXHJcbiAgICAgICAgcmV0dXJuIHRocm93RXJyb3IoJ0N1cG9tIGludsOhbGlkbyBwYXJhIHN1YSBhc3NpbmF0dXJhLicpXHJcbiAgICB9XHJcblxyXG4gICAgaWYgKGlzU3Vic2NyaXB0aW9uKSByZXR1cm4gb2YoY291cG9uKVxyXG5cclxuICAgIC8vIFZlcmlmaWNhIHNlIHBvc3N1aSBvIHZhbG9yIG1pbmltbyBkZSBjb21wcmEgcGFyYSB1dGlsaXphw6fDo28gZG8gY3Vwb21cclxuICAgIGNvbnN0IGhhc01pblN1YlRvdGFsID0gdGhpcy5oYXNNaW5TdWJUb3RhbChjb3Vwb24sIGNoZWNrb3V0KVxyXG5cclxuICAgIC8vIFNlIG7Do28gdGVtIHZhbG9yIG3DrW5pbW8gYXRpbmdpZG8sIHJldG9ybmEgZXJyb1xyXG4gICAgaWYgKCFoYXNNaW5TdWJUb3RhbClcclxuICAgICAgcmV0dXJuIHRocm93RXJyb3IoXHJcbiAgICAgICAgYFZhbG9yIG3DrW5pbW8gZGUgJHtJbnRsLk51bWJlckZvcm1hdCgncHQtQlInLCB7IHN0eWxlOiAnY3VycmVuY3knLCBjdXJyZW5jeTogJ0JSTCcgfSkuZm9ybWF0KFxyXG4gICAgICAgICAgY291cG9uLm1pblN1YlRvdGFsVmFsdWUsXHJcbiAgICAgICAgKX0gbsOjbyBhdGluZ2lkb2AsXHJcbiAgICAgIClcclxuXHJcbiAgICByZXR1cm4gb2YoY291cG9uKVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBpc1ZhbGlkQ291cG9uKGNvdXBvbjogQ291cG9uLCB1c2VyRW1haWw6IHN0cmluZyk6IENvdXBvbiB7XHJcbiAgICAvLyBWZXJpZmljYSBhIGRhdGEgZGUgaW5pY2lvIGRlIHZhbGlkYWRlIGRvIGN1cG9tXHJcbiAgICBpZiAoY291cG9uPy5iZWdpbkF0ID4gbmV3IERhdGUoKSkgdGhyb3cgbmV3IEludmFsaWRDb3Vwb25FcnJvcignQ3Vwb20gYWluZGEgbsOjbyBsaWJlcmFkby4nKVxyXG5cclxuICAgIC8vIFZlcmlmaWNhIGEgZGF0YSBkZSB2YWxpZGFkZSBkbyBjdXBvbVxyXG4gICAgaWYgKGNvdXBvbj8uZXhwaXJlc0luIDwgbmV3IERhdGUoKSkgdGhyb3cgbmV3IEludmFsaWRDb3Vwb25FcnJvcignQ3Vwb20gZXhwaXJhZG8uJylcclxuXHJcbiAgICByZXR1cm4gY291cG9uXHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGFzeW5jIGNoZWNrQ291cG9uVXNlQW5kTGltaXQoY291cG9uOiBDb3Vwb24sIHVzZXJFbWFpbDogc3RyaW5nLCBjaGVja291dDogUGFydGlhbDxDaGVja291dD4pIHtcclxuICAgIGNvbnN0IG9yZGVycyA9IGF3YWl0IHRoaXMub3JkZXJSZXBvc2l0b3J5LmZpbmQoe1xyXG4gICAgICBmaWx0ZXJzOiB7XHJcbiAgICAgICAgY291cG9uOiB7IGlkOiBjb3Vwb24uaWQgfSxcclxuICAgICAgICBwYXltZW50OiB7IHN0YXR1czogJ3BhaWQnIH0sXHJcbiAgICAgIH0sXHJcbiAgICB9KVxyXG5cclxuICAgIC8vIG9yZGVycyBxdWUgdXN1YXJpbyBqYSBmZXogY29tIG8gY3Vwb21cclxuICAgIGNvbnN0IG9yZGVyc1VzZXJDb3Vwb24gPSBvcmRlcnMuZGF0YS5maWx0ZXIoKG8pID0+IG8udXNlci5lbWFpbCA9PSB1c2VyRW1haWwpXHJcblxyXG4gICAgLy8gVmVyaWZpY2EgbyBsaW1pdGUgZGUgdXNvIGRlIGN1cG9tIHBvciB1c3VhcmlvXHJcbiAgICBpZiAoY291cG9uLnVzZUxpbWl0UGVyVXNlciAmJiBvcmRlcnNVc2VyQ291cG9uLmxlbmd0aClcclxuICAgICAgdGhyb3cgbmV3IEludmFsaWRDb3Vwb25FcnJvcignTGltaXRlIGRlIHVzbyBwb3IgdXN1w6FyaW8gYXRpbmdpZG8uJylcclxuXHJcbiAgICAvLyBWZXJpZmljYSBvIGxpbWl0ZSBkZSB1c28gZ2VyYWwgcG9yIHVzdWFyaW9cclxuICAgIGlmIChjb3Vwb24udXNlTGltaXQgJiYgb3JkZXJzLmRhdGEubGVuZ3RoID49IGNvdXBvbi51c2VMaW1pdClcclxuICAgICAgdGhyb3cgbmV3IEludmFsaWRDb3Vwb25FcnJvcignTGltaXRlIGRlIHVzbyBhdGluZ2lkby4nKVxyXG5cclxuICAgIGNvbnN0IHZhbGlkVXNlciA9IHRoaXMudXNlclZhbGlkYXRpb25BbmRTdWJzY3JpcHRpb25TdGF0dXMoY291cG9uLCBjaGVja291dD8udXNlcilcclxuICAgIGlmICghdmFsaWRVc2VyKSB0aHJvdyBuZXcgSW52YWxpZENvdXBvbkVycm9yKCdVc3XDoXJpbyBuw6NvIGVsZWfDrXZlbC4nKVxyXG5cclxuICAgIGNvbnN0IGhhc1Byb2R1Y3RDYXRlZ29yaWVzID0gYXdhaXQgdGhpcy5oYXNQcm9kdWN0Q2F0ZWdvcmllcyhjb3Vwb24sIGNoZWNrb3V0KVxyXG5cclxuICAgIGlmICghaGFzUHJvZHVjdENhdGVnb3JpZXMpIHRocm93ICdTZXUgY2FycmluaG8gbsOjbyBwb3NzdWkgcHJvZHV0b3MgZWxlZ8OtdmVpcyBwYXJhIGRlc2NvbnRvLidcclxuXHJcbiAgICByZXR1cm4gY291cG9uXHJcbiAgfVxyXG5cclxuICBwdWJsaWMgY2FsY0Rpc2NvdW50U3Vic2NyaXB0aW9uKGNvdXBvbjogQ291cG9uLCBjaGVja291dDogUGFydGlhbDxDaGVja291dFN1YnNjcmlwdGlvbj4pOiBPYnNlcnZhYmxlPG51bWJlcj4ge1xyXG4gICAgLy9cclxuICAgIGxldCBkaXNjb3VudCA9IDBcclxuXHJcbiAgICBpZiAoY291cG9uLnR5cGUgPT09IENvdXBvblR5cGVzLkFCU09MVVRFKSBkaXNjb3VudCA9IGNvdXBvbi5kaXNjb3VudFxyXG4gICAgZWxzZSBpZiAoY291cG9uLnR5cGUgPT09IENvdXBvblR5cGVzLlBFUkNFTlRBR0UpXHJcbiAgICAgIGRpc2NvdW50ID0gY2hlY2tvdXQuc3Vic2NyaXB0aW9uUGxhbi5yZWN1cnJlbmNlUHJpY2UgKiAoY291cG9uLmRpc2NvdW50IC8gMTAwKVxyXG5cclxuICAgIHJldHVybiBvZihkaXNjb3VudClcclxuICB9XHJcblxyXG4gIHB1YmxpYyBhc3luYyBjYWxjRGlzY291bnRTaG9wcGluZyhjb3Vwb246IENvdXBvbiwgY2hlY2tvdXQ6IFBhcnRpYWw8Q2hlY2tvdXQ+KTogUHJvbWlzZTxudW1iZXI+IHtcclxuICAgIGxldCBkaXNjb3VudCA9IDBcclxuXHJcbiAgICBzd2l0Y2ggKGNvdXBvbi50eXBlKSB7XHJcbiAgICAgIGNhc2UgQ291cG9uVHlwZXMuQUJTT0xVVEU6IHtcclxuICAgICAgICBkaXNjb3VudCA9IGNvdXBvbi5kaXNjb3VudFxyXG4gICAgICAgIGJyZWFrXHJcbiAgICAgIH1cclxuICAgICAgY2FzZSBDb3Vwb25UeXBlcy5QRVJDRU5UQUdFOiB7XHJcbiAgICAgICAgZGlzY291bnQgPSBhd2FpdCB0aGlzLmNhbGNTaG9wcGluZ1BlcmNlbnRhZ2VEaXNjb3VudChjb3Vwb24sIGNoZWNrb3V0KVxyXG4gICAgICAgIGJyZWFrXHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gZGlzY291bnRcclxuICB9XHJcblxyXG4gIHByaXZhdGUgYXN5bmMgY2FsY1Nob3BwaW5nUGVyY2VudGFnZURpc2NvdW50KGNvdXBvbjogQ291cG9uLCBjaGVja291dDogUGFydGlhbDxDaGVja291dD4pOiBQcm9taXNlPG51bWJlcj4ge1xyXG4gICAgbGV0IGRpc2NvdW50ID0gMFxyXG4gICAgY29uc3Qgc2hvcCA9IGNoZWNrb3V0LnNob3BcclxuICAgIGxldCBsaW5lSXRlbnNEaXNjb3VudCA9IFtdXHJcbiAgICBjb25zdCBjb3Vwb25DYXRlZ29yaWVzID0gYXdhaXQgdGhpcy5nZXRDb3Vwb25DYXRlZ29yaWVzSWQoY291cG9uKVxyXG5cclxuICAgIGlmIChjb3Vwb24ucHJvZHVjdHNDYXRlZ29yaWVzICYmIGNvdXBvbi5wcm9kdWN0c0NhdGVnb3JpZXMubGVuZ3RoKSB7XHJcbiAgICAgIGxpbmVJdGVuc0Rpc2NvdW50ID0gY2hlY2tvdXQubGluZUl0ZW1zPy5maWx0ZXIoKGkpID0+IHtcclxuICAgICAgICBpZiAoaS5jYXRlZ29yaWVzPy5sZW5ndGgpIHtcclxuICAgICAgICAgIHJldHVybiBpLmNhdGVnb3JpZXMuc29tZSgoYykgPT4gY291cG9uQ2F0ZWdvcmllcy5zb21lKChjYXQpID0+IGNhdC5pZCA9PSBjIHx8IGNhdC5maXJlc3RvcmVJZCA9PSBjKSlcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHRydWVcclxuICAgICAgfSlcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGxpbmVJdGVuc0Rpc2NvdW50ID0gY2hlY2tvdXQubGluZUl0ZW1zXHJcbiAgICB9XHJcblxyXG4gICAgY29uc3Qgc3ViVG90YWwgPVxyXG4gICAgICBsaW5lSXRlbnNEaXNjb3VudC5yZWR1Y2UoXHJcbiAgICAgICAgKGFjYywgY3VycjogTGluZUl0ZW0pID0+XHJcbiAgICAgICAgICBjaGVja291dC51c2VyPy5pc1N1YnNjcmliZXIgJiYgY3Vyci5wcmljZVtzaG9wXT8uc3Vic2NyaWJlclByaWNlXHJcbiAgICAgICAgICAgID8gYWNjICsgY3Vyci5wcmljZVtzaG9wXT8uc3Vic2NyaWJlclByaWNlICogY3Vyci5xdWFudGl0eVxyXG4gICAgICAgICAgICA6IGFjYyArIGN1cnIucHJpY2VQYWlkICogY3Vyci5xdWFudGl0eSxcclxuICAgICAgICAwLFxyXG4gICAgICApIHx8IDBcclxuXHJcbiAgICBkaXNjb3VudCA9IHN1YlRvdGFsICogKGNvdXBvbi5kaXNjb3VudCAvIDEwMClcclxuXHJcbiAgICByZXR1cm4gZGlzY291bnRcclxuICB9XHJcblxyXG4gIHByaXZhdGUgaGFzTWluU3ViVG90YWwoY291cG9uOiBDb3Vwb24sIGNoZWNrb3V0OiBQYXJ0aWFsPENoZWNrb3V0Pik6IGJvb2xlYW4ge1xyXG4gICAgaWYgKCFjb3Vwb24ubWluU3ViVG90YWxWYWx1ZSkgcmV0dXJuIHRydWVcclxuXHJcbiAgICBjb25zdCBzaG9wID0gY2hlY2tvdXQuc2hvcFxyXG5cclxuICAgIGxldCBzdWJUb3RhbCA9XHJcbiAgICAgIGNoZWNrb3V0LmxpbmVJdGVtcz8ucmVkdWNlKFxyXG4gICAgICAgIChhY2MsIGN1cnIpID0+XHJcbiAgICAgICAgICBjaGVja291dC51c2VyPy5pc1N1YnNjcmliZXIgJiYgY3Vyci5wcmljZVtzaG9wXT8uc3Vic2NyaWJlclByaWNlXHJcbiAgICAgICAgICAgID8gYWNjICsgY3Vyci5wcmljZVtzaG9wXT8uc3Vic2NyaWJlclByaWNlICogY3Vyci5xdWFudGl0eVxyXG4gICAgICAgICAgICA6IGFjYyArIGN1cnIucHJpY2VQYWlkICogY3Vyci5xdWFudGl0eSxcclxuICAgICAgICAwLFxyXG4gICAgICApIHx8IDBcclxuXHJcbiAgICBpZiAoY291cG9uLm1pblN1YlRvdGFsVmFsdWUgPD0gc3ViVG90YWwpIHJldHVybiB0cnVlXHJcbiAgICByZXR1cm4gZmFsc2VcclxuICB9XHJcblxyXG4gIHByaXZhdGUgYXN5bmMgaGFzUHJvZHVjdENhdGVnb3JpZXMoY291cG9uOiBDb3Vwb24sIGNoZWNrb3V0OiBQYXJ0aWFsPENoZWNrb3V0Pik6IFByb21pc2U8Ym9vbGVhbj4ge1xyXG4gICAgaWYgKCFjb3Vwb24ucHJvZHVjdHNDYXRlZ29yaWVzIHx8ICFjb3Vwb24ucHJvZHVjdHNDYXRlZ29yaWVzLmxlbmd0aCkge1xyXG4gICAgICByZXR1cm4gdHJ1ZVxyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IGNvdXBvbkNhdGVnb3JpZXMgPSBhd2FpdCB0aGlzLmdldENvdXBvbkNhdGVnb3JpZXNJZChjb3Vwb24pXHJcblxyXG4gICAgY29uc3QgaGFzQ2F0ZWdvcmllcyA9IGNoZWNrb3V0LmxpbmVJdGVtcz8uZmlsdGVyKChpKSA9PiB7XHJcbiAgICAgIGlmICghaS5jYXRlZ29yaWVzIHx8ICFpLmNhdGVnb3JpZXM/Lmxlbmd0aCkgcmV0dXJuIHRydWVcclxuICAgICAgcmV0dXJuIGkuY2F0ZWdvcmllcy5zb21lKChjKSA9PiBjb3Vwb25DYXRlZ29yaWVzLnNvbWUoKGNhdCkgPT4gY2F0LmlkID09IGMgfHwgY2F0LmZpcmVzdG9yZUlkID09IGMpKVxyXG4gICAgfSlcclxuXHJcbiAgICByZXR1cm4gaGFzQ2F0ZWdvcmllcy5sZW5ndGggPyB0cnVlIDogZmFsc2VcclxuICB9XHJcblxyXG4gIHByaXZhdGUgdXNlclZhbGlkYXRpb25BbmRTdWJzY3JpcHRpb25TdGF0dXMoY291cG9uOiBDb3Vwb24sIHVzZXI6IFVzZXIpOiBib29sZWFuIHtcclxuICAgIGlmIChjb3Vwb24uZXhjbHVzaXZpdHlUeXBlID09PSBFeGNsdXNpdml0aWVzLkFMTF9VU0VSUykgcmV0dXJuIHRydWVcclxuICAgIGlmICghdXNlcikgcmV0dXJuIHRydWVcclxuXHJcbiAgICAvLyBWZXJpZmljYSBzZSBvIGVtYWlsIGRvIHVzdcOhcmlvIMOpIGNvb3Jwb3JhdGl2b1xyXG4gICAgaWYgKCF0aGlzLmVtYWlsSXNGcm9tQ29sbGFib3JhdG9yKHVzZXIuZW1haWwpICYmIGNvdXBvbi5leGNsdXNpdml0eVR5cGUgPT09IEV4Y2x1c2l2aXRpZXMuQ09MTEFCT1JBVE9SUylcclxuICAgICAgdGhyb3cgbmV3IEludmFsaWRDb3Vwb25FcnJvcignVm9jw6ogbsOjbyDDqSBjb2xhYm9yYWRvci4nKVxyXG5cclxuICAgIC8vIFZlcmlmaWNhIHNlIG8gZW1haWwgZG8gdXN1w6FyaW8gw6kgYXNzb2NpYWRvIGFvIGN1cG9tIGRlIHVzbyBwb3IgdXN1YXJpb1xyXG4gICAgaWYgKGNvdXBvbi5leGNsdXNpdml0eVR5cGUgPT09IEV4Y2x1c2l2aXRpZXMuU1BFQ0lGSUNfVVNFUiAmJiBjb3Vwb24udXNlckV4Y2x1c2l2ZUVtYWlsICE9PSB1c2VyLmVtYWlsKVxyXG4gICAgICB0aHJvdyBuZXcgSW52YWxpZENvdXBvbkVycm9yKCdDdXBvbSBuw6NvIMOpIHbDoWxpZG8gcGFyYSBlc3RlIHVzdcOhcmlvLicpXHJcblxyXG4gICAgc3dpdGNoIChjb3Vwb24uZXhjbHVzaXZpdHlUeXBlKSB7XHJcbiAgICAgIGNhc2UgRXhjbHVzaXZpdGllcy5BQ1RJVkVfU1VCU0NSSUJFUjpcclxuICAgICAgICByZXR1cm4gdXNlci5pc1N1YnNjcmliZXIgPyB0cnVlIDogZmFsc2VcclxuXHJcbiAgICAgIGNhc2UgRXhjbHVzaXZpdGllcy5JTkFDVElWRV9TVUJTQ1JJQkVSOlxyXG4gICAgICAgIHJldHVybiB1c2VyLmlzU3Vic2NyaWJlciA/IGZhbHNlIDogdHJ1ZVxyXG5cclxuICAgICAgY2FzZSBFeGNsdXNpdml0aWVzLk5PTl9TVUJTQ1JJQkVSOlxyXG4gICAgICAgIHJldHVybiB1c2VyLmlzU3Vic2NyaWJlciA/IGZhbHNlIDogdHJ1ZVxyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiB0cnVlXHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGFzeW5jIGdldENvdXBvbkNhdGVnb3JpZXNJZChjb3Vwb246IENvdXBvbikge1xyXG4gICAgbGV0IGNvdXBvbkNhdGVnb3JpZXM6IHsgaWQ6IHN0cmluZzsgZmlyZXN0b3JlSWQ6IHN0cmluZyB9W10gPSBbXVxyXG5cclxuICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBjb3Vwb24ucHJvZHVjdHNDYXRlZ29yaWVzLmxlbmd0aDsgaW5kZXgrKykge1xyXG4gICAgICBsZXQgYzogQ2F0ZWdvcnkgJiB7IGZpcmVzdG9yZUlkPzogc3RyaW5nIH0gPSBhd2FpdCB0aGlzLmNhdGVnb3J5UmVwb3NpdG9yeS5nZXQoe1xyXG4gICAgICAgIGlkOiBjb3Vwb24ucHJvZHVjdHNDYXRlZ29yaWVzW2luZGV4XSxcclxuICAgICAgfSlcclxuICAgICAgY291cG9uQ2F0ZWdvcmllcy5wdXNoKHsgaWQ6IGMuaWQsIGZpcmVzdG9yZUlkOiBjLmZpcmVzdG9yZUlkIH0pXHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIGNvdXBvbkNhdGVnb3JpZXNcclxuICB9XHJcblxyXG4gIHByaXZhdGUgc2VwYXJhdGVWYWxpZENvdXBvbnMgPSAoXHJcbiAgICBjb3Vwb25zOiBDb3Vwb25bXSxcclxuICAgIHVzZXJFbWFpbDogc3RyaW5nLFxyXG4gICk6IHsgdmFsaWRzOiBDb3Vwb25bXTsgaW52YWxpZHM6IEludmFsaWRDb3Vwb25FcnJvcltdIH0gPT5cclxuICAgIGNvdXBvbnNcclxuICAgICAgLm1hcCgoY291cG9uKSA9PiB7XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgIGlmICghKGNvdXBvbiBpbnN0YW5jZW9mIENvdXBvbikpIHRocm93IG5ldyBJbnZhbGlkQ291cG9uRXJyb3IoJ0N1cG9tIGludsOhbGlkby4nKVxyXG4gICAgICAgICAgaWYgKHRoaXMuaXNWYWxpZENvdXBvbihjb3Vwb24sIHVzZXJFbWFpbCkpIHJldHVybiBjb3Vwb25cclxuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xyXG4gICAgICAgICAgcmV0dXJuIGVycm9yIGFzIEludmFsaWRDb3Vwb25FcnJvclxyXG4gICAgICAgIH1cclxuICAgICAgfSlcclxuICAgICAgLnJlZHVjZShcclxuICAgICAgICAoY3VycmVudCwgY291cG9uKSA9PiAoe1xyXG4gICAgICAgICAgLi4uY3VycmVudCxcclxuICAgICAgICAgIC4uLihjb3Vwb24gaW5zdGFuY2VvZiBDb3Vwb25cclxuICAgICAgICAgICAgPyB7IHZhbGlkczogWy4uLmN1cnJlbnQudmFsaWRzLCBjb3Vwb25dIH1cclxuICAgICAgICAgICAgOiB7IGludmFsaWRzOiBbLi4uY3VycmVudC5pbnZhbGlkcywgY291cG9uXSB9KSxcclxuICAgICAgICB9KSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICB2YWxpZHM6IFtdIGFzIENvdXBvbltdLFxyXG4gICAgICAgICAgaW52YWxpZHM6IFtdIGFzIEludmFsaWRDb3Vwb25FcnJvcltdLFxyXG4gICAgICAgIH0sXHJcbiAgICAgIClcclxufVxyXG4iXX0=
1
+ import { __awaiter } from "tslib";
2
+ import { Inject, Injectable } from '@angular/core';
3
+ import { CheckoutTypes, Coupon, CouponTypes, Exclusivities, Shops, Where, } from '@infrab4a/connect';
4
+ import { from, of, throwError } from 'rxjs';
5
+ import { concatMap, map } from 'rxjs/operators';
6
+ import { DEFAULT_SHOP } from '../consts';
7
+ import { InvalidCouponError } from './errors';
8
+ import * as i0 from "@angular/core";
9
+ import * as i1 from "@infrab4a/connect";
10
+ export class CouponService {
11
+ constructor(couponRepository, defaultShop, orderRepository, categoryRepository) {
12
+ this.couponRepository = couponRepository;
13
+ this.defaultShop = defaultShop;
14
+ this.orderRepository = orderRepository;
15
+ this.categoryRepository = categoryRepository;
16
+ this.emailIsFromCollaborator = (userEmail) => !!(userEmail === null || userEmail === void 0 ? void 0 : userEmail.match(/@b4a.com.br/g));
17
+ this.separateValidCoupons = (coupons, userEmail) => coupons
18
+ .map((coupon) => {
19
+ try {
20
+ if (!(coupon instanceof Coupon))
21
+ throw new InvalidCouponError('Cupom inválido.');
22
+ if (this.isValidCoupon(coupon, userEmail))
23
+ return coupon;
24
+ }
25
+ catch (error) {
26
+ return error;
27
+ }
28
+ })
29
+ .reduce((current, coupon) => (Object.assign(Object.assign({}, current), (coupon instanceof Coupon
30
+ ? { valids: [...current.valids, coupon] }
31
+ : { invalids: [...current.invalids, coupon] }))), {
32
+ valids: [],
33
+ invalids: [],
34
+ });
35
+ }
36
+ checkCoupon(nickname, userEmail, checkoutType, plan, checkout, isSubscription) {
37
+ return from(this.couponRepository.find({
38
+ filters: {
39
+ nickname: { operator: Where.EQUALS, value: nickname },
40
+ active: { operator: Where.EQUALS, value: true },
41
+ },
42
+ })).pipe(concatMap((coupons) => this.checkCouponRules(coupons, checkoutType, plan, checkout, isSubscription)), concatMap((coupon) => this.checkCouponUseAndLimit(coupon, userEmail, checkout)), map((coupon) => this.isValidCoupon(coupon, userEmail)), map((coupon) => coupon));
43
+ }
44
+ checkCouponRules(coupons, checkoutType, plan, checkout, isSubscription) {
45
+ // Caso não ache nenhum cupom, retorna erro
46
+ if (coupons.count < 1) {
47
+ return throwError('Cupom inválido.');
48
+ }
49
+ // Get Primeiro Cupom (o find do repository retorna um array)
50
+ const coupon = coupons.data.shift();
51
+ // Verifica se o cupom é aplicavel na loja
52
+ const isInShop = coupon.shopAvailability === Shops.ALL || coupon.shopAvailability === this.defaultShop;
53
+ // Cupon não aplicavel a loja retorna erro
54
+ if (!isInShop)
55
+ return throwError('Cupom inválido para loja.');
56
+ // Verifica se o coupon é aplicado no checkout que está sendo realizado
57
+ const isCheckoutType = coupon.checkoutType === CheckoutTypes.ALL || coupon.checkoutType === checkoutType;
58
+ // Cupon não aplicavel ao checkout retorna erro
59
+ if (!isCheckoutType)
60
+ return throwError('Cupom inválido. Erro de checkout.');
61
+ // Verifica se o cupom é ou pode ser aplicado para subscription
62
+ if (checkoutType === CheckoutTypes.ALL || checkoutType === CheckoutTypes.SUBSCRIPTION) {
63
+ // Se o cupom tiver um plano associado, verifica se é o mesmo plano do checkout da assinatura
64
+ if (coupon.plan && coupon.plan.toUpperCase() !== plan.toUpperCase())
65
+ return throwError('Cupom inválido para sua assinatura.');
66
+ }
67
+ if (isSubscription)
68
+ return of(coupon);
69
+ // Verifica se possui o valor minimo de compra para utilização do cupom
70
+ const hasMinSubTotal = this.hasMinSubTotal(coupon, checkout);
71
+ // Se não tem valor mínimo atingido, retorna erro
72
+ if (!hasMinSubTotal)
73
+ return throwError(`Valor mínimo de ${Intl.NumberFormat('pt-BR', { style: 'currency', currency: 'BRL' }).format(coupon.minSubTotalValue)} não atingido`);
74
+ return of(coupon);
75
+ }
76
+ isValidCoupon(coupon, userEmail) {
77
+ // Verifica a data de inicio de validade do cupom
78
+ if ((coupon === null || coupon === void 0 ? void 0 : coupon.beginAt) > new Date())
79
+ throw new InvalidCouponError('Cupom ainda não liberado.');
80
+ // Verifica a data de validade do cupom
81
+ if ((coupon === null || coupon === void 0 ? void 0 : coupon.expiresIn) < new Date())
82
+ throw new InvalidCouponError('Cupom expirado.');
83
+ return coupon;
84
+ }
85
+ checkCouponUseAndLimit(coupon, userEmail, checkout) {
86
+ return __awaiter(this, void 0, void 0, function* () {
87
+ const orders = yield this.orderRepository.find({
88
+ filters: {
89
+ coupon: { id: coupon.id },
90
+ payment: { status: 'paid' },
91
+ },
92
+ });
93
+ // orders que usuario ja fez com o cupom
94
+ const ordersUserCoupon = orders.data.filter((o) => o.user.email == userEmail);
95
+ // Verifica o limite de uso de cupom por usuario
96
+ if (coupon.useLimitPerUser && ordersUserCoupon.length)
97
+ throw new InvalidCouponError('Limite de uso por usuário atingido.');
98
+ // Verifica o limite de uso geral por usuario
99
+ if (coupon.useLimit && orders.data.length >= coupon.useLimit)
100
+ throw new InvalidCouponError('Limite de uso atingido.');
101
+ const validUser = this.userValidationAndSubscriptionStatus(coupon, checkout === null || checkout === void 0 ? void 0 : checkout.user);
102
+ if (!validUser)
103
+ throw new InvalidCouponError('Usuário não elegível.');
104
+ const hasProductCategories = yield this.hasProductCategories(coupon, checkout);
105
+ if (!hasProductCategories)
106
+ throw 'Seu carrinho não possui produtos elegíveis para desconto.';
107
+ return coupon;
108
+ });
109
+ }
110
+ calcDiscountSubscription(coupon, checkout) {
111
+ //
112
+ let discount = 0;
113
+ if (coupon.type === CouponTypes.ABSOLUTE)
114
+ discount = coupon.discount;
115
+ else if (coupon.type === CouponTypes.PERCENTAGE)
116
+ discount = checkout.subscriptionPlan.recurrencePrice * (coupon.discount / 100);
117
+ return of(discount);
118
+ }
119
+ calcDiscountShopping(coupon, checkout) {
120
+ return __awaiter(this, void 0, void 0, function* () {
121
+ let discount = 0;
122
+ switch (coupon.type) {
123
+ case CouponTypes.ABSOLUTE: {
124
+ discount = coupon.discount;
125
+ break;
126
+ }
127
+ case CouponTypes.PERCENTAGE: {
128
+ discount = yield this.calcShoppingPercentageDiscount(coupon, checkout);
129
+ break;
130
+ }
131
+ }
132
+ return discount;
133
+ });
134
+ }
135
+ calcShoppingPercentageDiscount(coupon, checkout) {
136
+ var _a;
137
+ return __awaiter(this, void 0, void 0, function* () {
138
+ let discount = 0;
139
+ const shop = checkout.shop;
140
+ let lineItensDiscount = [];
141
+ const couponCategories = yield this.getCouponCategoriesId(coupon);
142
+ if (coupon.productsCategories && coupon.productsCategories.length) {
143
+ lineItensDiscount = (_a = checkout.lineItems) === null || _a === void 0 ? void 0 : _a.filter((i) => {
144
+ var _a;
145
+ if ((_a = i.categories) === null || _a === void 0 ? void 0 : _a.length) {
146
+ return i.categories.some((c) => couponCategories.some((cat) => cat.id == c || cat.firestoreId == c));
147
+ }
148
+ return true;
149
+ });
150
+ }
151
+ else {
152
+ lineItensDiscount = checkout.lineItems;
153
+ }
154
+ const subTotal = lineItensDiscount.reduce((acc, curr) => {
155
+ var _a, _b, _c;
156
+ return ((_a = checkout.user) === null || _a === void 0 ? void 0 : _a.isSubscriber) && ((_b = curr.price[shop]) === null || _b === void 0 ? void 0 : _b.subscriberPrice)
157
+ ? acc + ((_c = curr.price[shop]) === null || _c === void 0 ? void 0 : _c.subscriberPrice) * curr.quantity
158
+ : acc + curr.pricePaid * curr.quantity;
159
+ }, 0) || 0;
160
+ discount = subTotal * (coupon.discount / 100);
161
+ return discount;
162
+ });
163
+ }
164
+ hasMinSubTotal(coupon, checkout) {
165
+ var _a;
166
+ if (!coupon.minSubTotalValue)
167
+ return true;
168
+ const shop = checkout.shop;
169
+ let subTotal = ((_a = checkout.lineItems) === null || _a === void 0 ? void 0 : _a.reduce((acc, curr) => {
170
+ var _a, _b, _c;
171
+ return ((_a = checkout.user) === null || _a === void 0 ? void 0 : _a.isSubscriber) && ((_b = curr.price[shop]) === null || _b === void 0 ? void 0 : _b.subscriberPrice)
172
+ ? acc + ((_c = curr.price[shop]) === null || _c === void 0 ? void 0 : _c.subscriberPrice) * curr.quantity
173
+ : acc + curr.pricePaid * curr.quantity;
174
+ }, 0)) || 0;
175
+ if (coupon.minSubTotalValue <= subTotal)
176
+ return true;
177
+ return false;
178
+ }
179
+ hasProductCategories(coupon, checkout) {
180
+ var _a;
181
+ return __awaiter(this, void 0, void 0, function* () {
182
+ if (!coupon.productsCategories || !coupon.productsCategories.length) {
183
+ return true;
184
+ }
185
+ const couponCategories = yield this.getCouponCategoriesId(coupon);
186
+ const hasCategories = (_a = checkout.lineItems) === null || _a === void 0 ? void 0 : _a.filter((i) => {
187
+ var _a;
188
+ if (!i.categories || !((_a = i.categories) === null || _a === void 0 ? void 0 : _a.length))
189
+ return true;
190
+ return i.categories.some((c) => couponCategories.some((cat) => cat.id == c || cat.firestoreId == c));
191
+ });
192
+ return hasCategories.length ? true : false;
193
+ });
194
+ }
195
+ userValidationAndSubscriptionStatus(coupon, user) {
196
+ if (coupon.exclusivityType === Exclusivities.ALL_USERS)
197
+ return true;
198
+ if (!user)
199
+ return true;
200
+ // Verifica se o email do usuário é coorporativo
201
+ if (!this.emailIsFromCollaborator(user.email) && coupon.exclusivityType === Exclusivities.COLLABORATORS)
202
+ throw new InvalidCouponError('Você não é colaborador.');
203
+ // Verifica se o email do usuário é associado ao cupom de uso por usuario
204
+ if (coupon.exclusivityType === Exclusivities.SPECIFIC_USER && coupon.userExclusiveEmail !== user.email)
205
+ throw new InvalidCouponError('Cupom não é válido para este usuário.');
206
+ switch (coupon.exclusivityType) {
207
+ case Exclusivities.ACTIVE_SUBSCRIBER:
208
+ return user.isSubscriber ? true : false;
209
+ case Exclusivities.INACTIVE_SUBSCRIBER:
210
+ return user.isSubscriber ? false : true;
211
+ case Exclusivities.NON_SUBSCRIBER:
212
+ return user.isSubscriber ? false : true;
213
+ }
214
+ return true;
215
+ }
216
+ getCouponCategoriesId(coupon) {
217
+ return __awaiter(this, void 0, void 0, function* () {
218
+ let couponCategories = [];
219
+ for (let index = 0; index < coupon.productsCategories.length; index++) {
220
+ let c = yield this.categoryRepository.get({
221
+ id: coupon.productsCategories[index],
222
+ });
223
+ couponCategories.push({ id: c.id, firestoreId: c.firestoreId });
224
+ }
225
+ return couponCategories;
226
+ });
227
+ }
228
+ }
229
+ 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 });
230
+ CouponService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0, type: CouponService, providedIn: 'root' });
231
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0, type: CouponService, decorators: [{
232
+ type: Injectable,
233
+ args: [{
234
+ providedIn: 'root',
235
+ }]
236
+ }], ctorParameters: function () { return [{ type: undefined, decorators: [{
237
+ type: Inject,
238
+ args: ['CouponRepository']
239
+ }] }, { type: i1.Shops, decorators: [{
240
+ type: Inject,
241
+ args: [DEFAULT_SHOP]
242
+ }] }, { type: undefined, decorators: [{
243
+ type: Inject,
244
+ args: ['OrderRepository']
245
+ }] }, { type: undefined, decorators: [{
246
+ type: Inject,
247
+ args: ['CategoryRepository']
248
+ }] }]; } });
249
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY291cG9uLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9jb25uZWN0LWFuZ3VsYXIvc3JjL3NlcnZpY2VzL2NvdXBvbi5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQTtBQUNsRCxPQUFPLEVBS0wsYUFBYSxFQUNiLE1BQU0sRUFFTixXQUFXLEVBQ1gsYUFBYSxFQUdiLEtBQUssRUFFTCxLQUFLLEdBQ04sTUFBTSxtQkFBbUIsQ0FBQTtBQUMxQixPQUFPLEVBQWMsSUFBSSxFQUFFLEVBQUUsRUFBRSxVQUFVLEVBQUUsTUFBTSxNQUFNLENBQUE7QUFDdkQsT0FBTyxFQUFFLFNBQVMsRUFBRSxHQUFHLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQTtBQUUvQyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sV0FBVyxDQUFBO0FBRXhDLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLFVBQVUsQ0FBQTs7O0FBSzdDLE1BQU0sT0FBTyxhQUFhO0lBQ3hCLFlBQytDLGdCQUFrQyxFQUN4QyxXQUFrQixFQUNiLGVBQWdDLEVBQzdCLGtCQUFzQztRQUh4QyxxQkFBZ0IsR0FBaEIsZ0JBQWdCLENBQWtCO1FBQ3hDLGdCQUFXLEdBQVgsV0FBVyxDQUFPO1FBQ2Isb0JBQWUsR0FBZixlQUFlLENBQWlCO1FBQzdCLHVCQUFrQixHQUFsQixrQkFBa0IsQ0FBb0I7UUEwQi9FLDRCQUF1QixHQUFHLENBQUMsU0FBaUIsRUFBVyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUEsU0FBUyxhQUFULFNBQVMsdUJBQVQsU0FBUyxDQUFFLEtBQUssQ0FBQyxjQUFjLENBQUMsQ0FBQSxDQUFBO1FBNk41Rix5QkFBb0IsR0FBRyxDQUM3QixPQUFpQixFQUNqQixTQUFpQixFQUNxQyxFQUFFLENBQ3hELE9BQU87YUFDSixHQUFHLENBQUMs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YUFDbEIsWUFBWSxhQUNaLGlCQUFpQixhQUNqQixvQkFBb0I7K0dBTG5CLGFBQWEsY0FGWixNQUFNOzRGQUVQLGFBQWE7a0JBSHpCLFVBQVU7bUJBQUM7b0JBQ1YsVUFBVSxFQUFFLE1BQU07aUJBQ25COzswQkFHSSxNQUFNOzJCQUFDLGtCQUFrQjs7MEJBQ3pCLE1BQU07MkJBQUMsWUFBWTs7MEJBQ25CLE1BQU07MkJBQUMsaUJBQWlCOzswQkFDeEIsTUFBTTsyQkFBQyxvQkFBb0IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3QsIEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJ1xuaW1wb3J0IHtcbiAgQ2F0ZWdvcnksXG4gIENhdGVnb3J5UmVwb3NpdG9yeSxcbiAgQ2hlY2tvdXQsXG4gIENoZWNrb3V0U3Vic2NyaXB0aW9uLFxuICBDaGVja291dFR5cGVzLFxuICBDb3Vwb24sXG4gIENvdXBvblJlcG9zaXRvcnksXG4gIENvdXBvblR5cGVzLFxuICBFeGNsdXNpdml0aWVzLFxuICBMaW5lSXRlbSxcbiAgT3JkZXJSZXBvc2l0b3J5LFxuICBTaG9wcyxcbiAgVXNlcixcbiAgV2hlcmUsXG59IGZyb20gJ0BpbmZyYWI0YS9jb25uZWN0J1xuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgZnJvbSwgb2YsIHRocm93RXJyb3IgfSBmcm9tICdyeGpzJ1xuaW1wb3J0IHsgY29uY2F0TWFwLCBtYXAgfSBmcm9tICdyeGpzL29wZXJhdG9ycydcblxuaW1wb3J0IHsgREVGQVVMVF9TSE9QIH0gZnJvbSAnLi4vY29uc3RzJ1xuXG5pbXBvcnQgeyBJbnZhbGlkQ291cG9uRXJyb3IgfSBmcm9tICcuL2Vycm9ycydcblxuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCcsXG59KVxuZXhwb3J0IGNsYXNzIENvdXBvblNlcnZpY2Uge1xuICBjb25zdHJ1Y3RvcihcbiAgICBASW5qZWN0KCdDb3Vwb25SZXBvc2l0b3J5JykgcHJpdmF0ZSByZWFkb25seSBjb3Vwb25SZXBvc2l0b3J5OiBDb3Vwb25SZXBvc2l0b3J5LFxuICAgIEBJbmplY3QoREVGQVVMVF9TSE9QKSBwcml2YXRlIHJlYWRvbmx5IGRlZmF1bHRTaG9wOiBTaG9wcyxcbiAgICBASW5qZWN0KCdPcmRlclJlcG9zaXRvcnknKSBwcml2YXRlIHJlYWRvbmx5IG9yZGVyUmVwb3NpdG9yeTogT3JkZXJSZXBvc2l0b3J5LFxuICAgIEBJbmplY3QoJ0NhdGVnb3J5UmVwb3NpdG9yeScpIHByaXZhdGUgcmVhZG9ubHkgY2F0ZWdvcnlSZXBvc2l0b3J5OiBDYXRlZ29yeVJlcG9zaXRvcnksXG4gICkge31cblxuICBjaGVja0NvdXBvbihcbiAgICBuaWNrbmFtZTogc3RyaW5nLFxuICAgIHVzZXJFbWFpbDogc3RyaW5nLFxuICAgIGNoZWNrb3V0VHlwZTogQ2hlY2tvdXRUeXBlcyxcbiAgICBwbGFuPzogc3RyaW5nLFxuICAgIGNoZWNrb3V0PzogUGFydGlhbDxDaGVja291dD4sXG4gICAgaXNTdWJzY3JpcHRpb24/OiBib29sZWFuLFxuICApOiBPYnNlcnZhYmxlPENvdXBvbj4ge1xuICAgIHJldHVybiBmcm9tKFxuICAgICAgdGhpcy5jb3Vwb25SZXBvc2l0b3J5LmZpbmQoe1xuICAgICAgICBmaWx0ZXJzOiB7XG4gICAgICAgICAgbmlja25hbWU6IHsgb3BlcmF0b3I6IFdoZXJlLkVRVUFMUywgdmFsdWU6IG5pY2tuYW1lIH0sXG4gICAgICAgICAgYWN0aXZlOiB7IG9wZXJhdG9yOiBXaGVyZS5FUVVBTFMsIHZhbHVlOiB0cnVlIH0sXG4gICAgICAgIH0sXG4gICAgICB9KSxcbiAgICApLnBpcGUoXG4gICAgICBjb25jYXRNYXAoKGNvdXBvbnMpID0+IHRoaXMuY2hlY2tDb3Vwb25SdWxlcyhjb3Vwb25zLCBjaGVja291dFR5cGUsIHBsYW4sIGNoZWNrb3V0LCBpc1N1YnNjcmlwdGlvbikpLFxuICAgICAgY29uY2F0TWFwKChjb3Vwb246IENvdXBvbikgPT4gdGhpcy5jaGVja0NvdXBvblVzZUFuZExpbWl0KGNvdXBvbiwgdXNlckVtYWlsLCBjaGVja291dCkpLFxuICAgICAgbWFwKChjb3Vwb246IENvdXBvbikgPT4gdGhpcy5pc1ZhbGlkQ291cG9uKGNvdXBvbiwgdXNlckVtYWlsKSksXG4gICAgICBtYXAoKGNvdXBvbjogQ291cG9uKSA9PiBjb3Vwb24pLFxuICAgIClcbiAgfVxuXG4gIHByaXZhdGUgZW1haWxJc0Zyb21Db2xsYWJvcmF0b3IgPSAodXNlckVtYWlsOiBzdHJpbmcpOiBib29sZWFuID0+ICEhdXNlckVtYWlsPy5tYXRjaCgvQGI0YS5jb20uYnIvZylcblxuICBwcml2YXRlIGNoZWNrQ291cG9uUnVsZXMoXG4gICAgY291cG9ucyxcbiAgICBjaGVja291dFR5cGU6IENoZWNrb3V0VHlwZXMsXG4gICAgcGxhbj86IHN0cmluZyxcbiAgICBjaGVja291dD86IFBhcnRpYWw8Q2hlY2tvdXQ+LFxuICAgIGlzU3Vic2NyaXB0aW9uPzogYm9vbGVhbixcbiAgKSB7XG4gICAgLy8gQ2FzbyBuw6NvIGFjaGUgbmVuaHVtIGN1cG9tLCByZXRvcm5hIGVycm9cbiAgICBpZiAoY291cG9ucy5jb3VudCA8IDEpIHtcbiAgICAgIHJldHVybiB0aHJvd0Vycm9yKCdDdXBvbSBpbnbDoWxpZG8uJylcbiAgICB9XG5cbiAgICAvLyBHZXQgUHJpbWVpcm8gQ3Vwb20gKG8gZmluZCBkbyByZXBvc2l0b3J5IHJldG9ybmEgdW0gYXJyYXkpXG4gICAgY29uc3QgY291cG9uOiBDb3Vwb24gPSBjb3Vwb25zLmRhdGEuc2hpZnQoKVxuICAgIC8vIFZlcmlmaWNhIHNlIG8gY3Vwb20gw6kgYXBsaWNhdmVsIG5hIGxvamFcbiAgICBjb25zdCBpc0luU2hvcCA9IGNvdXBvbi5zaG9wQXZhaWxhYmlsaXR5ID09PSBTaG9wcy5BTEwgfHwgY291cG9uLnNob3BBdmFpbGFiaWxpdHkgPT09IHRoaXMuZGVmYXVsdFNob3BcblxuICAgIC8vIEN1cG9uIG7Do28gYXBsaWNhdmVsIGEgbG9qYSByZXRvcm5hIGVycm9cbiAgICBpZiAoIWlzSW5TaG9wKSByZXR1cm4gdGhyb3dFcnJvcignQ3Vwb20gaW52w6FsaWRvIHBhcmEgbG9qYS4nKVxuXG4gICAgLy8gVmVyaWZpY2Egc2UgbyBjb3Vwb24gw6kgYXBsaWNhZG8gbm8gY2hlY2tvdXQgcXVlIGVzdMOhIHNlbmRvIHJlYWxpemFkb1xuICAgIGNvbnN0IGlzQ2hlY2tvdXRUeXBlID0gY291cG9uLmNoZWNrb3V0VHlwZSA9PT0gQ2hlY2tvdXRUeXBlcy5BTEwgfHwgY291cG9uLmNoZWNrb3V0VHlwZSA9PT0gY2hlY2tvdXRUeXBlXG5cbiAgICAvLyBDdXBvbiBuw6NvIGFwbGljYXZlbCBhbyBjaGVja291dCByZXRvcm5hIGVycm9cbiAgICBpZiAoIWlzQ2hlY2tvdXRUeXBlKSByZXR1cm4gdGhyb3dFcnJvcignQ3Vwb20gaW52w6FsaWRvLiBFcnJvIGRlIGNoZWNrb3V0LicpXG5cbiAgICAvLyBWZXJpZmljYSBzZSBvIGN1cG9tIMOpIG91IHBvZGUgc2VyIGFwbGljYWRvIHBhcmEgc3Vic2NyaXB0aW9uXG4gICAgaWYgKGNoZWNrb3V0VHlwZSA9PT0gQ2hlY2tvdXRUeXBlcy5BTEwgfHwgY2hlY2tvdXRUeXBlID09PSBDaGVja291dFR5cGVzLlNVQlNDUklQVElPTikge1xuICAgICAgLy8gU2UgbyBjdXBvbSB0aXZlciB1bSBwbGFubyBhc3NvY2lhZG8sIHZlcmlmaWNhIHNlIMOpIG8gbWVzbW8gcGxhbm8gZG8gY2hlY2tvdXQgZGEgYXNzaW5hdHVyYVxuICAgICAgaWYgKGNvdXBvbi5wbGFuICYmIGNvdXBvbi5wbGFuLnRvVXBwZXJDYXNlKCkgIT09IHBsYW4udG9VcHBlckNhc2UoKSlcbiAgICAgICAgcmV0dXJuIHRocm93RXJyb3IoJ0N1cG9tIGludsOhbGlkbyBwYXJhIHN1YSBhc3NpbmF0dXJhLicpXG4gICAgfVxuXG4gICAgaWYgKGlzU3Vic2NyaXB0aW9uKSByZXR1cm4gb2YoY291cG9uKVxuXG4gICAgLy8gVmVyaWZpY2Egc2UgcG9zc3VpIG8gdmFsb3IgbWluaW1vIGRlIGNvbXByYSBwYXJhIHV0aWxpemHDp8OjbyBkbyBjdXBvbVxuICAgIGNvbnN0IGhhc01pblN1YlRvdGFsID0gdGhpcy5oYXNNaW5TdWJUb3RhbChjb3Vwb24sIGNoZWNrb3V0KVxuXG4gICAgLy8gU2UgbsOjbyB0ZW0gdmFsb3IgbcOtbmltbyBhdGluZ2lkbywgcmV0b3JuYSBlcnJvXG4gICAgaWYgKCFoYXNNaW5TdWJUb3RhbClcbiAgICAgIHJldHVybiB0aHJvd0Vycm9yKFxuICAgICAgICBgVmFsb3IgbcOtbmltbyBkZSAke0ludGwuTnVtYmVyRm9ybWF0KCdwdC1CUicsIHsgc3R5bGU6ICdjdXJyZW5jeScsIGN1cnJlbmN5OiAnQlJMJyB9KS5mb3JtYXQoXG4gICAgICAgICAgY291cG9uLm1pblN1YlRvdGFsVmFsdWUsXG4gICAgICAgICl9IG7Do28gYXRpbmdpZG9gLFxuICAgICAgKVxuXG4gICAgcmV0dXJuIG9mKGNvdXBvbilcbiAgfVxuXG4gIHByaXZhdGUgaXNWYWxpZENvdXBvbihjb3Vwb246IENvdXBvbiwgdXNlckVtYWlsOiBzdHJpbmcpOiBDb3Vwb24ge1xuICAgIC8vIFZlcmlmaWNhIGEgZGF0YSBkZSBpbmljaW8gZGUgdmFsaWRhZGUgZG8gY3Vwb21cbiAgICBpZiAoY291cG9uPy5iZWdpbkF0ID4gbmV3IERhdGUoKSkgdGhyb3cgbmV3IEludmFsaWRDb3Vwb25FcnJvcignQ3Vwb20gYWluZGEgbsOjbyBsaWJlcmFkby4nKVxuXG4gICAgLy8gVmVyaWZpY2EgYSBkYXRhIGRlIHZhbGlkYWRlIGRvIGN1cG9tXG4gICAgaWYgKGNvdXBvbj8uZXhwaXJlc0luIDwgbmV3IERhdGUoKSkgdGhyb3cgbmV3IEludmFsaWRDb3Vwb25FcnJvcignQ3Vwb20gZXhwaXJhZG8uJylcblxuICAgIHJldHVybiBjb3Vwb25cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgY2hlY2tDb3Vwb25Vc2VBbmRMaW1pdChjb3Vwb246IENvdXBvbiwgdXNlckVtYWlsOiBzdHJpbmcsIGNoZWNrb3V0OiBQYXJ0aWFsPENoZWNrb3V0Pikge1xuICAgIGNvbnN0IG9yZGVycyA9IGF3YWl0IHRoaXMub3JkZXJSZXBvc2l0b3J5LmZpbmQoe1xuICAgICAgZmlsdGVyczoge1xuICAgICAgICBjb3Vwb246IHsgaWQ6IGNvdXBvbi5pZCB9LFxuICAgICAgICBwYXltZW50OiB7IHN0YXR1czogJ3BhaWQnIH0sXG4gICAgICB9LFxuICAgIH0pXG5cbiAgICAvLyBvcmRlcnMgcXVlIHVzdWFyaW8gamEgZmV6IGNvbSBvIGN1cG9tXG4gICAgY29uc3Qgb3JkZXJzVXNlckNvdXBvbiA9IG9yZGVycy5kYXRhLmZpbHRlcigobykgPT4gby51c2VyLmVtYWlsID09IHVzZXJFbWFpbClcblxuICAgIC8vIFZlcmlmaWNhIG8gbGltaXRlIGRlIHVzbyBkZSBjdXBvbSBwb3IgdXN1YXJpb1xuICAgIGlmIChjb3Vwb24udXNlTGltaXRQZXJVc2VyICYmIG9yZGVyc1VzZXJDb3Vwb24ubGVuZ3RoKVxuICAgICAgdGhyb3cgbmV3IEludmFsaWRDb3Vwb25FcnJvcignTGltaXRlIGRlIHVzbyBwb3IgdXN1w6FyaW8gYXRpbmdpZG8uJylcblxuICAgIC8vIFZlcmlmaWNhIG8gbGltaXRlIGRlIHVzbyBnZXJhbCBwb3IgdXN1YXJpb1xuICAgIGlmIChjb3Vwb24udXNlTGltaXQgJiYgb3JkZXJzLmRhdGEubGVuZ3RoID49IGNvdXBvbi51c2VMaW1pdClcbiAgICAgIHRocm93IG5ldyBJbnZhbGlkQ291cG9uRXJyb3IoJ0xpbWl0ZSBkZSB1c28gYXRpbmdpZG8uJylcblxuICAgIGNvbnN0IHZhbGlkVXNlciA9IHRoaXMudXNlclZhbGlkYXRpb25BbmRTdWJzY3JpcHRpb25TdGF0dXMoY291cG9uLCBjaGVja291dD8udXNlcilcbiAgICBpZiAoIXZhbGlkVXNlcikgdGhyb3cgbmV3IEludmFsaWRDb3Vwb25FcnJvcignVXN1w6FyaW8gbsOjbyBlbGVnw612ZWwuJylcblxuICAgIGNvbnN0IGhhc1Byb2R1Y3RDYXRlZ29yaWVzID0gYXdhaXQgdGhpcy5oYXNQcm9kdWN0Q2F0ZWdvcmllcyhjb3Vwb24sIGNoZWNrb3V0KVxuXG4gICAgaWYgKCFoYXNQcm9kdWN0Q2F0ZWdvcmllcykgdGhyb3cgJ1NldSBjYXJyaW5obyBuw6NvIHBvc3N1aSBwcm9kdXRvcyBlbGVnw612ZWlzIHBhcmEgZGVzY29udG8uJ1xuXG4gICAgcmV0dXJuIGNvdXBvblxuICB9XG5cbiAgcHVibGljIGNhbGNEaXNjb3VudFN1YnNjcmlwdGlvbihjb3Vwb246IENvdXBvbiwgY2hlY2tvdXQ6IFBhcnRpYWw8Q2hlY2tvdXRTdWJzY3JpcHRpb24+KTogT2JzZXJ2YWJsZTxudW1iZXI+IHtcbiAgICAvL1xuICAgIGxldCBkaXNjb3VudCA9IDBcblxuICAgIGlmIChjb3Vwb24udHlwZSA9PT0gQ291cG9uVHlwZXMuQUJTT0xVVEUpIGRpc2NvdW50ID0gY291cG9uLmRpc2NvdW50XG4gICAgZWxzZSBpZiAoY291cG9uLnR5cGUgPT09IENvdXBvblR5cGVzLlBFUkNFTlRBR0UpXG4gICAgICBkaXNjb3VudCA9IGNoZWNrb3V0LnN1YnNjcmlwdGlvblBsYW4ucmVjdXJyZW5jZVByaWNlICogKGNvdXBvbi5kaXNjb3VudCAvIDEwMClcblxuICAgIHJldHVybiBvZihkaXNjb3VudClcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBjYWxjRGlzY291bnRTaG9wcGluZyhjb3Vwb246IENvdXBvbiwgY2hlY2tvdXQ6IFBhcnRpYWw8Q2hlY2tvdXQ+KTogUHJvbWlzZTxudW1iZXI+IHtcbiAgICBsZXQgZGlzY291bnQgPSAwXG5cbiAgICBzd2l0Y2ggKGNvdXBvbi50eXBlKSB7XG4gICAgICBjYXNlIENvdXBvblR5cGVzLkFCU09MVVRFOiB7XG4gICAgICAgIGRpc2NvdW50ID0gY291cG9uLmRpc2NvdW50XG4gICAgICAgIGJyZWFrXG4gICAgICB9XG4gICAgICBjYXNlIENvdXBvblR5cGVzLlBFUkNFTlRBR0U6IHtcbiAgICAgICAgZGlzY291bnQgPSBhd2FpdCB0aGlzLmNhbGNTaG9wcGluZ1BlcmNlbnRhZ2VEaXNjb3VudChjb3Vwb24sIGNoZWNrb3V0KVxuICAgICAgICBicmVha1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBkaXNjb3VudFxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBjYWxjU2hvcHBpbmdQZXJjZW50YWdlRGlzY291bnQoY291cG9uOiBDb3Vwb24sIGNoZWNrb3V0OiBQYXJ0aWFsPENoZWNrb3V0Pik6IFByb21pc2U8bnVtYmVyPiB7XG4gICAgbGV0IGRpc2NvdW50ID0gMFxuICAgIGNvbnN0IHNob3AgPSBjaGVja291dC5zaG9wXG4gICAgbGV0IGxpbmVJdGVuc0Rpc2NvdW50ID0gW11cbiAgICBjb25zdCBjb3Vwb25DYXRlZ29yaWVzID0gYXdhaXQgdGhpcy5nZXRDb3Vwb25DYXRlZ29yaWVzSWQoY291cG9uKVxuXG4gICAgaWYgKGNvdXBvbi5wcm9kdWN0c0NhdGVnb3JpZXMgJiYgY291cG9uLnByb2R1Y3RzQ2F0ZWdvcmllcy5sZW5ndGgpIHtcbiAgICAgIGxpbmVJdGVuc0Rpc2NvdW50ID0gY2hlY2tvdXQubGluZUl0ZW1zPy5maWx0ZXIoKGkpID0+IHtcbiAgICAgICAgaWYgKGkuY2F0ZWdvcmllcz8ubGVuZ3RoKSB7XG4gICAgICAgICAgcmV0dXJuIGkuY2F0ZWdvcmllcy5zb21lKChjKSA9PiBjb3Vwb25DYXRlZ29yaWVzLnNvbWUoKGNhdCkgPT4gY2F0LmlkID09IGMgfHwgY2F0LmZpcmVzdG9yZUlkID09IGMpKVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlXG4gICAgICB9KVxuICAgIH0gZWxzZSB7XG4gICAgICBsaW5lSXRlbnNEaXNjb3VudCA9IGNoZWNrb3V0LmxpbmVJdGVtc1xuICAgIH1cblxuICAgIGNvbnN0IHN1YlRvdGFsID1cbiAgICAgIGxpbmVJdGVuc0Rpc2NvdW50LnJlZHVjZShcbiAgICAgICAgKGFjYywgY3VycjogTGluZUl0ZW0pID0+XG4gICAgICAgICAgY2hlY2tvdXQudXNlcj8uaXNTdWJzY3JpYmVyICYmIGN1cnIucHJpY2Vbc2hvcF0/LnN1YnNjcmliZXJQcmljZVxuICAgICAgICAgICAgPyBhY2MgKyBjdXJyLnByaWNlW3Nob3BdPy5zdWJzY3JpYmVyUHJpY2UgKiBjdXJyLnF1YW50aXR5XG4gICAgICAgICAgICA6IGFjYyArIGN1cnIucHJpY2VQYWlkICogY3Vyci5xdWFudGl0eSxcbiAgICAgICAgMCxcbiAgICAgICkgfHwgMFxuXG4gICAgZGlzY291bnQgPSBzdWJUb3RhbCAqIChjb3Vwb24uZGlzY291bnQgLyAxMDApXG5cbiAgICByZXR1cm4gZGlzY291bnRcbiAgfVxuXG4gIHByaXZhdGUgaGFzTWluU3ViVG90YWwoY291cG9uOiBDb3Vwb24sIGNoZWNrb3V0OiBQYXJ0aWFsPENoZWNrb3V0Pik6IGJvb2xlYW4ge1xuICAgIGlmICghY291cG9uLm1pblN1YlRvdGFsVmFsdWUpIHJldHVybiB0cnVlXG5cbiAgICBjb25zdCBzaG9wID0gY2hlY2tvdXQuc2hvcFxuXG4gICAgbGV0IHN1YlRvdGFsID1cbiAgICAgIGNoZWNrb3V0LmxpbmVJdGVtcz8ucmVkdWNlKFxuICAgICAgICAoYWNjLCBjdXJyKSA9PlxuICAgICAgICAgIGNoZWNrb3V0LnVzZXI/LmlzU3Vic2NyaWJlciAmJiBjdXJyLnByaWNlW3Nob3BdPy5zdWJzY3JpYmVyUHJpY2VcbiAgICAgICAgICAgID8gYWNjICsgY3Vyci5wcmljZVtzaG9wXT8uc3Vic2NyaWJlclByaWNlICogY3Vyci5xdWFudGl0eVxuICAgICAgICAgICAgOiBhY2MgKyBjdXJyLnByaWNlUGFpZCAqIGN1cnIucXVhbnRpdHksXG4gICAgICAgIDAsXG4gICAgICApIHx8IDBcblxuICAgIGlmIChjb3Vwb24ubWluU3ViVG90YWxWYWx1ZSA8PSBzdWJUb3RhbCkgcmV0dXJuIHRydWVcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgaGFzUHJvZHVjdENhdGVnb3JpZXMoY291cG9uOiBDb3Vwb24sIGNoZWNrb3V0OiBQYXJ0aWFsPENoZWNrb3V0Pik6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGlmICghY291cG9uLnByb2R1Y3RzQ2F0ZWdvcmllcyB8fCAhY291cG9uLnByb2R1Y3RzQ2F0ZWdvcmllcy5sZW5ndGgpIHtcbiAgICAgIHJldHVybiB0cnVlXG4gICAgfVxuXG4gICAgY29uc3QgY291cG9uQ2F0ZWdvcmllcyA9IGF3YWl0IHRoaXMuZ2V0Q291cG9uQ2F0ZWdvcmllc0lkKGNvdXBvbilcblxuICAgIGNvbnN0IGhhc0NhdGVnb3JpZXMgPSBjaGVja291dC5saW5lSXRlbXM/LmZpbHRlcigoaSkgPT4ge1xuICAgICAgaWYgKCFpLmNhdGVnb3JpZXMgfHwgIWkuY2F0ZWdvcmllcz8ubGVuZ3RoKSByZXR1cm4gdHJ1ZVxuICAgICAgcmV0dXJuIGkuY2F0ZWdvcmllcy5zb21lKChjKSA9PiBjb3Vwb25DYXRlZ29yaWVzLnNvbWUoKGNhdCkgPT4gY2F0LmlkID09IGMgfHwgY2F0LmZpcmVzdG9yZUlkID09IGMpKVxuICAgIH0pXG5cbiAgICByZXR1cm4gaGFzQ2F0ZWdvcmllcy5sZW5ndGggPyB0cnVlIDogZmFsc2VcbiAgfVxuXG4gIHByaXZhdGUgdXNlclZhbGlkYXRpb25BbmRTdWJzY3JpcHRpb25TdGF0dXMoY291cG9uOiBDb3Vwb24sIHVzZXI6IFVzZXIpOiBib29sZWFuIHtcbiAgICBpZiAoY291cG9uLmV4Y2x1c2l2aXR5VHlwZSA9PT0gRXhjbHVzaXZpdGllcy5BTExfVVNFUlMpIHJldHVybiB0cnVlXG4gICAgaWYgKCF1c2VyKSByZXR1cm4gdHJ1ZVxuXG4gICAgLy8gVmVyaWZpY2Egc2UgbyBlbWFpbCBkbyB1c3XDoXJpbyDDqSBjb29ycG9yYXRpdm9cbiAgICBpZiAoIXRoaXMuZW1haWxJc0Zyb21Db2xsYWJvcmF0b3IodXNlci5lbWFpbCkgJiYgY291cG9uLmV4Y2x1c2l2aXR5VHlwZSA9PT0gRXhjbHVzaXZpdGllcy5DT0xMQUJPUkFUT1JTKVxuICAgICAgdGhyb3cgbmV3IEludmFsaWRDb3Vwb25FcnJvcignVm9jw6ogbsOjbyDDqSBjb2xhYm9yYWRvci4nKVxuXG4gICAgLy8gVmVyaWZpY2Egc2UgbyBlbWFpbCBkbyB1c3XDoXJpbyDDqSBhc3NvY2lhZG8gYW8gY3Vwb20gZGUgdXNvIHBvciB1c3VhcmlvXG4gICAgaWYgKGNvdXBvbi5leGNsdXNpdml0eVR5cGUgPT09IEV4Y2x1c2l2aXRpZXMuU1BFQ0lGSUNfVVNFUiAmJiBjb3Vwb24udXNlckV4Y2x1c2l2ZUVtYWlsICE9PSB1c2VyLmVtYWlsKVxuICAgICAgdGhyb3cgbmV3IEludmFsaWRDb3Vwb25FcnJvcignQ3Vwb20gbsOjbyDDqSB2w6FsaWRvIHBhcmEgZXN0ZSB1c3XDoXJpby4nKVxuXG4gICAgc3dpdGNoIChjb3Vwb24uZXhjbHVzaXZpdHlUeXBlKSB7XG4gICAgICBjYXNlIEV4Y2x1c2l2aXRpZXMuQUNUSVZFX1NVQlNDUklCRVI6XG4gICAgICAgIHJldHVybiB1c2VyLmlzU3Vic2NyaWJlciA/IHRydWUgOiBmYWxzZVxuXG4gICAgICBjYXNlIEV4Y2x1c2l2aXRpZXMuSU5BQ1RJVkVfU1VCU0NSSUJFUjpcbiAgICAgICAgcmV0dXJuIHVzZXIuaXNTdWJzY3JpYmVyID8gZmFsc2UgOiB0cnVlXG5cbiAgICAgIGNhc2UgRXhjbHVzaXZpdGllcy5OT05fU1VCU0NSSUJFUjpcbiAgICAgICAgcmV0dXJuIHVzZXIuaXNTdWJzY3JpYmVyID8gZmFsc2UgOiB0cnVlXG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWVcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgZ2V0Q291cG9uQ2F0ZWdvcmllc0lkKGNvdXBvbjogQ291cG9uKSB7XG4gICAgbGV0IGNvdXBvbkNhdGVnb3JpZXM6IHsgaWQ6IHN0cmluZzsgZmlyZXN0b3JlSWQ6IHN0cmluZyB9W10gPSBbXVxuXG4gICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IGNvdXBvbi5wcm9kdWN0c0NhdGVnb3JpZXMubGVuZ3RoOyBpbmRleCsrKSB7XG4gICAgICBsZXQgYzogQ2F0ZWdvcnkgJiB7IGZpcmVzdG9yZUlkPzogc3RyaW5nIH0gPSBhd2FpdCB0aGlzLmNhdGVnb3J5UmVwb3NpdG9yeS5nZXQoe1xuICAgICAgICBpZDogY291cG9uLnByb2R1Y3RzQ2F0ZWdvcmllc1tpbmRleF0sXG4gICAgICB9KVxuICAgICAgY291cG9uQ2F0ZWdvcmllcy5wdXNoKHsgaWQ6IGMuaWQsIGZpcmVzdG9yZUlkOiBjLmZpcmVzdG9yZUlkIH0pXG4gICAgfVxuXG4gICAgcmV0dXJuIGNvdXBvbkNhdGVnb3JpZXNcbiAgfVxuXG4gIHByaXZhdGUgc2VwYXJhdGVWYWxpZENvdXBvbnMgPSAoXG4gICAgY291cG9uczogQ291cG9uW10sXG4gICAgdXNlckVtYWlsOiBzdHJpbmcsXG4gICk6IHsgdmFsaWRzOiBDb3Vwb25bXTsgaW52YWxpZHM6IEludmFsaWRDb3Vwb25FcnJvcltdIH0gPT5cbiAgICBjb3Vwb25zXG4gICAgICAubWFwKChjb3Vwb24pID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBpZiAoIShjb3Vwb24gaW5zdGFuY2VvZiBDb3Vwb24pKSB0aHJvdyBuZXcgSW52YWxpZENvdXBvbkVycm9yKCdDdXBvbSBpbnbDoWxpZG8uJylcbiAgICAgICAgICBpZiAodGhpcy5pc1ZhbGlkQ291cG9uKGNvdXBvbiwgdXNlckVtYWlsKSkgcmV0dXJuIGNvdXBvblxuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgIHJldHVybiBlcnJvciBhcyBJbnZhbGlkQ291cG9uRXJyb3JcbiAgICAgICAgfVxuICAgICAgfSlcbiAgICAgIC5yZWR1Y2UoXG4gICAgICAgIChjdXJyZW50LCBjb3Vwb24pID0+ICh7XG4gICAgICAgICAgLi4uY3VycmVudCxcbiAgICAgICAgICAuLi4oY291cG9uIGluc3RhbmNlb2YgQ291cG9uXG4gICAgICAgICAgICA/IHsgdmFsaWRzOiBbLi4uY3VycmVudC52YWxpZHMsIGNvdXBvbl0gfVxuICAgICAgICAgICAgOiB7IGludmFsaWRzOiBbLi4uY3VycmVudC5pbnZhbGlkcywgY291cG9uXSB9KSxcbiAgICAgICAgfSksXG4gICAgICAgIHtcbiAgICAgICAgICB2YWxpZHM6IFtdIGFzIENvdXBvbltdLFxuICAgICAgICAgIGludmFsaWRzOiBbXSBhcyBJbnZhbGlkQ291cG9uRXJyb3JbXSxcbiAgICAgICAgfSxcbiAgICAgIClcbn1cbiJdfQ==