UNPKG

@nackamoto/medusa-paypal-payment

Version:
279 lines 23.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const utils_1 = require("@medusajs/framework/utils"); const utils_2 = require("@medusajs/utils"); const paypal_server_sdk_1 = require("@paypal/paypal-server-sdk"); const formatters_1 = require("./formatters"); class PaypalPaymentProviderService extends utils_1.AbstractPaymentProvider { constructor(container, options) { super(container, options); this.logger_ = container.logger; this.options_ = options; this.eventBusService_ = container.event_bus; if (this.options_.oAuthClientId && this.options_.oAuthClientSecret && this.options_.environment) { this.paypal_ = new paypal_server_sdk_1.Client({ clientCredentialsAuthCredentials: { oAuthClientId: this.options_.oAuthClientId, oAuthClientSecret: this.options_.oAuthClientSecret, }, timeout: 0, environment: this.options_.environment === "sandbox" ? paypal_server_sdk_1.Environment.Sandbox : paypal_server_sdk_1.Environment.Production, logging: { logLevel: paypal_server_sdk_1.LogLevel.Info, logRequest: { logBody: true, }, logResponse: { logHeaders: true, }, }, }); } else { throw new utils_2.MedusaError(utils_2.MedusaError.Types.INVALID_DATA, "oAuthClientId, oAuthClientSecret and environment are required in the provider's options."); } } static validateOptions(options) { if (!options.oAuthClientId) { throw new utils_2.MedusaError(utils_2.MedusaError.Types.INVALID_DATA, "oAuthClientId is required in the provider's options."); } if (!options.oAuthClientSecret) { throw new utils_2.MedusaError(utils_2.MedusaError.Types.INVALID_DATA, "oAuthClientSecret is required in the provider's options."); } if (options.environment !== "production" && options.environment !== "sandbox") { throw new utils_2.MedusaError(utils_2.MedusaError.Types.INVALID_DATA, "environment needs to be either production or sandbox"); } } async capturePayment(paymentData) { const paypalOrder = paymentData.data.paypalOrder; if (paypalOrder.purchaseUnits?.length && paypalOrder.purchaseUnits[0].payments && paypalOrder.purchaseUnits[0].payments.authorizations?.length) { const id = paypalOrder.purchaseUnits[0].payments.authorizations[0] .id; try { const paymentsController = new paypal_server_sdk_1.PaymentsController(this.paypal_); await paymentsController.captureAuthorizedPayment({ authorizationId: id, }); return await this.retrievePayment(paymentData); } catch (error) { this.logger_.error(error); throw new Error("An error occurred in capturePayment"); } } throw new Error("An error occurred in capturePayment"); } async authorizePayment(paymentData) { try { const status = (await this.getPaymentStatus(paymentData)).status; const retrievedPayment = await this.retrievePayment(paymentData); return { data: { ...paymentData, paypalOrder: retrievedPayment.data.paypalOrder, paypalOrderId: retrievedPayment.data.paypalOrder .id, }, status: status, }; } catch (error) { throw new Error("Authorize payment failed"); } } async cancelPayment(paymentData) { const paypalOrder = paymentData.data.paypalOrder; if (paypalOrder.purchaseUnits?.length && paypalOrder.purchaseUnits[0].payments) { const isAlreadyCanceled = paypalOrder.status === paypal_server_sdk_1.OrderStatus.Voided; const isCanceledAndFullyRefund = paypalOrder.status === paypal_server_sdk_1.OrderStatus.Completed && !!paypalOrder.purchaseUnits[0].invoiceId; if (isAlreadyCanceled || isCanceledAndFullyRefund) { return await this.retrievePayment(paymentData); } const paymentsController = new paypal_server_sdk_1.PaymentsController(this.paypal_); try { const isAlreadyCaptured = paypalOrder.purchaseUnits.some((pu) => pu.payments?.captures?.length); if (isAlreadyCaptured) { const payments = paypalOrder.purchaseUnits[0].payments; const capturesId = payments.captures[0].id; await paymentsController.refundCapturedPayment({ captureId: capturesId, }); } else { const id = paypalOrder.purchaseUnits[0].payments.authorizations[0] .id; await paymentsController.voidPayment({ authorizationId: id, }); } return await this.retrievePayment(paymentData); } catch (error) { throw new Error("An error occurred in cancelPayment"); } } throw new Error("An error occurred in cancelPayment"); } async initiatePayment(paymentData) { const ordersController = new paypal_server_sdk_1.OrdersController(this.paypal_); const { currency_code, amount } = paymentData; try { const { result, ...httpResponse } = await ordersController.createOrder({ body: { intent: paypal_server_sdk_1.CheckoutPaymentIntent.Authorize, purchaseUnits: [ { amount: (0, formatters_1.convertAmount)(amount, currency_code), }, ], }, }); if (result.id) { return { id: result.id, data: { ...paymentData, paypalOrderId: result.id, paypalOrder: result, }, }; } } catch (error) { if (error instanceof paypal_server_sdk_1.ApiError) { const { statusCode, headers } = error; this.logger_.error(`Status code ${statusCode.toString()}`); this.logger_.error(JSON.stringify(headers)); } } throw new Error("Initialize payment failed"); } async deletePayment(paymentSessionData) { return paymentSessionData; } async getPaymentStatus(paymentData) { const retrievedPayment = await this.retrievePayment(paymentData); const paypalOrder = retrievedPayment.data.paypalOrder; switch (paypalOrder.status) { case paypal_server_sdk_1.OrderStatus.Created: return { status: "pending", }; case paypal_server_sdk_1.OrderStatus.Saved: case paypal_server_sdk_1.OrderStatus.Approved: case paypal_server_sdk_1.OrderStatus.PayerActionRequired: return { status: "requires_more", }; case paypal_server_sdk_1.OrderStatus.Voided: return { status: "canceled", }; case paypal_server_sdk_1.OrderStatus.Completed: return { status: "authorized", }; default: return { status: "pending", }; } } async refundPayment(paymentData) { const paypalOrder = paymentData.data.paypalOrder; if (paypalOrder.purchaseUnits?.length && paypalOrder.purchaseUnits[0].payments) { const purchaseUnit = paypalOrder.purchaseUnits[0]; const isAlreadyCaptured = paypalOrder.purchaseUnits.some((pu) => pu.payments?.captures?.length); if (!isAlreadyCaptured) { throw new Error("Cannot refund an uncaptured payment"); } const paymentId = purchaseUnit.payments?.captures[0].id; const currencyCode = purchaseUnit.amount?.currencyCode; const amount = paymentData.amount; const paymentsController = new paypal_server_sdk_1.PaymentsController(this.paypal_); try { await paymentsController.refundCapturedPayment({ captureId: paymentId, body: { amount: (0, formatters_1.convertAmount)(amount, currencyCode), }, }); return await this.retrievePayment(paymentData); } catch (error) { this.logger_.error(error); throw new Error("An error occurred in refundPayment"); } } throw new Error("An error occurred in refundPayment"); } async retrievePayment(paymentSessionData) { const ordersController = new paypal_server_sdk_1.OrdersController(this.paypal_); try { const paypalOrderId = paymentSessionData.data.paypalOrder.id; const { result, ...httpResponse } = await ordersController.getOrder({ id: paypalOrderId, }); if (result.id) { return { data: { ...paymentSessionData, paypalOrderId: result.id, paypalOrder: result, }, }; } } catch (error) { if (error instanceof paypal_server_sdk_1.ApiError) { const { statusCode, headers } = error; this.logger_.error(`Status code ${statusCode.toString()}`); this.logger_.error(JSON.stringify(headers)); throw new Error("Initialize payment failed"); } } throw new Error("Initialize payment failed."); } async updatePayment(context) { const ordersController = new paypal_server_sdk_1.OrdersController(this.paypal_); const { amount, currency_code } = context; try { const paypalOrderId = context.data.paypalOrder .id; await ordersController.patchOrder({ id: paypalOrderId, body: [ { op: paypal_server_sdk_1.PatchOp.Replace, value: { amount: (0, formatters_1.convertAmount)(amount, currency_code), }, }, ], }); return await this.retrievePayment(context); } catch (error) { this.logger_.error(error); throw new Error("An error occurred in updatePayment"); } } async getWebhookActionAndData(data) { return { action: utils_1.PaymentActions.NOT_SUPPORTED, }; } } PaypalPaymentProviderService.identifier = "paypal-payment"; exports.default = PaypalPaymentProviderService; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9wcm92aWRlcnMvcGF5cGFsLXBheW1lbnQvc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLHFEQUdtQztBQTBCbkMsMkNBQTZFO0FBQzdFLGlFQVltQztBQUNuQyw2Q0FBNkM7QUFhN0MsTUFBTSw0QkFBNkIsU0FBUSwrQkFBZ0M7SUFPekUsWUFBWSxTQUErQixFQUFFLE9BQWdCO1FBQzNELEtBQUssQ0FBQyxTQUFTLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFFMUIsSUFBSSxDQUFDLE9BQU8sR0FBRyxTQUFTLENBQUMsTUFBTSxDQUFDO1FBQ2hDLElBQUksQ0FBQyxRQUFRLEdBQUcsT0FBTyxDQUFDO1FBQ3hCLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxTQUFTLENBQUMsU0FBUyxDQUFDO1FBRTVDLElBQ0UsSUFBSSxDQUFDLFFBQVEsQ0FBQyxhQUFhO1lBQzNCLElBQUksQ0FBQyxRQUFRLENBQUMsaUJBQWlCO1lBQy9CLElBQUksQ0FBQyxRQUFRLENBQUMsV0FBVyxFQUN6QixDQUFDO1lBQ0QsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLDBCQUFZLENBQUM7Z0JBQzlCLGdDQUFnQyxFQUFFO29CQUNoQyxhQUFhLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxhQUFhO29CQUMxQyxpQkFBaUIsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLGlCQUFpQjtpQkFDbkQ7Z0JBQ0QsT0FBTyxFQUFFLENBQUM7Z0JBQ1YsV0FBVyxFQUNULElBQUksQ0FBQyxRQUFRLENBQUMsV0FBVyxLQUFLLFNBQVM7b0JBQ3JDLENBQUMsQ0FBQywrQkFBVyxDQUFDLE9BQU87b0JBQ3JCLENBQUMsQ0FBQywrQkFBVyxDQUFDLFVBQVU7Z0JBQzVCLE9BQU8sRUFBRTtvQkFDUCxRQUFRLEVBQUUsNEJBQVEsQ0FBQyxJQUFJO29CQUN2QixVQUFVLEVBQUU7d0JBQ1YsT0FBTyxFQUFFLElBQUk7cUJBQ2Q7b0JBQ0QsV0FBVyxFQUFFO3dCQUNYLFVBQVUsRUFBRSxJQUFJO3FCQUNqQjtpQkFDRjthQUNGLENBQUMsQ0FBQztRQUNMLENBQUM7YUFBTSxDQUFDO1lBQ04sTUFBTSxJQUFJLG1CQUFXLENBQ25CLG1CQUFXLENBQUMsS0FBSyxDQUFDLFlBQVksRUFDOUIsMEZBQTBGLENBQzNGLENBQUM7UUFDSixDQUFDO0lBQ0gsQ0FBQztJQUVELE1BQU0sQ0FBQyxlQUFlLENBQUMsT0FBeUI7UUFDOUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxhQUFhLEVBQUUsQ0FBQztZQUMzQixNQUFNLElBQUksbUJBQVcsQ0FDbkIsbUJBQVcsQ0FBQyxLQUFLLENBQUMsWUFBWSxFQUM5QixzREFBc0QsQ0FDdkQsQ0FBQztRQUNKLENBQUM7UUFDRCxJQUFJLENBQUMsT0FBTyxDQUFDLGlCQUFpQixFQUFFLENBQUM7WUFDL0IsTUFBTSxJQUFJLG1CQUFXLENBQ25CLG1CQUFXLENBQUMsS0FBSyxDQUFDLFlBQVksRUFDOUIsMERBQTBELENBQzNELENBQUM7UUFDSixDQUFDO1FBQ0QsSUFDRSxPQUFPLENBQUMsV0FBVyxLQUFLLFlBQVk7WUFDcEMsT0FBTyxDQUFDLFdBQVcsS0FBSyxTQUFTLEVBQ2pDLENBQUM7WUFDRCxNQUFNLElBQUksbUJBQVcsQ0FDbkIsbUJBQVcsQ0FBQyxLQUFLLENBQUMsWUFBWSxFQUM5QixzREFBc0QsQ0FDdkQsQ0FBQztRQUNKLENBQUM7SUFDSCxDQUFDO0lBRUQsS0FBSyxDQUFDLGNBQWMsQ0FDbEIsV0FBZ0M7UUFFaEMsTUFBTSxXQUFXLEdBQUcsV0FBVyxDQUFDLElBQUssQ0FBQyxXQUEwQixDQUFDO1FBRWpFLElBQ0UsV0FBVyxDQUFDLGFBQWEsRUFBRSxNQUFNO1lBQ2pDLFdBQVcsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUTtZQUNyQyxXQUFXLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxjQUFjLEVBQUUsTUFBTSxFQUM1RCxDQUFDO1lBQ0QsTUFBTSxFQUFFLEdBQUcsV0FBVyxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFTLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQztpQkFDaEUsRUFBWSxDQUFDO1lBQ2hCLElBQUksQ0FBQztnQkFDSCxNQUFNLGtCQUFrQixHQUFHLElBQUksc0NBQWtCLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO2dCQUNoRSxNQUFNLGtCQUFrQixDQUFDLHdCQUF3QixDQUFDO29CQUNoRCxlQUFlLEVBQUUsRUFBRTtpQkFDcEIsQ0FBQyxDQUFDO2dCQUNILE9BQU8sTUFBTSxJQUFJLENBQUMsZUFBZSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1lBQ2pELENBQUM7WUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO2dCQUNmLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUMxQixNQUFNLElBQUksS0FBSyxDQUFDLHFDQUFxQyxDQUFDLENBQUM7WUFDekQsQ0FBQztRQUNILENBQUM7UUFDRCxNQUFNLElBQUksS0FBSyxDQUFDLHFDQUFxQyxDQUFDLENBQUM7SUFDekQsQ0FBQztJQUVELEtBQUssQ0FBQyxnQkFBZ0IsQ0FDcEIsV0FBa0M7UUFFbEMsSUFBSSxDQUFDO1lBQ0gsTUFBTSxNQUFNLEdBQUcsQ0FBQyxNQUFNLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQztZQUNqRSxNQUFNLGdCQUFnQixHQUFHLE1BQU0sSUFBSSxDQUFDLGVBQWUsQ0FBQyxXQUFXLENBQUMsQ0FBQztZQUNqRSxPQUFPO2dCQUNMLElBQUksRUFBRTtvQkFDSixHQUFHLFdBQVc7b0JBQ2QsV0FBVyxFQUFFLGdCQUFnQixDQUFDLElBQUssQ0FBQyxXQUFXO29CQUMvQyxhQUFhLEVBQUcsZ0JBQWdCLENBQUMsSUFBSyxDQUFDLFdBQTRCO3lCQUNoRSxFQUFFO2lCQUNOO2dCQUNELE1BQU0sRUFBRSxNQUFNO2FBQ2YsQ0FBQztRQUNKLENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsTUFBTSxJQUFJLEtBQUssQ0FBQywwQkFBMEIsQ0FBQyxDQUFDO1FBQzlDLENBQUM7SUFDSCxDQUFDO0lBQ0QsS0FBSyxDQUFDLGFBQWEsQ0FDakIsV0FBK0I7UUFFL0IsTUFBTSxXQUFXLEdBQUcsV0FBVyxDQUFDLElBQUssQ0FBQyxXQUEwQixDQUFDO1FBQ2pFLElBQ0UsV0FBVyxDQUFDLGFBQWEsRUFBRSxNQUFNO1lBQ2pDLFdBQVcsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxFQUNyQyxDQUFDO1lBQ0QsTUFBTSxpQkFBaUIsR0FBRyxXQUFXLENBQUMsTUFBTSxLQUFLLCtCQUFpQixDQUFDLE1BQU0sQ0FBQztZQUMxRSxNQUFNLHdCQUF3QixHQUM1QixXQUFXLENBQUMsTUFBTSxLQUFLLCtCQUFpQixDQUFDLFNBQVM7Z0JBQ2xELENBQUMsQ0FBQyxXQUFXLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztZQUMzQyxJQUFJLGlCQUFpQixJQUFJLHdCQUF3QixFQUFFLENBQUM7Z0JBQ2xELE9BQU8sTUFBTSxJQUFJLENBQUMsZUFBZSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1lBQ2pELENBQUM7WUFDRCxNQUFNLGtCQUFrQixHQUFHLElBQUksc0NBQWtCLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ2hFLElBQUksQ0FBQztnQkFDSCxNQUFNLGlCQUFpQixHQUFHLFdBQVcsQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUN0RCxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLFFBQVEsRUFBRSxRQUFRLEVBQUUsTUFBTSxDQUN0QyxDQUFDO2dCQUNGLElBQUksaUJBQWlCLEVBQUUsQ0FBQztvQkFDdEIsTUFBTSxRQUFRLEdBQUcsV0FBVyxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUM7b0JBQ3ZELE1BQU0sVUFBVSxHQUFHLFFBQVEsQ0FBQyxRQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO29CQUM1QyxNQUFNLGtCQUFrQixDQUFDLHFCQUFxQixDQUFDO3dCQUM3QyxTQUFTLEVBQUUsVUFBb0I7cUJBQ2hDLENBQUMsQ0FBQztnQkFDTCxDQUFDO3FCQUFNLENBQUM7b0JBQ04sTUFBTSxFQUFFLEdBQUcsV0FBVyxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFTLENBQUMsY0FBZSxDQUFDLENBQUMsQ0FBQzt5QkFDakUsRUFBWSxDQUFDO29CQUNoQixNQUFNLGtCQUFrQixDQUFDLFdBQVcsQ0FBQzt3QkFDbkMsZUFBZSxFQUFFLEVBQUU7cUJBQ3BCLENBQUMsQ0FBQztnQkFDTCxDQUFDO2dCQUNELE9BQU8sTUFBTSxJQUFJLENBQUMsZUFBZSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1lBQ2pELENBQUM7WUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO2dCQUNmLE1BQU0sSUFBSSxLQUFLLENBQUMsb0NBQW9DLENBQUMsQ0FBQztZQUN4RCxDQUFDO1FBQ0gsQ0FBQztRQUNELE1BQU0sSUFBSSxLQUFLLENBQUMsb0NBQW9DLENBQUMsQ0FBQztJQUN4RCxDQUFDO0lBQ0QsS0FBSyxDQUFDLGVBQWUsQ0FDbkIsV0FBaUM7UUFFakMsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLG9DQUFnQixDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUM1RCxNQUFNLEVBQUUsYUFBYSxFQUFFLE1BQU0sRUFBRSxHQUFHLFdBQVcsQ0FBQztRQUU5QyxJQUFJLENBQUM7WUFDSCxNQUFNLEVBQUUsTUFBTSxFQUFFLEdBQUcsWUFBWSxFQUFFLEdBQUcsTUFBTSxnQkFBZ0IsQ0FBQyxXQUFXLENBQUM7Z0JBQ3JFLElBQUksRUFBRTtvQkFDSixNQUFNLEVBQUUseUNBQXFCLENBQUMsU0FBUztvQkFDdkMsYUFBYSxFQUFFO3dCQUNiOzRCQUNFLE1BQU0sRUFBRSxJQUFBLDBCQUFhLEVBQUMsTUFBTSxFQUFFLGFBQWEsQ0FBcUI7eUJBQ2pFO3FCQUNGO2lCQUNGO2FBQ0YsQ0FBQyxDQUFDO1lBQ0gsSUFBSSxNQUFNLENBQUMsRUFBRSxFQUFFLENBQUM7Z0JBQ2QsT0FBTztvQkFDTCxFQUFFLEVBQUUsTUFBTSxDQUFDLEVBQUU7b0JBQ2IsSUFBSSxFQUFFO3dCQUNKLEdBQUcsV0FBVzt3QkFDZCxhQUFhLEVBQUUsTUFBTSxDQUFDLEVBQUU7d0JBQ3hCLFdBQVcsRUFBRSxNQUFNO3FCQUNwQjtpQkFDRixDQUFDO1lBQ0osQ0FBQztRQUNILENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsSUFBSSxLQUFLLFlBQVksNEJBQVEsRUFBRSxDQUFDO2dCQUM5QixNQUFNLEVBQUUsVUFBVSxFQUFFLE9BQU8sRUFBRSxHQUFHLEtBQUssQ0FBQztnQkFDdEMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsZUFBZSxVQUFVLENBQUMsUUFBUSxFQUFFLEVBQUUsQ0FBQyxDQUFDO2dCQUMzRCxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7WUFDOUMsQ0FBQztRQUNILENBQUM7UUFDRCxNQUFNLElBQUksS0FBSyxDQUFDLDJCQUEyQixDQUFDLENBQUM7SUFDL0MsQ0FBQztJQUNELEtBQUssQ0FBQyxhQUFhLENBQ2pCLGtCQUFzQztRQUV0QyxPQUFPLGtCQUFrQixDQUFDO0lBQzVCLENBQUM7SUFDRCxLQUFLLENBQUMsZ0JBQWdCLENBQ3BCLFdBQWtDO1FBRWxDLE1BQU0sZ0JBQWdCLEdBQUcsTUFBTSxJQUFJLENBQUMsZUFBZSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQ2pFLE1BQU0sV0FBVyxHQUFHLGdCQUFnQixDQUFDLElBQUssQ0FBQyxXQUEwQixDQUFDO1FBRXRFLFFBQVEsV0FBVyxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQzNCLEtBQUssK0JBQWlCLENBQUMsT0FBTztnQkFDNUIsT0FBTztvQkFDTCxNQUFNLEVBQUUsU0FBUztpQkFDbEIsQ0FBQztZQUNKLEtBQUssK0JBQWlCLENBQUMsS0FBSyxDQUFDO1lBQzdCLEtBQUssK0JBQWlCLENBQUMsUUFBUSxDQUFDO1lBQ2hDLEtBQUssK0JBQWlCLENBQUMsbUJBQW1CO2dCQUN4QyxPQUFPO29CQUNMLE1BQU0sRUFBRSxlQUFlO2lCQUN4QixDQUFDO1lBQ0osS0FBSywrQkFBaUIsQ0FBQyxNQUFNO2dCQUMzQixPQUFPO29CQUNMLE1BQU0sRUFBRSxVQUFVO2lCQUNuQixDQUFDO1lBQ0osS0FBSywrQkFBaUIsQ0FBQyxTQUFTO2dCQUM5QixPQUFPO29CQUNMLE1BQU0sRUFBRSxZQUFZO2lCQUNyQixDQUFDO1lBQ0o7Z0JBQ0UsT0FBTztvQkFDTCxNQUFNLEVBQUUsU0FBUztpQkFDbEIsQ0FBQztRQUNOLENBQUM7SUFDSCxDQUFDO0lBQ0QsS0FBSyxDQUFDLGFBQWEsQ0FDakIsV0FBK0I7UUFFL0IsTUFBTSxXQUFXLEdBQUcsV0FBVyxDQUFDLElBQUssQ0FBQyxXQUEwQixDQUFDO1FBRWpFLElBQ0UsV0FBVyxDQUFDLGFBQWEsRUFBRSxNQUFNO1lBQ2pDLFdBQVcsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxFQUNyQyxDQUFDO1lBQ0QsTUFBTSxZQUFZLEdBQUcsV0FBVyxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNsRCxNQUFNLGlCQUFpQixHQUFHLFdBQVcsQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUN0RCxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLFFBQVEsRUFBRSxRQUFRLEVBQUUsTUFBTSxDQUN0QyxDQUFDO1lBQ0YsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7Z0JBQ3ZCLE1BQU0sSUFBSSxLQUFLLENBQUMscUNBQXFDLENBQUMsQ0FBQztZQUN6RCxDQUFDO1lBRUQsTUFBTSxTQUFTLEdBQUcsWUFBWSxDQUFDLFFBQVEsRUFBRSxRQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBWSxDQUFDO1lBQ25FLE1BQU0sWUFBWSxHQUFHLFlBQVksQ0FBQyxNQUFNLEVBQUUsWUFBc0IsQ0FBQztZQUNqRSxNQUFNLE1BQU0sR0FBRyxXQUFXLENBQUMsTUFBTSxDQUFDO1lBQ2xDLE1BQU0sa0JBQWtCLEdBQUcsSUFBSSxzQ0FBa0IsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDaEUsSUFBSSxDQUFDO2dCQUNILE1BQU0sa0JBQWtCLENBQUMscUJBQXFCLENBQUM7b0JBQzdDLFNBQVMsRUFBRSxTQUFTO29CQUNwQixJQUFJLEVBQUU7d0JBQ0osTUFBTSxFQUFFLElBQUEsMEJBQWEsRUFBQyxNQUFNLEVBQUUsWUFBWSxDQUFxQjtxQkFDaEU7aUJBQ0YsQ0FBQyxDQUFDO2dCQUNILE9BQU8sTUFBTSxJQUFJLENBQUMsZUFBZSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1lBQ2pELENBQUM7WUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO2dCQUNmLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUMxQixNQUFNLElBQUksS0FBSyxDQUFDLG9DQUFvQyxDQUFDLENBQUM7WUFDeEQsQ0FBQztRQUNILENBQUM7UUFDRCxNQUFNLElBQUksS0FBSyxDQUFDLG9DQUFvQyxDQUFDLENBQUM7SUFDeEQsQ0FBQztJQUNELEtBQUssQ0FBQyxlQUFlLENBQ25CLGtCQUF3QztRQUV4QyxNQUFNLGdCQUFnQixHQUFHLElBQUksb0NBQWdCLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQzVELElBQUksQ0FBQztZQUNILE1BQU0sYUFBYSxHQUNqQixrQkFBa0IsQ0FBQyxJQUFLLENBQUMsV0FDMUIsQ0FBQyxFQUFZLENBQUM7WUFDZixNQUFNLEVBQUUsTUFBTSxFQUFFLEdBQUcsWUFBWSxFQUFFLEdBQUcsTUFBTSxnQkFBZ0IsQ0FBQyxRQUFRLENBQUM7Z0JBQ2xFLEVBQUUsRUFBRSxhQUFhO2FBQ2xCLENBQUMsQ0FBQztZQUNILElBQUksTUFBTSxDQUFDLEVBQUUsRUFBRSxDQUFDO2dCQUNkLE9BQU87b0JBQ0wsSUFBSSxFQUFFO3dCQUNKLEdBQUcsa0JBQWtCO3dCQUNyQixhQUFhLEVBQUUsTUFBTSxDQUFDLEVBQUU7d0JBQ3hCLFdBQVcsRUFBRSxNQUFNO3FCQUNwQjtpQkFDRixDQUFDO1lBQ0osQ0FBQztRQUNILENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsSUFBSSxLQUFLLFlBQVksNEJBQVEsRUFBRSxDQUFDO2dCQUM5QixNQUFNLEVBQUUsVUFBVSxFQUFFLE9BQU8sRUFBRSxHQUFHLEtBQUssQ0FBQztnQkFDdEMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsZUFBZSxVQUFVLENBQUMsUUFBUSxFQUFFLEVBQUUsQ0FBQyxDQUFDO2dCQUMzRCxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7Z0JBQzVDLE1BQU0sSUFBSSxLQUFLLENBQUMsMkJBQTJCLENBQUMsQ0FBQztZQUMvQyxDQUFDO1FBQ0gsQ0FBQztRQUNELE1BQU0sSUFBSSxLQUFLLENBQUMsNEJBQTRCLENBQUMsQ0FBQztJQUNoRCxDQUFDO0lBQ0QsS0FBSyxDQUFDLGFBQWEsQ0FDakIsT0FBMkI7UUFFM0IsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLG9DQUFnQixDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUM1RCxNQUFNLEVBQUUsTUFBTSxFQUFFLGFBQWEsRUFBRSxHQUFHLE9BQU8sQ0FBQztRQUMxQyxJQUFJLENBQUM7WUFDSCxNQUFNLGFBQWEsR0FBSSxPQUFPLENBQUMsSUFBSyxDQUFDLFdBQTJCO2lCQUM3RCxFQUFZLENBQUM7WUFDaEIsTUFBTSxnQkFBZ0IsQ0FBQyxVQUFVLENBQUM7Z0JBQ2hDLEVBQUUsRUFBRSxhQUFhO2dCQUNqQixJQUFJLEVBQUU7b0JBQ0o7d0JBQ0UsRUFBRSxFQUFFLDJCQUFPLENBQUMsT0FBTzt3QkFDbkIsS0FBSyxFQUFFOzRCQUNMLE1BQU0sRUFBRSxJQUFBLDBCQUFhLEVBQUMsTUFBTSxFQUFFLGFBQWEsQ0FBcUI7eUJBQ2pFO3FCQUNGO2lCQUNGO2FBQ0YsQ0FBQyxDQUFDO1lBQ0gsT0FBTyxNQUFNLElBQUksQ0FBQyxlQUFlLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDN0MsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUMxQixNQUFNLElBQUksS0FBSyxDQUFDLG9DQUFvQyxDQUFDLENBQUM7UUFDeEQsQ0FBQztJQUNILENBQUM7SUFDRCxLQUFLLENBQUMsdUJBQXVCLENBQzNCLElBQXVDO1FBRXZDLE9BQU87WUFDTCxNQUFNLEVBQUUsc0JBQWMsQ0FBQyxhQUFhO1NBQ3JDLENBQUM7SUFDSixDQUFDOztBQXBVTSx1Q0FBVSxHQUFHLGdCQUFnQixDQUFDO0FBdVV2QyxrQkFBZSw0QkFBNEIsQ0FBQyJ9