@infrab4a/connect-angular 5.0.0-beta.97 → 5.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/angular-connect.module.d.ts +8 -14
- package/angular-firestore.module.d.ts +2 -1
- package/angular-hasura-graphql.module.d.ts +6 -4
- package/consts/firebase-const.d.ts +0 -1
- package/consts/index.d.ts +0 -1
- package/esm2020/angular-connect.module.mjs +115 -0
- package/esm2020/angular-elastic-search.module.mjs +34 -0
- package/esm2020/angular-firebase-auth.module.mjs +115 -0
- package/esm2020/angular-firestore.module.mjs +504 -0
- package/esm2020/angular-hasura-graphql.module.mjs +265 -0
- package/{esm2022 → esm2020}/consts/firebase-const.mjs +1 -2
- package/{esm2022 → esm2020}/consts/index.mjs +1 -2
- package/{esm2022 → esm2020}/persistence/cookie-data-persistence.mjs +4 -4
- package/{esm2022 → esm2020}/services/auth.service.mjs +6 -6
- package/esm2020/services/cart.service.mjs +281 -0
- package/{esm2022 → esm2020}/services/catalog/adapters/new-category-structure.adapter.mjs +6 -6
- package/{esm2022 → esm2020}/services/catalog/adapters/old-category-structure.adapter.mjs +6 -6
- package/esm2020/services/catalog/catalog.service.mjs +194 -0
- package/esm2020/services/catalog/category.service.mjs +51 -0
- package/{esm2022 → esm2020}/services/catalog/models/category-with-tree.model.mjs +1 -1
- package/esm2020/services/catalog/wishlist.service.mjs +115 -0
- package/{esm2022 → esm2020}/services/checkout-subscription.service.mjs +6 -6
- package/esm2020/services/checkout.service.mjs +68 -0
- package/esm2020/services/coupon.service.mjs +235 -0
- package/{esm2022 → esm2020}/services/home-shop.service.mjs +9 -9
- package/{esm2022 → esm2020}/services/index.mjs +2 -1
- package/{esm2022 → esm2020}/services/order.service.mjs +6 -6
- package/esm2020/services/shipping.service.mjs +96 -0
- package/esm2020/services/types/shipping-methods.type.mjs +2 -0
- package/fesm2015/infrab4a-connect-angular.mjs +2417 -0
- package/fesm2015/infrab4a-connect-angular.mjs.map +1 -0
- package/{fesm2022 → fesm2020}/infrab4a-connect-angular.mjs +1304 -1555
- package/fesm2020/infrab4a-connect-angular.mjs.map +1 -0
- package/package.json +15 -9
- package/services/cart.service.d.ts +19 -8
- package/services/catalog/catalog.service.d.ts +5 -15
- package/services/catalog/category.service.d.ts +3 -7
- package/services/catalog/wishlist.service.d.ts +4 -16
- package/services/checkout.service.d.ts +6 -16
- package/services/coupon.service.d.ts +2 -0
- package/services/index.d.ts +1 -0
- package/services/shipping.service.d.ts +19 -0
- package/services/types/shipping-methods.type.d.ts +12 -0
- package/angular-vertex-search.module.d.ts +0 -9
- package/consts/vertex-config.const.d.ts +0 -1
- package/esm2022/angular-connect.module.mjs +0 -187
- package/esm2022/angular-elastic-search.module.mjs +0 -34
- package/esm2022/angular-firebase-auth.module.mjs +0 -141
- package/esm2022/angular-firestore.module.mjs +0 -541
- package/esm2022/angular-hasura-graphql.module.mjs +0 -333
- package/esm2022/angular-vertex-search.module.mjs +0 -34
- package/esm2022/consts/vertex-config.const.mjs +0 -2
- package/esm2022/services/cart.service.mjs +0 -86
- package/esm2022/services/catalog/catalog.service.mjs +0 -325
- package/esm2022/services/catalog/category.service.mjs +0 -51
- package/esm2022/services/catalog/wishlist.service.mjs +0 -235
- package/esm2022/services/checkout.service.mjs +0 -122
- package/esm2022/services/coupon.service.mjs +0 -228
- package/fesm2022/infrab4a-connect-angular.mjs.map +0 -1
- /package/{esm2022 → esm2020}/consts/backend-url.const.mjs +0 -0
- /package/{esm2022 → esm2020}/consts/category-structure.mjs +0 -0
- /package/{esm2022 → esm2020}/consts/default-shop.const.mjs +0 -0
- /package/{esm2022 → esm2020}/consts/es-config.const.mjs +0 -0
- /package/{esm2022 → esm2020}/consts/hasura-options.const.mjs +0 -0
- /package/{esm2022 → esm2020}/consts/persistence.const.mjs +0 -0
- /package/{esm2022 → esm2020}/consts/storage-base-url.const.mjs +0 -0
- /package/{esm2022 → esm2020}/helpers/index.mjs +0 -0
- /package/{esm2022 → esm2020}/helpers/mobile-operation-system-checker.helper.mjs +0 -0
- /package/{esm2022 → esm2020}/index.mjs +0 -0
- /package/{esm2022 → esm2020}/infrab4a-connect-angular.mjs +0 -0
- /package/{esm2022 → esm2020}/persistence/data-persistence.mjs +0 -0
- /package/{esm2022 → esm2020}/persistence/index.mjs +0 -0
- /package/{esm2022 → esm2020}/services/catalog/adapters/category-structure.adapter.mjs +0 -0
- /package/{esm2022 → esm2020}/services/catalog/adapters/index.mjs +0 -0
- /package/{esm2022 → esm2020}/services/catalog/enums/index.mjs +0 -0
- /package/{esm2022 → esm2020}/services/catalog/enums/product-sorts.enum.mjs +0 -0
- /package/{esm2022 → esm2020}/services/catalog/index.mjs +0 -0
- /package/{esm2022 → esm2020}/services/catalog/models/index.mjs +0 -0
- /package/{esm2022 → esm2020}/services/catalog/types/index.mjs +0 -0
- /package/{esm2022 → esm2020}/services/catalog/types/product-sort.type.mjs +0 -0
- /package/{esm2022 → esm2020}/services/helpers/index.mjs +0 -0
- /package/{esm2022 → esm2020}/services/helpers/util.helper.mjs +0 -0
- /package/{esm2022 → esm2020}/services/types/index.mjs +0 -0
- /package/{esm2022 → esm2020}/services/types/required-checkout-data.type.mjs +0 -0
- /package/{esm2022 → esm2020}/services/types/required-checkout-subscription-data.type.mjs +0 -0
- /package/{esm2022 → esm2020}/types/firebase-app-config.type.mjs +0 -0
- /package/{esm2022 → esm2020}/types/index.mjs +0 -0
|
@@ -1,228 +0,0 @@
|
|
|
1
|
-
import { Inject, Injectable } from '@angular/core';
|
|
2
|
-
import { CheckoutTypes, CouponTypes, Exclusivities, OrderStatus, Shops, Where, } from '@infrab4a/connect';
|
|
3
|
-
import { from, of } from 'rxjs';
|
|
4
|
-
import { concatMap, map } from 'rxjs/operators';
|
|
5
|
-
import { DEFAULT_SHOP } from '../consts';
|
|
6
|
-
import * as i0 from "@angular/core";
|
|
7
|
-
import * as i1 from "@infrab4a/connect";
|
|
8
|
-
export class CouponService {
|
|
9
|
-
constructor(couponRepository, defaultShop, orderRepository, categoryRepository) {
|
|
10
|
-
this.couponRepository = couponRepository;
|
|
11
|
-
this.defaultShop = defaultShop;
|
|
12
|
-
this.orderRepository = orderRepository;
|
|
13
|
-
this.categoryRepository = categoryRepository;
|
|
14
|
-
this.emailIsFromCollaborator = (userEmail) => !!userEmail?.match(/@b4a.com.br/g);
|
|
15
|
-
}
|
|
16
|
-
checkCoupon(nickname, checkoutType, checkout, plan) {
|
|
17
|
-
return from(this.couponRepository
|
|
18
|
-
.find({
|
|
19
|
-
filters: {
|
|
20
|
-
nickname: { operator: Where.EQUALS, value: nickname },
|
|
21
|
-
active: { operator: Where.EQUALS, value: true },
|
|
22
|
-
},
|
|
23
|
-
})
|
|
24
|
-
.then((result) => result.data[0])).pipe(concatMap((coupon) => this.couponValidation(coupon, checkoutType)), concatMap((couponValid) => this.couponRulesValidation(couponValid, checkoutType, checkout, plan)), map((couponValidated) => couponValidated));
|
|
25
|
-
}
|
|
26
|
-
async couponValidation(coupon, checkoutType) {
|
|
27
|
-
if (!coupon)
|
|
28
|
-
throw 'Cupom inválido.';
|
|
29
|
-
if (coupon?.beginAt && coupon?.beginAt.getTime() > new Date().getTime())
|
|
30
|
-
throw 'Cupom inválido.';
|
|
31
|
-
if (coupon?.expiresIn && (coupon?.expiresIn).getTime() < new Date().getTime())
|
|
32
|
-
throw 'Cupom expirado.';
|
|
33
|
-
const isInShop = coupon.shopAvailability === Shops.ALL || coupon.shopAvailability === this.defaultShop;
|
|
34
|
-
if (!isInShop)
|
|
35
|
-
throw 'Cupom inválido para loja.';
|
|
36
|
-
const isCheckoutType = coupon.checkoutType === CheckoutTypes.ALL || coupon.checkoutType === checkoutType;
|
|
37
|
-
if (!isCheckoutType)
|
|
38
|
-
throw 'Cupom inválido. Erro de checkout.';
|
|
39
|
-
return coupon;
|
|
40
|
-
}
|
|
41
|
-
async couponRulesValidation(coupon, checkoutType, checkout, plan) {
|
|
42
|
-
if (checkoutType == CheckoutTypes.SUBSCRIPTION) {
|
|
43
|
-
if (coupon.plan && coupon.plan.toUpperCase() !== plan.toUpperCase())
|
|
44
|
-
throw 'Cupom inválido para sua assinatura.';
|
|
45
|
-
return coupon;
|
|
46
|
-
}
|
|
47
|
-
const validUser = this.coupomUserValidation(coupon, checkout?.user);
|
|
48
|
-
if (!validUser)
|
|
49
|
-
throw 'Usuário não elegível.';
|
|
50
|
-
const couponUseLimits = this.getCouponUseLimits(coupon, checkoutType, checkout.user);
|
|
51
|
-
if (couponUseLimits.firstOrder) {
|
|
52
|
-
const ordersUser = await this.getOrdersFromUser(checkout.user.email.toLocaleLowerCase());
|
|
53
|
-
if (couponUseLimits.firstOrder && ordersUser.length >= 1)
|
|
54
|
-
throw 'Limite de uso atingido';
|
|
55
|
-
}
|
|
56
|
-
if (!couponUseLimits.unlimited || couponUseLimits.limitedPerUser) {
|
|
57
|
-
const ordersCoupon = await this.getOrdersWithCoupon(coupon);
|
|
58
|
-
if (!couponUseLimits.unlimited && couponUseLimits.total && ordersCoupon.length >= couponUseLimits.total)
|
|
59
|
-
throw 'Limite de uso atingido.';
|
|
60
|
-
if (couponUseLimits.limitedPerUser) {
|
|
61
|
-
const ordersWithUser = this.countOrdersWithUser(ordersCoupon, checkout.user.email);
|
|
62
|
-
if (ordersWithUser > 0)
|
|
63
|
-
throw 'Limite de uso por usuário atingido.';
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
const hasProductCategories = await this.hasProductCategories(coupon, checkout);
|
|
67
|
-
if (!hasProductCategories)
|
|
68
|
-
throw 'Seu carrinho não possui produtos elegíveis para desconto.';
|
|
69
|
-
const hasMinSubTotal = await this.hasMinSubTotal(coupon, checkout);
|
|
70
|
-
if (!hasMinSubTotal) {
|
|
71
|
-
if (coupon.productsCategories?.length) {
|
|
72
|
-
throw `Valor mínimo de ${Intl.NumberFormat('pt-BR', { style: 'currency', currency: 'BRL' }).format(coupon.minSubTotalValue)} não atingido na(s) categoria(s) elegíveis para o desconto.`;
|
|
73
|
-
}
|
|
74
|
-
throw `Valor mínimo de ${Intl.NumberFormat('pt-BR', { style: 'currency', currency: 'BRL' }).format(coupon.minSubTotalValue)} não atingido.`;
|
|
75
|
-
}
|
|
76
|
-
return coupon;
|
|
77
|
-
}
|
|
78
|
-
calcDiscountSubscription(coupon, checkout) {
|
|
79
|
-
let discount = 0;
|
|
80
|
-
if (coupon.discount.subscription.type == CouponTypes.ABSOLUTE)
|
|
81
|
-
discount = coupon.discount.subscription.value;
|
|
82
|
-
else
|
|
83
|
-
discount = checkout.subscriptionPlan.recurrencePrice * (coupon.discount.subscription.value / 100);
|
|
84
|
-
return of(discount);
|
|
85
|
-
}
|
|
86
|
-
async hasMinSubTotal(coupon, checkout) {
|
|
87
|
-
if (!coupon.minSubTotalValue)
|
|
88
|
-
return true;
|
|
89
|
-
const lineItensDiscount = await this.getLineItensEligebleForDiscount(coupon.productsCategories, checkout);
|
|
90
|
-
const subTotal = this.calcCheckoutSubtotal(lineItensDiscount, checkout.user);
|
|
91
|
-
if (coupon.minSubTotalValue <= subTotal)
|
|
92
|
-
return true;
|
|
93
|
-
return false;
|
|
94
|
-
}
|
|
95
|
-
async hasProductCategories(coupon, checkout) {
|
|
96
|
-
if (!coupon.productsCategories || !coupon.productsCategories?.length) {
|
|
97
|
-
return true;
|
|
98
|
-
}
|
|
99
|
-
const couponCategories = await this.getCouponCategoriesId(coupon.productsCategories);
|
|
100
|
-
const hasCategories = checkout.lineItems?.filter((item) => {
|
|
101
|
-
if (item.isGift)
|
|
102
|
-
return false;
|
|
103
|
-
if (!item.categories || !item.categories?.length)
|
|
104
|
-
return true;
|
|
105
|
-
return item.categories.some((c) => couponCategories.some((cat) => cat == c));
|
|
106
|
-
});
|
|
107
|
-
return hasCategories.length ? true : false;
|
|
108
|
-
}
|
|
109
|
-
coupomUserValidation(coupon, user) {
|
|
110
|
-
if (!user || coupon.exclusivityType.includes(Exclusivities.ALL_USERS))
|
|
111
|
-
return true;
|
|
112
|
-
let userTypes = [];
|
|
113
|
-
if (coupon.exclusivityType.includes(Exclusivities.COLLABORATORS) &&
|
|
114
|
-
this.emailIsFromCollaborator(user.email.toLocaleLowerCase()))
|
|
115
|
-
userTypes.push(Exclusivities.COLLABORATORS);
|
|
116
|
-
if (coupon.exclusivityType.includes(Exclusivities.SPECIFIC_USER) &&
|
|
117
|
-
coupon.userExclusiveEmail.includes(user.email.toLocaleLowerCase()))
|
|
118
|
-
userTypes.push(Exclusivities.SPECIFIC_USER);
|
|
119
|
-
if (coupon.exclusivityType.includes(Exclusivities.ACTIVE_SUBSCRIBER) &&
|
|
120
|
-
user.isSubscriber &&
|
|
121
|
-
user.subscriptionPlan != '')
|
|
122
|
-
userTypes.push(Exclusivities.ACTIVE_SUBSCRIBER);
|
|
123
|
-
if (user.isSubscriber &&
|
|
124
|
-
user.subscriptionPlan == '' &&
|
|
125
|
-
coupon.exclusivityType.includes(Exclusivities.INACTIVE_SUBSCRIBER))
|
|
126
|
-
userTypes.push(Exclusivities.INACTIVE_SUBSCRIBER);
|
|
127
|
-
if (coupon.exclusivityType.includes(Exclusivities.NON_SUBSCRIBER) && !user.isSubscriber)
|
|
128
|
-
userTypes.push(Exclusivities.NON_SUBSCRIBER);
|
|
129
|
-
return coupon.exclusivityType.some((r) => userTypes.includes(r));
|
|
130
|
-
}
|
|
131
|
-
async getCouponCategoriesId(productsCategories) {
|
|
132
|
-
const couponCategories = [];
|
|
133
|
-
for (let index = 0; index < productsCategories.length; index++) {
|
|
134
|
-
const category = await this.categoryRepository.get({
|
|
135
|
-
id: productsCategories[index],
|
|
136
|
-
});
|
|
137
|
-
if (category) {
|
|
138
|
-
const children = await this.categoryRepository.getChildren(parseInt(productsCategories[index]));
|
|
139
|
-
couponCategories.push(category.id, ...children.map((c) => c.id.toString()));
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
return [...new Set(couponCategories)];
|
|
143
|
-
}
|
|
144
|
-
async getLineItensEligebleForDiscount(productsCategories, checkout) {
|
|
145
|
-
let lineItensDiscount = [];
|
|
146
|
-
const couponCategories = await this.getCouponCategoriesId(productsCategories);
|
|
147
|
-
if (productsCategories && productsCategories.length) {
|
|
148
|
-
lineItensDiscount = checkout.lineItems?.filter((item) => {
|
|
149
|
-
if (item.isGift)
|
|
150
|
-
return false;
|
|
151
|
-
if (item.categories?.length) {
|
|
152
|
-
return item.categories.some((c) => couponCategories.some((cat) => cat == c));
|
|
153
|
-
}
|
|
154
|
-
return true;
|
|
155
|
-
});
|
|
156
|
-
}
|
|
157
|
-
else {
|
|
158
|
-
lineItensDiscount = checkout.lineItems.filter((item) => !item.isGift);
|
|
159
|
-
}
|
|
160
|
-
return lineItensDiscount;
|
|
161
|
-
}
|
|
162
|
-
calcCheckoutSubtotal(lineItens, user) {
|
|
163
|
-
return (lineItens
|
|
164
|
-
?.filter((item) => !item.isGift)
|
|
165
|
-
.reduce((acc, curr) => user?.isSubscriber && curr.price.subscriberPrice
|
|
166
|
-
? acc + curr.price?.subscriberPrice * curr.quantity
|
|
167
|
-
: acc + curr.pricePaid * curr.quantity, 0) || 0);
|
|
168
|
-
}
|
|
169
|
-
async getOrdersWithCoupon(coupon) {
|
|
170
|
-
return await this.orderRepository
|
|
171
|
-
.find({
|
|
172
|
-
filters: {
|
|
173
|
-
coupon: { id: coupon.id },
|
|
174
|
-
status: { operator: Where.NOTEQUALS, value: OrderStatus.CANCELADO },
|
|
175
|
-
},
|
|
176
|
-
})
|
|
177
|
-
.then((result) => result.data);
|
|
178
|
-
}
|
|
179
|
-
async getOrdersFromUser(email) {
|
|
180
|
-
return await this.orderRepository
|
|
181
|
-
.find({
|
|
182
|
-
filters: {
|
|
183
|
-
user: { email: { operator: Where.EQUALS, value: email } },
|
|
184
|
-
status: { operator: Where.NOTEQUALS, value: OrderStatus.CANCELADO },
|
|
185
|
-
},
|
|
186
|
-
})
|
|
187
|
-
.then((result) => result.data);
|
|
188
|
-
}
|
|
189
|
-
countOrdersWithUser(orders, email) {
|
|
190
|
-
return orders.filter((o) => o.user.email == email).length;
|
|
191
|
-
}
|
|
192
|
-
getCouponUseLimits(coupon, checkoutType, user) {
|
|
193
|
-
let couponUseLimits;
|
|
194
|
-
if (checkoutType == CheckoutTypes.ECOMMERCE || checkoutType == CheckoutTypes.ALL) {
|
|
195
|
-
if (coupon.exclusivityType.length === 1 &&
|
|
196
|
-
(coupon.exclusivityType.at(0) === Exclusivities.SPECIFIC_USER ||
|
|
197
|
-
coupon.exclusivityType.at(0) === Exclusivities.COLLABORATORS))
|
|
198
|
-
couponUseLimits = coupon.useLimits.non_subscriber;
|
|
199
|
-
else
|
|
200
|
-
couponUseLimits = user && user.isSubscriber ? coupon.useLimits.subscriber : coupon.useLimits.non_subscriber;
|
|
201
|
-
}
|
|
202
|
-
else {
|
|
203
|
-
couponUseLimits = coupon.useLimits.subscription;
|
|
204
|
-
}
|
|
205
|
-
return couponUseLimits;
|
|
206
|
-
}
|
|
207
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: CouponService, deps: [{ token: 'CouponRepository' }, { token: DEFAULT_SHOP }, { token: 'OrderRepository' }, { token: 'CategoryRepository' }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
208
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: CouponService, providedIn: 'root' }); }
|
|
209
|
-
}
|
|
210
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: CouponService, decorators: [{
|
|
211
|
-
type: Injectable,
|
|
212
|
-
args: [{
|
|
213
|
-
providedIn: 'root',
|
|
214
|
-
}]
|
|
215
|
-
}], ctorParameters: () => [{ type: undefined, decorators: [{
|
|
216
|
-
type: Inject,
|
|
217
|
-
args: ['CouponRepository']
|
|
218
|
-
}] }, { type: i1.Shops, decorators: [{
|
|
219
|
-
type: Inject,
|
|
220
|
-
args: [DEFAULT_SHOP]
|
|
221
|
-
}] }, { type: undefined, decorators: [{
|
|
222
|
-
type: Inject,
|
|
223
|
-
args: ['OrderRepository']
|
|
224
|
-
}] }, { type: undefined, decorators: [{
|
|
225
|
-
type: Inject,
|
|
226
|
-
args: ['CategoryRepository']
|
|
227
|
-
}] }] });
|
|
228
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY291cG9uLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9jb25uZWN0LWFuZ3VsYXIvc3JjL3NlcnZpY2VzL2NvdXBvbi5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFBO0FBQ2xELE9BQU8sRUFLTCxhQUFhLEVBR2IsV0FBVyxFQUNYLGFBQWEsRUFJYixXQUFXLEVBQ1gsS0FBSyxFQUVMLEtBQUssR0FDTixNQUFNLG1CQUFtQixDQUFBO0FBQzFCLE9BQU8sRUFBRSxJQUFJLEVBQWMsRUFBRSxFQUFFLE1BQU0sTUFBTSxDQUFBO0FBQzNDLE9BQU8sRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLE1BQU0sZ0JBQWdCLENBQUE7QUFDL0MsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLFdBQVcsQ0FBQTs7O0FBS3hDLE1BQU0sT0FBTyxhQUFhO0lBQ3hCLFlBQytDLGdCQUFrQyxFQUN4QyxXQUFrQixFQUNiLGVBQWdDLEVBQzdCLGtCQUFzQztRQUh4QyxxQkFBZ0IsR0FBaEIsZ0JBQWdCLENBQWtCO1FBQ3hDLGdCQUFXLEdBQVgsV0FBVyxDQUFPO1FBQ2Isb0JBQWUsR0FBZixlQUFlLENBQWlCO1FBQzdCLHVCQUFrQixHQUFsQixrQkFBa0IsQ0FBb0I7UUErTC9FLDRCQUF1QixHQUFHLENBQUMsU0FBaUIsRUFBVyxFQUFFLENBQUMsQ0FBQyxDQUFDLFNBQVMsRUFBRSxLQUFLLENBQUMsY0FBYyxDQUFDLENBQUE7SUE5TGpHLENBQUM7SUFFSixXQUFXLENBQ1QsUUFBZ0IsRUFDaEIsWUFBMkIsRUFDM0IsUUFBMkIsRUFDM0IsSUFBWTtRQUVaLE9BQU8sSUFBSSxDQUNULElBQUksQ0FBQyxnQkFBZ0I7YUFDbEIsSUFBSSxDQUFDO1lBQ0osT0FBTyxFQUFFO2dCQUNQLFFBQVEsRUFBRSxFQUFFLFFBQVEsRUFB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QyxlQUFlLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxLQUFLLGFBQWEsQ0FBQyxhQUFhLENBQUM7Z0JBRS9ELGVBQWUsR0FBRyxNQUFNLENBQUMsU0FBUyxDQUFDLGNBQWMsQ0FBQTs7Z0JBQzlDLGVBQWUsR0FBRyxJQUFJLElBQUksSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsY0FBYyxDQUFBO1NBQ2pIO2FBQU07WUFDTCxlQUFlLEdBQUcsTUFBTSxDQUFDLFNBQVMsQ0FBQyxZQUFZLENBQUE7U0FDaEQ7UUFFRCxPQUFPLGVBQWUsQ0FBQTtJQUN4QixDQUFDOzhHQXBSVSxhQUFhLGtCQUVkLGtCQUFrQixhQUNsQixZQUFZLGFBQ1osaUJBQWlCLGFBQ2pCLG9CQUFvQjtrSEFMbkIsYUFBYSxjQUZaLE1BQU07OzJGQUVQLGFBQWE7a0JBSHpCLFVBQVU7bUJBQUM7b0JBQ1YsVUFBVSxFQUFFLE1BQU07aUJBQ25COzswQkFHSSxNQUFNOzJCQUFDLGtCQUFrQjs7MEJBQ3pCLE1BQU07MkJBQUMsWUFBWTs7MEJBQ25CLE1BQU07MkJBQUMsaUJBQWlCOzswQkFDeEIsTUFBTTsyQkFBQyxvQkFBb0IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3QsIEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJ1xuaW1wb3J0IHtcbiAgQ2F0ZWdvcnksXG4gIENhdGVnb3J5UmVwb3NpdG9yeSxcbiAgQ2hlY2tvdXQsXG4gIENoZWNrb3V0U3Vic2NyaXB0aW9uLFxuICBDaGVja291dFR5cGVzLFxuICBDb3Vwb24sXG4gIENvdXBvblJlcG9zaXRvcnksXG4gIENvdXBvblR5cGVzLFxuICBFeGNsdXNpdml0aWVzLFxuICBMaW5lSXRlbSxcbiAgT3JkZXIsXG4gIE9yZGVyUmVwb3NpdG9yeSxcbiAgT3JkZXJTdGF0dXMsXG4gIFNob3BzLFxuICBVc2VyLFxuICBXaGVyZSxcbn0gZnJvbSAnQGluZnJhYjRhL2Nvbm5lY3QnXG5pbXBvcnQgeyBmcm9tLCBPYnNlcnZhYmxlLCBvZiB9IGZyb20gJ3J4anMnXG5pbXBvcnQgeyBjb25jYXRNYXAsIG1hcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJ1xuaW1wb3J0IHsgREVGQVVMVF9TSE9QIH0gZnJvbSAnLi4vY29uc3RzJ1xuXG5ASW5qZWN0YWJsZSh7XG4gIHByb3ZpZGVkSW46ICdyb290Jyxcbn0pXG5leHBvcnQgY2xhc3MgQ291cG9uU2VydmljZSB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIEBJbmplY3QoJ0NvdXBvblJlcG9zaXRvcnknKSBwcml2YXRlIHJlYWRvbmx5IGNvdXBvblJlcG9zaXRvcnk6IENvdXBvblJlcG9zaXRvcnksXG4gICAgQEluamVjdChERUZBVUxUX1NIT1ApIHByaXZhdGUgcmVhZG9ubHkgZGVmYXVsdFNob3A6IFNob3BzLFxuICAgIEBJbmplY3QoJ09yZGVyUmVwb3NpdG9yeScpIHByaXZhdGUgcmVhZG9ubHkgb3JkZXJSZXBvc2l0b3J5OiBPcmRlclJlcG9zaXRvcnksXG4gICAgQEluamVjdCgnQ2F0ZWdvcnlSZXBvc2l0b3J5JykgcHJpdmF0ZSByZWFkb25seSBjYXRlZ29yeVJlcG9zaXRvcnk6IENhdGVnb3J5UmVwb3NpdG9yeSxcbiAgKSB7fVxuXG4gIGNoZWNrQ291cG9uKFxuICAgIG5pY2tuYW1lOiBzdHJpbmcsXG4gICAgY2hlY2tvdXRUeXBlOiBDaGVja291dFR5cGVzLFxuICAgIGNoZWNrb3V0OiBQYXJ0aWFsPENoZWNrb3V0PixcbiAgICBwbGFuOiBzdHJpbmcsXG4gICk6IE9ic2VydmFibGU8Q291cG9uPiB7XG4gICAgcmV0dXJuIGZyb20oXG4gICAgICB0aGlzLmNvdXBvblJlcG9zaXRvcnlcbiAgICAgICAgLmZpbmQoe1xuICAgICAgICAgIGZpbHRlcnM6IHtcbiAgICAgICAgICAgIG5pY2tuYW1lOiB7IG9wZXJhdG9yOiBXaGVyZS5FUVVBTFMsIHZhbHVlOiBuaWNrbmFtZSB9LFxuICAgICAgICAgICAgYWN0aXZlOiB7IG9wZXJhdG9yOiBXaGVyZS5FUVVBTFMsIHZhbHVlOiB0cnVlIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4oKHJlc3VsdCkgPT4gcmVzdWx0LmRhdGFbMF0pLFxuICAgICkucGlwZShcbiAgICAgIGNvbmNhdE1hcCgoY291cG9uKSA9PiB0aGlzLmNvdXBvblZhbGlkYXRpb24oY291cG9uLCBjaGVja291dFR5cGUpKSxcbiAgICAgIGNvbmNhdE1hcCgoY291cG9uVmFsaWQ6IENvdXBvbikgPT4gdGhpcy5jb3Vwb25SdWxlc1ZhbGlkYXRpb24oY291cG9uVmFsaWQsIGNoZWNrb3V0VHlwZSwgY2hlY2tvdXQsIHBsYW4pKSxcbiAgICAgIG1hcCgoY291cG9uVmFsaWRhdGVkOiBDb3Vwb24pID0+IGNvdXBvblZhbGlkYXRlZCBhcyBDb3Vwb24pLFxuICAgIClcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgY291cG9uVmFsaWRhdGlvbihjb3Vwb246IENvdXBvbiwgY2hlY2tvdXRUeXBlOiBDaGVja291dFR5cGVzKSB7XG4gICAgaWYgKCFjb3Vwb24pIHRocm93ICdDdXBvbSBpbnbDoWxpZG8uJ1xuXG4gICAgaWYgKGNvdXBvbj8uYmVnaW5BdCAmJiBjb3Vwb24/LmJlZ2luQXQuZ2V0VGltZSgpID4gbmV3IERhdGUoKS5nZXRUaW1lKCkpIHRocm93ICdDdXBvbSBpbnbDoWxpZG8uJ1xuXG4gICAgaWYgKGNvdXBvbj8uZXhwaXJlc0luICYmIChjb3Vwb24/LmV4cGlyZXNJbiBhcyBEYXRlKS5nZXRUaW1lKCkgPCBuZXcgRGF0ZSgpLmdldFRpbWUoKSkgdGhyb3cgJ0N1cG9tIGV4cGlyYWRvLidcblxuICAgIGNvbnN0IGlzSW5TaG9wID0gY291cG9uLnNob3BBdmFpbGFiaWxpdHkgPT09IFNob3BzLkFMTCB8fCBjb3Vwb24uc2hvcEF2YWlsYWJpbGl0eSA9PT0gdGhpcy5kZWZhdWx0U2hvcFxuXG4gICAgaWYgKCFpc0luU2hvcCkgdGhyb3cgJ0N1cG9tIGludsOhbGlkbyBwYXJhIGxvamEuJ1xuXG4gICAgY29uc3QgaXNDaGVja291dFR5cGUgPSBjb3Vwb24uY2hlY2tvdXRUeXBlID09PSBDaGVja291dFR5cGVzLkFMTCB8fCBjb3Vwb24uY2hlY2tvdXRUeXBlID09PSBjaGVja291dFR5cGVcblxuICAgIGlmICghaXNDaGVja291dFR5cGUpIHRocm93ICdDdXBvbSBpbnbDoWxpZG8uIEVycm8gZGUgY2hlY2tvdXQuJ1xuXG4gICAgcmV0dXJuIGNvdXBvblxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBjb3Vwb25SdWxlc1ZhbGlkYXRpb24oXG4gICAgY291cG9uOiBDb3Vwb24sXG4gICAgY2hlY2tvdXRUeXBlOiBDaGVja291dFR5cGVzLFxuICAgIGNoZWNrb3V0OiBQYXJ0aWFsPENoZWNrb3V0PixcbiAgICBwbGFuOiBzdHJpbmcsXG4gICkge1xuICAgIGlmIChjaGVja291dFR5cGUgPT0gQ2hlY2tvdXRUeXBlcy5TVUJTQ1JJUFRJT04pIHtcbiAgICAgIGlmIChjb3Vwb24ucGxhbiAmJiBjb3Vwb24ucGxhbi50b1VwcGVyQ2FzZSgpICE9PSBwbGFuLnRvVXBwZXJDYXNlKCkpIHRocm93ICdDdXBvbSBpbnbDoWxpZG8gcGFyYSBzdWEgYXNzaW5hdHVyYS4nXG5cbiAgICAgIHJldHVybiBjb3Vwb25cbiAgICB9XG5cbiAgICBjb25zdCB2YWxpZFVzZXIgPSB0aGlzLmNvdXBvbVVzZXJWYWxpZGF0aW9uKGNvdXBvbiwgY2hlY2tvdXQ/LnVzZXIpXG5cbiAgICBpZiAoIXZhbGlkVXNlcikgdGhyb3cgJ1VzdcOhcmlvIG7Do28gZWxlZ8OtdmVsLidcblxuICAgIGNvbnN0IGNvdXBvblVzZUxpbWl0cyA9IHRoaXMuZ2V0Q291cG9uVXNlTGltaXRzKGNvdXBvbiwgY2hlY2tvdXRUeXBlLCBjaGVja291dC51c2VyKVxuXG4gICAgaWYgKGNvdXBvblVzZUxpbWl0cy5maXJzdE9yZGVyKSB7XG4gICAgICBjb25zdCBvcmRlcnNVc2VyID0gYXdhaXQgdGhpcy5nZXRPcmRlcnNGcm9tVXNlcihjaGVja291dC51c2VyLmVtYWlsLnRvTG9jYWxlTG93ZXJDYXNlKCkpXG4gICAgICBpZiAoY291cG9uVXNlTGltaXRzLmZpcnN0T3JkZXIgJiYgb3JkZXJzVXNlci5sZW5ndGggPj0gMSkgdGhyb3cgJ0xpbWl0ZSBkZSB1c28gYXRpbmdpZG8nXG4gICAgfVxuXG4gICAgaWYgKCFjb3Vwb25Vc2VMaW1pdHMudW5saW1pdGVkIHx8IGNvdXBvblVzZUxpbWl0cy5saW1pdGVkUGVyVXNlcikge1xuICAgICAgY29uc3Qgb3JkZXJzQ291cG9uID0gYXdhaXQgdGhpcy5nZXRPcmRlcnNXaXRoQ291cG9uKGNvdXBvbilcblxuICAgICAgaWYgKCFjb3Vwb25Vc2VMaW1pdHMudW5saW1pdGVkICYmIGNvdXBvblVzZUxpbWl0cy50b3RhbCAmJiBvcmRlcnNDb3Vwb24ubGVuZ3RoID49IGNvdXBvblVzZUxpbWl0cy50b3RhbClcbiAgICAgICAgdGhyb3cgJ0xpbWl0ZSBkZSB1c28gYXRpbmdpZG8uJ1xuXG4gICAgICBpZiAoY291cG9uVXNlTGltaXRzLmxpbWl0ZWRQZXJVc2VyKSB7XG4gICAgICAgIGNvbnN0IG9yZGVyc1dpdGhVc2VyID0gdGhpcy5jb3VudE9yZGVyc1dpdGhVc2VyKG9yZGVyc0NvdXBvbiwgY2hlY2tvdXQudXNlci5lbWFpbClcblxuICAgICAgICBpZiAob3JkZXJzV2l0aFVzZXIgPiAwKSB0aHJvdyAnTGltaXRlIGRlIHVzbyBwb3IgdXN1w6FyaW8gYXRpbmdpZG8uJ1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IGhhc1Byb2R1Y3RDYXRlZ29yaWVzID0gYXdhaXQgdGhpcy5oYXNQcm9kdWN0Q2F0ZWdvcmllcyhjb3Vwb24sIGNoZWNrb3V0KVxuXG4gICAgaWYgKCFoYXNQcm9kdWN0Q2F0ZWdvcmllcykgdGhyb3cgJ1NldSBjYXJyaW5obyBuw6NvIHBvc3N1aSBwcm9kdXRvcyBlbGVnw612ZWlzIHBhcmEgZGVzY29udG8uJ1xuXG4gICAgY29uc3QgaGFzTWluU3ViVG90YWwgPSBhd2FpdCB0aGlzLmhhc01pblN1YlRvdGFsKGNvdXBvbiwgY2hlY2tvdXQpXG5cbiAgICBpZiAoIWhhc01pblN1YlRvdGFsKSB7XG4gICAgICBpZiAoY291cG9uLnByb2R1Y3RzQ2F0ZWdvcmllcz8ubGVuZ3RoKSB7XG4gICAgICAgIHRocm93IGBWYWxvciBtw61uaW1vIGRlICR7SW50bC5OdW1iZXJGb3JtYXQoJ3B0LUJSJywgeyBzdHlsZTogJ2N1cnJlbmN5JywgY3VycmVuY3k6ICdCUkwnIH0pLmZvcm1hdChcbiAgICAgICAgICBjb3Vwb24ubWluU3ViVG90YWxWYWx1ZSxcbiAgICAgICAgKX0gbsOjbyBhdGluZ2lkbyBuYShzKSBjYXRlZ29yaWEocykgZWxlZ8OtdmVpcyBwYXJhIG8gZGVzY29udG8uYFxuICAgICAgfVxuXG4gICAgICB0aHJvdyBgVmFsb3IgbcOtbmltbyBkZSAke0ludGwuTnVtYmVyRm9ybWF0KCdwdC1CUicsIHsgc3R5bGU6ICdjdXJyZW5jeScsIGN1cnJlbmN5OiAnQlJMJyB9KS5mb3JtYXQoXG4gICAgICAgIGNvdXBvbi5taW5TdWJUb3RhbFZhbHVlLFxuICAgICAgKX0gbsOjbyBhdGluZ2lkby5gXG4gICAgfVxuXG4gICAgcmV0dXJuIGNvdXBvblxuICB9XG5cbiAgcHVibGljIGNhbGNEaXNjb3VudFN1YnNjcmlwdGlvbihjb3Vwb246IENvdXBvbiwgY2hlY2tvdXQ6IFBhcnRpYWw8Q2hlY2tvdXRTdWJzY3JpcHRpb24+KTogT2JzZXJ2YWJsZTxudW1iZXI+IHtcbiAgICBsZXQgZGlzY291bnQgPSAwXG5cbiAgICBpZiAoY291cG9uLmRpc2NvdW50LnN1YnNjcmlwdGlvbi50eXBlID09IENvdXBvblR5cGVzLkFCU09MVVRFKSBkaXNjb3VudCA9IGNvdXBvbi5kaXNjb3VudC5zdWJzY3JpcHRpb24udmFsdWVcbiAgICBlbHNlIGRpc2NvdW50ID0gY2hlY2tvdXQuc3Vic2NyaXB0aW9uUGxhbi5yZWN1cnJlbmNlUHJpY2UgKiAoY291cG9uLmRpc2NvdW50LnN1YnNjcmlwdGlvbi52YWx1ZSAvIDEwMClcblxuICAgIHJldHVybiBvZihkaXNjb3VudClcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgaGFzTWluU3ViVG90YWwoY291cG9uOiBDb3Vwb24sIGNoZWNrb3V0OiBQYXJ0aWFsPENoZWNrb3V0Pik6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGlmICghY291cG9uLm1pblN1YlRvdGFsVmFsdWUpIHJldHVybiB0cnVlXG5cbiAgICBjb25zdCBsaW5lSXRlbnNEaXNjb3VudCA9IGF3YWl0IHRoaXMuZ2V0TGluZUl0ZW5zRWxpZ2VibGVGb3JEaXNjb3VudChjb3Vwb24ucHJvZHVjdHNDYXRlZ29yaWVzLCBjaGVja291dClcbiAgICBjb25zdCBzdWJUb3RhbCA9IHRoaXMuY2FsY0NoZWNrb3V0U3VidG90YWwobGluZUl0ZW5zRGlzY291bnQsIGNoZWNrb3V0LnVzZXIpXG5cbiAgICBpZiAoY291cG9uLm1pblN1YlRvdGFsVmFsdWUgPD0gc3ViVG90YWwpIHJldHVybiB0cnVlXG5cbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgaGFzUHJvZHVjdENhdGVnb3JpZXMoY291cG9uOiBDb3Vwb24sIGNoZWNrb3V0OiBQYXJ0aWFsPENoZWNrb3V0Pik6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGlmICghY291cG9uLnByb2R1Y3RzQ2F0ZWdvcmllcyB8fCAhY291cG9uLnByb2R1Y3RzQ2F0ZWdvcmllcz8ubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gdHJ1ZVxuICAgIH1cblxuICAgIGNvbnN0IGNvdXBvbkNhdGVnb3JpZXMgPSBhd2FpdCB0aGlzLmdldENvdXBvbkNhdGVnb3JpZXNJZChjb3Vwb24ucHJvZHVjdHNDYXRlZ29yaWVzKVxuICAgIGNvbnN0IGhhc0NhdGVnb3JpZXMgPSBjaGVja291dC5saW5lSXRlbXM/LmZpbHRlcigoaXRlbSkgPT4ge1xuICAgICAgaWYgKGl0ZW0uaXNHaWZ0KSByZXR1cm4gZmFsc2VcbiAgICAgIGlmICghaXRlbS5jYXRlZ29yaWVzIHx8ICFpdGVtLmNhdGVnb3JpZXM/Lmxlbmd0aCkgcmV0dXJuIHRydWVcblxuICAgICAgcmV0dXJuIGl0ZW0uY2F0ZWdvcmllcy5zb21lKChjKSA9PiBjb3Vwb25DYXRlZ29yaWVzLnNvbWUoKGNhdCkgPT4gY2F0ID09IGMpKVxuICAgIH0pXG5cbiAgICByZXR1cm4gaGFzQ2F0ZWdvcmllcy5sZW5ndGggPyB0cnVlIDogZmFsc2VcbiAgfVxuXG4gIHByaXZhdGUgY291cG9tVXNlclZhbGlkYXRpb24oY291cG9uOiBDb3Vwb24sIHVzZXI6IFVzZXIpIHtcbiAgICBpZiAoIXVzZXIgfHwgY291cG9uLmV4Y2x1c2l2aXR5VHlwZS5pbmNsdWRlcyhFeGNsdXNpdml0aWVzLkFMTF9VU0VSUykpIHJldHVybiB0cnVlXG5cbiAgICBsZXQgdXNlclR5cGVzOiBFeGNsdXNpdml0aWVzW10gPSBbXVxuXG4gICAgaWYgKFxuICAgICAgY291cG9uLmV4Y2x1c2l2aXR5VHlwZS5pbmNsdWRlcyhFeGNsdXNpdml0aWVzLkNPTExBQk9SQVRPUlMpICYmXG4gICAgICB0aGlzLmVtYWlsSXNGcm9tQ29sbGFib3JhdG9yKHVzZXIuZW1haWwudG9Mb2NhbGVMb3dlckNhc2UoKSlcbiAgICApXG4gICAgICB1c2VyVHlwZXMucHVzaChFeGNsdXNpdml0aWVzLkNPTExBQk9SQVRPUlMpXG5cbiAgICBpZiAoXG4gICAgICBjb3Vwb24uZXhjbHVzaXZpdHlUeXBlLmluY2x1ZGVzKEV4Y2x1c2l2aXRpZXMuU1BFQ0lGSUNfVVNFUikgJiZcbiAgICAgIGNvdXBvbi51c2VyRXhjbHVzaXZlRW1haWwuaW5jbHVkZXModXNlci5lbWFpbC50b0xvY2FsZUxvd2VyQ2FzZSgpKVxuICAgIClcbiAgICAgIHVzZXJUeXBlcy5wdXNoKEV4Y2x1c2l2aXRpZXMuU1BFQ0lGSUNfVVNFUilcblxuICAgIGlmIChcbiAgICAgIGNvdXBvbi5leGNsdXNpdml0eVR5cGUuaW5jbHVkZXMoRXhjbHVzaXZpdGllcy5BQ1RJVkVfU1VCU0NSSUJFUikgJiZcbiAgICAgIHVzZXIuaXNTdWJzY3JpYmVyICYmXG4gICAgICB1c2VyLnN1YnNjcmlwdGlvblBsYW4gIT0gJydcbiAgICApXG4gICAgICB1c2VyVHlwZXMucHVzaChFeGNsdXNpdml0aWVzLkFDVElWRV9TVUJTQ1JJQkVSKVxuXG4gICAgaWYgKFxuICAgICAgdXNlci5pc1N1YnNjcmliZXIgJiZcbiAgICAgIHVzZXIuc3Vic2NyaXB0aW9uUGxhbiA9PSAnJyAmJlxuICAgICAgY291cG9uLmV4Y2x1c2l2aXR5VHlwZS5pbmNsdWRlcyhFeGNsdXNpdml0aWVzLklOQUNUSVZFX1NVQlNDUklCRVIpXG4gICAgKVxuICAgICAgdXNlclR5cGVzLnB1c2goRXhjbHVzaXZpdGllcy5JTkFDVElWRV9TVUJTQ1JJQkVSKVxuXG4gICAgaWYgKGNvdXBvbi5leGNsdXNpdml0eVR5cGUuaW5jbHVkZXMoRXhjbHVzaXZpdGllcy5OT05fU1VCU0NSSUJFUikgJiYgIXVzZXIuaXNTdWJzY3JpYmVyKVxuICAgICAgdXNlclR5cGVzLnB1c2goRXhjbHVzaXZpdGllcy5OT05fU1VCU0NSSUJFUilcblxuICAgIHJldHVybiBjb3Vwb24uZXhjbHVzaXZpdHlUeXBlLnNvbWUoKHIpID0+IHVzZXJUeXBlcy5pbmNsdWRlcyhyKSlcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgZ2V0Q291cG9uQ2F0ZWdvcmllc0lkKHByb2R1Y3RzQ2F0ZWdvcmllczogc3RyaW5nW10pOiBQcm9taXNlPEFycmF5PFN0cmluZz4+IHtcbiAgICBjb25zdCBjb3Vwb25DYXRlZ29yaWVzOiBBcnJheTxTdHJpbmc+ID0gW11cblxuICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBwcm9kdWN0c0NhdGVnb3JpZXMubGVuZ3RoOyBpbmRleCsrKSB7XG4gICAgICBjb25zdCBjYXRlZ29yeTogQ2F0ZWdvcnkgJiB7IGZpcmVzdG9yZUlkPzogc3RyaW5nIH0gPSBhd2FpdCB0aGlzLmNhdGVnb3J5UmVwb3NpdG9yeS5nZXQoe1xuICAgICAgICBpZDogcHJvZHVjdHNDYXRlZ29yaWVzW2luZGV4XSxcbiAgICAgIH0pXG5cbiAgICAgIGlmIChjYXRlZ29yeSkge1xuICAgICAgICBjb25zdCBjaGlsZHJlbiA9IGF3YWl0IHRoaXMuY2F0ZWdvcnlSZXBvc2l0b3J5LmdldENoaWxkcmVuKHBhcnNlSW50KHByb2R1Y3RzQ2F0ZWdvcmllc1tpbmRleF0pKVxuXG4gICAgICAgIGNvdXBvbkNhdGVnb3JpZXMucHVzaChjYXRlZ29yeS5pZCwgLi4uY2hpbGRyZW4ubWFwKChjKSA9PiBjLmlkLnRvU3RyaW5nKCkpKVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBbLi4ubmV3IFNldChjb3Vwb25DYXRlZ29yaWVzKV1cbiAgfVxuXG4gIHByaXZhdGUgZW1haWxJc0Zyb21Db2xsYWJvcmF0b3IgPSAodXNlckVtYWlsOiBzdHJpbmcpOiBib29sZWFuID0+ICEhdXNlckVtYWlsPy5tYXRjaCgvQGI0YS5jb20uYnIvZylcblxuICBwcml2YXRlIGFzeW5jIGdldExpbmVJdGVuc0VsaWdlYmxlRm9yRGlzY291bnQoXG4gICAgcHJvZHVjdHNDYXRlZ29yaWVzOiBzdHJpbmdbXSxcbiAgICBjaGVja291dDogUGFydGlhbDxDaGVja291dD4sXG4gICk6IFByb21pc2U8TGluZUl0ZW1bXT4ge1xuICAgIGxldCBsaW5lSXRlbnNEaXNjb3VudCA9IFtdXG4gICAgY29uc3QgY291cG9uQ2F0ZWdvcmllcyA9IGF3YWl0IHRoaXMuZ2V0Q291cG9uQ2F0ZWdvcmllc0lkKHByb2R1Y3RzQ2F0ZWdvcmllcylcblxuICAgIGlmIChwcm9kdWN0c0NhdGVnb3JpZXMgJiYgcHJvZHVjdHNDYXRlZ29yaWVzLmxlbmd0aCkge1xuICAgICAgbGluZUl0ZW5zRGlzY291bnQgPSBjaGVja291dC5saW5lSXRlbXM/LmZpbHRlcigoaXRlbSkgPT4ge1xuICAgICAgICBpZiAoaXRlbS5pc0dpZnQpIHJldHVybiBmYWxzZVxuICAgICAgICBpZiAoaXRlbS5jYXRlZ29yaWVzPy5sZW5ndGgpIHtcbiAgICAgICAgICByZXR1cm4gaXRlbS5jYXRlZ29yaWVzLnNvbWUoKGMpID0+IGNvdXBvbkNhdGVnb3JpZXMuc29tZSgoY2F0KSA9PiBjYXQgPT0gYykpXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgfSlcbiAgICB9IGVsc2Uge1xuICAgICAgbGluZUl0ZW5zRGlzY291bnQgPSBjaGVja291dC5saW5lSXRlbXMuZmlsdGVyKChpdGVtKSA9PiAhaXRlbS5pc0dpZnQpXG4gICAgfVxuXG4gICAgcmV0dXJuIGxpbmVJdGVuc0Rpc2NvdW50XG4gIH1cblxuICBwcml2YXRlIGNhbGNDaGVja291dFN1YnRvdGFsKGxpbmVJdGVuczogTGluZUl0ZW1bXSwgdXNlcjogVXNlcik6IG51bWJlciB7XG4gICAgcmV0dXJuIChcbiAgICAgIGxpbmVJdGVuc1xuICAgICAgICA/LmZpbHRlcigoaXRlbSkgPT4gIWl0ZW0uaXNHaWZ0KVxuICAgICAgICAucmVkdWNlKFxuICAgICAgICAgIChhY2MsIGN1cnIpID0+XG4gICAgICAgICAgICB1c2VyPy5pc1N1YnNjcmliZXIgJiYgY3Vyci5wcmljZS5zdWJzY3JpYmVyUHJpY2VcbiAgICAgICAgICAgICAgPyBhY2MgKyBjdXJyLnByaWNlPy5zdWJzY3JpYmVyUHJpY2UgKiBjdXJyLnF1YW50aXR5XG4gICAgICAgICAgICAgIDogYWNjICsgY3Vyci5wcmljZVBhaWQgKiBjdXJyLnF1YW50aXR5LFxuICAgICAgICAgIDAsXG4gICAgICAgICkgfHwgMFxuICAgIClcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgZ2V0T3JkZXJzV2l0aENvdXBvbihjb3Vwb246IENvdXBvbik6IFByb21pc2U8T3JkZXJbXT4ge1xuICAgIHJldHVybiBhd2FpdCB0aGlzLm9yZGVyUmVwb3NpdG9yeVxuICAgICAgLmZpbmQoe1xuICAgICAgICBmaWx0ZXJzOiB7XG4gICAgICAgICAgY291cG9uOiB7IGlkOiBjb3Vwb24uaWQgfSxcbiAgICAgICAgICBzdGF0dXM6IHsgb3BlcmF0b3I6IFdoZXJlLk5PVEVRVUFMUywgdmFsdWU6IE9yZGVyU3RhdHVzLkNBTkNFTEFETyB9LFxuICAgICAgICB9LFxuICAgICAgfSlcbiAgICAgIC50aGVuKChyZXN1bHQpID0+IHJlc3VsdC5kYXRhKVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBnZXRPcmRlcnNGcm9tVXNlcihlbWFpbDogc3RyaW5nKSB7XG4gICAgcmV0dXJuIGF3YWl0IHRoaXMub3JkZXJSZXBvc2l0b3J5XG4gICAgICAuZmluZCh7XG4gICAgICAgIGZpbHRlcnM6IHtcbiAgICAgICAgICB1c2VyOiB7IGVtYWlsOiB7IG9wZXJhdG9yOiBXaGVyZS5FUVVBTFMsIHZhbHVlOiBlbWFpbCB9IH0sXG4gICAgICAgICAgc3RhdHVzOiB7IG9wZXJhdG9yOiBXaGVyZS5OT1RFUVVBTFMsIHZhbHVlOiBPcmRlclN0YXR1cy5DQU5DRUxBRE8gfSxcbiAgICAgICAgfSxcbiAgICAgIH0pXG4gICAgICAudGhlbigocmVzdWx0KSA9PiByZXN1bHQuZGF0YSlcbiAgfVxuXG4gIHByaXZhdGUgY291bnRPcmRlcnNXaXRoVXNlcihvcmRlcnM6IE9yZGVyW10sIGVtYWlsOiBzdHJpbmcpOiBudW1iZXIge1xuICAgIHJldHVybiBvcmRlcnMuZmlsdGVyKChvKSA9PiBvLnVzZXIuZW1haWwgPT0gZW1haWwpLmxlbmd0aFxuICB9XG5cbiAgcHJpdmF0ZSBnZXRDb3Vwb25Vc2VMaW1pdHMoY291cG9uOiBDb3Vwb24sIGNoZWNrb3V0VHlwZTogQ2hlY2tvdXRUeXBlcywgdXNlcjogVXNlcikge1xuICAgIGxldCBjb3Vwb25Vc2VMaW1pdHM6IHsgdW5saW1pdGVkPzogYm9vbGVhbjsgdG90YWw/OiBudW1iZXI7IGxpbWl0ZWRQZXJVc2VyPzogYm9vbGVhbjsgZmlyc3RPcmRlcj86IGJvb2xlYW4gfVxuICAgIGlmIChjaGVja291dFR5cGUgPT0gQ2hlY2tvdXRUeXBlcy5FQ09NTUVSQ0UgfHwgY2hlY2tvdXRUeXBlID09IENoZWNrb3V0VHlwZXMuQUxMKSB7XG4gICAgICBpZiAoXG4gICAgICAgIGNvdXBvbi5leGNsdXNpdml0eVR5cGUubGVuZ3RoID09PSAxICYmXG4gICAgICAgIChjb3Vwb24uZXhjbHVzaXZpdHlUeXBlLmF0KDApID09PSBFeGNsdXNpdml0aWVzLlNQRUNJRklDX1VTRVIgfHxcbiAgICAgICAgICBjb3Vwb24uZXhjbHVzaXZpdHlUeXBlLmF0KDApID09PSBFeGNsdXNpdml0aWVzLkNPTExBQk9SQVRPUlMpXG4gICAgICApXG4gICAgICAgIGNvdXBvblVzZUxpbWl0cyA9IGNvdXBvbi51c2VMaW1pdHMubm9uX3N1YnNjcmliZXJcbiAgICAgIGVsc2UgY291cG9uVXNlTGltaXRzID0gdXNlciAmJiB1c2VyLmlzU3Vic2NyaWJlciA/IGNvdXBvbi51c2VMaW1pdHMuc3Vic2NyaWJlciA6IGNvdXBvbi51c2VMaW1pdHMubm9uX3N1YnNjcmliZXJcbiAgICB9IGVsc2Uge1xuICAgICAgY291cG9uVXNlTGltaXRzID0gY291cG9uLnVzZUxpbWl0cy5zdWJzY3JpcHRpb25cbiAgICB9XG5cbiAgICByZXR1cm4gY291cG9uVXNlTGltaXRzXG4gIH1cbn1cbiJdfQ==
|