@spartacus/order
Version:
Order feature library for Spartacus
85 lines • 29.6 kB
JavaScript
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { isNotUndefined, } from '@spartacus/core';
import { combineLatest } from 'rxjs';
import { filter, map, take, tap } from 'rxjs/operators';
import * as i0 from "@angular/core";
import * as i1 from "@spartacus/core";
import * as i2 from "@spartacus/order/root";
import * as i3 from "@spartacus/storefront";
import * as i4 from "@angular/common";
import * as i5 from "@angular/router";
export class OrderHistoryComponent {
constructor(routing, userOrderService, translation, userReplenishmentOrderService) {
this.routing = routing;
this.userOrderService = userOrderService;
this.translation = translation;
this.userReplenishmentOrderService = userReplenishmentOrderService;
this.PAGE_SIZE = 5;
this.orders$ = this.userOrderService
.getOrderHistoryList(this.PAGE_SIZE)
.pipe(tap((orders) => {
var _a;
if ((_a = orders === null || orders === void 0 ? void 0 : orders.pagination) === null || _a === void 0 ? void 0 : _a.sort) {
this.sortType = orders.pagination.sort;
}
}));
this.hasReplenishmentOrder$ = this.userReplenishmentOrderService
.getReplenishmentOrderDetails()
.pipe(map((order) => order && Object.keys(order).length !== 0));
this.isLoaded$ = this.userOrderService.getOrderHistoryListLoaded();
/**
* When "Order Return" feature is enabled, this component becomes one tab in
* TabParagraphContainerComponent. This can be read from TabParagraphContainer.
*/
this.tabTitleParam$ = this.orders$.pipe(map((order) => { var _a; return (_a = order === null || order === void 0 ? void 0 : order.pagination) === null || _a === void 0 ? void 0 : _a.totalResults; }), filter(isNotUndefined), take(1));
}
ngOnDestroy() {
this.userOrderService.clearOrderList();
}
changeSortCode(sortCode) {
const event = {
sortCode,
currentPage: 0,
};
this.sortType = sortCode;
this.fetchOrders(event);
}
pageChange(page) {
const event = {
sortCode: this.sortType,
currentPage: page,
};
this.fetchOrders(event);
}
goToOrderDetail(order) {
this.routing.go({
cxRoute: 'orderDetails',
params: order,
});
}
getSortLabels() {
return combineLatest([
this.translation.translate('sorting.date'),
this.translation.translate('sorting.orderNumber'),
]).pipe(map(([textByDate, textByOrderNumber]) => {
return {
byDate: textByDate,
byOrderNumber: textByOrderNumber,
};
}));
}
fetchOrders(event) {
this.userOrderService.loadOrderList(this.PAGE_SIZE, event.currentPage, event.sortCode);
}
}
OrderHistoryComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: OrderHistoryComponent, deps: [{ token: i1.RoutingService }, { token: i2.OrderFacade }, { token: i1.TranslationService }, { token: i2.ReplenishmentOrderFacade }], target: i0.ɵɵFactoryTarget.Component });
OrderHistoryComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.0.5", type: OrderHistoryComponent, selector: "cx-order-history", ngImport: i0, template: "<ng-container\n *ngIf=\"{\n orderHistory: orders$ | async,\n replenishmentOrder: hasReplenishmentOrder$ | async\n } as type\"\n>\n <ng-container *ngIf=\"type.orderHistory\">\n <div [ngClass]=\"type.replenishmentOrder ? '' : 'container'\">\n <!-- HEADER -->\n <div\n [ngClass]=\"\n type.replenishmentOrder\n ? 'cx-replenishment-details-order-history-header'\n : 'cx-order-history-header'\n \"\n >\n <h4 *ngIf=\"type.replenishmentOrder\">\n {{ 'orderHistory.replenishmentHistory' | cxTranslate }}\n </h4>\n <h3 *ngIf=\"!type.replenishmentOrder\">\n {{ 'orderHistory.orderHistory' | cxTranslate }}\n </h3>\n </div>\n\n <!-- BODY -->\n <div class=\"cx-order-history-body\">\n <ng-container\n *ngIf=\"type.orderHistory.pagination.totalResults > 0; else noOrder\"\n >\n <!-- Select Form and Pagination Top -->\n <div class=\"cx-order-history-sort top row\">\n <label\n class=\"\n cx-order-history-form-group\n form-group\n col-sm-12 col-md-4 col-lg-4\n \"\n ><span>\n {{ 'orderHistory.sortBy' | cxTranslate }}\n </span>\n <cx-sorting\n [sortOptions]=\"type.orderHistory.sorts\"\n [sortLabels]=\"getSortLabels() | async\"\n (sortListEvent)=\"changeSortCode($event)\"\n [selectedOption]=\"type.orderHistory.pagination.sort\"\n placeholder=\"{{ 'orderHistory.sortBy' | cxTranslate }}\"\n ></cx-sorting>\n </label>\n <div\n *ngIf=\"type.orderHistory.pagination.totalPages > 1\"\n class=\"cx-order-history-pagination\"\n >\n <cx-pagination\n [pagination]=\"type.orderHistory.pagination\"\n (viewPageEvent)=\"pageChange($event)\"\n ></cx-pagination>\n </div>\n </div>\n <!-- TABLE -->\n <table class=\"table cx-order-history-table\">\n <thead class=\"cx-order-history-thead-mobile\">\n <th scope=\"col\">\n {{ 'orderHistory.orderId' | cxTranslate }}\n </th>\n <th scope=\"col\">{{ 'orderHistory.date' | cxTranslate }}</th>\n <th scope=\"col\">\n {{ 'orderHistory.status' | cxTranslate }}\n </th>\n <th scope=\"col\">{{ 'orderHistory.total' | cxTranslate }}</th>\n </thead>\n <tbody>\n <tr\n *ngFor=\"let order of type.orderHistory.orders\"\n (click)=\"goToOrderDetail(order)\"\n >\n <td class=\"cx-order-history-code\">\n <div class=\"d-md-none cx-order-history-label\">\n {{ 'orderHistory.orderId' | cxTranslate }}\n </div>\n <a\n [routerLink]=\"\n {\n cxRoute: 'orderDetails',\n params: order\n } | cxUrl\n \"\n class=\"cx-order-history-value\"\n >\n {{ order?.code }}</a\n >\n </td>\n <td class=\"cx-order-history-placed\">\n <div class=\"d-md-none cx-order-history-label\">\n {{ 'orderHistory.date' | cxTranslate }}\n </div>\n <a\n [routerLink]=\"\n {\n cxRoute: 'orderDetails',\n params: order\n } | cxUrl\n \"\n class=\"cx-order-history-value\"\n >{{ order?.placed | cxDate: 'longDate' }}</a\n >\n </td>\n <td class=\"cx-order-history-status\">\n <div class=\"d-md-none cx-order-history-label\">\n {{ 'orderHistory.status' | cxTranslate }}\n </div>\n <a\n [routerLink]=\"\n {\n cxRoute: 'orderDetails',\n params: order\n } | cxUrl\n \"\n class=\"cx-order-history-value\"\n >\n {{\n 'orderDetails.statusDisplay_' + order?.statusDisplay\n | cxTranslate\n }}</a\n >\n </td>\n <td class=\"cx-order-history-total\">\n <div class=\"d-md-none cx-order-history-label\">\n {{ 'orderHistory.total' | cxTranslate }}\n </div>\n <a\n [routerLink]=\"\n {\n cxRoute: 'orderDetails',\n params: order\n } | cxUrl\n \"\n class=\"cx-order-history-value\"\n >\n {{ order?.total.formattedValue }}</a\n >\n </td>\n </tr>\n </tbody>\n </table>\n <!-- Select Form and Pagination Bottom -->\n <div class=\"cx-order-history-sort bottom row\">\n <div\n *ngIf=\"type.orderHistory.pagination.totalPages > 1\"\n class=\"cx-order-history-pagination\"\n >\n <cx-pagination\n [pagination]=\"type.orderHistory.pagination\"\n (viewPageEvent)=\"pageChange($event)\"\n ></cx-pagination>\n </div>\n </div>\n </ng-container>\n\n <!-- NO ORDER CONTAINER -->\n <ng-template #noOrder>\n <div\n *ngIf=\"isLoaded$ | async\"\n [ngClass]=\"\n type.replenishmentOrder\n ? 'cx-replenishment-details-order-history-no-order row'\n : 'cx-order-history-no-order row'\n \"\n >\n <div\n [ngClass]=\"\n type.replenishmentOrder ? '' : 'col-sm-12 col-md-6 col-lg-4'\n \"\n >\n <ng-container *ngIf=\"type.replenishmentOrder; else otherOrder\">\n <div>{{ 'orderHistory.notFound' | cxTranslate }}</div>\n </ng-container>\n\n <ng-template #otherOrder>\n <div>{{ 'orderHistory.noOrders' | cxTranslate }}</div>\n <a\n [routerLink]=\"{ cxRoute: 'home' } | cxUrl\"\n routerLinkActive=\"active\"\n class=\"btn btn-primary btn-block\"\n >{{ 'orderHistory.startShopping' | cxTranslate }}</a\n >\n </ng-template>\n </div>\n </div>\n </ng-template>\n </div>\n </div>\n </ng-container>\n</ng-container>\n", components: [{ type: i3.SortingComponent, selector: "cx-sorting", inputs: ["sortOptions", "selectedOption", "placeholder", "sortLabels"], outputs: ["sortListEvent"] }, { type: i3.PaginationComponent, selector: "cx-pagination", inputs: ["pageRoute", "queryParam", "defaultPage", "pagination"], outputs: ["viewPageEvent"] }], directives: [{ type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i5.RouterLinkWithHref, selector: "a[routerLink],area[routerLink]", inputs: ["routerLink", "target", "queryParams", "fragment", "queryParamsHandling", "preserveFragment", "skipLocationChange", "replaceUrl", "state", "relativeTo"] }, { type: i5.RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "routerLinkActive"], exportAs: ["routerLinkActive"] }], pipes: { "async": i4.AsyncPipe, "cxTranslate": i1.TranslatePipe, "cxUrl": i1.UrlPipe, "cxDate": i1.CxDatePipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: OrderHistoryComponent, decorators: [{
type: Component,
args: [{
selector: 'cx-order-history',
templateUrl: './order-history.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
}]
}], ctorParameters: function () { return [{ type: i1.RoutingService }, { type: i2.OrderFacade }, { type: i1.TranslationService }, { type: i2.ReplenishmentOrderFacade }]; } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3JkZXItaGlzdG9yeS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9mZWF0dXJlLWxpYnMvb3JkZXIvY29tcG9uZW50cy9vcmRlci1oaXN0b3J5L29yZGVyLWhpc3RvcnkuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vZmVhdHVyZS1saWJzL29yZGVyL2NvbXBvbmVudHMvb3JkZXItaGlzdG9yeS9vcmRlci1oaXN0b3J5LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxTQUFTLEVBQWEsTUFBTSxlQUFlLENBQUM7QUFDOUUsT0FBTyxFQUNMLGNBQWMsR0FLZixNQUFNLGlCQUFpQixDQUFDO0FBRXpCLE9BQU8sRUFBRSxhQUFhLEVBQWMsTUFBTSxNQUFNLENBQUM7QUFDakQsT0FBTyxFQUFFLE1BQU0sRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLEdBQUcsRUFBRSxNQUFNLGdCQUFnQixDQUFDOzs7Ozs7O0FBT3hELE1BQU0sT0FBTyxxQkFBcUI7SUFDaEMsWUFDWSxPQUF1QixFQUN2QixnQkFBNkIsRUFDN0IsV0FBK0IsRUFDL0IsNkJBQXVEO1FBSHZELFlBQU8sR0FBUCxPQUFPLENBQWdCO1FBQ3ZCLHFCQUFnQixHQUFoQixnQkFBZ0IsQ0FBYTtRQUM3QixnQkFBVyxHQUFYLFdBQVcsQ0FBb0I7UUFDL0Isa0NBQTZCLEdBQTdCLDZCQUE2QixDQUEwQjtRQUczRCxjQUFTLEdBQUcsQ0FBQyxDQUFDO1FBR3RCLFlBQU8sR0FBNkMsSUFBSSxDQUFDLGdCQUFnQjthQUN0RSxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDO2FBQ25DLElBQUksQ0FDSCxHQUFHLENBQUMsQ0FBQyxNQUFvQyxFQUFFLEVBQUU7O1lBQzNDLElBQUksTUFBQSxNQUFNLGFBQU4sTUFBTSx1QkFBTixNQUFNLENBQUUsVUFBVSwwQ0FBRSxJQUFJLEVBQUU7Z0JBQzVCLElBQUksQ0FBQyxRQUFRLEdBQUcsTUFBTSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUM7YUFDeEM7UUFDSCxDQUFDLENBQUMsQ0FDSCxDQUFDO1FBRUosMkJBQXNCLEdBQ3BCLElBQUksQ0FBQyw2QkFBNkI7YUFDL0IsNEJBQTRCLEVBQUU7YUFDOUIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsS0FBSyxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsTUFBTSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFcEUsY0FBUyxHQUNQLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyx5QkFBeUIsRUFBRSxDQUFDO1FBRXBEOzs7V0FHRztRQUNILG1CQUFjLEdBQXVCLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUNwRCxHQUFHLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxXQUFDLE9BQUEsTUFBQSxLQUFLLGFBQUwsS0FBSyx1QkFBTCxLQUFLLENBQUUsVUFBVSwwQ0FBRSxZQUFZLENBQUEsRUFBQSxDQUFDLEVBQy9DLE1BQU0sQ0FBQyxjQUFjLENBQUMsRUFDdEIsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUNSLENBQUM7SUEvQkMsQ0FBQztJQWlDSixXQUFXO1FBQ1QsSUFBSSxDQUFDLGdCQUFnQixDQUFDLGNBQWMsRUFBRSxDQUFDO0lBQ3pDLENBQUM7SUFFRCxjQUFjLENBQUMsUUFBZ0I7UUFDN0IsTUFBTSxLQUFLLEdBQThDO1lBQ3ZELFFBQVE7WUFDUixXQUFXLEVBQUUsQ0FBQztTQUNmLENBQUM7UUFDRixJQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQztRQUN6QixJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzFCLENBQUM7SUFFRCxVQUFVLENBQUMsSUFBWTtRQUNyQixNQUFNLEtBQUssR0FBOEM7WUFDdkQsUUFBUSxFQUFFLElBQUksQ0FBQyxRQUFRO1lBQ3ZCLFdBQVcsRUFBRSxJQUFJO1NBQ2xCLENBQUM7UUFDRixJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzFCLENBQUM7SUFFRCxlQUFlLENBQUMsS0FBWTtRQUMxQixJQUFJLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztZQUNkLE9BQU8sRUFBRSxjQUFjO1lBQ3ZCLE1BQU0sRUFBRSxLQUFLO1NBQ2QsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELGFBQWE7UUFDWCxPQUFPLGFBQWEsQ0FBQztZQUNuQixJQUFJLENBQUMsV0FBVyxDQUFDLFNBQVMsQ0FBQyxjQUFjLENBQUM7WUFDMUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxTQUFTLENBQUMscUJBQXFCLENBQUM7U0FDbEQsQ0FBQyxDQUFDLElBQUksQ0FDTCxHQUFHLENBQUMsQ0FBQyxDQUFDLFVBQVUsRUFBRSxpQkFBaUIsQ0FBQyxFQUFFLEVBQUU7WUFDdEMsT0FBTztnQkFDTCxNQUFNLEVBQUUsVUFBVTtnQkFDbEIsYUFBYSxFQUFFLGlCQUFpQjthQUNqQyxDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQ0gsQ0FBQztJQUNKLENBQUM7SUFFTyxXQUFXLENBQUMsS0FBZ0Q7UUFDbEUsSUFBSSxDQUFDLGdCQUFnQixDQUFDLGFBQWEsQ0FDakMsSUFBSSxDQUFDLFNBQVMsRUFDZCxLQUFLLENBQUMsV0FBVyxFQUNqQixLQUFLLENBQUMsUUFBUSxDQUNmLENBQUM7SUFDSixDQUFDOztrSEF2RlUscUJBQXFCO3NHQUFyQixxQkFBcUIsd0RDakJsQyxnaE9BaU1BOzJGRGhMYSxxQkFBcUI7a0JBTGpDLFNBQVM7bUJBQUM7b0JBQ1QsUUFBUSxFQUFFLGtCQUFrQjtvQkFDNUIsV0FBVyxFQUFFLGdDQUFnQztvQkFDN0MsZUFBZSxFQUFFLHVCQUF1QixDQUFDLE1BQU07aUJBQ2hEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENvbXBvbmVudCwgT25EZXN0cm95IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge1xuICBpc05vdFVuZGVmaW5lZCxcbiAgT3JkZXIsXG4gIE9yZGVySGlzdG9yeUxpc3QsXG4gIFJvdXRpbmdTZXJ2aWNlLFxuICBUcmFuc2xhdGlvblNlcnZpY2UsXG59IGZyb20gJ0BzcGFydGFjdXMvY29yZSc7XG5pbXBvcnQgeyBPcmRlckZhY2FkZSwgUmVwbGVuaXNobWVudE9yZGVyRmFjYWRlIH0gZnJvbSAnQHNwYXJ0YWN1cy9vcmRlci9yb290JztcbmltcG9ydCB7IGNvbWJpbmVMYXRlc3QsIE9ic2VydmFibGUgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IGZpbHRlciwgbWFwLCB0YWtlLCB0YXAgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2N4LW9yZGVyLWhpc3RvcnknLFxuICB0ZW1wbGF0ZVVybDogJy4vb3JkZXItaGlzdG9yeS5jb21wb25lbnQuaHRtbCcsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxufSlcbmV4cG9ydCBjbGFzcyBPcmRlckhpc3RvcnlDb21wb25lbnQgaW1wbGVtZW50cyBPbkRlc3Ryb3kge1xuICBjb25zdHJ1Y3RvcihcbiAgICBwcm90ZWN0ZWQgcm91dGluZzogUm91dGluZ1NlcnZpY2UsXG4gICAgcHJvdGVjdGVkIHVzZXJPcmRlclNlcnZpY2U6IE9yZGVyRmFjYWRlLFxuICAgIHByb3RlY3RlZCB0cmFuc2xhdGlvbjogVHJhbnNsYXRpb25TZXJ2aWNlLFxuICAgIHByb3RlY3RlZCB1c2VyUmVwbGVuaXNobWVudE9yZGVyU2VydmljZTogUmVwbGVuaXNobWVudE9yZGVyRmFjYWRlXG4gICkge31cblxuICBwcml2YXRlIFBBR0VfU0laRSA9IDU7XG4gIHNvcnRUeXBlOiBzdHJpbmc7XG5cbiAgb3JkZXJzJDogT2JzZXJ2YWJsZTxPcmRlckhpc3RvcnlMaXN0IHwgdW5kZWZpbmVkPiA9IHRoaXMudXNlck9yZGVyU2VydmljZVxuICAgIC5nZXRPcmRlckhpc3RvcnlMaXN0KHRoaXMuUEFHRV9TSVpFKVxuICAgIC5waXBlKFxuICAgICAgdGFwKChvcmRlcnM6IE9yZGVySGlzdG9yeUxpc3QgfCB1bmRlZmluZWQpID0+IHtcbiAgICAgICAgaWYgKG9yZGVycz8ucGFnaW5hdGlvbj8uc29ydCkge1xuICAgICAgICAgIHRoaXMuc29ydFR5cGUgPSBvcmRlcnMucGFnaW5hdGlvbi5zb3J0O1xuICAgICAgICB9XG4gICAgICB9KVxuICAgICk7XG5cbiAgaGFzUmVwbGVuaXNobWVudE9yZGVyJDogT2JzZXJ2YWJsZTxib29sZWFuPiA9XG4gICAgdGhpcy51c2VyUmVwbGVuaXNobWVudE9yZGVyU2VydmljZVxuICAgICAgLmdldFJlcGxlbmlzaG1lbnRPcmRlckRldGFpbHMoKVxuICAgICAgLnBpcGUobWFwKChvcmRlcikgPT4gb3JkZXIgJiYgT2JqZWN0LmtleXMob3JkZXIpLmxlbmd0aCAhPT0gMCkpO1xuXG4gIGlzTG9hZGVkJDogT2JzZXJ2YWJsZTxib29sZWFuPiA9XG4gICAgdGhpcy51c2VyT3JkZXJTZXJ2aWNlLmdldE9yZGVySGlzdG9yeUxpc3RMb2FkZWQoKTtcblxuICAvKipcbiAgICogV2hlbiBcIk9yZGVyIFJldHVyblwiIGZlYXR1cmUgaXMgZW5hYmxlZCwgdGhpcyBjb21wb25lbnQgYmVjb21lcyBvbmUgdGFiIGluXG4gICAqIFRhYlBhcmFncmFwaENvbnRhaW5lckNvbXBvbmVudC4gVGhpcyBjYW4gYmUgcmVhZCBmcm9tIFRhYlBhcmFncmFwaENvbnRhaW5lci5cbiAgICovXG4gIHRhYlRpdGxlUGFyYW0kOiBPYnNlcnZhYmxlPG51bWJlcj4gPSB0aGlzLm9yZGVycyQucGlwZShcbiAgICBtYXAoKG9yZGVyKSA9PiBvcmRlcj8ucGFnaW5hdGlvbj8udG90YWxSZXN1bHRzKSxcbiAgICBmaWx0ZXIoaXNOb3RVbmRlZmluZWQpLFxuICAgIHRha2UoMSlcbiAgKTtcblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLnVzZXJPcmRlclNlcnZpY2UuY2xlYXJPcmRlckxpc3QoKTtcbiAgfVxuXG4gIGNoYW5nZVNvcnRDb2RlKHNvcnRDb2RlOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBldmVudDogeyBzb3J0Q29kZTogc3RyaW5nOyBjdXJyZW50UGFnZTogbnVtYmVyIH0gPSB7XG4gICAgICBzb3J0Q29kZSxcbiAgICAgIGN1cnJlbnRQYWdlOiAwLFxuICAgIH07XG4gICAgdGhpcy5zb3J0VHlwZSA9IHNvcnRDb2RlO1xuICAgIHRoaXMuZmV0Y2hPcmRlcnMoZXZlbnQpO1xuICB9XG5cbiAgcGFnZUNoYW5nZShwYWdlOiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCBldmVudDogeyBzb3J0Q29kZTogc3RyaW5nOyBjdXJyZW50UGFnZTogbnVtYmVyIH0gPSB7XG4gICAgICBzb3J0Q29kZTogdGhpcy5zb3J0VHlwZSxcbiAgICAgIGN1cnJlbnRQYWdlOiBwYWdlLFxuICAgIH07XG4gICAgdGhpcy5mZXRjaE9yZGVycyhldmVudCk7XG4gIH1cblxuICBnb1RvT3JkZXJEZXRhaWwob3JkZXI6IE9yZGVyKTogdm9pZCB7XG4gICAgdGhpcy5yb3V0aW5nLmdvKHtcbiAgICAgIGN4Um91dGU6ICdvcmRlckRldGFpbHMnLFxuICAgICAgcGFyYW1zOiBvcmRlcixcbiAgICB9KTtcbiAgfVxuXG4gIGdldFNvcnRMYWJlbHMoKTogT2JzZXJ2YWJsZTx7IGJ5RGF0ZTogc3RyaW5nOyBieU9yZGVyTnVtYmVyOiBzdHJpbmcgfT4ge1xuICAgIHJldHVybiBjb21iaW5lTGF0ZXN0KFtcbiAgICAgIHRoaXMudHJhbnNsYXRpb24udHJhbnNsYXRlKCdzb3J0aW5nLmRhdGUnKSxcbiAgICAgIHRoaXMudHJhbnNsYXRpb24udHJhbnNsYXRlKCdzb3J0aW5nLm9yZGVyTnVtYmVyJyksXG4gICAgXSkucGlwZShcbiAgICAgIG1hcCgoW3RleHRCeURhdGUsIHRleHRCeU9yZGVyTnVtYmVyXSkgPT4ge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGJ5RGF0ZTogdGV4dEJ5RGF0ZSxcbiAgICAgICAgICBieU9yZGVyTnVtYmVyOiB0ZXh0QnlPcmRlck51bWJlcixcbiAgICAgICAgfTtcbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgZmV0Y2hPcmRlcnMoZXZlbnQ6IHsgc29ydENvZGU6IHN0cmluZzsgY3VycmVudFBhZ2U6IG51bWJlciB9KTogdm9pZCB7XG4gICAgdGhpcy51c2VyT3JkZXJTZXJ2aWNlLmxvYWRPcmRlckxpc3QoXG4gICAgICB0aGlzLlBBR0VfU0laRSxcbiAgICAgIGV2ZW50LmN1cnJlbnRQYWdlLFxuICAgICAgZXZlbnQuc29ydENvZGVcbiAgICApO1xuICB9XG59XG4iLCI8bmctY29udGFpbmVyXG4gICpuZ0lmPVwie1xuICAgIG9yZGVySGlzdG9yeTogb3JkZXJzJCB8IGFzeW5jLFxuICAgIHJlcGxlbmlzaG1lbnRPcmRlcjogaGFzUmVwbGVuaXNobWVudE9yZGVyJCB8IGFzeW5jXG4gIH0gYXMgdHlwZVwiXG4+XG4gIDxuZy1jb250YWluZXIgKm5nSWY9XCJ0eXBlLm9yZGVySGlzdG9yeVwiPlxuICAgIDxkaXYgW25nQ2xhc3NdPVwidHlwZS5yZXBsZW5pc2htZW50T3JkZXIgPyAnJyA6ICdjb250YWluZXInXCI+XG4gICAgICA8IS0tIEhFQURFUiAtLT5cbiAgICAgIDxkaXZcbiAgICAgICAgW25nQ2xhc3NdPVwiXG4gICAgICAgICAgdHlwZS5yZXBsZW5pc2htZW50T3JkZXJcbiAgICAgICAgICAgID8gJ2N4LXJlcGxlbmlzaG1lbnQtZGV0YWlscy1vcmRlci1oaXN0b3J5LWhlYWRlcidcbiAgICAgICAgICAgIDogJ2N4LW9yZGVyLWhpc3RvcnktaGVhZGVyJ1xuICAgICAgICBcIlxuICAgICAgPlxuICAgICAgICA8aDQgKm5nSWY9XCJ0eXBlLnJlcGxlbmlzaG1lbnRPcmRlclwiPlxuICAgICAgICAgIHt7ICdvcmRlckhpc3RvcnkucmVwbGVuaXNobWVudEhpc3RvcnknIHwgY3hUcmFuc2xhdGUgfX1cbiAgICAgICAgPC9oND5cbiAgICAgICAgPGgzICpuZ0lmPVwiIXR5cGUucmVwbGVuaXNobWVudE9yZGVyXCI+XG4gICAgICAgICAge3sgJ29yZGVySGlzdG9yeS5vcmRlckhpc3RvcnknIHwgY3hUcmFuc2xhdGUgfX1cbiAgICAgICAgPC9oMz5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8IS0tIEJPRFkgLS0+XG4gICAgICA8ZGl2IGNsYXNzPVwiY3gtb3JkZXItaGlzdG9yeS1ib2R5XCI+XG4gICAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgICAqbmdJZj1cInR5cGUub3JkZXJIaXN0b3J5LnBhZ2luYXRpb24udG90YWxSZXN1bHRzID4gMDsgZWxzZSBub09yZGVyXCJcbiAgICAgICAgPlxuICAgICAgICAgIDwhLS0gU2VsZWN0IEZvcm0gYW5kIFBhZ2luYXRpb24gVG9wIC0tPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJjeC1vcmRlci1oaXN0b3J5LXNvcnQgdG9wIHJvd1wiPlxuICAgICAgICAgICAgPGxhYmVsXG4gICAgICAgICAgICAgIGNsYXNzPVwiXG4gICAgICAgICAgICAgICAgY3gtb3JkZXItaGlzdG9yeS1mb3JtLWdyb3VwXG4gICAgICAgICAgICAgICAgZm9ybS1ncm91cFxuICAgICAgICAgICAgICAgIGNvbC1zbS0xMiBjb2wtbWQtNCBjb2wtbGctNFxuICAgICAgICAgICAgICBcIlxuICAgICAgICAgICAgICA+PHNwYW4+XG4gICAgICAgICAgICAgICAge3sgJ29yZGVySGlzdG9yeS5zb3J0QnknIHwgY3hUcmFuc2xhdGUgfX1cbiAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICA8Y3gtc29ydGluZ1xuICAgICAgICAgICAgICAgIFtzb3J0T3B0aW9uc109XCJ0eXBlLm9yZGVySGlzdG9yeS5zb3J0c1wiXG4gICAgICAgICAgICAgICAgW3NvcnRMYWJlbHNdPVwiZ2V0U29ydExhYmVscygpIHwgYXN5bmNcIlxuICAgICAgICAgICAgICAgIChzb3J0TGlzdEV2ZW50KT1cImNoYW5nZVNvcnRDb2RlKCRldmVudClcIlxuICAgICAgICAgICAgICAgIFtzZWxlY3RlZE9wdGlvbl09XCJ0eXBlLm9yZGVySGlzdG9yeS5wYWdpbmF0aW9uLnNvcnRcIlxuICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwie3sgJ29yZGVySGlzdG9yeS5zb3J0QnknIHwgY3hUcmFuc2xhdGUgfX1cIlxuICAgICAgICAgICAgICA+PC9jeC1zb3J0aW5nPlxuICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgKm5nSWY9XCJ0eXBlLm9yZGVySGlzdG9yeS5wYWdpbmF0aW9uLnRvdGFsUGFnZXMgPiAxXCJcbiAgICAgICAgICAgICAgY2xhc3M9XCJjeC1vcmRlci1oaXN0b3J5LXBhZ2luYXRpb25cIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICA8Y3gtcGFnaW5hdGlvblxuICAgICAgICAgICAgICAgIFtwYWdpbmF0aW9uXT1cInR5cGUub3JkZXJIaXN0b3J5LnBhZ2luYXRpb25cIlxuICAgICAgICAgICAgICAgICh2aWV3UGFnZUV2ZW50KT1cInBhZ2VDaGFuZ2UoJGV2ZW50KVwiXG4gICAgICAgICAgICAgID48L2N4LXBhZ2luYXRpb24+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8IS0tIFRBQkxFIC0tPlxuICAgICAgICAgIDx0YWJsZSBjbGFzcz1cInRhYmxlIGN4LW9yZGVyLWhpc3RvcnktdGFibGVcIj5cbiAgICAgICAgICAgIDx0aGVhZCBjbGFzcz1cImN4LW9yZGVyLWhpc3RvcnktdGhlYWQtbW9iaWxlXCI+XG4gICAgICAgICAgICAgIDx0aCBzY29wZT1cImNvbFwiPlxuICAgICAgICAgICAgICAgIHt7ICdvcmRlckhpc3Rvcnkub3JkZXJJZCcgfCBjeFRyYW5zbGF0ZSB9fVxuICAgICAgICAgICAgICA8L3RoPlxuICAgICAgICAgICAgICA8dGggc2NvcGU9XCJjb2xcIj57eyAnb3JkZXJIaXN0b3J5LmRhdGUnIHwgY3hUcmFuc2xhdGUgfX08L3RoPlxuICAgICAgICAgICAgICA8dGggc2NvcGU9XCJjb2xcIj5cbiAgICAgICAgICAgICAgICB7eyAnb3JkZXJIaXN0b3J5LnN0YXR1cycgfCBjeFRyYW5zbGF0ZSB9fVxuICAgICAgICAgICAgICA8L3RoPlxuICAgICAgICAgICAgICA8dGggc2NvcGU9XCJjb2xcIj57eyAnb3JkZXJIaXN0b3J5LnRvdGFsJyB8IGN4VHJhbnNsYXRlIH19PC90aD5cbiAgICAgICAgICAgIDwvdGhlYWQ+XG4gICAgICAgICAgICA8dGJvZHk+XG4gICAgICAgICAgICAgIDx0clxuICAgICAgICAgICAgICAgICpuZ0Zvcj1cImxldCBvcmRlciBvZiB0eXBlLm9yZGVySGlzdG9yeS5vcmRlcnNcIlxuICAgICAgICAgICAgICAgIChjbGljayk9XCJnb1RvT3JkZXJEZXRhaWwob3JkZXIpXCJcbiAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIDx0ZCBjbGFzcz1cImN4LW9yZGVyLWhpc3RvcnktY29kZVwiPlxuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImQtbWQtbm9uZSBjeC1vcmRlci1oaXN0b3J5LWxhYmVsXCI+XG4gICAgICAgICAgICAgICAgICAgIHt7ICdvcmRlckhpc3Rvcnkub3JkZXJJZCcgfCBjeFRyYW5zbGF0ZSB9fVxuICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICA8YVxuICAgICAgICAgICAgICAgICAgICBbcm91dGVyTGlua109XCJcbiAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjeFJvdXRlOiAnb3JkZXJEZXRhaWxzJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtczogb3JkZXJcbiAgICAgICAgICAgICAgICAgICAgICB9IHwgY3hVcmxcbiAgICAgICAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJjeC1vcmRlci1oaXN0b3J5LXZhbHVlXCJcbiAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAge3sgb3JkZXI/LmNvZGUgfX08L2FcbiAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgIDx0ZCBjbGFzcz1cImN4LW9yZGVyLWhpc3RvcnktcGxhY2VkXCI+XG4gICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1tZC1ub25lIGN4LW9yZGVyLWhpc3RvcnktbGFiZWxcIj5cbiAgICAgICAgICAgICAgICAgICAge3sgJ29yZGVySGlzdG9yeS5kYXRlJyB8IGN4VHJhbnNsYXRlIH19XG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgIDxhXG4gICAgICAgICAgICAgICAgICAgIFtyb3V0ZXJMaW5rXT1cIlxuICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGN4Um91dGU6ICdvcmRlckRldGFpbHMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgcGFyYW1zOiBvcmRlclxuICAgICAgICAgICAgICAgICAgICAgIH0gfCBjeFVybFxuICAgICAgICAgICAgICAgICAgICBcIlxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImN4LW9yZGVyLWhpc3RvcnktdmFsdWVcIlxuICAgICAgICAgICAgICAgICAgICA+e3sgb3JkZXI/LnBsYWNlZCB8IGN4RGF0ZTogJ2xvbmdEYXRlJyB9fTwvYVxuICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgICAgPHRkIGNsYXNzPVwiY3gtb3JkZXItaGlzdG9yeS1zdGF0dXNcIj5cbiAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLW1kLW5vbmUgY3gtb3JkZXItaGlzdG9yeS1sYWJlbFwiPlxuICAgICAgICAgICAgICAgICAgICB7eyAnb3JkZXJIaXN0b3J5LnN0YXR1cycgfCBjeFRyYW5zbGF0ZSB9fVxuICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICA8YVxuICAgICAgICAgICAgICAgICAgICBbcm91dGVyTGlua109XCJcbiAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjeFJvdXRlOiAnb3JkZXJEZXRhaWxzJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtczogb3JkZXJcbiAgICAgICAgICAgICAgICAgICAgICB9IHwgY3hVcmxcbiAgICAgICAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJjeC1vcmRlci1oaXN0b3J5LXZhbHVlXCJcbiAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAge3tcbiAgICAgICAgICAgICAgICAgICAgICAnb3JkZXJEZXRhaWxzLnN0YXR1c0Rpc3BsYXlfJyArIG9yZGVyPy5zdGF0dXNEaXNwbGF5XG4gICAgICAgICAgICAgICAgICAgICAgICB8IGN4VHJhbnNsYXRlXG4gICAgICAgICAgICAgICAgICAgIH19PC9hXG4gICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICA8dGQgY2xhc3M9XCJjeC1vcmRlci1oaXN0b3J5LXRvdGFsXCI+XG4gICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1tZC1ub25lIGN4LW9yZGVyLWhpc3RvcnktbGFiZWxcIj5cbiAgICAgICAgICAgICAgICAgICAge3sgJ29yZGVySGlzdG9yeS50b3RhbCcgfCBjeFRyYW5zbGF0ZSB9fVxuICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICA8YVxuICAgICAgICAgICAgICAgICAgICBbcm91dGVyTGlua109XCJcbiAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjeFJvdXRlOiAnb3JkZXJEZXRhaWxzJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtczogb3JkZXJcbiAgICAgICAgICAgICAgICAgICAgICB9IHwgY3hVcmxcbiAgICAgICAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJjeC1vcmRlci1oaXN0b3J5LXZhbHVlXCJcbiAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAge3sgb3JkZXI/LnRvdGFsLmZvcm1hdHRlZFZhbHVlIH19PC9hXG4gICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgPC90cj5cbiAgICAgICAgICAgIDwvdGJvZHk+XG4gICAgICAgICAgPC90YWJsZT5cbiAgICAgICAgICA8IS0tIFNlbGVjdCBGb3JtIGFuZCBQYWdpbmF0aW9uIEJvdHRvbSAtLT5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiY3gtb3JkZXItaGlzdG9yeS1zb3J0IGJvdHRvbSByb3dcIj5cbiAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgKm5nSWY9XCJ0eXBlLm9yZGVySGlzdG9yeS5wYWdpbmF0aW9uLnRvdGFsUGFnZXMgPiAxXCJcbiAgICAgICAgICAgICAgY2xhc3M9XCJjeC1vcmRlci1oaXN0b3J5LXBhZ2luYXRpb25cIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICA8Y3gtcGFnaW5hdGlvblxuICAgICAgICAgICAgICAgIFtwYWdpbmF0aW9uXT1cInR5cGUub3JkZXJIaXN0b3J5LnBhZ2luYXRpb25cIlxuICAgICAgICAgICAgICAgICh2aWV3UGFnZUV2ZW50KT1cInBhZ2VDaGFuZ2UoJGV2ZW50KVwiXG4gICAgICAgICAgICAgID48L2N4LXBhZ2luYXRpb24+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgPCEtLSBOTyBPUkRFUiBDT05UQUlORVIgLS0+XG4gICAgICAgIDxuZy10ZW1wbGF0ZSAjbm9PcmRlcj5cbiAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAqbmdJZj1cImlzTG9hZGVkJCB8IGFzeW5jXCJcbiAgICAgICAgICAgIFtuZ0NsYXNzXT1cIlxuICAgICAgICAgICAgICB0eXBlLnJlcGxlbmlzaG1lbnRPcmRlclxuICAgICAgICAgICAgICAgID8gJ2N4LXJlcGxlbmlzaG1lbnQtZGV0YWlscy1vcmRlci1oaXN0b3J5LW5vLW9yZGVyIHJvdydcbiAgICAgICAgICAgICAgICA6ICdjeC1vcmRlci1oaXN0b3J5LW5vLW9yZGVyIHJvdydcbiAgICAgICAgICAgIFwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICBbbmdDbGFzc109XCJcbiAgICAgICAgICAgICAgICB0eXBlLnJlcGxlbmlzaG1lbnRPcmRlciA/ICcnIDogJ2NvbC1zbS0xMiBjb2wtbWQtNiBjb2wtbGctNCdcbiAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInR5cGUucmVwbGVuaXNobWVudE9yZGVyOyBlbHNlIG90aGVyT3JkZXJcIj5cbiAgICAgICAgICAgICAgICA8ZGl2Pnt7ICdvcmRlckhpc3Rvcnkubm90Rm91bmQnIHwgY3hUcmFuc2xhdGUgfX08L2Rpdj5cbiAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNvdGhlck9yZGVyPlxuICAgICAgICAgICAgICAgIDxkaXY+e3sgJ29yZGVySGlzdG9yeS5ub09yZGVycycgfCBjeFRyYW5zbGF0ZSB9fTwvZGl2PlxuICAgICAgICAgICAgICAgIDxhXG4gICAgICAgICAgICAgICAgICBbcm91dGVyTGlua109XCJ7IGN4Um91dGU6ICdob21lJyB9IHwgY3hVcmxcIlxuICAgICAgICAgICAgICAgICAgcm91dGVyTGlua0FjdGl2ZT1cImFjdGl2ZVwiXG4gICAgICAgICAgICAgICAgICBjbGFzcz1cImJ0biBidG4tcHJpbWFyeSBidG4tYmxvY2tcIlxuICAgICAgICAgICAgICAgICAgPnt7ICdvcmRlckhpc3Rvcnkuc3RhcnRTaG9wcGluZycgfCBjeFRyYW5zbGF0ZSB9fTwvYVxuICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gIDwvbmctY29udGFpbmVyPlxuPC9uZy1jb250YWluZXI+XG4iXX0=