From 64f9f5bd12f1f35a4367a2325890edab20b46141 Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Thu, 9 Jan 2025 13:50:56 +0100 Subject: [PATCH 01/30] WIP: Take over Changes form v2.5.2-rc4 --- metadata.php | 200 ++++------ src/Component/BasketComponent.php | 21 +- src/Component/UserComponent.php | 12 +- src/Controller/Admin/OrderMain.php | 15 +- src/Controller/Admin/OrderOverview.php | 8 +- .../Admin/PayPalConfigController.php | 63 +--- .../Admin/PayPalOrderController.php | 61 ++-- src/Controller/OrderController.php | 182 +++++----- .../PayPalVaultingCardController.php | 37 +- src/Controller/PayPalVaultingController.php | 34 +- src/Controller/PaymentController.php | 71 ++-- src/Controller/ProxyController.php | 127 ++----- src/Controller/VaultingTokenController.php | 5 +- src/Controller/WebhookController.php | 5 +- src/Core/Api/IdentityService.php | 18 +- src/Core/Api/VaultingService.php | 20 +- src/Core/Config.php | 32 +- src/Core/ConfirmOrderRequestFactory.php | 14 +- src/Core/Events/Events.php | 34 +- src/Core/LegacyOeppModuleDetails.php | 1 - src/Core/Onboarding/Onboarding.php | 55 ++- src/Core/Onboarding/Webhook.php | 16 +- src/Core/OrderRequestFactory.php | 68 ++-- src/Core/PartnerConfig.php | 2 - src/Core/PatchRequestFactory.php | 5 +- src/Core/PayPalDefinitions.php | 30 +- src/Core/PayPalRequestAmountFactory.php | 10 +- src/Core/ServiceFactory.php | 10 +- src/Core/ShopControl.php | 8 +- src/Core/Tracker/Tracker.php | 8 +- src/Core/TransactionEventCodes.php | 3 +- .../PayPalAddressResponseToOxidAddress.php | 10 +- src/Core/Utils/PriceToMoney.php | 6 +- src/Core/ViewConfig.php | 172 ++++----- src/Core/Webhook/EventVerifier.php | 12 +- .../Handler/CheckoutOrderApprovedHandler.php | 8 +- .../PaymentCaptureCompletedHandler.php | 5 +- .../Handler/PaymentCaptureRefundedHandler.php | 14 +- .../Webhook/Handler/WebhookHandlerBase.php | 34 +- src/Core/Webhook/RequestHandler.php | 16 +- src/Exception/Redirect.php | 4 +- src/Exception/RedirectWithMessage.php | 10 +- src/Model/Basket.php | 4 +- src/Model/Order.php | 92 ++--- src/Model/PayPalOrder.php | 1 - src/Model/PayPalPlusOrder.php | 12 +- src/Model/PayPalPlusPui.php | 16 +- src/Model/PayPalSoapOrder.php | 4 +- src/Model/PayPalTrackingCarrierList.php | 9 +- src/Model/PaymentGateway.php | 40 +- src/Model/State.php | 6 +- src/Model/User.php | 3 - src/Service/Context.php | 6 +- .../GooglePay/GooglePayPayPalService.php | 4 +- src/Service/Logger.php | 8 +- src/Service/ModuleSettings.php | 140 +++++-- src/Service/OrderRepository.php | 34 +- src/Service/Payment.php | 216 ++++------- src/Service/StaticContent.php | 45 +-- src/Service/UserRepository.php | 20 +- src/Traits/AccountControllerTrait.php | 30 ++ src/Traits/AdminOrderTrait.php | 32 +- src/Traits/ServiceContainer.php | 6 +- translations/de/oscpaypal_de_lang.php | 9 +- translations/en/oscpaypal_en_lang.php | 2 - views/admin/tpl/oscpaypalorder.tpl | 243 ------------- views/{de => admin_de}/admin_translations.php | 8 +- .../transaction_type_codes_translations.php | 0 views/{en => admin_en}/admin_translations.php | 10 +- .../transaction_type_codes_translations.php | 0 views/admin_smarty/de/admin_lang.php | 9 +- .../de/transaction_type_codes_lang.php | 2 +- views/admin_smarty/en/admin_lang.php | 9 +- views/admin_twig/de/admin_lang.php | 2 +- .../de/transaction_type_codes_lang.php | 2 +- .../blocks/page/account/inc/account_menu.tpl | 11 - views/blocks/page/checkout/change_payment.tpl | 6 - ...m_inccss.tpl => admin_headitem_inccss.tpl} | 0 ...tem_incjs.tpl => admin_headitem_incjs.tpl} | 0 ...tpl => admin_order_main_form_shipping.tpl} | 0 ...er.tpl => admin_order_main_send_order.tpl} | 0 views/smarty/admin/oscpaypalconfig.tpl | 48 ++- .../frontend/blocks/layout/base__base_js.tpl | 22 -- .../blocks/layout/base__base_style.tpl | 5 - .../smarty/frontend/blocks/layout/base_js.tpl | 26 ++ .../frontend/blocks/layout/base_style.tpl | 6 + .../page/account/account_vaulting_card.tpl | 2 +- .../account_vaulting_card.tpl:Zone.Identifier | 2 + .../page/account/account_vaulting_paypal.tpl | 2 +- ...ccount_vaulting_paypal.tpl:Zone.Identifier | 2 + .../blocks/page/account/inc/account_menu.tpl | 13 + .../inc/account_menu.tpl:Zone.Identifier | 0 ...ket__checkout_basket_emptyshippingcart.tpl | 8 - .../basket__checkout_basket_next_step_top.tpl | 8 - ..._bottom.tpl => basket_btn_next_bottom.tpl} | 4 +- .../basket_installment_banner_after.tpl | 8 + .../basket_installment_banner_before.tpl | 7 + .../blocks/page/checkout/change_payment.tpl | 6 + .../checkout_order_btn_submit_bottom.tpl | 12 +- .../checkout/order__shippingAndPayment.tpl | 62 ---- .../payment__checkout_payment_main.tpl | 7 - .../page/checkout/payment__select_payment.tpl | 49 --- .../blocks/page/checkout/select_payment.tpl | 14 +- .../page/checkout/shipping_and_payment.tpl | 8 +- .../blocks/page/checkout/thankyou.tpl | 0 .../inc/details_productmain_tobasket.tpl | 2 + ...s_productmain_tobasket.tpl:Zone.Identifier | 0 ...ctmain_price_value.tpl => productmain.tpl} | 4 +- .../inc/productmain.tpl:Zone.Identifier | 0 ...roductmain_price_value.tpl:Zone.Identifier | 2 + ...ductmain__details_productmain_tobasket.tpl | 6 - ...s_productmain_tobasket.tpl:Zone.Identifier | 2 + .../list.tpl} | 10 +- .../blocks/page/list/list.tpl:Zone.Identifier | 0 .../page/list/list__page_list_listhead.tpl | 11 - ...st__page_list_listhead.tpl:Zone.Identifier | 2 + .../frontend/blocks/page/search/search.tpl | 10 + .../page/search/search.tpl:Zone.Identifier | 0 .../page/search/search__search_header.tpl | 11 - .../search__search_header.tpl:Zone.Identifier | 2 + .../frontend/blocks/page/shop/start.tpl | 10 + .../page/shop/start.tpl:Zone.Identifier | 0 ..._start_newest_articles.tpl:Zone.Identifier | 2 + .../frontend/blocks/vaultedpaymentsources.tpl | 4 +- ..._header_icon_menu_minibasket_functions.tpl | 8 + ..._header_icon_menu_minibasket_functions.tpl | 10 - .../flow/page/checkout/change_payment.tpl | 0 .../checkout_order_btn_submit_bottom.tpl | 27 ++ .../frontend/flow/page/checkout/pui.tpl | 77 ++++ .../page/checkout/shipping_and_payment.tpl | 4 +- .../checkout/shipping_and_payment_paypal.tpl | 0 .../flow/vaulting/vaultedpaymentsources.tpl | 0 views/smarty/frontend/google_pay.tpl | 8 - views/smarty/frontend/shared/applepay.tpl | 341 ++++++++++++++++++ views/smarty/frontend/shared/googlepay.tpl | 34 ++ .../{ => shared}/installment_banners.tpl | 0 .../page/account/account_vaulting_card.tpl | 102 ++++++ .../page/account/account_vaulting_paypal.tpl | 67 ++++ .../{ => shared/page/checkout}/acdc.tpl | 1 + .../{ => shared/page/checkout}/apple_pay.tpl | 0 .../shared/page/checkout/pui_fraudnet.tpl | 10 + .../page/checkout}/select_payment.tpl | 0 .../page/checkout/sepa_cc_alternative.tpl | 7 + .../inc/details_productmain_tobasket.tpl | 5 + .../frontend/{ => shared}/paymentbuttons.tpl | 10 +- .../frontend/shared/vaultedpaymentsources.tpl | 5 + ..._header_icon_menu_minibasket_functions.tpl | 7 + .../page/checkout/change_payment.tpl} | 2 - .../checkout_order_btn_submit_bottom.tpl | 27 ++ .../page/checkout/pui.tpl} | 69 +--- .../page/checkout/shipping_and_payment.tpl | 4 +- .../checkout/shipping_and_payment_paypal.tpl | 0 .../wave/vaulting/vaultedpaymentsources.tpl | 0 153 files changed, 1797 insertions(+), 1934 deletions(-) create mode 100644 src/Traits/AccountControllerTrait.php delete mode 100644 views/admin/tpl/oscpaypalorder.tpl rename views/{de => admin_de}/admin_translations.php (98%) rename views/{de => admin_de}/transaction_type_codes_translations.php (100%) rename views/{en => admin_en}/admin_translations.php (99%) rename views/{en => admin_en}/transaction_type_codes_translations.php (100%) delete mode 100644 views/blocks/page/account/inc/account_menu.tpl delete mode 100644 views/blocks/page/checkout/change_payment.tpl rename views/smarty/admin/blocks/{headitem__admin_headitem_inccss.tpl => admin_headitem_inccss.tpl} (100%) rename views/smarty/admin/blocks/{headitem__admin_headitem_incjs.tpl => admin_headitem_incjs.tpl} (100%) rename views/smarty/admin/blocks/{order_main__admin_order_main_form_shipping.tpl => admin_order_main_form_shipping.tpl} (100%) rename views/smarty/admin/blocks/{order_main__admin_order_main_send_order.tpl => admin_order_main_send_order.tpl} (100%) mode change 100755 => 100644 views/smarty/admin/oscpaypalconfig.tpl delete mode 100644 views/smarty/frontend/blocks/layout/base__base_js.tpl delete mode 100644 views/smarty/frontend/blocks/layout/base__base_style.tpl create mode 100644 views/smarty/frontend/blocks/layout/base_js.tpl create mode 100644 views/smarty/frontend/blocks/layout/base_style.tpl create mode 100644 views/smarty/frontend/blocks/page/account/account_vaulting_card.tpl:Zone.Identifier create mode 100644 views/smarty/frontend/blocks/page/account/account_vaulting_paypal.tpl:Zone.Identifier create mode 100644 views/smarty/frontend/blocks/page/account/inc/account_menu.tpl create mode 100644 views/smarty/frontend/blocks/page/account/inc/account_menu.tpl:Zone.Identifier delete mode 100644 views/smarty/frontend/blocks/page/checkout/basket__checkout_basket_emptyshippingcart.tpl delete mode 100644 views/smarty/frontend/blocks/page/checkout/basket__checkout_basket_next_step_top.tpl rename views/smarty/frontend/blocks/page/checkout/{inc/basket__basket_btn_next_bottom.tpl => basket_btn_next_bottom.tpl} (52%) create mode 100644 views/smarty/frontend/blocks/page/checkout/basket_installment_banner_after.tpl create mode 100644 views/smarty/frontend/blocks/page/checkout/basket_installment_banner_before.tpl create mode 100644 views/smarty/frontend/blocks/page/checkout/change_payment.tpl rename views/{ => smarty/frontend}/blocks/page/checkout/checkout_order_btn_submit_bottom.tpl (63%) delete mode 100644 views/smarty/frontend/blocks/page/checkout/order__shippingAndPayment.tpl delete mode 100644 views/smarty/frontend/blocks/page/checkout/payment__checkout_payment_main.tpl delete mode 100644 views/smarty/frontend/blocks/page/checkout/payment__select_payment.tpl rename views/{ => smarty/frontend}/blocks/page/checkout/select_payment.tpl (77%) rename views/{ => smarty/frontend}/blocks/page/checkout/shipping_and_payment.tpl (55%) rename views/{ => smarty/frontend}/blocks/page/checkout/thankyou.tpl (100%) create mode 100644 views/smarty/frontend/blocks/page/details/inc/details_productmain_tobasket.tpl create mode 100644 views/smarty/frontend/blocks/page/details/inc/details_productmain_tobasket.tpl:Zone.Identifier rename views/smarty/frontend/blocks/page/details/inc/{productmain__details_productmain_price_value.tpl => productmain.tpl} (70%) create mode 100644 views/smarty/frontend/blocks/page/details/inc/productmain.tpl:Zone.Identifier create mode 100644 views/smarty/frontend/blocks/page/details/inc/productmain__details_productmain_price_value.tpl:Zone.Identifier delete mode 100644 views/smarty/frontend/blocks/page/details/inc/productmain__details_productmain_tobasket.tpl create mode 100644 views/smarty/frontend/blocks/page/details/inc/productmain__details_productmain_tobasket.tpl:Zone.Identifier rename views/smarty/frontend/blocks/page/{shop/start__start_newest_articles.tpl => list/list.tpl} (50%) create mode 100644 views/smarty/frontend/blocks/page/list/list.tpl:Zone.Identifier delete mode 100644 views/smarty/frontend/blocks/page/list/list__page_list_listhead.tpl create mode 100644 views/smarty/frontend/blocks/page/list/list__page_list_listhead.tpl:Zone.Identifier create mode 100644 views/smarty/frontend/blocks/page/search/search.tpl create mode 100644 views/smarty/frontend/blocks/page/search/search.tpl:Zone.Identifier delete mode 100644 views/smarty/frontend/blocks/page/search/search__search_header.tpl create mode 100644 views/smarty/frontend/blocks/page/search/search__search_header.tpl:Zone.Identifier create mode 100644 views/smarty/frontend/blocks/page/shop/start.tpl create mode 100644 views/smarty/frontend/blocks/page/shop/start.tpl:Zone.Identifier create mode 100644 views/smarty/frontend/blocks/page/shop/start__start_newest_articles.tpl:Zone.Identifier create mode 100644 views/smarty/frontend/blocks/widget/minibasket/dd_layout_page_header_icon_menu_minibasket_functions.tpl delete mode 100644 views/smarty/frontend/blocks/widget/minibasket/minibasket__dd_layout_page_header_icon_menu_minibasket_functions.tpl rename views/{tpl => smarty/frontend}/flow/page/checkout/change_payment.tpl (100%) create mode 100644 views/smarty/frontend/flow/page/checkout/checkout_order_btn_submit_bottom.tpl create mode 100644 views/smarty/frontend/flow/page/checkout/pui.tpl rename views/{tpl => smarty/frontend}/flow/page/checkout/shipping_and_payment.tpl (93%) rename views/{tpl => smarty/frontend}/flow/page/checkout/shipping_and_payment_paypal.tpl (100%) rename views/{tpl => smarty/frontend}/flow/vaulting/vaultedpaymentsources.tpl (100%) delete mode 100644 views/smarty/frontend/google_pay.tpl create mode 100644 views/smarty/frontend/shared/applepay.tpl create mode 100644 views/smarty/frontend/shared/googlepay.tpl rename views/smarty/frontend/{ => shared}/installment_banners.tpl (100%) create mode 100644 views/smarty/frontend/shared/page/account/account_vaulting_card.tpl create mode 100644 views/smarty/frontend/shared/page/account/account_vaulting_paypal.tpl rename views/smarty/frontend/{ => shared/page/checkout}/acdc.tpl (99%) rename views/smarty/frontend/{ => shared/page/checkout}/apple_pay.tpl (100%) create mode 100644 views/smarty/frontend/shared/page/checkout/pui_fraudnet.tpl rename views/smarty/frontend/{ => shared/page/checkout}/select_payment.tpl (100%) create mode 100644 views/smarty/frontend/shared/page/checkout/sepa_cc_alternative.tpl create mode 100644 views/smarty/frontend/shared/page/details/inc/details_productmain_tobasket.tpl rename views/smarty/frontend/{ => shared}/paymentbuttons.tpl (96%) create mode 100644 views/smarty/frontend/shared/vaultedpaymentsources.tpl create mode 100644 views/smarty/frontend/shared/widget/minibasket/dd_layout_page_header_icon_menu_minibasket_functions.tpl rename views/smarty/frontend/{blocks/page/checkout/payment__change_payment.tpl => wave/page/checkout/change_payment.tpl} (99%) create mode 100644 views/smarty/frontend/wave/page/checkout/checkout_order_btn_submit_bottom.tpl rename views/smarty/frontend/{pui_flow.tpl => wave/page/checkout/pui.tpl} (60%) rename views/{tpl => smarty/frontend}/wave/page/checkout/shipping_and_payment.tpl (93%) rename views/{tpl => smarty/frontend}/wave/page/checkout/shipping_and_payment_paypal.tpl (100%) rename views/{tpl => smarty/frontend}/wave/vaulting/vaultedpaymentsources.tpl (100%) diff --git a/metadata.php b/metadata.php index d69766856..9976a9d23 100755 --- a/metadata.php +++ b/metadata.php @@ -97,197 +97,163 @@ 'onDeactivate' => '\OxidSolutionCatalysts\PayPal\Core\Events\Events::onDeactivate' ], 'templates' => [ + // Admin: Config '@osc_paypal/admin/oscpaypalconfig.tpl' => 'views/smarty/admin/oscpaypalconfig.tpl', + + // Admin: Order '@osc_paypal/admin/oscpaypalorder.tpl' => 'views/smarty/admin/oscpaypalorder.tpl', '@osc_paypal/admin/oscpaypalorder_pp.tpl' => 'views/smarty/admin/oscpaypalorder_pp.tpl', '@osc_paypal/admin/oscpaypalorder_ppplus.tpl' => 'views/smarty/admin/oscpaypalorder_ppplus.tpl', - '@osc_paypal/frontend/acdc.tpl' => 'views/smarty/frontend/acdc.tpl', - '@osc_paypal/frontend/installment_banners.tpl' => 'views/smarty/frontend/installment_banners.tpl', - '@osc_paypal/frontend/paymentbuttons.tpl' => 'views/smarty/frontend/paymentbuttons.tpl', - '@osc_paypal/frontend/pui_flow.tpl' => 'views/smarty/frontend/pui_flow.tpl', - '@osc_paypal/frontend/select_payment.tpl' => 'views/smarty/frontend/select_payment.tpl', - // Admin: Config - 'oscpaypalconfig.tpl' => 'osc/paypal/views/admin/tpl/oscpaypalconfig.tpl', + '@osc_paypal/frontend/shared/paymentbuttons.tpl' => 'views/smarty/frontend/shared/paymentbuttons.tpl', - // Admin: Order - 'oscpaypalorder.tpl' => 'osc/paypal/views/admin/tpl/oscpaypalorder.tpl', - 'oscpaypalorder_ppplus.tpl' => 'osc/paypal/views/admin/tpl/oscpaypalorder_ppplus.tpl', - 'oscpaypalorder_pp.tpl' => 'osc/paypal/views/admin/tpl/oscpaypalorder_pp.tpl', - - 'modules/osc/paypal/paymentbuttons.tpl' => 'osc/paypal/views/tpl/shared/paymentbuttons.tpl', - - 'modules/osc/paypal/pui_flow.tpl' => 'osc/paypal/views/tpl/flow/page/checkout/pui.tpl', - 'modules/osc/paypal/pui_wave.tpl' => 'osc/paypal/views/tpl/wave/page/checkout/pui.tpl', - 'modules/osc/paypal/pui_fraudnet.tpl' => 'osc/paypal/views/tpl/shared/page/checkout/pui_fraudnet.tpl', - 'modules/osc/paypal/apple_pay.tpl' => 'osc/paypal/views/tpl/shared/page/checkout/apple_pay.tpl', - 'modules/osc/paypal/shipping_and_payment_flow.tpl' => 'osc/paypal/views/tpl/flow/page/checkout/shipping_and_payment.tpl', - 'modules/osc/paypal/shipping_and_payment_wave.tpl' => 'osc/paypal/views/tpl/wave/page/checkout/shipping_and_payment.tpl', - 'modules/osc/paypal/shipping_and_payment_paypal_flow.tpl' => 'osc/paypal/views/tpl/flow/page/checkout/shipping_and_payment_paypal.tpl', - 'modules/osc/paypal/shipping_and_payment_paypal_wave.tpl' => 'osc/paypal/views/tpl/wave/page/checkout/shipping_and_payment_paypal.tpl', - 'modules/osc/paypal/checkout_order_btn_submit_bottom_flow.tpl' => 'osc/paypal/views/tpl/flow/page/checkout/checkout_order_btn_submit_bottom.tpl', - 'modules/osc/paypal/checkout_order_btn_submit_bottom_wave.tpl' => 'osc/paypal/views/tpl/wave/page/checkout/checkout_order_btn_submit_bottom.tpl', + '@osc_paypal/frontend/flow/pui.tpl' => 'views/smarty/frontend/flow/page/checkout/pui.tpl', + '@osc_paypal/frontend/wave/pui.tpl' => 'views/smarty/frontend/wave/page/checkout/pui.tpl', + '@osc_paypal/frontend/shared/pui_fraudnet.tpl' => 'views/smarty/frontend/shared/page/checkout/pui_fraudnet.tpl', + '@osc_paypal/frontend/shared/apple_pay.tpl' => 'views/smarty/frontend/shared/page/checkout/apple_pay.tpl', + '@osc_paypal/frontend/flow/shipping_and_payment.tpl' => 'views/smarty/frontend/flow/page/checkout/shipping_and_payment.tpl', + '@osc_paypal/frontend/wave/shipping_and_payment.tpl' => 'views/smarty/frontend/wave/page/checkout/shipping_and_payment.tpl', + '@osc_paypal/frontend/flow/shipping_and_payment_paypal.tpl' => 'views/smarty/frontend/flow/page/checkout/shipping_and_payment_paypal.tpl', + '@osc_paypal/frontend/wave/shipping_and_payment_paypal.tpl' => 'views/smarty/frontend/wave/page/checkout/shipping_and_payment_paypal.tpl', + '@osc_paypal/frontend/flow/checkout_order_btn_submit_bottom.tpl' => 'views/smarty/frontend/flow/page/checkout/checkout_order_btn_submit_bottom.tpl', + '@osc_paypal/frontend/wave/checkout_order_btn_submit_bottom.tpl' => 'views/smarty/frontend/wave/page/checkout/checkout_order_btn_submit_bottom.tpl', // PAYPAL-486 Register templates for overloading here; // use theme name in key when theme-specific. Shared templates don't receive a theme-specific key. - 'modules/osc/paypal/acdc.tpl' => 'osc/paypal/views/tpl/shared/page/checkout/acdc.tpl', - 'modules/osc/paypal/sepa_cc_alternative.tpl' => 'osc/paypal/views/tpl/shared/page/checkout/sepa_cc_alternative.tpl', - 'modules/osc/paypal/base_js.tpl' => 'osc/paypal/views/tpl/shared/layout/base_js.tpl', - 'modules/osc/paypal/base_style.tpl' => 'osc/paypal/views/tpl/shared/layout/base_style.tpl', - 'modules/osc/paypal/basket_btn_next_bottom.tpl' => - 'osc/paypal/views/tpl/shared/page/checkout/basket_btn_next_bottom.tpl', - 'modules/osc/paypal/select_payment.tpl' => 'osc/paypal/views/tpl/shared/page/checkout/select_payment.tpl', - 'modules/osc/paypal/details_productmain_tobasket.tpl' => - 'osc/paypal/views/tpl/shared/page/details/inc/details_productmain_tobasket.tpl', - 'modules/osc/paypal/dd_layout_page_header_icon_menu_minibasket_functions.tpl' => - 'osc/paypal/views/tpl/shared/widget/minibasket/dd_layout_page_header_icon_menu_minibasket_functions.tpl', + '@osc_paypal/frontend/shared/acdc.tpl' => 'views/smarty/frontend/shared/page/checkout/acdc.tpl', + '@osc_paypal/frontend/shared/sepa_cc_alternative.tpl' => 'views/smarty/frontend/shared/page/checkout/sepa_cc_alternative.tpl', + '@osc_paypal/frontend/shared/select_payment.tpl' => 'views/smarty/frontend/shared/page/checkout/select_payment.tpl', + '@osc_paypal/frontend/shared/details_productmain_tobasket.tpl' => + 'views/smarty/frontend/shared/page/details/inc/details_productmain_tobasket.tpl', // PAYPAL-486 Theme-specific - 'modules/osc/paypal/change_payment_flow.tpl' => 'osc/paypal/views/tpl/flow/page/checkout/change_payment.tpl', - 'modules/osc/paypal/change_payment_wave.tpl' => 'osc/paypal/views/tpl/wave/page/checkout/change_payment.tpl', + '@osc_paypal/frontend/flow/change_payment.tpl' => 'views/smarty/frontend/flow/page/checkout/change_payment.tpl', + '@osc_paypal/frontend/wave/change_payment.tpl' => 'views/smarty/frontend/wave/page/checkout/change_payment.tpl', // PSPAYPAL-491 Installment banners - 'modules/osc/paypal/installment_banners.tpl' => 'osc/paypal/views/tpl/shared/installment_banners.tpl', - - 'modules/osc/paypal/applepay.tpl' => 'osc/paypal/views/tpl/shared/applepay.tpl', + '@osc_paypal/frontend/shared/installment_banners.tpl' => 'views/smarty/frontend/shared/installment_banners.tpl', // PSPAYPAL-685 Installment banners - 'modules/osc/paypal/googlepay.tpl' => 'osc/paypal/views/tpl/shared/googlepay.tpl', + '@osc_paypal/frontend/shared/googlepay.tpl' => 'views/smarty/frontend/shared/googlepay.tpl', + + '@osc_paypal/frontend/shared/applepay.tpl' => 'views/smarty/frontend/shared/applepay.tpl', //PSPAYPAL-680 Vaulting - 'modules/osc/paypal/account_vaulting_paypal.tpl' => 'osc/paypal/views/tpl/shared/page/account/account_vaulting_paypal.tpl', - 'modules/osc/paypal/account_vaulting_card.tpl' => 'osc/paypal/views/tpl/shared/page/account/account_vaulting_card.tpl', - 'modules/osc/paypal/vaultedpaymentsources.tpl' => 'osc/paypal/views/tpl/shared/vaultedpaymentsources.tpl', - 'modules/osc/paypal/vaultedpaymentsources_flow.tpl' => 'osc/paypal/views/tpl/flow/vaulting/vaultedpaymentsources.tpl', - 'modules/osc/paypal/vaultedpaymentsources_wave.tpl' => 'osc/paypal/views/tpl/wave/vaulting/vaultedpaymentsources.tpl', + '@osc_paypal/frontend/shared/account_vaulting_paypal.tpl' => 'views/smarty/frontend/shared/page/account/account_vaulting_paypal.tpl', + '@osc_paypal/frontend/shared/account_vaulting_card.tpl' => 'views/smarty/frontend/shared/page/account/account_vaulting_card.tpl', + '@osc_paypal/frontend/shared/vaultedpaymentsources.tpl' => 'views/smarty/frontend/shared/vaultedpaymentsources.tpl', + '@osc_paypal/frontend/flow/vaultedpaymentsources.tpl' => 'views/smarty/frontend/flow/vaulting/vaultedpaymentsources.tpl', + '@osc_paypal/frontend/wave/vaultedpaymentsources.tpl' => 'views/smarty/frontend/wave/vaulting/vaultedpaymentsources.tpl', ], 'blocks' => [ [ 'template' => 'headitem.tpl', 'block' => 'admin_headitem_inccss', - 'file' => 'views/smarty/admin/blocks/headitem__admin_headitem_inccss.tpl' + 'file' => 'views/smarty/admin/blocks/admin_headitem_inccss.tpl' ], [ 'template' => 'headitem.tpl', 'block' => 'admin_headitem_incjs', - 'file' => 'views/smarty/admin/blocks/headitem__admin_headitem_incjs.tpl' + 'file' => 'views/smarty/admin/blocks/admin_headitem_incjs.tpl' ], [ 'template' => 'order_main.tpl', 'block' => 'admin_order_main_form_shipping', - 'file' => 'views/smarty/admin/blocks/order_main__admin_order_main_form_shipping.tpl' + 'file' => 'views/smarty/admin/blocks/admin_order_main_form_shipping.tpl' ], [ 'template' => 'order_main.tpl', 'block' => 'admin_order_main_send_order', - 'file' => 'views/smarty/admin/blocks/order_main__admin_order_main_send_order.tpl' + 'file' => 'views/smarty/admin/blocks/admin_order_main_send_order.tpl' ], - [ 'template' => 'layout/base.tpl', 'block' => 'base_js', - 'file' => 'views/smarty/frontend/blocks/layout/base__base_js.tpl' + 'file' => 'views/smarty/frontend/blocks/layout/base_js.tpl' ], [ 'template' => 'layout/base.tpl', 'block' => 'base_style', - 'file' => 'views/smarty/frontend/blocks/layout/base__base_style.tpl' - ], - [ - 'template' => 'page/checkout/basket.tpl', - 'block' => 'basket_btn_next_bottom', - 'file' => '/views/blocks/page/checkout/basket_btn_next_bottom.tpl', - ], - [ - 'template' => 'widget/minibasket/minibasket.tpl', - 'block' => 'dd_layout_page_header_icon_menu_minibasket_functions', - 'file' => '/views/blocks/widget/minibasket/dd_layout_page_header_icon_menu_minibasket_functions.tpl', - ], - [ - 'template' => 'payment_main.tpl', - 'block' => 'admin_payment_main_form', - 'file' => '/views/blocks/admin/admin_payment_main_form.tpl', + 'file' => 'views/smarty/frontend/blocks/layout/base_style.tpl' ], - // @Todo PAYPAL-486: Using the same file, with 2 themes. Should be more generic, if possible. [ - 'template' => 'page/checkout/payment.tpl', - 'block' => 'select_payment', - 'file' => '/views/blocks/page/checkout/select_payment.tpl', + 'template' => 'page/account/inc/account_menu.tpl', + 'block' => 'account_menu', + 'file' => 'views/smarty/frontend/blocks/page/account/inc/account_menu.tpl', ], [ - 'template' => 'page/checkout/payment.tpl', - 'block' => 'change_payment', - 'file' => '/views/blocks/page/checkout/change_payment.tpl', + 'template' => 'page/checkout/basket.tpl', + 'block' => 'basket_btn_next_bottom', + 'file' => 'views/smarty/frontend/blocks/page/checkout/basket_btn_next_bottom.tpl', ], [ 'template' => 'page/checkout/basket.tpl', 'block' => 'checkout_basket_next_step_top', - 'file' => 'views/smarty/frontend/blocks/page/checkout/basket__checkout_basket_next_step_top.tpl', + 'file' => 'views/smarty/frontend/blocks/page/checkout/basket_installment_banner_after.tpl', ], [ 'template' => 'page/checkout/basket.tpl', 'block' => 'checkout_basket_emptyshippingcart', - 'file' => 'views/smarty/frontend/blocks/page/checkout/basket__checkout_basket_emptyshippingcart.tpl', + 'file' => 'views/smarty/frontend/blocks/page/checkout/basket_installment_banner_before.tpl', ], [ - 'template' => 'payment_main.tpl', - 'block' => 'admin_payment_main_form', - 'file' => '/views/blocks/admin/admin_payment_main_form.tpl', + 'template' => 'page/checkout/order.tpl', + 'block' => 'checkout_order_btn_submit_bottom', + 'file' => 'views/smarty/frontend/blocks/page/checkout/checkout_order_btn_submit_bottom.tpl' ], [ - 'template' => 'page/checkout/payment.tpl', - 'block' => 'select_payment', - 'file' => 'views/smarty/frontend/blocks/page/checkout/payment__select_payment.tpl', + 'template' => 'page/checkout/order.tpl', + 'block' => 'shippingAndPayment', + 'file' => 'views/smarty/frontend/blocks/page/checkout/shipping_and_payment.tpl', ], [ 'template' => 'page/checkout/payment.tpl', 'block' => 'change_payment', - 'file' => 'views/smarty/frontend/blocks/page/checkout/payment__change_payment.tpl', + 'file' => 'views/smarty/frontend/blocks/page/checkout/change_payment.tpl', ], [ 'template' => 'page/checkout/payment.tpl', 'block' => 'checkout_payment_main', - 'file' => 'views/smarty/frontend/blocks/page/checkout/payment__checkout_payment_main.tpl', + 'file' => 'views/smarty/frontend/blocks/page/checkout/basket_installment_banner_before.tpl', ], [ - 'template' => 'page/checkout/order.tpl', - 'block' => 'shippingAndPayment', - 'file' => 'views/smarty/frontend/blocks/page/checkout/order__shippingAndPayment.tpl', + 'template' => 'page/checkout/payment.tpl', + 'block' => 'select_payment', + 'file' => 'views/smarty/frontend/blocks/page/checkout/select_payment.tpl', ], [ - 'template' => 'page/details/inc/productmain.tpl', - 'block' => 'details_productmain_tobasket', - 'file' => 'views/smarty/frontend/blocks/page/details/inc/productmain__details_productmain_tobasket.tpl', + 'template' => 'page/checkout/thankyou.tpl', + 'block' => 'checkout_thankyou_info', + 'file' => 'views/smarty/frontend/blocks/page/checkout/thankyou.tpl', ], [ 'template' => 'page/details/inc/productmain.tpl', 'block' => 'details_productmain_price_value', - 'file' => 'views/smarty/frontend/blocks/page/details/inc/productmain__details_productmain_price_value.tpl', + 'file' => 'views/smarty/frontend/blocks/page/details/inc/details_productmain_price_value.tpl', ], [ - 'template' => 'page/list/list.tpl', - 'block' => 'page_list_listhead', - 'file' => 'views/smarty/frontend/blocks/page/list/list__page_list_listhead.tpl', + 'template' => 'page/details/inc/productmain.tpl', + 'block' => 'details_productmain_tobasket', + 'file' => 'views/smarty/frontend/blocks/page/details/inc/details_productmain_tobasket.tpl', ], [ - 'template' => 'page/shop/start.tpl', - 'block' => 'start_newest_articles', - 'file' => 'views/smarty/frontend/blocks/page/shop/start__start_newest_articles.tpl', + 'template' => 'page/list/list.tpl', + 'block' => 'page_list_listhead', + 'file' => 'views/smarty/frontend/blocks/page/list/page_list_listhead.tpl', ], [ - 'template' => 'page/account/inc/account_menu.tpl', - 'block' => 'account_menu', - 'file' => '/views/blocks/page/account/inc/account_menu.tpl', + 'template' => 'page/search/search.tpl', + 'block' => 'search_header', + 'file' => 'views/smarty/frontend/blocks/page/search/search.tpl' ], [ - 'template' => 'page/checkout/thankyou.tpl', - 'block' => 'checkout_thankyou_info', - 'file' => '/views/blocks/page/checkout/thankyou.tpl', + 'template' => 'page/shop/start.tpl', + 'block' => 'start_welcome_text', + 'file' => 'views/smarty/frontend/blocks/page/shop/start.tpl', ], - // <-- PSPAYPAL-491 [ 'template' => 'widget/minibasket/minibasket.tpl', 'block' => 'dd_layout_page_header_icon_menu_minibasket_functions', - 'file' => 'views/smarty/frontend/blocks/widget/minibasket/minibasket__dd_layout_page_header_icon_menu_minibasket_functions.tpl', + 'file' => 'views/smarty/frontend/blocks/widget/minibasket/dd_layout_page_header_icon_menu_minibasket_functions.tpl', ], ], 'settings' => [ @@ -565,24 +531,12 @@ 'value' => 60, 'group' => null ], - [ - 'name' => 'oscPayPalActivePayments', - 'type' => 'arr', - 'value' => [], - 'group' => null - ], [ 'group' => null, 'name' => 'oscPayPalLocales', 'type' => 'str', 'value' => 'de_DE,en_US', ], - [ - 'name' => 'oscPayPalDefaultShippingPriceExpress', - 'type' => 'num', - 'value' => 3.5, - 'group' => null - ], [ 'name' => 'oscPayPalSetVaulting', 'type' => 'bool', @@ -597,8 +551,14 @@ ], [ 'name' => 'oscPayPalDefaultShippingPriceExpress', - 'type' => 'float', - 'value' => 3.5, + 'type' => 'str', + 'value' => '3.5', + 'group' => null + ], + [ + 'name' => 'oscPayPalUseStructuralCustomIdSchema', + 'type' => 'bool', + 'value' => false, 'group' => null ], ], diff --git a/src/Component/BasketComponent.php b/src/Component/BasketComponent.php index d50abc644..1a8aab321 100644 --- a/src/Component/BasketComponent.php +++ b/src/Component/BasketComponent.php @@ -16,11 +16,11 @@ class BasketComponent extends BasketComponent_parent { /** - * @param $sProductId - * @param $dAmount - * @param $aSel - * @param $aPersParam - * @param $blOverride + * @param $sProductId + * @param $dAmount + * @param $aSel + * @param $aPersParam + * @param $blOverride * @return mixed */ public function changeBasket( @@ -35,11 +35,11 @@ public function changeBasket( } /** - * @param $sProductId - * @param $dAmount - * @param $aSel - * @param $aPersParam - * @param $blOverride + * @param $sProductId + * @param $dAmount + * @param $aSel + * @param $aPersParam + * @param $blOverride * @return mixed */ public function toBasket($sProductId = null, $dAmount = null, $aSel = null, $aPersParam = null, $blOverride = false) @@ -51,7 +51,6 @@ public function toBasket($sProductId = null, $dAmount = null, $aSel = null, $aPe /** * Resets the session if the user has previously authorized a payment * with PayPal Express and is now adding or changing an item to the basket. - * * @return void */ protected function resetExpressOrderAndShowError() diff --git a/src/Component/UserComponent.php b/src/Component/UserComponent.php index d6980731a..791f95e55 100644 --- a/src/Component/UserComponent.php +++ b/src/Component/UserComponent.php @@ -7,9 +7,11 @@ namespace OxidSolutionCatalysts\PayPal\Component; +use OxidEsales\Eshop\Core\Exception\UserException; use OxidEsales\Eshop\Core\Registry; use OxidEsales\Eshop\Application\Model\User; use OxidSolutionCatalysts\PayPal\Core\Utils\PayPalAddressResponseToOxidAddress; +use OxidSolutionCatalysts\PayPalApi\Model\Orders\Order; /** * @mixin \OxidEsales\Eshop\Application\Component\UserComponent @@ -40,7 +42,7 @@ public function login_noredirect() //phpcs:ignore PSR1.Methods.CamelCapsMethodNa } } - public function createPayPalGuestUser(\OxidSolutionCatalysts\PayPalApi\Model\Orders\Order $response): void + public function createPayPalGuestUser(Order $response): void { $this->setParent(oxNew('Register')); @@ -57,9 +59,11 @@ public function createPayPalGuestUser(\OxidSolutionCatalysts\PayPalApi\Model\Ord } /** - * @param \OxidSolutionCatalysts\PayPalApi\Model\Orders\Order $response + * @param Order $response + * @return bool + * @throws UserException */ - public function loginPayPalCustomer(\OxidSolutionCatalysts\PayPalApi\Model\Orders\Order $response): bool + public function loginPayPalCustomer(Order $response): bool { $user = oxNew(User::class); @@ -78,7 +82,7 @@ public function loginPayPalCustomer(\OxidSolutionCatalysts\PayPalApi\Model\Order /** * @param string $paramName - * @param mixed $paramValue + * @param mixed $paramValue */ protected function setRequestParameterByPayPal(string $paramName, $paramValue): void { diff --git a/src/Controller/Admin/OrderMain.php b/src/Controller/Admin/OrderMain.php index ad4c99b2b..22a0a045b 100644 --- a/src/Controller/Admin/OrderMain.php +++ b/src/Controller/Admin/OrderMain.php @@ -16,18 +16,16 @@ use OxidSolutionCatalysts\PayPalApi\Exception\ApiException; /** - * OrderMain class - * - * @mixin \OxidEsales\Eshop\Application\Controller\Admin\OrderMain - */ +* OrderMain class +* +* @mixin \OxidEsales\Eshop\Application\Controller\Admin\OrderMain +*/ class OrderMain extends OrderMain_parent { use AdminOrderTrait; use JsonTrait; - /** - * @var array|null - */ + /** @var array|null */ protected $trackingCarrierCountries = null; /** @@ -67,6 +65,9 @@ public function save() parent::save(); } + /** + * @throws StandardException + */ public function getPayPalTrackingCode(): string { return $this->getOrder()->getPayPalTrackingCode(); diff --git a/src/Controller/Admin/OrderOverview.php b/src/Controller/Admin/OrderOverview.php index 22ebd5222..388c8401b 100644 --- a/src/Controller/Admin/OrderOverview.php +++ b/src/Controller/Admin/OrderOverview.php @@ -10,10 +10,10 @@ use OxidSolutionCatalysts\PayPal\Traits\AdminOrderTrait; /** - * OrderMain class - * - * @mixin \OxidEsales\Eshop\Application\Controller\Admin\OrderOverview - */ +* OrderMain class +* +* @mixin \OxidEsales\Eshop\Application\Controller\Admin\OrderOverview +*/ class OrderOverview extends OrderOverview_parent { use AdminOrderTrait; diff --git a/src/Controller/Admin/PayPalConfigController.php b/src/Controller/Admin/PayPalConfigController.php index 0b39ee3cf..342faf128 100644 --- a/src/Controller/Admin/PayPalConfigController.php +++ b/src/Controller/Admin/PayPalConfigController.php @@ -61,14 +61,11 @@ public function render() /** * Template Getter: Get a Link for SignUp the Live Merchant Integration * see getSignUpMerchantIntegrationLink - * * @return string */ public function getLiveSignUpMerchantIntegrationLink(): string { - /** - * @var PartnerConfig $partnerConfig -*/ + /** @var PartnerConfig $partnerConfig */ $partnerConfig = oxNew(PartnerConfig::class); return $this->buildSignUpLink( @@ -82,14 +79,11 @@ public function getLiveSignUpMerchantIntegrationLink(): string /** * Template Getter: Get a Link for SignUp the Live Merchant Integration * see getSignUpMerchantIntegrationLink - * * @return string */ public function getSandboxSignUpMerchantIntegrationLink(): string { - /** - * @var PartnerConfig $partnerConfig -*/ + /** @var PartnerConfig $partnerConfig */ $partnerConfig = oxNew(PartnerConfig::class); return $this->buildSignUpLink( @@ -159,9 +153,7 @@ public function createNonce(): string return $session->getVariable('PAYPAL_MODULE_NONCE'); } - /** - * @var PartnerConfig $partnerConfig -*/ + /** @var PartnerConfig $partnerConfig */ $partnerConfig = oxNew(PartnerConfig::class); $nonce = $partnerConfig->createNonce(); @@ -205,13 +197,11 @@ protected function saveConfig(array $conf): void protected function checkEligibility(array $confArr): void { $config = new Config(); - /** - * skip check if no client ID provided -*/ + /** skip check if no client ID provided */ if ( - $config->getClientId() === '' - || $config->getMerchantId() === '' - || $config->getWebhookId() === '' + $config->getClientId() === '' || + $config->getMerchantId() === '' || + $config->getWebhookId() === '' ) { return; } @@ -233,9 +223,7 @@ protected function checkEligibility(array $confArr): void } } catch (ClientException | ApiException $exception) { - /** - * @var Logger $logger -*/ + /** @var Logger $logger */ $logger = $this->getServiceFromContainer(Logger::class); $logger->log('error', 'Error on checkEligibility', [$exception]); } @@ -288,12 +276,6 @@ protected function handleSpecialFields(array $conf): array if (!isset($conf['oscPayPalCleanUpNotFinishedOrdersAutomaticlly'])) { $conf['oscPayPalCleanUpNotFinishedOrdersAutomaticlly'] = false; } - if (!isset($conf['oscPayPalDefaultShippingPriceExpress'])) { - $conf['oscPayPalDefaultShippingPriceExpress'] = false; - } else { - $dAmount = (float) str_replace(',', '.', $conf['oscPayPalDefaultShippingPriceExpress']); - $conf['oscPayPalDefaultShippingPriceExpress'] = $dAmount; - } if (!isset($conf['oscPayPalSetVaulting'])) { $conf['oscPayPalSetVaulting'] = false; } @@ -306,6 +288,9 @@ protected function handleSpecialFields(array $conf): array $dAmount = (string) str_replace(',', '.', $conf['oscPayPalDefaultShippingPriceExpress']); $conf['oscPayPalDefaultShippingPriceExpress'] = $dAmount; } + if (!isset($conf['oscPayPalUseStructuralCustomIdSchema'])) { + $conf['oscPayPalUseStructuralCustomIdSchema'] = false; + } return $conf; } @@ -325,7 +310,6 @@ public function getTotalCycleDefaults() /** * Template variable getter, check whether legacy oepaypal module exists and show button when config value is false - * * @return bool */ public function showTransferLegacySettingsButton(): bool @@ -385,7 +369,6 @@ public function transferBannerSettings() /** * Get ClientID, ClientSecret, WebhookID - * * @throws JsonException */ public function autoConfigurationFromCallback() @@ -394,9 +377,7 @@ public function autoConfigurationFromCallback() $requestReader = oxNew(RequestReader::class); PayPalSession::storeOnboardingPayload($requestReader->getRawPost()); } catch (\Exception $exception) { - /** - * @var Logger $logger -*/ + /** @var Logger $logger */ $logger = $this->getServiceFromContainer(Logger::class); $logger->log('error', $exception->getMessage(), [$exception]); } @@ -415,9 +396,7 @@ public function returnFromSignup() $request = Registry::getRequest(); if ($merchantId = (string)$request->getRequestParameter('merchantIdInPayPal')) { - /** - * @var ModuleSettings $moduleSettings -*/ + /** @var ModuleSettings $moduleSettings */ $moduleSettings = $this->getServiceFromContainer(ModuleSettings::class); $isSandbox = (string)$request->getRequestParameter('isSandbox'); $isSandbox = $isSandbox === '1'; @@ -443,15 +422,11 @@ protected function autoConfiguration(): array $credentials = []; try { - /** - * @var Onboarding $handler -*/ + /** @var Onboarding $handler */ $handler = oxNew(Onboarding::class); $credentials = $handler->autoConfigurationFromCallback(); } catch (\Exception $exception) { - /** - * @var Logger $logger -*/ + /** @var Logger $logger */ $logger = $this->getServiceFromContainer(Logger::class); $logger->log('error', $exception->getMessage(), [$exception]); } @@ -466,17 +441,13 @@ protected function registerWebhooks(): string $webhookId = ''; try { - /** - * @var Webhook $handler -*/ + /** @var Webhook $handler */ $handler = oxNew(Webhook::class); $webhookId = $handler->ensureWebhook(); } catch (OnboardingException $exception) { Registry::getUtilsView()->addErrorToDisplay($exception->getMessage()); } catch (\Exception $exception) { - /** - * @var Logger $logger -*/ + /** @var Logger $logger */ $logger = $this->getServiceFromContainer(Logger::class); $logger->log('error', $exception->getMessage(), [$exception]); } diff --git a/src/Controller/Admin/PayPalOrderController.php b/src/Controller/Admin/PayPalOrderController.php index efd553821..df115e27f 100644 --- a/src/Controller/Admin/PayPalOrderController.php +++ b/src/Controller/Admin/PayPalOrderController.php @@ -11,7 +11,6 @@ use OxidEsales\Eshop\Application\Model\Order; use OxidEsales\Eshop\Core\Exception\StandardException; use OxidEsales\Eshop\Core\Registry; -use OxidSolutionCatalysts\PayPal\Service\Logger; use OxidSolutionCatalysts\PayPal\Core\Constants; use OxidSolutionCatalysts\PayPal\Core\ServiceFactory; use OxidSolutionCatalysts\PayPal\Model\PayPalOrder as PayPalModelPayPalOrder; @@ -118,38 +117,34 @@ public function render() if ($order->paidWithPayPal()) { // normal paypal order try { - /** - * @var PayPalOrder $paypalOrder -*/ + /** @var PayPalOrder $paypalOrder */ $paypalOrder = $this->getPayPalCheckoutOrder(); $this->addTplParam('payPalOrder', $paypalOrder); - /** - * @var ?Capture $capture -*/ + /** @var ?Capture $capture */ $capture = $order->getOrderPaymentCapture(); $this->addTplParam('capture', $capture); $transactionId = $capture ? $capture->id : ''; - /** - * @var \OxidSolutionCatalysts\PayPal\Model\PayPalOrder $paypalOrderModel -*/ + /** @var PayPalModelPayPalOrder $paypalOrderModel */ $paypalOrderModel = $this->getServiceFromContainer(OrderRepository::class) ->paypalOrderByOrderIdAndPayPalId($orderId, $paypalOrder->id, $transactionId); $this->addTplParam('payPalOrderDetails', $paypalOrderModel); //TODO: refactor, this is workaround if webhook failed to update information if ( - $capture - && + $capture && ( - (ApiOrderModel::STATUS_SAVED === $paypalOrderModel->getStatus() - && Capture::STATUS_COMPLETED === $capture->status) - || ( - Capture::STATUS_COMPLETED === $paypalOrderModel->getStatus() - && (Capture::STATUS_REFUNDED === $capture->status - || Capture::STATUS_PARTIALLY_REFUNDED === $capture->status) + ApiOrderModel::STATUS_SAVED === $paypalOrderModel->getStatus() && + Capture::STATUS_COMPLETED === $capture->status + ) || + ( + Capture::STATUS_COMPLETED === $paypalOrderModel->getStatus() && + ( + Capture::STATUS_REFUNDED === $capture->status || + Capture::STATUS_PARTIALLY_REFUNDED === $capture->status + ) ) ) ) { @@ -160,8 +155,8 @@ public function render() $this->addTplParam('error', $lang->translateString('OSC_PAYPAL_ERROR_' . $exception->getErrorIssue())); } } elseif ( - $order->getFieldData('oxpaymenttype') == $this->payPalPlusPaymentType - && !$order->tableExitsForPayPalPlus() + $order->getFieldData('oxpaymenttype') === $this->payPalPlusPaymentType && + !$order->tableExitsForPayPalPlus() ) { $this->addTplParam('error', $lang->translateString('OSC_PAYPAL_PAYPALPLUS_TABLE_DOES_NOT_EXISTS')); } elseif ($order->paidWithPayPalPlus()) { @@ -169,8 +164,8 @@ public function render() $this->addTplParam('payPalOrder', $this->getPayPalPlusOrder()); $result = "@osc_paypal/admin/oscpaypalorder_ppplus"; } elseif ( - $order->getFieldData('oxpaymenttype') == $this->payPalSoapPaymentType - && !$order->tableExitsForPayPalSoap() + $order->getFieldData('oxpaymenttype') === $this->payPalSoapPaymentType && + !$order->tableExitsForPayPalSoap() ) { $this->addTplParam('error', $lang->translateString('OSC_PAYPAL_PAYPALSOAP_TABLE_DOES_NOT_EXISTS')); } elseif ($order->paidWithPayPalSoap()) { @@ -199,9 +194,6 @@ public function refund(): void $refundAll = $request->getRequestEscapedParameter('refundAll'); $noteToPayer = $request->getRequestEscapedParameter('noteToPayer'); - /** - * @var Order $order -*/ $order = $this->getOrder(); $capture = $order->getOrderPaymentCapture(); @@ -215,27 +207,18 @@ public function refund(): void $request->amount->value = $refundAmount; } - /** - * @var Payments $paymentService -*/ + /** @var Payments $paymentService */ $apiPaymentService = Registry::get(ServiceFactory::class)->getPaymentService(); - /** - * @var OrderRepository $orderRepository -*/ + /** @var OrderRepository $orderRepository */ $orderRepository = $this->getServiceFromContainer(OrderRepository::class); - /** - * @var PayPalModelPayPalOrder $payPalOrder -*/ $payPalOrder = $orderRepository->paypalOrderByOrderIdAndPayPalId( $order->getId(), '', $order->getFieldData('oxtransid') ); - /** - * @var Refund $refund -*/ + /** @var Refund $refund */ $refund = $apiPaymentService->refundCapturedPayment( $capture->id, $request, @@ -243,9 +226,7 @@ public function refund(): void Constants::PAYPAL_PARTNER_ATTRIBUTION_ID_PPCP ); - /** - * @var PaymentService $paymentService -*/ + /** @var PaymentService $paymentService */ $paymentService = $this->getServiceFromContainer(PaymentService::class); $paymentService->trackPayPalOrder( $order->getId(), diff --git a/src/Controller/OrderController.php b/src/Controller/OrderController.php index f981ab1bb..ae8ff5bf8 100644 --- a/src/Controller/OrderController.php +++ b/src/Controller/OrderController.php @@ -12,6 +12,7 @@ use OxidEsales\Eshop\Core\DisplayError; use OxidEsales\Eshop\Core\Exception\StandardException; use OxidEsales\Eshop\Core\Registry; +use OxidSolutionCatalysts\PayPal\Service\Logger; use OxidSolutionCatalysts\PayPal\Core\Constants; use OxidSolutionCatalysts\PayPal\Core\PayPalDefinitions; use OxidSolutionCatalysts\PayPal\Core\PayPalSession; @@ -21,7 +22,6 @@ use OxidSolutionCatalysts\PayPal\Exception\Redirect; use OxidSolutionCatalysts\PayPal\Exception\RedirectWithMessage; use OxidSolutionCatalysts\PayPal\Model\Order as PayPalOrderModel; -use OxidSolutionCatalysts\PayPal\Service\Logger; use OxidSolutionCatalysts\PayPal\Service\ModuleSettings; use OxidSolutionCatalysts\PayPal\Service\Payment as PaymentService; use OxidSolutionCatalysts\PayPal\Service\UserRepository; @@ -36,7 +36,6 @@ /** * Class OrderController - * * @package OxidSolutionCatalysts\PayPal\Controller * * @mixin \OxidEsales\Eshop\Application\Controller\OrderController @@ -83,11 +82,11 @@ public function render() } if ( - $paymentService->getSessionPaymentId() === PayPalDefinitions::SEPA_PAYPAL_PAYMENT_ID - || $paymentService->getSessionPaymentId() === PayPalDefinitions::CCALTERNATIVE_PAYPAL_PAYMENT_ID - || $paymentService->getSessionPaymentId() === PayPalDefinitions::STANDARD_PAYPAL_PAYMENT_ID - || $paymentService->getSessionPaymentId() === PayPalDefinitions::PAYLATER_PAYPAL_PAYMENT_ID - || $paymentService->getSessionPaymentId() === PayPalDefinitions::GOOGLEPAY_PAYPAL_PAYMENT_ID + $paymentService->getSessionPaymentId() === PayPalDefinitions::SEPA_PAYPAL_PAYMENT_ID || + $paymentService->getSessionPaymentId() === PayPalDefinitions::CCALTERNATIVE_PAYPAL_PAYMENT_ID || + $paymentService->getSessionPaymentId() === PayPalDefinitions::STANDARD_PAYPAL_PAYMENT_ID || + $paymentService->getSessionPaymentId() === PayPalDefinitions::PAYLATER_PAYPAL_PAYMENT_ID || + $paymentService->getSessionPaymentId() === PayPalDefinitions::GOOGLEPAY_PAYPAL_PAYMENT_ID ) { $paymentService->removeTemporaryOrder(); } @@ -95,20 +94,20 @@ public function render() $user = $this->getUser(); if ($user) { - $isVaultingPossible = false; + $paymentId = (string) $paymentService->getSessionPaymentId(); + $moduleSettings = $this->getServiceFromContainer(ModuleSettings::class); - if ($moduleSettings->getIsVaultingActive() && $user->getFieldData('oxpassword')) { - $isVaultingPossible = true; - } + $isVaultingPossible = $moduleSettings->isVaultingAllowedForPayment($paymentId) + && $user->getFieldData('oxpassword'); $this->addTplParam('oscpaypal_isVaultingPossible', $isVaultingPossible); $selectedVaultPaymentSourceIndex = $session->getVariable("selectedVaultPaymentSourceIndex"); if ( - $isVaultingPossible - && !is_null($selectedVaultPaymentSourceIndex) - && $payPalCustomerId = $user->getFieldData("oscpaypalcustomerid") + $isVaultingPossible && + !is_null($selectedVaultPaymentSourceIndex) && + $payPalCustomerId = $user->getFieldData("oscpaypalcustomerid") ) { $vaultingService = Registry::get(ServiceFactory::class)->getVaultingService(); @@ -144,16 +143,16 @@ protected function renderRetryOrderExecution(): bool $order->load(Registry::getSession()->getVariable('sess_challenge')); if ( - !$order->getFieldData('oxtransid') - && $retryRequest - && isset($this->retryPaymentMessages[$retryRequest]) + !$order->getFieldData('oxtransid') && + $retryRequest && + isset($this->retryPaymentMessages[$retryRequest]) ) { $displayError = oxNew(DisplayError::class); $displayError->setMessage($this->retryPaymentMessages[$retryRequest]); Registry::getUtilsView()->addErrorToDisplay($displayError); $paymentService = $this->getServiceFromContainer(PaymentService::class); - if (in_array((string) $paymentService->getSessionPaymentId(), $this->removeTemporaryOrderOnRetry)) { + if (in_array((string)$paymentService->getSessionPaymentId(), $this->removeTemporaryOrderOnRetry, true)) { $paymentService->removeTemporaryOrder(); } return true; @@ -184,9 +183,9 @@ public function createAcdcOrder(): void $acdcStatus = Registry::getSession()->getVariable(Constants::SESSION_ACDC_PAYPALORDER_STATUS); if ( - $sessionOrderId - && $sessionAcdcOrderId - && $acdcStatus === Constants::PAYPAL_STATUS_COMPLETED + $sessionOrderId && + $sessionAcdcOrderId && + $acdcStatus === Constants::PAYPAL_STATUS_COMPLETED ) { //we already have a completed acdc order $this->outputJson(['acdcerror' => 'shop order already completed']); @@ -199,16 +198,16 @@ public function createAcdcOrder(): void Registry::getSession()->setVariable('sess_challenge', $this->getUtilsObjectInstance()->generateUID()); $status = $this->execute(); } catch (Exception $exception) { - /** - * @var Logger $logger -*/ + /** @var Logger $logger */ $logger = $this->getServiceFromContainer(Logger::class); $logger->log('error', $exception->getMessage(), [$exception]); $this->outputJson(['acdcerror' => 'failed to execute shop order']); return; } - $response = $this->doCreatePatchedOrder(); + $response = $paymentService->doCreatePatchedOrder( + Registry::getSession()->getBasket() + ); if (!($paypalOrderId = $response['id'])) { $this->outputJson(['acdcerror' => 'cannot create paypal order']); return; @@ -227,20 +226,21 @@ public function createAcdcOrder(): void $this->outputJson($response); } - public function createGooglePayOrder(): void + + /** + * @throws Exception + */ + public function executeGooglePayOrder(): void { try { $paymentService = $this->getServiceFromContainer(PaymentService::class); - $paymentService->removeTemporaryOrder(); - Registry::getSession()->setVariable('sess_challenge', $this->getUtilsObjectInstance()->generateUID()); - /** - * @var Logger $logger -*/ + + /** @var Logger $logger */ $logger = $this->getServiceFromContainer(Logger::class); $_POST['sDeliveryAddressMD5'] = $this->getDeliveryAddressMD5(); - $paypalOrderId = Registry::getRequest()->getRequestParameter('token'); - $_POST['orderID'] = $paypalOrderId; + $orderId = Registry::getRequest()->getRequestParameter('orderID'); + $_POST['orderID'] = $orderId; $this->execute(); } catch (Exception $exception) { $logger->log('error', $exception->getMessage(), [$exception]); @@ -250,20 +250,20 @@ public function createGooglePayOrder(): void $paymentService->doPatchPayPalOrder( Registry::getSession()->getBasket(), - $paypalOrderId + $orderId ); } public function captureGooglePayOrder(): void { $orderService = Registry::get(ServiceFactory::class)->getOrderService(); - $checkoutOrderId = $_GET['token']; + $orderId = (string) Registry::getRequest()->getRequestParameter('orderID'); $request = new OrderCaptureRequest(); try { $orderService->capturePaymentForOrder( '', - $checkoutOrderId, + $orderId, $request, '', Constants::PAYPAL_PARTNER_ATTRIBUTION_ID_PPCP @@ -283,6 +283,13 @@ public function captureGooglePayOrder(): void $logger = $this->getServiceFromContainer(Logger::class); $logger->log('error', $exception->getMessage(), [$exception]); } + $result = [ + 'location' => [ + 'cl=order&fnc=finalizeGooglePay&token=' . $orderId + ] + ]; + + $this->outputJson($result); } public function captureAcdcOrder(): void @@ -292,15 +299,13 @@ public function captureAcdcOrder(): void $sessionAcdcOrderId = (string) PayPalSession::getCheckoutOrderId(); $acdcStatus = Registry::getSession()->getVariable(Constants::SESSION_ACDC_PAYPALORDER_STATUS); - /** - * @var Logger $logger -*/ + /** @var Logger $logger */ $logger = $this->getServiceFromContainer(Logger::class); if ( - 'COMPLETED' === $acdcStatus - && $sessionOrderId - && $sessionAcdcOrderId + 'COMPLETED' === $acdcStatus && + $sessionOrderId && + $sessionAcdcOrderId ) { $logger->log( 'debug', @@ -371,16 +376,16 @@ public function createApplePayOrder(): void $_POST['sDeliveryAddressMD5'] = $this->getDeliveryAddressMD5(); $status = $this->execute(); } catch (Exception $exception) { - /** - * @var Logger $logger -*/ + /** @var Logger $logger */ $logger = $this->getServiceFromContainer(Logger::class); $logger->log('error', $exception->getMessage(), [$exception]); $this->outputJson(['error' => 'failed to execute shop order' . $exception->getMessage()]); return; } - $response = $this->doCreatePatchedOrder(); + $response = $paymentService->doCreatePatchedOrder( + Registry::getSession()->getBasket() + ); if (!($paypalOrderId = $response['id'])) { $this->outputJson(['error' => 'cannot create paypal order']); return; @@ -405,13 +410,10 @@ public function captureApplePayOrder() $orderId = (string) Registry::getRequest()->getRequestEscapedParameter('orderID'); $orderService = Registry::get(ServiceFactory::class)->getOrderService(); $sessionOrderId = (string) Registry::getSession()->getVariable('sess_challenge'); - $checkoutOrderId = (string) PayPalSession::getCheckoutOrderId(); $request = new OrderCaptureRequest(); $logger = $this->getServiceFromContainer(Logger::class); try { - /** - * @var $result ApiOrderModel -*/ + /** @var $result ApiOrderModel */ $result = $orderService->capturePaymentForOrder( '', $orderId, @@ -462,9 +464,7 @@ public function finalizeApplePay(): string $order->finalizeOrderAfterExternalPayment($sessionGooglePayOrderId, $forceFetchDetails); $goNext = 'thankyou'; } catch (Exception $exception) { - /** - * @var Logger $logger -*/ + /** @var Logger $logger */ $logger = $this->getServiceFromContainer(Logger::class); $logger->log( 'error', @@ -495,9 +495,7 @@ public function finalizepaypalsession(): string try { $paymentService = $this->getServiceFromContainer(PaymentService::class); - /** - * @var PayPalApiModelOrder $payPalOrder -*/ + /** @var PayPalApiModelOrder $payPalOrder */ $payPalOrder = $paymentService->fetchOrderFields((string) $sessionCheckoutOrderId, ''); $vaultingPaymentCompleted = $vaulting && $payPalOrder->status === "COMPLETED"; if (!$vaultingPaymentCompleted && 'APPROVED' !== $payPalOrder->status) { @@ -517,9 +515,7 @@ public function finalizepaypalsession(): string $order->finalizeOrderAfterExternalPayment($sessionCheckoutOrderId); $order->save(); } catch (PayPalException $exception) { - /** - * @var Logger $logger -*/ + /** @var Logger $logger */ $logger = $this->getServiceFromContainer(Logger::class); $logger->log( 'debug', @@ -546,9 +542,7 @@ public function finalizeacdc(): string $order->finalizeOrderAfterExternalPayment($sessionAcdcOrderId, $forceFetchDetails); $goNext = 'thankyou'; } catch (Exception $exception) { - /** - * @var Logger $logger -*/ + /** @var Logger $logger */ $logger = $this->getServiceFromContainer(Logger::class); $logger->log( 'error', @@ -561,19 +555,16 @@ public function finalizeacdc(): string return $goNext; } + public function finalizeGooglePay(): string { - $paypalOrderId = $_GET['token']; + $paypalOrderId = (string) Registry::getRequest()->getRequestParameter('token'); $forceFetchDetails = (bool) Registry::getRequest()->getRequestParameter('fallbackfinalize'); - $this->createGooglePayOrder(); - $this->captureGooglePayOrder(); - $oxidOrderId = Registry::getSession()->getBasket()->getOrderId(); + $oxidOrderId = $oxidOrderId ?: Registry::getSession()->getVariable('sess_challenge'); - /** - * @var GooglePayPayPalService $googlePayPayPalService -*/ + /** @var GooglePayPayPalService $googlePayPayPalService */ $googlePayPayPalService = $this->getServiceFromContainer(GooglePayPayPalService::class); $sucesss = $googlePayPayPalService->finalizeGooglePay($oxidOrderId, $paypalOrderId, $forceFetchDetails); @@ -582,10 +573,27 @@ public function finalizeGooglePay(): string $this->getServiceFromContainer(OrderPayPalService::class)->cancelPayPalSession('cannot finalize order'); } + public function cancelpaypalsession(string $errorcode = null): string + { + //TODO: we get the PayPal order id retuned in token parameter, can be used for paranoia checks + //(string) Registry::getRequest()->getRequestParameter('token') + $requestErrorcode = (string) Registry::getRequest()->getRequestParameter('errorcode'); + + $this->getServiceFromContainer(PaymentService::class) + ->removeTemporaryOrder(); + + $goNext = 'payment'; + if ($errorcode || $requestErrorcode) { + $goNext = 'payment?payerror=2'; + } + + return $goNext; + } + /** * Template-Getter get a Fraudnet CmId * - * @param $response + * @return string * @psalm-suppress InternalMethod */ public function getPayPalPuiFraudnetCmId(): string @@ -600,42 +608,42 @@ public function getPayPalPuiFraudnetCmId(): string protected function getNextStep($success) // phpcs:ignore PSR2.Methods.MethodDeclaration.Underscore { if ( - (PayPalOrderModel::ORDER_STATE_SESSIONPAYMENT_INPROGRESS == $success) - && ($redirectLink = PayPalSession::getSessionRedirectLink()) + (PayPalOrderModel::ORDER_STATE_SESSIONPAYMENT_INPROGRESS === $success) && + ($redirectLink = PayPalSession::getSessionRedirectLink()) ) { PayPalSession::unsetSessionRedirectLink(); throw new Redirect($redirectLink); } - if (PayPalOrderModel::ORDER_STATE_ACDCINPROGRESS == $success) { + if (PayPalOrderModel::ORDER_STATE_ACDCINPROGRESS === $success) { return (string) $success; } - if (PaymentService::PAYMENT_ERROR_PUI_PHONE == $success) { + if (PaymentService::PAYMENT_ERROR_PUI_PHONE === $success) { //user needs to retry, entered pui phone number was not accepted by PayPal return 'order?retryoscpp=puiretry'; } - if (PayPalOrderModel::ORDER_STATE_WAIT_FOR_WEBHOOK_EVENTS == $success) { + if (PayPalOrderModel::ORDER_STATE_WAIT_FOR_WEBHOOK_EVENTS === $success) { return 'order'; } - if (PayPalOrderModel::ORDER_STATE_NEED_CALL_ACDC_FINALIZE == $success) { + if (PayPalOrderModel::ORDER_STATE_NEED_CALL_ACDC_FINALIZE === $success) { return 'order?fnc=finalizeacdc'; } - if (PayPalOrderModel::ORDER_STATE_TIMEOUT_FOR_WEBHOOK_EVENTS == $success) { + if (PayPalOrderModel::ORDER_STATE_TIMEOUT_FOR_WEBHOOK_EVENTS === $success) { return 'order?fnc=finalizeacdc&fallbackfinalize=1'; } - if (PayPalOrderModel::ORDER_STATE_ACDCCOMPLETED == $success) { + if (PayPalOrderModel::ORDER_STATE_ACDCCOMPLETED === $success) { return 'order?fnc=finalizeacdc&fallbackfinalize=1'; } if ( - EshopModelOrder::ORDER_STATE_ORDEREXISTS == $success - && Registry::getSession()->getVariable(Constants::SESSION_ACDC_PAYPALORDER_STATUS) - == Constants::PAYPAL_STATUS_COMPLETED + EshopModelOrder::ORDER_STATE_ORDEREXISTS === $success && + Registry::getSession()->getVariable(Constants::SESSION_ACDC_PAYPALORDER_STATUS) === + Constants::PAYPAL_STATUS_COMPLETED ) { Registry::getSession()->deleteVariable(Constants::SESSION_ACDC_PAYPALORDER_STATUS); PayPalSession::unsetPayPalSession(); @@ -643,16 +651,4 @@ protected function getNextStep($success) // phpcs:ignore PSR2.Methods.MethodDecl return parent::getNextStep($success); } - - private function doCreatePatchedOrder(): array - { - $paymentService = $this->getServiceFromContainer(PaymentService::class); - $order = oxNew(EshopModelOrder::class); - $orderId = Registry::getSession()->getVariable('sess_challenge'); - $order->load($orderId); - return $paymentService->doCreatePatchedOrder( - Registry::getSession()->getBasket(), - $order - ); - } } diff --git a/src/Controller/PayPalVaultingCardController.php b/src/Controller/PayPalVaultingCardController.php index 7e44030b8..613419075 100644 --- a/src/Controller/PayPalVaultingCardController.php +++ b/src/Controller/PayPalVaultingCardController.php @@ -3,38 +3,27 @@ namespace OxidSolutionCatalysts\PayPal\Controller; use OxidEsales\Eshop\Application\Controller\AccountController; -use OxidEsales\Eshop\Core\Registry; -use OxidSolutionCatalysts\PayPal\Core\ServiceFactory; +use OxidSolutionCatalysts\PayPal\Core\Config; +use OxidSolutionCatalysts\PayPal\Service\ModuleSettings; +use OxidSolutionCatalysts\PayPal\Traits\AccountControllerTrait; +use OxidSolutionCatalysts\PayPal\Traits\ServiceContainer; /** - * user account menu for saving paypal for purchase later (vaulting without purchase) + * user account menu for saving paypal (acdc) for purchase later (vaulting without purchase) */ class PayPalVaultingCardController extends AccountController { - /** - * @var string Current class template name. - */ - // phpcs:ignore PSR2.Classes.PropertyDeclaration - protected $_sThisTemplate = 'modules/osc/paypal/account_vaulting_card.tpl'; + use ServiceContainer; + use AccountControllerTrait; public function render() { - $this->_aViewData['vaultingUserId'] = $this->getViewConfig()->getUserIdForVaulting(); + $this->_aViewData['vaultingUserId'] = oxNew(Config::class)->getUserIdForVaulting(); + $moduleSettings = $this->getServiceFromContainer(ModuleSettings::class); + if ($moduleSettings->isVaultingAllowedForACDC()) { + $this->_sThisTemplate = '@osc_paypal/frontend/account_vaulting_card'; + } return parent::render(); } - - public function deleteVaultedPayment() - { - $paymentTokenId = Registry::getRequest()->getRequestEscapedParameter("paymentTokenId"); - $vaultingService = Registry::get(ServiceFactory::class)->getVaultingService(); - - if (!$vaultingService->deleteVaultedPayment($paymentTokenId)) { - Registry::getUtilsView()->addErrorToDisplay( - Registry::getLang()->translateString('OSC_PAYPAL_DELETE_FAILED'), - false, - true - ); - } - } -} +} \ No newline at end of file diff --git a/src/Controller/PayPalVaultingController.php b/src/Controller/PayPalVaultingController.php index 7c5c3d1c5..dbb893496 100644 --- a/src/Controller/PayPalVaultingController.php +++ b/src/Controller/PayPalVaultingController.php @@ -2,40 +2,28 @@ namespace OxidSolutionCatalysts\PayPal\Controller; -use mysql_xdevapi\Exception; use OxidEsales\Eshop\Application\Controller\AccountController; -use OxidEsales\Eshop\Core\Registry; -use OxidSolutionCatalysts\PayPal\Core\ServiceFactory; +use OxidSolutionCatalysts\PayPal\Core\Config; +use OxidSolutionCatalysts\PayPal\Service\ModuleSettings; +use OxidSolutionCatalysts\PayPal\Traits\AccountControllerTrait; +use OxidSolutionCatalysts\PayPal\Traits\ServiceContainer; /** * user account menu for saving paypal for purchase later (vaulting without purchase) */ class PayPalVaultingController extends AccountController { - /** - * @var string Current class template name. - */ - // phpcs:ignore PSR2.Classes.PropertyDeclaration - protected $_sThisTemplate = 'modules/osc/paypal/account_vaulting_paypal.tpl'; + use ServiceContainer; + use AccountControllerTrait; public function render() { - $this->_aViewData['vaultingUserId'] = $this->getViewConfig()->getUserIdForVaulting(); + $this->_aViewData['vaultingUserId'] = oxNew(Config::class)->getUserIdForVaulting(); + $moduleSettings = $this->getServiceFromContainer(ModuleSettings::class); + if ($moduleSettings->isVaultingAllowedForPayPal()) { + $this->_sThisTemplate = '@osc_paypal/frontend/account_vaulting_paypal'; + } return parent::render(); } - - public function deleteVaultedPayment() - { - $paymentTokenId = Registry::getRequest()->getRequestEscapedParameter("paymentTokenId"); - $vaultingService = Registry::get(ServiceFactory::class)->getVaultingService(); - - if (!$vaultingService->deleteVaultedPayment($paymentTokenId)) { - Registry::getUtilsView()->addErrorToDisplay( - Registry::getLang()->translateString('OSC_PAYPAL_DELETE_FAILED'), - false, - true - ); - } - } } diff --git a/src/Controller/PaymentController.php b/src/Controller/PaymentController.php index cca542dfb..fe666f5d0 100644 --- a/src/Controller/PaymentController.php +++ b/src/Controller/PaymentController.php @@ -35,8 +35,8 @@ public function render() } if ( - $paymentService->getSessionPaymentId() === PayPalDefinitions::STANDARD_PAYPAL_PAYMENT_ID - || $paymentService->getSessionPaymentId() === PayPalDefinitions::PAYLATER_PAYPAL_PAYMENT_ID + $paymentService->getSessionPaymentId() === PayPalDefinitions::STANDARD_PAYPAL_PAYMENT_ID || + $paymentService->getSessionPaymentId() === PayPalDefinitions::PAYLATER_PAYPAL_PAYMENT_ID ) { $paymentService->removeTemporaryOrder(); } @@ -53,8 +53,8 @@ public function render() $this->addTplParam('oscpaypal_isVaultingPossible', $isVaultingPossible); if ( - $isVaultingPossible - && ($paypalCustomerId = $user->getFieldData("oscpaypalcustomerid")) + $isVaultingPossible && + ($paypalCustomerId = $user->getFieldData("oscpaypalcustomerid")) ) { $vaultingService = Registry::get(ServiceFactory::class)->getVaultingService(); $vaultedPaymentTokens = $vaultingService->getVaultPaymentTokens($paypalCustomerId)["payment_tokens"]; @@ -62,14 +62,11 @@ public function render() $vaultedPaymentSources = []; foreach ($vaultedPaymentTokens as $vaultedPaymentToken) { foreach ($vaultedPaymentToken["payment_source"] as $paymentType => $paymentSource) { - if (!$this->paymentTypeExists($paymentType)) { - continue; - } - if ($paymentType === "card") { + if ($paymentType === "card" && $moduleSettings->isVaultingAllowedForACDC()) { $string = $lang->translateString("OSC_PAYPAL_CARD_ENDING_IN"); $vaultedPaymentSources[$paymentType][] = $paymentSource["brand"] . " " . $string . $paymentSource["last_digits"]; - } elseif ($paymentType === "paypal") { + } elseif ($paymentType === "paypal" && $moduleSettings->isVaultingAllowedForPayPal()) { $string = $lang->translateString("OSC_PAYPAL_CARD_PAYPAL_PAYMENT"); $vaultedPaymentSources[$paymentType][] = $string . " " . $paymentSource["email_address"]; @@ -88,22 +85,6 @@ public function render() return parent::render(); } - /** - * @param $paymentList - * @param $paymentType - * @return bool - */ - protected function paymentTypeExists($paymentType): bool - { - $paymentList = $this->getPaymentList(); - foreach ($paymentList as $payment) { - if (PayPalDefinitions::isPayPalVaultingPossible($payment->getId(), $paymentType)) { - return true; - } - } - return false; - } - public function getPayPalPuiFraudnetCmId(): string { @@ -145,16 +126,26 @@ public function getPaymentList() foreach ($paymentListRaw as $key => $payment) { if ( - !isset($payPalDefinitions[$key]) - || ( $payPalHealth - // don't add payment that is deprecated - && ( !PayPalDefinitions::isDeprecatedPayment($payment->getId()) ) - && ( empty($payPalDefinitions[$key]['currencies']) - || in_array($actShopCurrency->name, $payPalDefinitions[$key]['currencies'], true) ) - && ( empty($payPalDefinitions[$key]['countries']) - || in_array($userCountryIso, $payPalDefinitions[$key]['countries'], true) ) - && ( $payPalDefinitions[$key]['onlybrutto'] === false - || ( !$isCalculationModeNetto ) )) + !isset($payPalDefinitions[$key]) || + ( + $payPalHealth && + //dont add payment that is deprecated + ( !PayPalDefinitions::isDeprecatedPayment($payment->getId()) ) && + ( + empty($payPalDefinitions[$key]['currencies']) || + in_array($actShopCurrency->name, $payPalDefinitions[$key]['currencies'], true) + ) && + ( + empty($payPalDefinitions[$key]['countries']) || + in_array($userCountryIso, $payPalDefinitions[$key]['countries'], true) + ) && + ( + $payPalDefinitions[$key]['onlybrutto'] === false || + ( + !$isCalculationModeNetto + ) + ) + ) ) { $paymentList[$key] = $payment; } @@ -176,8 +167,8 @@ public function getPaymentList() /** * @inheritDoc * @SuppressWarnings(PHPMD.StaticAccess) - * @return mixed - * @throws PayPalException + * @return mixed + * @throws PayPalException */ public function validatePayment() { @@ -188,9 +179,9 @@ public function validatePayment() // remove the possible exist paypal-payment, if we choose another if ( - $actualPaymentId - && $actualPaymentId !== $newPaymentId - && PayPalDefinitions::isPayPalPayment($actualPaymentId) + $actualPaymentId && + $actualPaymentId !== $newPaymentId && + PayPalDefinitions::isPayPalPayment($actualPaymentId) ) { $paymentService->removeTemporaryOrder(); } diff --git a/src/Controller/ProxyController.php b/src/Controller/ProxyController.php index 28da59955..1703e92d6 100644 --- a/src/Controller/ProxyController.php +++ b/src/Controller/ProxyController.php @@ -8,6 +8,7 @@ namespace OxidSolutionCatalysts\PayPal\Controller; use Exception; +use JsonException; use OxidEsales\Eshop\Application\Component\UserComponent; use OxidEsales\Eshop\Application\Controller\FrontendController; use OxidEsales\Eshop\Application\Model\Address; @@ -101,70 +102,12 @@ public function createOrder() $this->outputJson($response); } - public function getGooglepayBasket() - { - $basket = Registry::getSession()->getBasket(); - $lang = Registry::getLang(); - $actShopCurrency = Registry::getConfig()->getActShopCurrencyObject(); - $blIsAdd = false; - - if ($basket->getItemsCount() === 0) { - $this->addToBasket(); - - $basket = Registry::getSession()->getBasket(); - $blIsAdd = true; - } - $deliveryCost = $basket->getDeliveryCost(); - $deliveryBruttoPrice = $deliveryCost->getBruttoPrice(); - $this->setPayPalPaymentMethod(); - - $sVat = 0; - foreach ($basket->getProductVats(false) as $key => $VATitem) { - $sVat += $VATitem; - } - - $aItems = [ - "displayItems" => [ - [ - "label" => $lang->translateString("TOTAL_NET"), - "type" => "SUBTOTAL", - "price" => number_format((double) $basket->getNettoSum(), 2, '.', ''), - ], - [ - "label" => $lang->translateString("VAT"), - "type" => "TAX", - "price" => number_format((double) $sVat, 2, '.', ''), - ], - [ - "label" => $lang->translateString("SHIPPING"), - "type" => "LINE_ITEM", - "price" => number_format((double) $deliveryBruttoPrice, 2, '.', ''), - "status" => "FINAL" - ] - ], - "countryCode" => strtoupper($lang->getLanguageAbbr()), - "currencyCode" => strtoupper($actShopCurrency->name), - "totalPriceStatus" => "ESTIMATED", - "totalPrice" => number_format((double) $basket->getPrice()->getBruttoPrice(), 2, '.', ''), - "totalPriceLabel" => $lang->translateString("TOTAL"), - ]; - if ($blIsAdd) { - if ($aid = (string)Registry::getRequest()->getRequestEscapedParameter('aid')) { - try { - $basket->addToBasket($aid, 0); - $basket->calculateBasket(false); - } catch (NoArticleException $exception) { - } - } - } - - $utils = Registry::getUtils(); - $utils->showMessageAndExit(json_encode($aItems)); - } - - public function createGooglepayOrder() + /** + * @throws JsonException + */ + public function createGooglePayOrder() { - $data = json_decode(file_get_contents('php://input'), true); + $data = json_decode(file_get_contents('php://input'), true, 512, JSON_THROW_ON_ERROR); $shippingAddress = new AddressPortable(); $shippingAddress->address_line_1 = $data['shippingAddress']['address1'] ?? ''; @@ -188,7 +131,6 @@ public function createGooglepayOrder() $this->addToBasket(); $this->setPayPalPaymentMethod($paymentId); $basket = Registry::getSession()->getBasket(); - $config = Registry::getConfig(); if ($basket->getItemsCount() === 0) { $this->outputJson(['ERROR' => 'No Article in the Basket']); @@ -244,9 +186,7 @@ public function createGooglepayOrder() } if ($user = $this->getUser()) { - /** - * @var array $userInvoiceAddress - */ + /** @var array $userInvoiceAddress */ $userInvoiceAddress = $user->getInvoiceAddress(); // add PayPal-Address as Delivery-Address if (($response !== null) && !empty($response->purchase_units[0]->shipping)) { @@ -289,21 +229,22 @@ public function createGooglepayOrder() } + /** + * @throws JsonException + */ public function approveOrder() { - $data = json_decode(file_get_contents('php://input'), true); + $data = json_decode(file_get_contents('php://input'), true, 512, JSON_THROW_ON_ERROR); $orderId = (string) Registry::getRequest()->getRequestEscapedParameter('orderID'); $sessionOrderId = PayPalSession::getCheckoutOrderId(); - if (!empty($data['orderID']) && $orderId == '') { + if (!empty($data['orderID']) && $orderId === '') { $orderId = $data['orderID']; } if (!$orderId || ($orderId !== $sessionOrderId)) { //TODO: improve $this->outputJson(['ERROR' => 'OrderId not found in PayPal session.']); } - /** - * @var ServiceFactory $serviceFactory -*/ + /** @var ServiceFactory $serviceFactory */ $serviceFactory = Registry::get(ServiceFactory::class); $service = $serviceFactory->getOrderService(); $nonGuestAccountDetected = false; @@ -316,17 +257,14 @@ public function approveOrder() Constants::PAYPAL_PARTNER_ATTRIBUTION_ID_PPCP ); } catch (Exception $exception) { - /** - * @var Logger $logger - */ + /** @var Logger $logger */ $logger = $this->getServiceFromContainer(Logger::class); $logger->log('error', "Error on order capture call.", [$exception]); } - if (!$this->getUser()) { + if (!$this->getUser() && $response) { $userRepository = $this->getServiceFromContainer(UserRepository::class); $paypalEmail = (string) $response->payer->email_address; - $nonGuestAccountDetected = false; if ($userRepository->userAccountExists($paypalEmail)) { //got a non-guest account, so either we log in or redirect customer to login step $isLoggedIn = $this->handleUserLogin($response); @@ -339,9 +277,7 @@ public function approveOrder() } if ($user = $this->getUser()) { - /** - * @var array $userInvoiceAddress -*/ + /** @var array $userInvoiceAddress */ $userInvoiceAddress = $user->getInvoiceAddress(); // add PayPal-Address as Delivery-Address $deliveryAddress = PayPalAddressResponseToOxidAddress::mapUserDeliveryAddress($response); @@ -356,12 +292,12 @@ public function approveOrder() $paymentId = Registry::getSession()->getVariable('paymentid'); // use a deliveryaddress in oxid-checkout Registry::getSession()->setVariable('blshowshipaddress', false); - if ($paymentId === 'oscpaypal_applepay') { + if ($paymentId === PayPalDefinitions::APPLEPAY_PAYPAL_PAYMENT_ID) { $this->setPayPalPaymentMethod($paymentId); } else { $this->setPayPalPaymentMethod(); } - if ($paymentId === 'oscpaypal_googlepay') { + if ($paymentId === PayPalDefinitions::GOOGLEPAY_PAYPAL_PAYMENT_ID) { $this->setPayPalPaymentMethod($paymentId); } else { $this->setPayPalPaymentMethod(); @@ -429,19 +365,20 @@ public function setPayPalPaymentMethod($defaultPayPalPaymentId = PayPalDefinitio $requestedPayPalPaymentId = $this->getRequestedPayPalPaymentId($defaultPayPalPaymentId); if ($session->getVariable('paymentid') !== $requestedPayPalPaymentId) { $basket->setPayment($requestedPayPalPaymentId); + $session->setVariable('paymentid', $requestedPayPalPaymentId); + } + $this->getActiveShippingSetId($session, $user, $basket); + } - // get the active shippingSetId - /** - * @psalm-suppress InvalidArgument -*/ - [, $shippingSetId,] = - Registry::get(DeliverySetList::class)->getDeliverySetData('', $user, $basket); + private function getActiveShippingSetId($session, $user, $basket): void + { + /** @psalm-suppress InvalidArgument */ + [, $shippingSetId,] = + Registry::get(DeliverySetList::class)->getDeliverySetData('', $user, $basket); - if ($shippingSetId) { - $basket->setShipping($shippingSetId); - $session->setVariable('sShipSet', $shippingSetId); - } - $session->setVariable('paymentid', $requestedPayPalPaymentId); + if ($shippingSetId) { + $basket->setShipping($shippingSetId); + $session->setVariable('sShipSet', $shippingSetId); } } @@ -625,9 +562,7 @@ public function createApplepayOrder() } if ($user = $this->getUser()) { - /** - * @var array $userInvoiceAddress - */ + /** @var array $userInvoiceAddress */ $userInvoiceAddress = $user->getInvoiceAddress(); // add PayPal-Address as Delivery-Address diff --git a/src/Controller/VaultingTokenController.php b/src/Controller/VaultingTokenController.php index 2fa28bebf..46786cccd 100644 --- a/src/Controller/VaultingTokenController.php +++ b/src/Controller/VaultingTokenController.php @@ -28,7 +28,6 @@ public function generateSetupToken() /** * Generate a Payment Token using a previously generated setup token - * * @return void */ public function generatePaymentToken() @@ -54,7 +53,7 @@ protected function getVaultingService() } /** - * @param string $token + * @param string $token * @return bool */ protected function storeSetupToken($token) @@ -66,7 +65,7 @@ protected function storeSetupToken($token) } /** - * @param string $id + * @param string $id * @return bool */ protected function storePayPalUserId($id) diff --git a/src/Controller/WebhookController.php b/src/Controller/WebhookController.php index 963e128fa..5a7251bb2 100644 --- a/src/Controller/WebhookController.php +++ b/src/Controller/WebhookController.php @@ -18,7 +18,6 @@ /** * Class WebhookController - * * @package OxidSolutionCatalysts\PayPal\Controller */ class WebhookController extends WidgetController @@ -32,9 +31,7 @@ public function init() { parent::init(); - /** - * @var Logger $logger -*/ + /** @var Logger $logger */ $logger = $this->getServiceFromContainer(Logger::class); try { diff --git a/src/Core/Api/IdentityService.php b/src/Core/Api/IdentityService.php index c00f3089b..a741c45f6 100644 --- a/src/Core/Api/IdentityService.php +++ b/src/Core/Api/IdentityService.php @@ -7,13 +7,18 @@ namespace OxidSolutionCatalysts\PayPal\Core\Api; +use GuzzleHttp\Exception\GuzzleException; +use JsonException; +use OxidSolutionCatalysts\PayPalApi\Exception\ApiException; use OxidSolutionCatalysts\PayPalApi\Service\BaseService; use Psr\Http\Message\ResponseInterface; class IdentityService extends BaseService { - protected $basePath = '/v1/identity'; - + /** + * @throws ApiException + * @throws JsonException + */ public function requestClientToken(): array { $headers = []; @@ -22,17 +27,18 @@ public function requestClientToken(): array $path = '/v1/identity/generate-token'; - /** - * @var ResponseInterface $response -*/ + /** @var ResponseInterface $response */ $response = $this->send('POST', $path, [], $headers); $body = $response->getBody(); - return $body ? json_decode((string)$body, true) : []; + $result = json_decode((string)$body, true, 512, JSON_THROW_ON_ERROR); + return is_array($result) ? $result : []; } /** * @return array + * @throws JsonException + * @throws GuzzleException */ protected function getAuthHeaders(): array { diff --git a/src/Core/Api/VaultingService.php b/src/Core/Api/VaultingService.php index b5ce504dc..25c6bd30f 100644 --- a/src/Core/Api/VaultingService.php +++ b/src/Core/Api/VaultingService.php @@ -13,6 +13,7 @@ use OxidEsales\Eshop\Core\Registry; use OxidEsales\Eshop\Core\ViewConfig; use OxidSolutionCatalysts\PayPal\Core\Constants; +use OxidSolutionCatalysts\PayPal\Service\Logger; use OxidSolutionCatalysts\PayPal\Service\ModuleSettings; use OxidSolutionCatalysts\PayPal\Traits\ServiceContainer; use OxidSolutionCatalysts\PayPalApi\Exception\ApiException; @@ -44,7 +45,7 @@ public function generateUserIdToken($payPalCustomerId = false): array $body = $response->getBody(); } $result = json_decode((string)$body, true, 512, JSON_THROW_ON_ERROR); - } catch (ApiException | JsonException $e) { + } catch (ApiException|JsonException $e) { $result = []; } @@ -53,8 +54,7 @@ public function generateUserIdToken($payPalCustomerId = false): array /** * Request a setup token either for card or for PayPal vaulting - * - * @param bool $card + * @param bool $card * @return array * @throws JsonException */ @@ -98,7 +98,7 @@ public function createVaultSetupToken(bool $card = false): array $body = $response->getBody(); } $result = json_decode((string)$body, true, 512, JSON_THROW_ON_ERROR); - } catch (ApiException | JsonException $e) { + } catch (ApiException|JsonException $e) { $result = []; } @@ -106,7 +106,7 @@ public function createVaultSetupToken(bool $card = false): array } /** - * @param bool $card + * @param bool $card * @return array */ public function getPaymentSourceForVaulting(bool $card): array @@ -149,7 +149,7 @@ public function getPaymentSourceForVaulting(bool $card): array "locale" => $locale, "return_url" => $config->getSslShopUrl() . 'index.php?cl=order&fnc=finalizepaypalsession', "cancel_url" => $config->getSslShopUrl() . 'index.php?cl=order&fnc=cancelpaypalsession', - // "shipping_preference" => "SET_PROVIDED_ADDRESS", +// "shipping_preference" => "SET_PROVIDED_ADDRESS", ]; if ($card) { @@ -215,7 +215,7 @@ public function createVaultPaymentToken(string $setupToken): array $body = $response->getBody(); } $result = json_decode((string)$body, true, 512, JSON_THROW_ON_ERROR); - } catch (ApiException | JsonException $e) { + } catch (ApiException|JsonException $e) { $result = []; } @@ -242,7 +242,9 @@ public function getVaultPaymentTokens(string $paypalCustomerId): array $body = $response->getBody(); } $result = json_decode((string)$body, true, 512, JSON_THROW_ON_ERROR); - } catch (ApiException | JsonException $e) { + } catch (ApiException|JsonException $e) { + $this->getServiceFromContainer(Logger::class) + ->log('error', __CLASS__ . ' ' . __FUNCTION__ . ' : ' . $e->getMessage()); $result = []; } @@ -257,7 +259,7 @@ public function getVaultPaymentTokenByIndex(string $paypalCustomerId, string $in } /** - * @param string $paymentTokenId + * @param string $paymentTokenId * @return bool */ public function deleteVaultedPayment(string $paymentTokenId): bool diff --git a/src/Core/Config.php b/src/Core/Config.php index ab0be29aa..50ac9bd85 100755 --- a/src/Core/Config.php +++ b/src/Core/Config.php @@ -307,6 +307,7 @@ public function getPayPalCheckoutBannerCartPageSelector(): string { return $this->getServiceFromContainer(ModuleSettings::class)->getPayPalCheckoutBannerCartPageSelector(); } + public function getPayPalCheckoutBannerPaymentPageSelector(): string { return $this->getServiceFromContainer(ModuleSettings::class)->getPayPalCheckoutBannerPaymentPageSelector(); @@ -342,6 +343,11 @@ public function getStartTimeCleanUpOrders(): int return $this->getServiceFromContainer(ModuleSettings::class)->getStartTimeCleanUpOrders(); } + public function isCustomIdSchemaStructural(): bool + { + return $this->getServiceFromContainer(ModuleSettings::class)->isCustomIdSchemaStructural(); + } + public function tableExists(string $tableName = ''): bool { $exists = false; @@ -456,21 +462,23 @@ public function getIsVaultingActive(): bool return $this->getServiceFromContainer(ModuleSettings::class)->getIsVaultingActive(); } - public function getIsGooglePayDeliveryAdressActive(): bool + public function getUserIdForVaulting(): string { - return $this->getServiceFromContainer(ModuleSettings::class)->getIsGooglePayDeliveryAddressActive(); + $user = Registry::getConfig()->getUser(); + $payPalCustomerId = $user ? $user->getFieldData("oscpaypalcustomerid") : ''; + + if (!$payPalCustomerId) { + return ""; + } + + $vaultingService = Registry::get(ServiceFactory::class)->getVaultingService(); + $response = $vaultingService->generateUserIdToken($payPalCustomerId); + + return $response["id_token"] ?? ""; } - public function isLogLevel(string $level): bool + public function getIsGooglePayDeliveryAdressActive(): bool { - $possiblePayPalLevels = [ - 'error' => 400, - 'info' => 200, - 'debug' => 100 - ]; - $logLevel = Registry::getConfig()->getConfigParam('sLogLevel') ?? 'error'; - $logLevel = isset($possiblePayPalLevels[$logLevel]) ? $logLevel : 'error'; - $level = isset($possiblePayPalLevels[$level]) ? $level : 'error'; - return $possiblePayPalLevels[$logLevel] <= $possiblePayPalLevels[$level]; + return $this->getServiceFromContainer(ModuleSettings::class)->getIsGooglePayDeliveryAddressActive(); } } diff --git a/src/Core/ConfirmOrderRequestFactory.php b/src/Core/ConfirmOrderRequestFactory.php index c31bf810d..535f9f104 100644 --- a/src/Core/ConfirmOrderRequestFactory.php +++ b/src/Core/ConfirmOrderRequestFactory.php @@ -12,6 +12,7 @@ use OxidEsales\Eshop\Application\Model\Address; use OxidEsales\Eshop\Application\Model\Basket; use OxidEsales\Eshop\Application\Model\Country; +use OxidEsales\Eshop\Core\Exception\LanguageNotFoundException; use OxidEsales\Eshop\Core\Registry; use OxidEsales\EshopCommunity\Core\Language; use OxidSolutionCatalysts\PayPalApi\Model\Orders\OrderConfirmApplicationContext; @@ -20,7 +21,6 @@ /** * Class ConfirmOrderRequestFactory - * * @package OxidSolutionCatalysts\PayPal\Core */ class ConfirmOrderRequestFactory @@ -35,6 +35,7 @@ class ConfirmOrderRequestFactory * @param string $requestName Name of the RequestClass defined in PayPalClient * * @return ConfirmOrderRequest + * @throws LanguageNotFoundException */ public function getRequest( Basket $basket, @@ -77,26 +78,21 @@ protected function getPaymentSource(Basket $basket, string $requestName) $paymentSource->$requestName->attributes->verification = new \stdClass(); $paymentSource->$requestName->attributes->verification->method = 'SCA_ALWAYS'; } else { - $paymentSource = new PaymentSource( - [ + $paymentSource = new PaymentSource([ $requestName => [ 'name' => $userName, 'country_code' => $country->getFieldData('oxisoalpha2') ] - ] - ); + ]); } - Registry::getLogger()->error('ConfirmOrder'); - Registry::getLogger()->error(print_r($paymentSource, true)); - - return $paymentSource; } /** * Sets application context * + * @throws LanguageNotFoundException * @return OrderConfirmApplicationContext */ protected function getApplicationContext(): OrderConfirmApplicationContext diff --git a/src/Core/Events/Events.php b/src/Core/Events/Events.php index 540a828de..b4958f4cc 100644 --- a/src/Core/Events/Events.php +++ b/src/Core/Events/Events.php @@ -10,7 +10,6 @@ namespace OxidSolutionCatalysts\PayPal\Core\Events; use OxidEsales\DoctrineMigrationWrapper\MigrationsBuilder; -use OxidEsales\Eshop\Application\Model\Payment as EshopModelPayment; use OxidEsales\Eshop\Core\Registry; use OxidEsales\EshopCommunity\Internal\Framework\Database\QueryBuilderFactoryInterface; use OxidEsales\EshopCommunity\Internal\Framework\Module\Configuration\Bridge\ModuleConfigurationDaoBridgeInterface; @@ -18,6 +17,7 @@ use OxidEsales\EshopCommunity\Internal\Transition\Utility\ContextInterface; use OxidSolutionCatalysts\PayPal\Service\Logger; use OxidSolutionCatalysts\PayPal\Service\ModuleSettings; +use OxidSolutionCatalysts\PayPal\Service\UserRepository; use OxidSolutionCatalysts\PayPal\Traits\ServiceContainer; use OxidSolutionCatalysts\PayPal\Service\StaticContent; use OxidEsales\EshopCommunity\Internal\Container\ContainerFactory; @@ -111,14 +111,10 @@ private static function getStaticContentService(): ?StaticContent */ try { - /** - * @var ContainerInterface $container -*/ + /** @var ContainerInterface $container */ $container = ContainerFactory::getInstance() ->getContainer(); - /** - * @var QueryBuilderFactoryInterface $queryBuilderFactory -*/ + /** @var QueryBuilderFactoryInterface $queryBuilderFactory */ $queryBuilderFactory = $container->get(QueryBuilderFactoryInterface::class); $moduleSettings = self::getModuleSettingsService(); @@ -146,33 +142,25 @@ private static function getModuleSettingsService(): ?ModuleSettings */ try { - /** - * @var ContainerInterface $container -*/ + /** @var ContainerInterface $container */ $container = ContainerFactory::getInstance() ->getContainer(); - /** - * @var ModuleSettingBridgeInterface $moduleSettingsBridge -*/ + /** @var ModuleSettingBridgeInterface $moduleSettingsBridge */ $moduleSettingsBridge = $container->get(ModuleSettingBridgeInterface::class); - /** - * @var ContextInterface $context -*/ + /** @var ContextInterface $context */ $context = $container->get(ContextInterface::class); - /** - * @var ModuleConfigurationDaoBridgeInterface $moduleConfigurationDaoBridgeInterface -*/ + /** @var ModuleConfigurationDaoBridgeInterface $moduleConfigurationDaoBridgeInterface */ $moduleConfigurationDaoBridgeInterface = $container->get(ModuleConfigurationDaoBridgeInterface::class); - /** - * @var Logger $logger -*/ + /** @var Logger $logger */ $logger = $container->get(Logger::class); + $userRepository = $container->get(UserRepository::class); return new ModuleSettings( $moduleSettingsBridge, $context, $moduleConfigurationDaoBridgeInterface, - $logger + $logger, + $userRepository ); } catch (NotFoundExceptionInterface | ContainerExceptionInterface $exception) { Registry::getUtilsView()->addErrorToDisplay('OSC_PAYPAL_INSTALLPROCESS_FAILED'); diff --git a/src/Core/LegacyOeppModuleDetails.php b/src/Core/LegacyOeppModuleDetails.php index f8d15ffaa..b728223fb 100644 --- a/src/Core/LegacyOeppModuleDetails.php +++ b/src/Core/LegacyOeppModuleDetails.php @@ -17,7 +17,6 @@ class LegacyOeppModuleDetails /** * Determines whether the legacy PayPal module "oepaypal" is enabled - * * @return bool */ public function isLegacyModulePresent(): bool diff --git a/src/Core/Onboarding/Onboarding.php b/src/Core/Onboarding/Onboarding.php index f3bbd781f..b91d1ed7b 100755 --- a/src/Core/Onboarding/Onboarding.php +++ b/src/Core/Onboarding/Onboarding.php @@ -49,7 +49,6 @@ public function autoConfigurationFromCallback(): array } /** - * @throws ApiException * @throws OnboardingException * @throws JsonException */ @@ -61,15 +60,12 @@ public function fetchCredentials(): array $nonce = Registry::getSession()->getVariable('PAYPAL_MODULE_NONCE'); Registry::getSession()->deleteVariable('PAYPAL_MODULE_NONCE'); + $credentials = []; try { - /** - * @var ApiOnboardingClient $apiClient -*/ - $apiClient = $this->getOnboardingClient($onboardingResponse['isSandBox']); - $apiClient->authAfterWebLogin($onboardingResponse['authCode'], $onboardingResponse['sharedId'], $nonce); + $apiClient = $this->getOnboardingClient($onboardingResponse['isSandBox']); + $apiClient->authAfterWebLogin($onboardingResponse['authCode'], $onboardingResponse['sharedId'], $nonce); $credentials = $apiClient->getCredentials(); - $credentials = $apiClient->getCredentials(); } catch (ApiException $exception) { /** * @var Logger $logger @@ -77,7 +73,6 @@ public function fetchCredentials(): array $logger = $this->getServiceFromContainer(Logger::class); $logger->log('error', $exception->getMessage(), [$exception]); } - return $credentials; } @@ -138,7 +133,7 @@ private function downloadAndSaveApplePayCertificate() } /** - * @param Filesystem $filesystem + * @param Filesystem $filesystem * @return void */ private function ensureDirectoryExists(Filesystem $filesystem): void @@ -152,9 +147,9 @@ private function ensureDirectoryExists(Filesystem $filesystem): void } /** - * @param Filesystem $filesystem - * @param string $environment - * @param array $config + * @param Filesystem $filesystem + * @param string $environment + * @param array $config * @return void */ private function updateCertificateIfChanged(Filesystem $filesystem, bool $isSandbox): void @@ -194,9 +189,7 @@ public function getOnboardingClient(bool $isSandbox, bool $withCredentials = fal $merchantId = $paypalConfig->getMerchantId(); } - /** - * @var LoggerInterface $logger -*/ + /** @var LoggerInterface $logger */ $logger = $this->getServiceFromContainer('OxidSolutionCatalysts\PayPal\Logger'); return new ApiOnboardingClient( @@ -212,6 +205,7 @@ public function getOnboardingClient(bool $isSandbox, bool $withCredentials = fal } /** + * @return array * @throws ApiException * @throws JsonException * @throws OnboardingException @@ -232,25 +226,26 @@ public function saveEligibility(array $merchantInformations): array $isAcdcEligibility = false; $isVaultingEligibility = false; $isVaultingCapability = false; + $isGooglePayCapability = false; $isApplePayEligibility = false; $isGooglePayCapability = false; foreach ($merchantInformations['capabilities'] as $capability) { if ( - $capability['name'] === 'PAYPAL_WALLET_VAULTING_ADVANCED' - && $capability['status'] === 'ACTIVE' + $capability['name'] === 'PAYPAL_WALLET_VAULTING_ADVANCED' && + $capability['status'] === 'ACTIVE' ) { $isVaultingCapability = true; } if ( - $capability['name'] === 'APPLE_PAY' - && $capability['status'] === 'ACTIVE' + $capability['name'] === 'APPLE_PAY' && + $capability['status'] === 'ACTIVE' ) { $isApplePayEligibility = true; } if ( - $capability['name'] === 'GOOGLE_PAY' - && $capability['status'] === 'ACTIVE' + $capability['name'] === 'GOOGLE_PAY' && + $capability['status'] === 'ACTIVE' ) { $isGooglePayCapability = true; } @@ -258,21 +253,21 @@ public function saveEligibility(array $merchantInformations): array foreach ($merchantInformations['products'] as $product) { if ( - $product['name'] === 'PAYMENT_METHODS' - && in_array('PAY_UPON_INVOICE', $product['capabilities'], true) + $product['name'] === 'PAYMENT_METHODS' && + in_array('PAY_UPON_INVOICE', $product['capabilities'], true) ) { $isPuiEligibility = true; } elseif ( - $product['name'] === 'PPCP_CUSTOM' - && in_array('CUSTOM_CARD_PROCESSING', $product['capabilities'], true) + $product['name'] === 'PPCP_CUSTOM' && + in_array('CUSTOM_CARD_PROCESSING', $product['capabilities'], true) ) { $isAcdcEligibility = true; } if ( - $isVaultingCapability - && $product['name'] === 'PPCP_CUSTOM' - && in_array('PAYPAL_WALLET_VAULTING_ADVANCED', $product['capabilities'], true) + $isVaultingCapability && + $product['name'] === 'PPCP_CUSTOM' && + in_array('PAYPAL_WALLET_VAULTING_ADVANCED', $product['capabilities'], true) ) { $isVaultingEligibility = true; } @@ -284,15 +279,15 @@ public function saveEligibility(array $merchantInformations): array $moduleSettings->savePuiEligibility($isPuiEligibility); $moduleSettings->saveAcdcEligibility($isAcdcEligibility); $moduleSettings->saveVaultingEligibility($isVaultingEligibility); - $moduleSettings->saveApplePayEligibility($isApplePayEligibility); $moduleSettings->saveGooglePayEligibility($isGooglePayCapability); + $moduleSettings->saveApplePayEligibility($isApplePayEligibility); return [ 'acdc' => $isAcdcEligibility, 'pui' => $isPuiEligibility, 'vaulting' => $isVaultingEligibility, - 'applepay' => $isVaultingEligibility, 'googlepay' => $isGooglePayCapability, + 'applepay' => $isVaultingEligibility, ]; } } diff --git a/src/Core/Onboarding/Webhook.php b/src/Core/Onboarding/Webhook.php index c333e0736..b6738a441 100644 --- a/src/Core/Onboarding/Webhook.php +++ b/src/Core/Onboarding/Webhook.php @@ -70,17 +70,13 @@ public function registerWebhooks(): string 'event_types' => $this->getAvailableEventNames(), ]; - /** - * @var GenericService $notificationService -*/ + /** @var GenericService $notificationService */ $webhookService = Registry::get(ServiceFactory::class)->getWebhookService(); $webHookResponse = $webhookService->request('POST', $paypload); $webhookId = $webHookResponse['id'] ?? ''; } catch (Exception $exception) { - /** - * @var Logger $logger -*/ + /** @var Logger $logger */ $logger = $this->getServiceFromContainer(Logger::class); $logger->log( 'error', @@ -99,9 +95,7 @@ public function removeWebhook(string $webhookId): void return; } - /** - * @var GenericService $notificationService -*/ + /** @var GenericService $notificationService */ $webhookService = Registry::get(ServiceFactory::class)->getWebhookService('/' . $webhookId); $headers = []; @@ -124,9 +118,7 @@ public function saveWebhookId(string $webhookId): void public function getAllRegisteredWebhooks(): array { - /** - * @var GenericService $notificationService -*/ + /** @var GenericService $notificationService */ $webhookService = Registry::get(ServiceFactory::class)->getWebhookService(); try { $result = $webhookService->request('GET'); diff --git a/src/Core/OrderRequestFactory.php b/src/Core/OrderRequestFactory.php index 771b76a26..a64d27829 100644 --- a/src/Core/OrderRequestFactory.php +++ b/src/Core/OrderRequestFactory.php @@ -40,7 +40,6 @@ /** * Class OrderRequestBuilder - * * @package OxidSolutionCatalysts\PayPal\Core */ class OrderRequestFactory @@ -67,16 +66,16 @@ class OrderRequestFactory private $basket; /** - * @param Basket $basket - * @param string $intent Order::INTENT_CAPTURE or Order::INTENT_AUTHORIZE constant values - * @param null|string $userAction USER_ACTION_CONTINUE constant values - * @param null|string $transactionId custom id reference + * @param Basket $basket + * @param string $intent Order::INTENT_CAPTURE or Order::INTENT_AUTHORIZE constant values + * @param null|string $userAction USER_ACTION_CONTINUE constant values + * @param null|string $customId custom id reference * @param null|string $processingInstruction processing instruction - * @param null|string $paymentSource Payment-Source Name - * @param null|string $invoiceId custom invoice number - * @param null|string $returnUrl Return Url - * @param null|string $cancelUrl Cancel Url - * @param bool $setProvidedAddress Address changeable in PayPal? + * @param null|string $paymentSource Payment-Source Name + * @param null|string $invoiceId custom invoice number + * @param null|string $returnUrl Return Url + * @param null|string $cancelUrl Cancel Url + * @param bool $setProvidedAddress Address changeable in PayPal? * * @return OrderRequest */ @@ -84,13 +83,12 @@ public function getRequest( Basket $basket, string $intent, ?string $userAction = null, - ?string $transactionId = null, + ?string $customId = null, ?string $processingInstruction = null, ?string $paymentSource = null, ?string $invoiceId = null, ?string $returnUrl = null, ?string $cancelUrl = null, - bool $withArticles = true, bool $setProvidedAddress = true ): OrderRequest { $request = $this->request = new OrderRequest(); @@ -101,15 +99,14 @@ public function getRequest( $setVaulting = $moduleSettings->getIsVaultingActive(); $selectedVaultPaymentSourceIndex = Registry::getSession()->getVariable("selectedVaultPaymentSourceIndex"); $paymentId = Registry::getSession()->getVariable('paymentid'); - if ($paymentId === PayPalDefinitions::APPLEPAY_PAYPAL_PAYMENT_ID) { - $request->payment_source = $this->getApplePayPaymentSource($basket, 'apple_pay'); - } - $paymentId = Registry::getSession()->getVariable('paymentid'); if ($paymentId === PayPalDefinitions::GOOGLEPAY_PAYPAL_PAYMENT_ID) { $request->payment_source = $this->getGooglePayPaymentSource($basket, 'google_pay'); } + if ($paymentId === PayPalDefinitions::APPLEPAY_PAYPAL_PAYMENT_ID) { + $request->payment_source = $this->getApplePayPaymentSource($basket, 'apple_pay'); + } $request->intent = $intent; - $request->purchase_units = $this->getPurchaseUnits($transactionId, $invoiceId, $withItems); + $request->purchase_units = $this->getPurchaseUnits($customId, $invoiceId, $withItems); $useVaultedPayment = $setVaulting && !is_null($selectedVaultPaymentSourceIndex); if ($useVaultedPayment) { @@ -155,8 +152,6 @@ public function getRequest( $request->payer = $this->getPayer(); } - $request->purchase_units = $this->getPurchaseUnits($transactionId, $invoiceId, $withArticles); - if ($userAction || $returnUrl || $cancelUrl) { $request->application_context = $this->getApplicationContext( $userAction, @@ -171,9 +166,7 @@ public function getRequest( } if ($paymentSource == PayPalDefinitions::PUI_REQUEST_PAYMENT_SOURCE_NAME) { - /** - * @var PaymentSource $puiPaymentSource -*/ + /** @var PaymentSource $puiPaymentSource */ $puiPaymentSource = $this->getPuiPaymentSource(); $request->payment_source = $puiPaymentSource; } @@ -196,14 +189,12 @@ protected function getApplePayPaymentSource($basket, $requestName) if ($deliveryId && $deliveryAddress->load($deliveryId)) { $country->load($deliveryAddress->getFieldData('oxcountryid')); } - $paymentSource = new PaymentSource( - [ + $paymentSource = new PaymentSource([ $requestName => [ 'name' => $userName, 'country_code' => $country->getFieldData('oxisoalpha2') ] - ] - ); + ]); return $paymentSource; } @@ -234,10 +225,10 @@ protected function getGooglePayPaymentSource($basket, $requestName) /** * Sets application context * - * @param string|null $userAction - * @param string|null $returnUrl - * @param string|null $cancelUrl - * @param bool|null $setProvidedAddress + * @param string|null $userAction + * @param string|null $returnUrl + * @param string|null $cancelUrl + * @param bool|null $setProvidedAddress * @return OrderApplicationContext */ protected function getApplicationContext( @@ -308,7 +299,7 @@ protected function getAmount(): AmountWithBreakdown } /** - * @return array + * @return array * @psalm-suppress UndefinedDocblockClass */ public function getItems(): array @@ -319,9 +310,7 @@ public function getItems(): array $language = Registry::getLang(); $items = []; - /** - * @var BasketItem $basketItem -*/ + /** @var BasketItem $basketItem */ foreach ($basket->getContents() as $basketItem) { $item = new Item(); $item->name = substr($basketItem->getTitle(), 0, 120); @@ -441,7 +430,6 @@ public function getItems(): array /** * Determine the item category based on the entire basket contents. If all items in the basket are virtual * the category "DIGITAL_GOODS" is used, in any other case it'll be "PHYSICAL_GOODS". - * * @return string */ public function getItemCategoryByBasketContent(): string @@ -470,9 +458,7 @@ protected function getPayer(string $payerClass = Payer::class): Payer $birthDate = $user->getFieldData('oxbirthdate'); if ($birthDate && $birthDate !== '0000-00-00') { - /** - * @var DateTime $birthDate -*/ + /** @var DateTime $birthDate */ $birthDate = oxNew(DateTime::class, $user->getFieldData('oxbirthdate')); $payer->birth_date = $birthDate->format('Y-m-d'); } @@ -644,9 +630,7 @@ protected function getPuiPaymentSource(): array $paymentSource->email = $payer->email_address; $paymentSource->billing_address = $billingAddress; - /** - * @var ApiModelPhone $phoneNumberForPuiRequest -*/ + /** @var ApiModelPhone $phoneNumberForPuiRequest */ $phoneNumberForPuiRequest = $user->getPhoneNumberForPuiRequest(); $paymentSource->phone = $phoneNumberForPuiRequest; if ($birthdate = $user->getBirthDateForPuiRequest()) { @@ -666,7 +650,7 @@ protected function getPuiPaymentSource(): array } /** - * @param OrderRequest $request + * @param OrderRequest $request * @return void */ protected function modifyPaymentSourceForVaulting(OrderRequest $request, $useCard = false): void diff --git a/src/Core/PartnerConfig.php b/src/Core/PartnerConfig.php index 3675a0f85..ad699a230 100644 --- a/src/Core/PartnerConfig.php +++ b/src/Core/PartnerConfig.php @@ -35,7 +35,6 @@ public function createNonce(): string * For this purpose, this ClientId is unencrypted, here as part * of this open Source Module * this method is private see getTechnicalClientId which respects the sandbox mode for you - * * @return string */ public function getLiveOxidClientId(): string @@ -62,7 +61,6 @@ public function getSandboxOxidClientId(): string * the request for the merchant ClientId and Secret. * For this purpose, this PartnerId is unencrypted, here as part * of this open Source Module - * * @return string */ public function getLiveOxidPartnerId(): string diff --git a/src/Core/PatchRequestFactory.php b/src/Core/PatchRequestFactory.php index 3cabc96ea..028d89493 100644 --- a/src/Core/PatchRequestFactory.php +++ b/src/Core/PatchRequestFactory.php @@ -22,7 +22,6 @@ /** * Class PatchRequestFactory - * * @package OxidSolutionCatalysts\PayPal\Core */ class PatchRequestFactory @@ -154,9 +153,7 @@ protected function getPurchaseUnitsPatch( $patch->path = "/purchase_units/@reference_id=='" . Constants::PAYPAL_ORDER_REFERENCE_ID . "'/items"; $patchValues = []; - /** - * @var BasketItem $basketItem -*/ + /** @var BasketItem $basketItem */ foreach ($basketItems as $basketItem) { $item = new Item(); $item->name = $basketItem->getTitle(); diff --git a/src/Core/PayPalDefinitions.php b/src/Core/PayPalDefinitions.php index d6c6a6e3b..b5e5f5170 100644 --- a/src/Core/PayPalDefinitions.php +++ b/src/Core/PayPalDefinitions.php @@ -73,44 +73,42 @@ final class PayPalDefinitions 'vaultingtype' => 'paypal' ], //GooglePay - self::APPLEPAY_PAYPAL_PAYMENT_ID => [ + self::GOOGLEPAY_PAYPAL_PAYMENT_ID => [ 'descriptions' => [ 'de' => [ - 'desc' => 'ApplePay', + 'desc' => 'GooglePay', 'longdesc' => '', - 'longdesc_beta' => 'Bezahlen Sie bequem mit ApplePay. Starten Sie direkt von der Detailsseite oder im Warenkorb.' + 'longdesc_beta' => 'Bezahlen Sie bequem mit GooglePay. Starten Sie direkt von der Detailsseite oder im Warenkorb.' ], 'en' => [ - 'desc' => 'ApplePay', + 'desc' => 'GooglePay', 'longdesc' => '', - 'longdesc_beta' => 'Pay conveniently with ApplePay. Start directly from the details page or in the shopping cart.' + 'longdesc_beta' => 'Pay conveniently with GooglePay. Start directly from the details page or in the shopping cart.' ] ], 'countries' => [], 'currencies' => ['AUD', 'BRL', 'CAD', 'CNY', 'CZK', 'DKK', 'EUR', 'HKD', 'HUF', 'ILS', 'JPY', 'MYR', 'MXN', 'TWD', 'NZD', 'NOK', 'PHP', 'PLN', 'GBP', 'RUB', 'SGD', 'SEK', 'CHF', 'THB', 'USD'], - 'uapmpaymentsource' => 'apple_pay', 'constraints' => self::PAYMENT_CONSTRAINTS_PAYPAL, 'onlybrutto' => false, 'buttonpayment' => false, 'defaulton' => true ], - //GooglePay - self::GOOGLEPAY_PAYPAL_PAYMENT_ID => [ + //ApplePay + self::APPLEPAY_PAYPAL_PAYMENT_ID => [ 'descriptions' => [ 'de' => [ - 'desc' => 'GooglePay', + 'desc' => 'ApplePay', 'longdesc' => '', - 'longdesc_beta' => 'Bezahlen Sie bequem mit GooglePay. Starten Sie direkt von der Detailsseite oder im Warenkorb.' + 'longdesc_beta' => 'Bezahlen Sie bequem mit ApplePay. Starten Sie direkt von der Detailsseite oder im Warenkorb.' ], 'en' => [ - 'desc' => 'GooglePay', + 'desc' => 'ApplePay', 'longdesc' => '', - 'longdesc_beta' => 'Pay conveniently with GooglePay. Start directly from the details page or in the shopping cart.' + 'longdesc_beta' => 'Pay conveniently with ApplePay. Start directly from the details page or in the shopping cart.' ] ], 'countries' => [], 'currencies' => ['AUD', 'BRL', 'CAD', 'CNY', 'CZK', 'DKK', 'EUR', 'HKD', 'HUF', 'ILS', 'JPY', 'MYR', 'MXN', 'TWD', 'NZD', 'NOK', 'PHP', 'PLN', 'GBP', 'RUB', 'SGD', 'SEK', 'CHF', 'THB', 'USD'], - 'uapmpaymentsource' => 'googlepay', 'constraints' => self::PAYMENT_CONSTRAINTS_PAYPAL, 'onlybrutto' => false, 'buttonpayment' => false, @@ -136,7 +134,6 @@ final class PayPalDefinitions 'onlybrutto' => false, 'buttonpayment' => false, 'defaulton' => true, - 'vaultingtype' => 'paypal' ], //Express PayPal self::EXPRESS_PAYPAL_PAYMENT_ID => [ @@ -158,7 +155,6 @@ final class PayPalDefinitions 'onlybrutto' => false, 'buttonpayment' => true, 'defaulton' => true, - 'vaultingtype' => 'paypal' ], self::PUI_PAYPAL_PAYMENT_ID => [ 'descriptions' => [ @@ -518,12 +514,12 @@ public static function isPayPalVaultingPossible(string $paymentId, string $paypa /** * Check if payment is deprecated * - * @param string $paymentId + * @param string $paymentId * @return bool */ public static function isDeprecatedPayment(string $paymentId): bool { - if (isset(self::PAYPAL_DEFINTIONS[$paymentId]['deprecated']) && self::PAYPAL_DEFINTIONS[$paymentId]['deprecated'] === true) { + if ( isset(self::PAYPAL_DEFINTIONS[$paymentId]['deprecated']) && self::PAYPAL_DEFINTIONS[$paymentId]['deprecated'] === true ) { return true; } return false; diff --git a/src/Core/PayPalRequestAmountFactory.php b/src/Core/PayPalRequestAmountFactory.php index bb7ecafbf..dac1ce348 100644 --- a/src/Core/PayPalRequestAmountFactory.php +++ b/src/Core/PayPalRequestAmountFactory.php @@ -16,7 +16,6 @@ /** * Class PayPalRequestFactory - * * @package OxidSolutionCatalysts\PayPal\Core */ class PayPalRequestAmountFactory @@ -48,18 +47,16 @@ public function getAmount(Basket $basket): AmountWithBreakdown } if ($netMode) { - $total = $brutBasketTotal - $shipping; + $total = $itemTotal - $shipping; } else { $total = $itemTotal - $discount + $itemTotalAdditionalCosts; } - $total_with_shipping = $total + $shipping; $total = PriceToMoney::convert($total, $currency); - $total_with_shipping = PriceToMoney::convert($total_with_shipping, $currency); //Total amount $amount = new AmountWithBreakdown(); - $amount->value = $total_with_shipping->value; + $amount->value = $brutBasketTotal; $amount->currency_code = $total->currency_code; //Cost breakdown @@ -69,7 +66,8 @@ public function getAmount(Basket $basket): AmountWithBreakdown $breakdown->discount = PriceToMoney::convert($netMode ? $brutDiscountValue : $discount, $currency); } - $breakdown->item_total = PriceToMoney::convert($total->value, $currency); + $breakDownItemTotal = $netMode ? $total->value : $itemTotal; + $breakdown->item_total = PriceToMoney::convert($breakDownItemTotal, $currency); //Item tax sum - we use 0% and calculate with brutto to avoid rounding errors $breakdown->tax_total = PriceToMoney::convert(0, $currency); diff --git a/src/Core/ServiceFactory.php b/src/Core/ServiceFactory.php index d46c14632..8e26fb071 100644 --- a/src/Core/ServiceFactory.php +++ b/src/Core/ServiceFactory.php @@ -22,7 +22,6 @@ /** * Class ServiceFactory - * * @package OxidSolutionCatalysts\PayPal\Core * * Responsible for creation of PayPal service objects @@ -129,13 +128,9 @@ public function getIdentityService(): IdentityService private function getClient(bool $useToken = true): Client { if ($this->client === null) { - /** - * @var Config $config -*/ + /** @var Config $config */ $config = oxNew(Config::class); - /** - * @var LoggerInterface $logger -*/ + /** @var LoggerInterface $logger */ $logger = $this->getServiceFromContainer('OxidSolutionCatalysts\PayPal\Logger'); $debug = Registry::getConfig()->getConfigParam('sLogLevel') === 'debug'; @@ -148,6 +143,7 @@ private function getClient(bool $useToken = true): Client $actionHash = md5($sessionId . $basketId . $paymentId); $sTokenCacheFileName = $useToken ? $config->getTokenCacheFileName() : ''; + $client = new Client( $logger, $config->isSandbox() ? Client::SANDBOX_URL : Client::PRODUCTION_URL, diff --git a/src/Core/ShopControl.php b/src/Core/ShopControl.php index 755087466..56f6cf336 100644 --- a/src/Core/ShopControl.php +++ b/src/Core/ShopControl.php @@ -22,12 +22,12 @@ class ShopControl extends ShopControl_parent /** * @param StandardException $exception */ - protected function handleBaseException($exception) // phpcs:ignore PSR2.Methods.MethodDeclaration.Underscore + protected function _handleBaseException($exception) // phpcs:ignore PSR2.Methods.MethodDeclaration.Underscore { if ($exception instanceof PayPalException) { $this->handleCustomPayPalException($exception); } else { - parent::handleBaseException($exception); + parent::_handleBaseException($exception); } } // @codeCoverageIgnore @@ -41,13 +41,13 @@ public function handleCustomPayPalException(PayPalException $exception): void } elseif ($exception instanceof Redirect) { $this->handlePayPalRedirectException($exception, false); } else { - parent::handleBaseException($exception); + parent::_handleBaseException($exception); } } // @codeCoverageIgnore /** * @param Redirect $redirectException - * @param bool $blAddRedirectParam + * @param bool $blAddRedirectParam */ protected function handlePayPalRedirectException(Redirect $redirectException, bool $blAddRedirectParam = true): void { diff --git a/src/Core/Tracker/Tracker.php b/src/Core/Tracker/Tracker.php index 1ed1a049a..8954852a7 100644 --- a/src/Core/Tracker/Tracker.php +++ b/src/Core/Tracker/Tracker.php @@ -47,17 +47,13 @@ public function sendtracking( ]] ]; - /** - * @var GenericService $notificationService -*/ + /** @var GenericService $notificationService */ $trackerService = Registry::get(ServiceFactory::class)->getTrackerService(); $trackerResponse = $trackerService->request('POST', $paypload); $result = $trackerResponse['tracker_identifiers'][0]['tracking_number'] === $trackingNumber; } catch (\Exception $exception) { - /** - * @var Logger $logger -*/ + /** @var Logger $logger */ $logger = $this->getServiceFromContainer(Logger::class); $logger->log( 'error', diff --git a/src/Core/TransactionEventCodes.php b/src/Core/TransactionEventCodes.php index c10f306dd..26bf6fa58 100644 --- a/src/Core/TransactionEventCodes.php +++ b/src/Core/TransactionEventCodes.php @@ -11,9 +11,8 @@ /** * Class TransactionEventCodes - * * @package OxidSolutionCatalysts\PayPal\Core - * @see https://developer.paypal.com/docs/integration/direct/transaction-search/transaction-event-codes/ + * @see https://developer.paypal.com/docs/integration/direct/transaction-search/transaction-event-codes/ */ class TransactionEventCodes { diff --git a/src/Core/Utils/PayPalAddressResponseToOxidAddress.php b/src/Core/Utils/PayPalAddressResponseToOxidAddress.php index 159e10cb2..b26d6d169 100644 --- a/src/Core/Utils/PayPalAddressResponseToOxidAddress.php +++ b/src/Core/Utils/PayPalAddressResponseToOxidAddress.php @@ -17,7 +17,7 @@ class PayPalAddressResponseToOxidAddress { /** - * @param PayPalApiOrderModel $response PayPal Response + * @param PayPalApiOrderModel $response PayPal Response * @return array */ public static function mapOrderDeliveryAddress( @@ -30,7 +30,7 @@ public static function mapOrderDeliveryAddress( } /** - * @param PayPalApiOrderModel $response PayPal Response + * @param PayPalApiOrderModel $response PayPal Response * @return array */ public static function mapUserDeliveryAddress( @@ -43,7 +43,7 @@ public static function mapUserDeliveryAddress( } /** - * @param PayPalApiOrderModel $response PayPal Response + * @param PayPalApiOrderModel $response PayPal Response * @return array */ public static function mapUserInvoiceAddress( @@ -56,8 +56,8 @@ public static function mapUserInvoiceAddress( } /** - * @param PayPalApiOrderModel $response PayPal Response - * @param string $DBTablePrefix + * @param PayPalApiOrderModel $response PayPal Response + * @param string $DBTablePrefix * @return array|bool */ private static function mapAddress( diff --git a/src/Core/Utils/PriceToMoney.php b/src/Core/Utils/PriceToMoney.php index fed9dd732..dd491ddb8 100644 --- a/src/Core/Utils/PriceToMoney.php +++ b/src/Core/Utils/PriceToMoney.php @@ -21,9 +21,9 @@ class PriceToMoney /** * @param Price | double $price - * @param int $mode sets which price value to use with BRUTTO_MODE or NETTO_MODE constants. - * If not set uses the mode set in the price object. - * @param stdClass $currency currency object. If not set uses the active shop currency. + * @param int $mode sets which price value to use with BRUTTO_MODE or NETTO_MODE constants. + * If not set uses the mode set in the price object. + * @param stdClass $currency currency object. If not set uses the active shop currency. * * @return Money */ diff --git a/src/Core/ViewConfig.php b/src/Core/ViewConfig.php index 4261e5ccc..99e13e97a 100644 --- a/src/Core/ViewConfig.php +++ b/src/Core/ViewConfig.php @@ -9,12 +9,11 @@ use Exception; use OxidEsales\Eshop\Core\Registry; -use OxidEsales\EshopCommunity\Core\Config; use OxidSolutionCatalysts\PayPal\Service\LanguageLocaleMapper; use OxidSolutionCatalysts\PayPal\Service\Logger; +use OxidSolutionCatalysts\PayPal\Service\Payment as PaymentService; use OxidSolutionCatalysts\PayPal\Traits\ServiceContainer; use OxidSolutionCatalysts\PayPal\Service\ModuleSettings; -use OxidSolutionCatalysts\PayPal\Core\Config as PayPalConfig; /** * @mixin \OxidEsales\Eshop\Core\ViewConfig @@ -25,14 +24,12 @@ class ViewConfig extends ViewConfig_parent /** * is this a "Flow"-Theme Compatible Theme? - * * @param boolean */ protected $isFlowCompatibleTheme = null; /** * is this a "Wave"-Theme Compatible Theme? - * * @param boolean */ protected $isWaveCompatibleTheme = null; @@ -110,9 +107,12 @@ public function isVaultingEligibility(): bool return $this->getServiceFromContainer(ModuleSettings::class)->isVaultingEligibility(); } - public function getPayPalCheckoutConfig(): PayPalConfig + /** + * @return Config + */ + public function getPayPalCheckoutConfig(): Config { - return oxNew(PayPalConfig::class); + return oxNew(Config::class); } /** @@ -234,55 +234,7 @@ public function getPayPalJsSdkUrl(): string $params['locale'] = $localeCode; - $baseJsSdkUrl = $this->getPayPalCheckoutConfig()->isSandbox() ? - Constants::PAYPAL_SANDBOX_JS_SDK_URL : Constants::PAYPAL_JS_SDK_URL; - - return $baseJsSdkUrl . '?' . http_build_query($params); - } - - /** - * Gets PayPal JS SDK url for Button Payments like SEPA and CreditCardFallback - * - * @return string - */ - public function getPayPalJsSdkUrlForButtonPayments(): string - { - return $this->getBasePayPalJsSdkUrl('funding-eligibility', true); - } - - protected function getBasePayPalJsSdkUrl($type = '', $continueFlow = false): string - { - $config = Registry::getConfig(); - $lang = Registry::getLang(); - - $localeCode = $this->getServiceFromContainer(LanguageLocaleMapper::class) - ->mapLanguageToLocale($lang->getLanguageAbbr()); - - $params = []; - - $params['client-id'] = $this->getPayPalClientId(); - $params['integration-date'] = Constants::PAYPAL_INTEGRATION_DATE; - - if ($currency = $config->getActShopCurrencyObject()) { - $params['currency'] = strtoupper($currency->name); - } - - if ($continueFlow) { - $params['intent'] = strtolower(Constants::PAYPAL_ORDER_INTENT_CAPTURE); - $params['commit'] = 'false'; - } - - $params['components'] = 'buttons,' . $type; - - if ($this->isPayPalBannerActive()) { - $params['components'] .= ',messages'; - } - $params['locale'] = $localeCode; - - $baseJsSdkUrl = $this->getPayPalCheckoutConfig()->isSandbox() ? - Constants::PAYPAL_SANDBOX_JS_SDK_URL : Constants::PAYPAL_JS_SDK_URL; - - return $baseJsSdkUrl . '?' . http_build_query($params); + return Constants::PAYPAL_JS_SDK_URL . '?' . http_build_query($params); } public function showPayPalExpressInMiniBasket(): bool @@ -295,13 +247,17 @@ public function showPayPalExpressInMiniBasket(): bool $ppExpressSessionActive = $this->isPayPalExpressSessionActive(); $acdcSessionActive = $this->isPayPalACDCSessionActive(); if ( - $className !== 'payment' - && $ppActive - && $configShowMiniBasketButton - && !$ppExpressSessionActive - && ( ( $className === 'order' - && !$acdcSessionActive ) - || $className !== 'order') + $className !== 'payment' && + $ppActive && + $configShowMiniBasketButton && + !$ppExpressSessionActive && + ( + ( + $className === 'order' && + !$acdcSessionActive + ) || + $className !== 'order' + ) ) { $showButton = true; } @@ -310,20 +266,17 @@ public function showPayPalExpressInMiniBasket(): bool public function getUserIdForVaulting(): string { - if (!$this->getUser()) { - return ""; - } - - $payPalCustomerId = $this->getUser()->getFieldData("oscpaypalcustomerid"); - - if (!$payPalCustomerId) { - return ""; - } + return oxNew(Config::class)->getUserIdForVaulting(); + } - $vaultingService = Registry::get(ServiceFactory::class)->getVaultingService(); - $response = $vaultingService->generateUserIdToken($payPalCustomerId); + public function isVaultingAllowedForPayPal(): bool + { + return $this->getServiceFromContainer(ModuleSettings::class)->isVaultingAllowedForPayPal(); + } - return $response["id_token"]; + public function isVaultingAllowedForACDC(): bool + { + return $this->getServiceFromContainer(ModuleSettings::class)->isVaultingAllowedForACDC(); } /** @@ -343,14 +296,16 @@ public function getSessionVaultSuccess() /** * get Vault Token * - * @return string|null + * @return array|null */ public function getVaultPaymentTokens() { if ($this->getIsVaultingActive() && $customerId = $this->getUser()->getFieldData("oscpaypalcustomerid")) { $vaultingService = Registry::get(ServiceFactory::class)->getVaultingService(); - return $vaultingService->getVaultPaymentTokens($customerId)["payment_tokens"] ?? null; + $vaultPaymentTokens = $vaultingService->getVaultPaymentTokens($customerId)["payment_tokens"] ?? null; + + return $this->filterVaultPaymentTokensByController($vaultPaymentTokens); } return null; @@ -361,17 +316,13 @@ public function getDataClientToken(): string $result = ''; try { - /** - * @var \OxidSolutionCatalysts\PayPal\Core\Api\IdentityService $identityService -*/ + /** @var \OxidSolutionCatalysts\PayPal\Core\Api\IdentityService $identityService */ $identityService = Registry::get(ServiceFactory::class)->getIdentityService(); $response = $identityService->requestClientToken(); $result = $response['client_token'] ?? ''; } catch (Exception $exception) { - /** - * @var Logger $logger -*/ + /** @var Logger $logger */ $logger = $this->getServiceFromContainer(Logger::class); $logger->log('error', $exception->getMessage(), [$exception]); } @@ -396,21 +347,6 @@ public function getPayPalClientId(): string return $this->getServiceFromContainer(ModuleSettings::class)->getClientId(); } - /** - * API URL getter for use with the installment banner feature - */ - public function getPayPalApiBannerUrl(): string - { - $params['client-id'] = $this->getPayPalClientId(); - - $params['components'] = 'messages'; - - $baseJsSdkUrl = $this->getPayPalCheckoutConfig()->isSandbox() ? - Constants::PAYPAL_SANDBOX_JS_SDK_URL : Constants::PAYPAL_JS_SDK_URL; - - return $baseJsSdkUrl . '?' . http_build_query($params); - } - /** * API ID getter for use with the installment banner feature */ @@ -605,7 +541,7 @@ public function isWaveCompatibleTheme() /** * Template variable getter. Check if is a ??? Theme Compatible Theme * - * @return boolean + * @return boolean * @psalm-suppress InternalMethod */ public function isCompatibleTheme($themeId = null) @@ -616,8 +552,8 @@ public function isCompatibleTheme($themeId = null) $theme->load($theme->getActiveThemeId()); // check active theme or parent theme if ( - $theme->getActiveThemeId() == $themeId - || $theme->getInfo('parentTheme') == $themeId + $theme->getActiveThemeId() == $themeId || + $theme->getInfo('parentTheme') == $themeId ) { $result = true; } @@ -666,18 +602,42 @@ public function isAcdcEligibility(): bool return $this->getServiceFromContainer(ModuleSettings::class)->isAcdcEligibility(); } - public function getMerchantId(): string + private function filterVaultPaymentTokensByController($vaultPaymentTokens) { - return $this->getServiceFromContainer(ModuleSettings::class)->getMerchantId(); + if (is_null($vaultPaymentTokens)) { + return null; + } + + if ($this->isAccountVaultController()) { + return array_filter( + $vaultPaymentTokens, + function ($token) { + return array_key_exists('payment_source', $token) + && !array_key_exists('card', $token['payment_source']); + } + ); + } + + if ($this->isAccountVaultCartController()) { + return array_filter( + $vaultPaymentTokens, + function ($token) { + return array_key_exists('payment_source', $token) + && array_key_exists('card', $token['payment_source']); + } + ); + } + + return $vaultPaymentTokens; } - public function getClientId(): string + private function isAccountVaultController(): bool { - return $this->getServiceFromContainer(ModuleSettings::class)->getClientId(); + return Registry::getRequest()->getRequestEscapedParameter("cl") === 'oscaccountvault'; } - public function getConfig(): Config + private function isAccountVaultCartController(): bool { - return Registry::getConfig(); + return Registry::getRequest()->getRequestEscapedParameter("cl") === 'oscaccountvaultcard'; } } diff --git a/src/Core/Webhook/EventVerifier.php b/src/Core/Webhook/EventVerifier.php index 3ebb62aa7..dce3a9c7e 100644 --- a/src/Core/Webhook/EventVerifier.php +++ b/src/Core/Webhook/EventVerifier.php @@ -34,8 +34,8 @@ class EventVerifier ]; /** - * @param array $headers Event request headers - * @param string $body Event request body + * @param array $headers Event request headers + * @param string $body Event request body * * @throws ApiException|WebhookEventVerificationException */ @@ -64,15 +64,13 @@ public function verify(array $headers, string $body): bool $headers = []; $headers['PayPal-Partner-Attribution-Id'] = Constants::PAYPAL_PARTNER_ATTRIBUTION_ID_PPCP; - /** - * @var GenericService $notificationService -*/ + /** @var GenericService $notificationService */ $notificationService = Registry::get(ServiceFactory::class)->getNotificationService(); $response = $notificationService->request('POST', $payload, [], $headers); if ( - !$response['verification_status'] - || ($response['verification_status'] !== self::VERIFICATION_STATUS_SUCCESS) + !$response['verification_status'] || ( + $response['verification_status'] !== self::VERIFICATION_STATUS_SUCCESS) ) { throw new WebhookEventVerificationException('Event verification failed'); } diff --git a/src/Core/Webhook/Handler/CheckoutOrderApprovedHandler.php b/src/Core/Webhook/Handler/CheckoutOrderApprovedHandler.php index 897569917..2b30008d3 100644 --- a/src/Core/Webhook/Handler/CheckoutOrderApprovedHandler.php +++ b/src/Core/Webhook/Handler/CheckoutOrderApprovedHandler.php @@ -40,9 +40,7 @@ public function handleWebhookTasks( ); $order->setOrderNumber(); //ensure the order has a number } catch (\Exception $exception) { - /** - * @var Logger $logger -*/ + /** @var Logger $logger */ $logger = $this->getServiceFromContainer(Logger::class); $logger->log( 'debug', @@ -83,9 +81,7 @@ protected function getStatusFromResource(array $eventPayload): string */ private function capturePayment(string $orderId): OrderResponse { - /** - * @var ServiceFactory $serviceFactory -*/ + /** @var ServiceFactory $serviceFactory */ $serviceFactory = Registry::get(ServiceFactory::class); $service = $serviceFactory->getOrderService(); $request = new OrderCaptureRequest(); diff --git a/src/Core/Webhook/Handler/PaymentCaptureCompletedHandler.php b/src/Core/Webhook/Handler/PaymentCaptureCompletedHandler.php index 495a469e7..89fed9de6 100644 --- a/src/Core/Webhook/Handler/PaymentCaptureCompletedHandler.php +++ b/src/Core/Webhook/Handler/PaymentCaptureCompletedHandler.php @@ -36,7 +36,6 @@ protected function getStatusFromResource(array $eventPayload): string protected function getPayPalOrderDetails(string $payPalOrderId): ?PayPalApiModelOrder { - try { $apiOrder = Registry::get(ServiceFactory::class) ->getOrderService() @@ -46,9 +45,7 @@ protected function getPayPalOrderDetails(string $payPalOrderId): ?PayPalApiModel Constants::PAYPAL_PARTNER_ATTRIBUTION_ID_PPCP ); } catch (ApiException $exception) { - /** - * @var Logger $logger -*/ + /** @var Logger $logger */ $logger = $this->getServiceFromContainer(Logger::class); $logger->log( 'debug', diff --git a/src/Core/Webhook/Handler/PaymentCaptureRefundedHandler.php b/src/Core/Webhook/Handler/PaymentCaptureRefundedHandler.php index 8b056c7ec..19b7209f2 100644 --- a/src/Core/Webhook/Handler/PaymentCaptureRefundedHandler.php +++ b/src/Core/Webhook/Handler/PaymentCaptureRefundedHandler.php @@ -26,7 +26,7 @@ class PaymentCaptureRefundedHandler extends WebhookHandlerBase /** * @inheritDoc - * @throws ApiException + * @throws ApiException */ public function handle(Event $event): void { @@ -35,9 +35,7 @@ public function handle(Event $event): void //NOTE: it is the capture (transaction) id, not the order we get from up link $transactionId = $this->getPayPalOrderIdFromResource($eventPayload); - /** - * @var EshopModelOrder $order -*/ + /** @var EshopModelOrder $order */ $order = $this->getOrderByPayPalTransactionId($transactionId); //track the refund @@ -103,9 +101,7 @@ protected function getAmountFromResource(array $eventPayload): float protected function getOrderByPayPalTransactionId(string $captureId): EshopModelOrder { try { - /** - * @var EshopModelOrder $order -*/ + /** @var EshopModelOrder $order */ $order = $this->getOrderRepository() ->getShopOrderByPayPalTransactionId($captureId); } catch (NotFound $exception) { @@ -118,9 +114,7 @@ protected function getOrderByPayPalTransactionId(string $captureId): EshopModelO protected function getPayPalOrderIdByShopOrderId(string $shopOrderId): string { try { - /** - * @var EshopModelOrder $order -*/ + /** @var EshopModelOrder $order */ $orderId = $this->getOrderRepository() ->getPayPalOrderIdByShopOrderId($shopOrderId); } catch (NotFound $exception) { diff --git a/src/Core/Webhook/Handler/WebhookHandlerBase.php b/src/Core/Webhook/Handler/WebhookHandlerBase.php index e44b6dff7..50f1341f8 100644 --- a/src/Core/Webhook/Handler/WebhookHandlerBase.php +++ b/src/Core/Webhook/Handler/WebhookHandlerBase.php @@ -29,7 +29,7 @@ abstract class WebhookHandlerBase /** * @inheritDoc - * @throws WebhookEventException + * @throws WebhookEventException */ public function handle(Event $event): void { @@ -42,14 +42,10 @@ public function handle(Event $event): void $payPalOrderId = $this->getPayPalOrderIdFromResource($eventPayload); if ($payPalOrderId) { - /** - * @var EshopModelOrder $order -*/ + /** @var EshopModelOrder $order */ $order = $this->getOrderByPayPalOrderId($payPalOrderId); - /** - * @var PayPalModelOrder $paypalOrderModel -*/ + /** @var PayPalModelOrder $paypalOrderModel */ $paypalOrderModel = $this->getPayPalModelOrder( (string) $order->getId(), $payPalOrderId, @@ -64,9 +60,7 @@ public function handle(Event $event): void $order ); } else { - /** - * @var Logger $logger -*/ + /** @var Logger $logger */ $logger = $this->getServiceFromContainer(Logger::class); $logger->log( 'debug', @@ -92,9 +86,7 @@ public function handleWebhookTasks( ): void { $paypalOrderModel->setTransactionId($payPalTransactionId); - /** - * @var ?PayPalApiModelOrder $orderDetail -*/ + /** @var ?PayPalApiModelOrder $orderDetail */ $orderDetail = $this->getPayPalOrderDetails($payPalOrderId); $this->updateStatus( @@ -109,9 +101,7 @@ public function handleWebhookTasks( public function cleanUpNotFinishedOrders(): void { // check for not finished orders and reset - /** - * @var \OxidSolutionCatalysts\PayPal\Model\PayPalOrder $paypalOrderModel -*/ + /** @var \OxidSolutionCatalysts\PayPal\Model\PayPalOrder $paypalOrderModel */ $this->getOrderRepository()->cleanUpNotFinishedOrders(); } @@ -143,9 +133,7 @@ public function getEventPayload(Event $event): array protected function getOrderByPayPalOrderId(string $payPalOrderId): EshopModelOrder { try { - /** - * @var EshopModelOrder $order -*/ + /** @var EshopModelOrder $order */ $order = $this->getOrderRepository() ->getShopOrderByPayPalOrderId($payPalOrderId); } catch (NotFound $exception) { @@ -160,9 +148,7 @@ protected function getPayPalModelOrder( string $payPalOrderId, string $payPalTransactionId ): PayPalModelOrder { - /** - * @var PayPalModelOrder $paypalOrderModel -*/ + /** @var PayPalModelOrder $paypalOrderModel */ $paypalOrderModel = $this->getOrderRepository() ->paypalOrderByOrderIdAndPayPalId( $shopOrderId, @@ -184,8 +170,8 @@ protected function updateStatus( ?PayPalApiModelOrder $orderDetails ): void { if ( - $orderDetails - && ($puiPaymentDetails = $orderDetails->payment_source->pay_upon_invoice ?? null) + $orderDetails && + ($puiPaymentDetails = $orderDetails->payment_source->pay_upon_invoice ?? null) ) { $paypalOrderModel->setPuiPaymentReference($puiPaymentDetails->payment_reference); $paypalOrderModel->setPuiBic($puiPaymentDetails->bic); diff --git a/src/Core/Webhook/RequestHandler.php b/src/Core/Webhook/RequestHandler.php index 24548f7c6..b97a8e754 100644 --- a/src/Core/Webhook/RequestHandler.php +++ b/src/Core/Webhook/RequestHandler.php @@ -23,19 +23,13 @@ final class RequestHandler { use ServiceContainer; - /** - * @var RequestReader - */ + /** @var RequestReader */ private $requestReader; - /** - * @var VerificationService - */ + /** @var VerificationService */ private $verificationService; - /** - * @var WebhookDispatcher - */ + /** @var WebhookDispatcher */ private $webhookDispatcher; public function __construct( @@ -55,9 +49,7 @@ public function __construct( public function process(): bool { $result = false; - /** - * @var Logger $logger -*/ + /** @var Logger $logger */ $logger = $this->getServiceFromContainer(Logger::class); try { diff --git a/src/Exception/Redirect.php b/src/Exception/Redirect.php index 67f747ef3..c9bb7acdb 100644 --- a/src/Exception/Redirect.php +++ b/src/Exception/Redirect.php @@ -9,9 +9,7 @@ class Redirect extends PayPalException { - /** - * @var string - */ + /** @var string */ private $destination; /** diff --git a/src/Exception/RedirectWithMessage.php b/src/Exception/RedirectWithMessage.php index 4860cab88..fbf27b4f4 100644 --- a/src/Exception/RedirectWithMessage.php +++ b/src/Exception/RedirectWithMessage.php @@ -9,20 +9,16 @@ class RedirectWithMessage extends Redirect { - /** - * @var string - */ + /** @var string */ private $messageKey; - /** - * @var array - */ + /** @var array */ private $messageParams; /** * @param string $destination * @param string $messageKey - * @param array $messageParams + * @param array $messageParams */ public function __construct(string $destination, string $messageKey, array $messageParams = []) { diff --git a/src/Model/Basket.php b/src/Model/Basket.php index c31e2ae04..62a40f730 100644 --- a/src/Model/Basket.php +++ b/src/Model/Basket.php @@ -213,8 +213,7 @@ public function getPayPalCheckoutRoundDiff() /** * Check if variants of the given product are already in the basket - * - * @param \OxidEsales\Eshop\Application\Model\Article $product + * @param \OxidEsales\Eshop\Application\Model\Article $product * @return bool */ public function hasProductVariantInBasket(\OxidEsales\Eshop\Application\Model\Article $product) @@ -234,7 +233,6 @@ public function hasProductVariantInBasket(\OxidEsales\Eshop\Application\Model\Ar /** * add a ShippingPrice for PPExpress if it is not defined before to prevent overcharge. - * * @param float $defaultShippingPriceExpress */ public function addShippingPriceForExpress(float $defaultShippingPriceExpress): void diff --git a/src/Model/Order.php b/src/Model/Order.php index c3b07ce50..4c99b1e0a 100644 --- a/src/Model/Order.php +++ b/src/Model/Order.php @@ -25,7 +25,6 @@ use OxidSolutionCatalysts\PayPal\Core\PayPalSession; use OxidSolutionCatalysts\PayPal\Core\ServiceFactory; use OxidSolutionCatalysts\PayPal\Core\Tracker\Tracker; -use OxidSolutionCatalysts\PayPal\Core\Tracker\TrackerTracker; use OxidSolutionCatalysts\PayPal\Exception\PayPalException; use OxidSolutionCatalysts\PayPal\Service\ModuleSettings; use OxidSolutionCatalysts\PayPal\Service\OrderRepository; @@ -96,35 +95,30 @@ class Order extends Order_parent /** * PayPal order information - * * @var null|PayPalApiOrder $payPalApiOrder */ protected $payPalApiOrder = null; /** * PayPal order Id - * * @var null|string */ protected $payPalOrderId = null; /** * PayPal order Repo - * * @var PayPalOrder $payPalOrder */ protected $payPalOrder; /** * PayPalPlus order Id - * * @var null|string */ protected $payPalPlusOrderId = null; /** * PayPalPlus order Id - * * @var null|string */ protected $payPalSoapOrderId = null; @@ -147,9 +141,7 @@ public function finalizeOrderAfterExternalPayment(string $payPalOrderId, bool $f throw PayPalException::cannotFinalizeOrderAfterExternalPaymentSuccess($payPalOrderId); } - /** - * @var PaymentService $paymentService -*/ + /** @var PaymentService $paymentService */ $paymentService = $this->getServiceFromContainer(PaymentService::class); $paymentsId = (string) $this->getFieldData('oxpaymenttype'); if (!$paymentService->isPayPalPayment($paymentsId)) { @@ -186,14 +178,15 @@ public function finalizeOrderAfterExternalPayment(string $payPalOrderId, bool $f } } - if ($isPayPalACDC || $isPaypalApplePay || $isPaypalGooglePay) { + if ($isPayPalACDC || $isPaypalGooglePay || $isPaypalApplePay) { //webhook should kick in and handle order state and we should not call the api too often Registry::getSession()->deleteVariable(Constants::SESSION_ACDC_PAYPALORDER_STATUS); // remove PayPal order id from session PayPalSession::unsetPayPalOrderId(); } elseif ( - $isPayPalStandard - && $this->getServiceFromContainer(ModuleSettings::class)->getPayPalStandardCaptureStrategy() !== 'directly' + $isPayPalStandard && + $this->getServiceFromContainer(ModuleSettings::class) + ->getPayPalStandardCaptureStrategy() !== 'directly' ) { //manual capture for PayPal standard will be done later, so no transaction id yet $transactionId = ''; @@ -220,8 +213,6 @@ public function finalizeOrderAfterExternalPayment(string $payPalOrderId, bool $f // so we set the order to "oxtransstatus" = ERROR // The Merchant has the opportunity to see what is going on and can contact the customer if necessary $this->setOrderStatus('ERROR'); - $paymentService = $this->getServiceFromContainer(PaymentService::class); - $paymentService->removeTemporaryOrder(); throw PayPalException::cannotFinalizeOrderAfterExternalPayment($payPalOrderId, $paymentsId); } $this->setTransId($capture->id); @@ -233,9 +224,7 @@ public function finalizeOrderAfterExternalPayment(string $payPalOrderId, bool $f $this->sendPayPalOrderByEmail($user, $basket); } - /** - * @inheritDoc - */ + /** @inheritDoc */ protected function sendPayPalOrderByEmail(User $user, Basket $basket): void { $userPayment = oxNew(UserPayment::class); @@ -288,14 +277,7 @@ protected function executePayment(Basket $basket, $userpayment) $isPayPalACDC = $sessionPaymentId === PayPalDefinitions::ACDC_PAYPAL_PAYMENT_ID; $isPayPalStandard = $sessionPaymentId === PayPalDefinitions::STANDARD_PAYPAL_PAYMENT_ID; $isPayPalPayLater = $sessionPaymentId === PayPalDefinitions::PAYLATER_PAYPAL_PAYMENT_ID; - $isApplePay = $sessionPaymentId === PayPalDefinitions::APPLEPAY_PAYPAL_PAYMENT_ID; - if ( - $sessionPaymentId === PayPalDefinitions::GOOGLEPAY_PAYPAL_PAYMENT_ID - || $sessionPaymentId === PayPalDefinitions::APPLEPAY_PAYPAL_PAYMENT_ID - ) { - $isPayPalUAPM = false; - } //catch UAPM, Standard and Pay Later PayPal payments here if ($isPayPalUAPM || $isPayPalStandard || $isPayPalPayLater) { try { @@ -320,17 +302,15 @@ protected function executePayment(Basket $basket, $userpayment) return self::ORDER_STATE_SESSIONPAYMENT_INPROGRESS; } catch (Exception $exception) { $this->delete(); - /** - * @var Logger $logger -*/ + /** @var Logger $logger */ $logger = $this->getServiceFromContainer(Logger::class); $logger->log('error', $exception->getMessage(), [$exception]); } return self::ORDER_STATE_PAYMENTERROR; } elseif ($isPayPalACDC) { if ( - Registry::getSession()->getVariable(Constants::SESSION_ACDC_PAYPALORDER_STATUS) - === Constants::PAYPAL_STATUS_COMPLETED + Registry::getSession()->getVariable(Constants::SESSION_ACDC_PAYPALORDER_STATUS) === + Constants::PAYPAL_STATUS_COMPLETED ) { return self::ORDER_STATE_ACDCCOMPLETED; } @@ -351,9 +331,7 @@ public function getPayPalCheckoutOrder($payPalOrderId = ''): PayPalApiOrder { $payPalOrderId = $payPalOrderId ?: $this->getPayPalOrderIdForOxOrderId(); if (!$this->payPalApiOrder) { - /** - * @var Orders $orderService -*/ + /** @var Orders $orderService */ $orderService = Registry::get(ServiceFactory::class)->getOrderService(); $this->payPalApiOrder = $orderService->showOrderDetails( $payPalOrderId, @@ -367,9 +345,7 @@ public function getPayPalCheckoutOrder($payPalOrderId = ''): PayPalApiOrder protected function doExecutePayPalPayment($payPalOrderId): bool { - /** - * @var PaymentService $paymentService -*/ + /** @var PaymentService $paymentService */ $paymentService = $this->getServiceFromContainer(PaymentService::class); $sessionPaymentId = (string) $paymentService->getSessionPaymentId(); $success = false; @@ -382,9 +358,7 @@ protected function doExecutePayPalPayment($payPalOrderId): bool // success means at this point, that we triggered the capture without errors $success = true; } catch (Exception $exception) { - /** - * @var Logger $logger -*/ + /** @var Logger $logger */ $logger = $this->getServiceFromContainer(Logger::class); $logger->log('error', "Error on order capture call.", [$exception]); } @@ -623,41 +597,39 @@ public function hasOrderNumber(): bool public function finalizeOrder(Basket $basket, $user, $recalculatingOrder = false) { //we might have the case that the order is already stored but we are waiting for webhook events - /** - * @var PaymentService $paymentService -*/ + /** @var PaymentService $paymentService */ $paymentService = $this->getServiceFromContainer(PaymentService::class); if ( - $paymentService->isPayPalPayment() - && $paymentService->isOrderExecutionInProgress() - && $this->load(Registry::getSession()->getVariable('sess_challenge')) + $paymentService->isPayPalPayment() && + $paymentService->isOrderExecutionInProgress() && + $this->load(Registry::getSession()->getVariable('sess_challenge')) ) { //order payment is being processed if ( - !$this->isOrderFinished() - && !$this->isOrderPaid() - && !$this->isWaitForWebhookTimeoutReached() + !$this->isOrderFinished() && + !$this->isOrderPaid() && + !$this->isWaitForWebhookTimeoutReached() ) { return self::ORDER_STATE_WAIT_FOR_WEBHOOK_EVENTS; } //ACDC payment dropoff scenario where webhook might have kicked in so we can continue if ( - (PayPalDefinitions::ACDC_PAYPAL_PAYMENT_ID === $paymentService->getSessionPaymentId()) - && $this->isOrderFinished() - && $this->isOrderPaid() - && !$this->hasOrderNumber() + (PayPalDefinitions::ACDC_PAYPAL_PAYMENT_ID === $paymentService->getSessionPaymentId()) && + $this->isOrderFinished() && + $this->isOrderPaid() && + !$this->hasOrderNumber() ) { return self::ORDER_STATE_NEED_CALL_ACDC_FINALIZE; } //webhook events might be delayed so try to fetch information from PayPal api if ( - (PayPalDefinitions::ACDC_PAYPAL_PAYMENT_ID === $paymentService->getSessionPaymentId()) - && !$this->isOrderFinished() - && !$this->isOrderPaid() - && !$this->hasOrderNumber() - && $this->isWaitForWebhookTimeoutReached() + (PayPalDefinitions::ACDC_PAYPAL_PAYMENT_ID === $paymentService->getSessionPaymentId()) && + !$this->isOrderFinished() && + !$this->isOrderPaid() && + !$this->hasOrderNumber() && + $this->isWaitForWebhookTimeoutReached() ) { return self::ORDER_STATE_TIMEOUT_FOR_WEBHOOK_EVENTS; } @@ -715,9 +687,7 @@ public function getPayPalTransactionId(): string protected function getPayPalRepository(): PayPalOrder { - /** - * @var OrderRepository $payPalOrderRepository -*/ + /** @var OrderRepository $payPalOrderRepository */ $payPalOrderRepository = $this->getServiceFromContainer(OrderRepository::class); $this->payPalOrder = $payPalOrderRepository->paypalOrderByOrderId( $this->getId() @@ -737,9 +707,7 @@ public function delete($sOxId = null) $sOxId = $sOxId ?? $this->getId(); // delete PayPalOrder too - /** - * @var OrderRepository $payPalOrderRepository -*/ + /** @var OrderRepository $payPalOrderRepository */ $payPalOrderRepository = $this->getServiceFromContainer(OrderRepository::class); $payPalOrder = $payPalOrderRepository->paypalOrderByOrderId( $sOxId diff --git a/src/Model/PayPalOrder.php b/src/Model/PayPalOrder.php index cd2b639b9..2094467cf 100644 --- a/src/Model/PayPalOrder.php +++ b/src/Model/PayPalOrder.php @@ -49,7 +49,6 @@ public function setId($oxid = null) } return $return; } - public function getPayPalOrderId(): string { return (string) $this->getFieldData('oxpaypalorderid'); diff --git a/src/Model/PayPalPlusOrder.php b/src/Model/PayPalPlusOrder.php index 8776344a2..5ff552893 100644 --- a/src/Model/PayPalPlusOrder.php +++ b/src/Model/PayPalPlusOrder.php @@ -179,9 +179,7 @@ public function getOrder(): ?Order { if (is_null($this->order)) { - /** - * @var Order $oOrder -*/ + /** @var Order $oOrder */ $oOrder = oxNew(Order::class); if ($oOrder->load($this->getOrderId())) { @@ -203,9 +201,7 @@ public function getRefundsList(): ?PayPalPlusRefundList { if (is_null($this->refundList)) { - /** - * @var PayPalPlusRefundList $oRefundList -*/ + /** @var PayPalPlusRefundList $oRefundList */ $oRefundList = oxNew(PayPalPlusRefundList::class); $oRefundList->loadRefundsBySaleId($this->getSaleId()); @@ -226,9 +222,7 @@ public function getTotalAmountRefunded(): float { if (is_null($this->totalAmountRefunded)) { - /** - * @var PayPalPlusRefundList $oRefundList -*/ + /** @var PayPalPlusRefundList $oRefundList */ $oRefundList = oxNew(PayPalPlusRefundList::class); $this->totalAmountRefunded = $oRefundList->getRefundedSumBySaleId($this->getSaleId()); } diff --git a/src/Model/PayPalPlusPui.php b/src/Model/PayPalPlusPui.php index d286f6a82..918a98a36 100644 --- a/src/Model/PayPalPlusPui.php +++ b/src/Model/PayPalPlusPui.php @@ -122,14 +122,14 @@ public function loadByReferenceNumber($sReferenceNumber) } /** - * Load entry by a field name and value. - * Used for loading by `OXORDERID`, `OXSALEID` and `OXPAYMENTID`. - * - * @param string $sFieldName - * @param string $sFieldValue - * - * @return bool - */ + * Load entry by a field name and value. + * Used for loading by `OXORDERID`, `OXSALEID` and `OXPAYMENTID`. + * + * @param string $sFieldName + * @param string $sFieldValue + * + * @return bool + */ protected function _loadBy($sFieldName, $sFieldValue) { if (!in_array($sFieldName, ['OXREFERENCENUMBER', 'OXPAYMENTID'])) { diff --git a/src/Model/PayPalSoapOrder.php b/src/Model/PayPalSoapOrder.php index 72e0acb35..8efec9739 100644 --- a/src/Model/PayPalSoapOrder.php +++ b/src/Model/PayPalSoapOrder.php @@ -20,9 +20,7 @@ class PayPalSoapOrder extends \OxidEsales\Eshop\Core\Model\BaseModel */ protected $_sCoreTable = 'oepaypal_order'; // phpcs:ignore PSR2.Classes.PropertyDeclaration - /** - * Completion status - */ + /** Completion status */ protected const PAYPAL_ORDER_STATE_COMPLETED = 'completed'; /** diff --git a/src/Model/PayPalTrackingCarrierList.php b/src/Model/PayPalTrackingCarrierList.php index 6e904aaa4..eb86861d8 100644 --- a/src/Model/PayPalTrackingCarrierList.php +++ b/src/Model/PayPalTrackingCarrierList.php @@ -45,15 +45,14 @@ public function loadTrackingCarriers(string $countryCode = '') /** * Load allowed Tracking-Carrier Country-Codes + * */ public function getAllowedTrackingCarrierCountryCodes(): array { $result = []; $queryBuilderFactory = $this->getServiceFromContainer(QueryBuilderFactoryInterface::class); - /** - * @var QueryBuilder $queryBuilder -*/ + /** @var QueryBuilder $queryBuilder */ $queryBuilder = $queryBuilderFactory->create(); $inQueryBuilder = $queryBuilderFactory->create(); $notInQueryBuilder = $queryBuilderFactory->create(); @@ -65,9 +64,7 @@ public function getAllowedTrackingCarrierCountryCodes(): array $notInQueryBuilder->select('oxisoalpha2') ->from('oxcountry'); - /** - * @var Result $resultDB -*/ + /** @var Result $resultDB */ $resultDB = $queryBuilder->select('count(oxid), oxcountrycode') ->from('oscpaypal_trackingcarrier') ->where($queryBuilder->expr()->in('CONVERT(oxcountrycode USING utf8)', $inQueryBuilder->getSQL())) diff --git a/src/Model/PaymentGateway.php b/src/Model/PaymentGateway.php index ef5767084..7d1fb33cc 100644 --- a/src/Model/PaymentGateway.php +++ b/src/Model/PaymentGateway.php @@ -18,7 +18,6 @@ /** * Class PaymentGateway - * * @package OxidSolutionCatalysts\PayPal\Model * * @mixin \OxidEsales\Eshop\Application\Model\PaymentGateway @@ -28,11 +27,12 @@ class PaymentGateway extends PaymentGateway_parent use ServiceContainer; /** - * Executes payment, returns true on success. - * - * @param double $amount Goods amount - * @param EshopModelOrder $order User ordering object - */ + * Executes payment, returns true on success. + * + * @param double $amount Goods amount + * @param EshopModelOrder $order User ordering object + * + */ public function executePayment($amount, &$order) { $paymentService = $this->getServiceFromContainer(PaymentService::class); @@ -47,14 +47,14 @@ public function executePayment($amount, &$order) } $paypalOrderId = ''; if ( - $sessionPaymentId === PayPalDefinitions::APPLEPAY_PAYPAL_PAYMENT_ID - || $sessionPaymentId === PayPalDefinitions::GOOGLEPAY_PAYPAL_PAYMENT_ID + $sessionPaymentId === PayPalDefinitions::APPLEPAY_PAYPAL_PAYMENT_ID || + $sessionPaymentId === PayPalDefinitions::GOOGLEPAY_PAYPAL_PAYMENT_ID ) { $paypalOrderId = Registry::getRequest()->getRequestParameter('orderID'); } if ( - $success - && $paymentService->isPayPalPayment() + $success && + $paymentService->isPayPalPayment() ) { $capture = $order->getOrderPaymentCapture($paypalOrderId); if ($capture && (string) $capture->status === 'COMPLETED') { @@ -68,24 +68,18 @@ public function executePayment($amount, &$order) protected function doExecutePayPalExpressPayment(EshopModelOrder $order): bool { - /** - * @var PaymentService $paymentService -*/ + /** @var PaymentService $paymentService */ $paymentService = $this->getServiceFromContainer(PaymentService::class); $sessionPaymentId = (string) $paymentService->getSessionPaymentId(); $success = false; - /** - * @var Logger $logger -*/ + /** @var Logger $logger */ $logger = $this->getServiceFromContainer(Logger::class); if ($checkoutOrderId = PayPalSession::getCheckoutOrderId()) { // Update Order try { - $basket = Registry::getSession()->getBasket(); - $shopOrderId = (string)$order->getFieldData('oxordernr'); - $paymentService->doPatchPayPalOrder($basket, $checkoutOrderId, $shopOrderId); + $paymentService->doPatchPayPalOrder(Registry::getSession()->getBasket(), $checkoutOrderId); } catch (Exception $exception) { $logger->log('error', 'Error on order patch call.', [$exception]); } @@ -110,9 +104,7 @@ protected function doExecutePayPalExpressPayment(EshopModelOrder $order): bool protected function doExecutePuiPayment(EshopModelOrder $order): bool { - /** - * @var PaymentService $paymentService - */ + /** @var PaymentService $paymentService */ $paymentService = $this->getServiceFromContainer(PaymentService::class); $success = false; @@ -126,9 +118,7 @@ protected function doExecutePuiPayment(EshopModelOrder $order): bool ); PayPalSession::unsetPayPalPuiCmId(); } catch (Exception $exception) { - /** - * @var Logger $logger - */ + /** @var Logger $logger */ $logger = $this->getServiceFromContainer(Logger::class); $logger->log('error', 'Error on execute pui payment call.', [$exception]); } diff --git a/src/Model/State.php b/src/Model/State.php index 9389028e0..024f187cf 100644 --- a/src/Model/State.php +++ b/src/Model/State.php @@ -7,12 +7,10 @@ class State extends State_parent public function loadByIdAndCountry($oxIsoAlpha2, $countryID) { // must mimic the original "load" functionality - $query = $this->buildSelectString( - [ + $query = $this->buildSelectString([ $this->getViewName() . '.oxisoalpha2' => $oxIsoAlpha2, $this->getViewName() . '.oxcountryid' => $countryID - ] - ); + ]); $this->_isLoaded = $this->assignRecord($query); return $this->_isLoaded; diff --git a/src/Model/User.php b/src/Model/User.php index 5ab7c792e..971cec32f 100644 --- a/src/Model/User.php +++ b/src/Model/User.php @@ -96,21 +96,18 @@ public function getPhoneNumberForPuiRequest(): ?ApiModelPhone /** * get the InvoiceAddress from user with all required fields - * * @return array */ public function getInvoiceAddress(): array { $result = []; $requiredAddressFields = oxNew(RequiredAddressFields::class); - // Needed to not produce an error in InputValidator->hasRequiredParametersForVatInCheck() $requiredFields = $requiredAddressFields->getRequiredFields(); $requiredFields[] = 'oxuser__oxustid'; $requiredFields[] = 'oxuser__oxcountryid'; $requiredFields[] = 'oxuser__oxcompany'; $requiredAddressFields->setRequiredFields($requiredFields); - foreach ($requiredAddressFields->getBillingFields() as $requiredAddressField) { $result[$requiredAddressField] = $this->{$requiredAddressField}->value; } diff --git a/src/Service/Context.php b/src/Service/Context.php index 0a1ec12b7..786f4e142 100644 --- a/src/Service/Context.php +++ b/src/Service/Context.php @@ -19,13 +19,11 @@ class Context */ public function getPayPalLogFilePath(): string { - return Path::join( - [ + return Path::join([ Registry::getConfig()->getLogsDir(), 'paypal', $this->getPayPalLogFileName() - ] - ); + ]); } private function getPayPalLogFileName(): string diff --git a/src/Service/GooglePay/GooglePayPayPalService.php b/src/Service/GooglePay/GooglePayPayPalService.php index 98a6e1ec3..41010ffcb 100644 --- a/src/Service/GooglePay/GooglePayPayPalService.php +++ b/src/Service/GooglePay/GooglePayPayPalService.php @@ -15,9 +15,7 @@ public function __construct(private Logger $logger) public function finalizeGooglePay(string $oxidOrderId, string $payPalOrderId, bool $forceFetchDetails): bool { try { - /** - * @var Order $order -*/ + /** @var Order $order */ $order = oxNew(Order::class); $order->load($oxidOrderId); $order->finalizeOrderAfterExternalPayment($payPalOrderId, $forceFetchDetails); diff --git a/src/Service/Logger.php b/src/Service/Logger.php index f8aba0c60..afba066b8 100644 --- a/src/Service/Logger.php +++ b/src/Service/Logger.php @@ -17,9 +17,7 @@ */ class Logger { - /** - * @var LoggerInterface $moduleLogger - */ + /** @var LoggerInterface $moduleLogger */ private $moduleLogger; public function __construct( @@ -28,9 +26,7 @@ public function __construct( $this->moduleLogger = $moduleLogger; } - /** - * @var array $possiblePayPalLevels - */ + /** @var array $possiblePayPalLevels */ private $possiblePayPalLevels = [ 'error' => 400, 'info' => 200, diff --git a/src/Service/ModuleSettings.php b/src/Service/ModuleSettings.php index 241edcc9e..05596b3c0 100755 --- a/src/Service/ModuleSettings.php +++ b/src/Service/ModuleSettings.php @@ -10,9 +10,9 @@ namespace OxidSolutionCatalysts\PayPal\Service; use OxidEsales\Eshop\Application\Model\Country; +use OxidEsales\Eshop\Application\Model\DeliverySetList; use OxidEsales\Eshop\Application\Model\Payment; use OxidEsales\Eshop\Application\Model\Shop; -use OxidEsales\Eshop\Application\Model\User; use OxidEsales\Eshop\Core\Registry; use OxidEsales\EshopCommunity\Internal\Framework\Module\Configuration\Bridge\ModuleConfigurationDaoBridgeInterface; use OxidEsales\EshopCommunity\Internal\Framework\Module\Configuration\Bridge\ModuleSettingBridgeInterface; @@ -44,37 +44,44 @@ class ModuleSettings protected $payPalCheckoutExpressPaymentEnabled = null; /** - * Country Restriction for PayPal as comma seperated string + * is Vaulting allowed for PayPal * - * @var string + * @var bool */ - protected $countryRestrictionForPayPalExpress = null; + protected $isVaultingAllowedForPayPal = null; /** - * @var ModuleSettingBridgeInterface + * is Vaulting allowed for ACDC + * + * @var bool */ - private $moduleSettingBridge; + protected $isVaultingAllowedForACDC = null; /** - * @var ModuleConfigurationDaoBridgeInterface + * Country Restriction for PayPal as comma seperated string + * + * @var string */ + protected $countryRestrictionForPayPalExpress = null; + + /** @var ModuleSettingBridgeInterface */ + private $moduleSettingBridge; + + /** @var ModuleConfigurationDaoBridgeInterface */ private $moduleConfigurationDaoBridgeInterface; - /** - * @var ModuleConfiguration - */ + /** @var ModuleConfiguration */ private $moduleConfiguration = null; - /** - * @var ContextInterface - */ + /** @var ContextInterface */ private $context; - /** - * @var Logger - */ + /** @var Logger */ private $logger; + /** @var UserRepository */ + private $userRepository; + //TODO: we need service for fetching module settings from db (this one) //another class for moduleconfiguration (database values/edefaults) //and the view configuration should go into some separate class @@ -84,12 +91,14 @@ public function __construct( ModuleSettingBridgeInterface $moduleSettingBridge, ContextInterface $context, ModuleConfigurationDaoBridgeInterface $moduleConfigurationDaoBridgeInterface, - Logger $logger + Logger $logger, + UserRepository $userRepository ) { $this->moduleSettingBridge = $moduleSettingBridge; $this->context = $context; $this->moduleConfigurationDaoBridgeInterface = $moduleConfigurationDaoBridgeInterface; $this->logger = $logger; + $this->userRepository = $userRepository; } public function showAllPayPalBanners(): bool @@ -276,6 +285,7 @@ public function showBannersOnCategoryPage(): bool { return (bool)$this->getSettingValue('oscPayPalBannersCategoryPage'); } + public function getCategoryPageBannerSelector(): string { return (string)$this->getSettingValue('oscPayPalBannersCategoryPageSelector'); @@ -346,6 +356,7 @@ public function getStartTimeCleanUpOrders(): int return (int)$this->getSettingValue('oscPayPalStartTimeCleanUpOrders'); } + public function isLiveAcdcEligibility(): bool { return (bool)$this->getSettingValue('oscPayPalAcdcEligibility'); @@ -397,25 +408,15 @@ public function isSandboxGooglePayEligibility(): bool return (bool)$this->getSettingValue('oscPayPalSandboxGooglePayEligibility'); } - public function getActivePayments(): array - { - /** - * @var array|null $activePayments -*/ - $activePayments = $this->getSettingValue('oscPayPalActivePayments'); - return $activePayments ?: []; - } - public function getShopName(): string { $value = ''; - /** - * @var Shop $shop -*/ + /** @var Shop $shop */ $shop = Registry::getConfig()->getActiveShop(); if (isset($shop->oxshops__oxname->rawValue)) { $value = $shop->oxshops__oxname->rawValue; - } elseif (isset($shop->oxshops__oxname->value)) { + } + elseif(isset($shop->oxshops__oxname->value)) { $value = $shop->oxshops__oxname->value; } return $value; @@ -427,13 +428,12 @@ public function getShopName(): string public function getInfoEMail(): string { $value = ''; - /** - * @var Shop $shop -*/ + /** @var Shop $shop */ $shop = Registry::getConfig()->getActiveShop(); if (isset($shop->oxshops__oxinfoemail->rawValue)) { $value = $shop->oxshops__oxinfoemail->rawValue; - } elseif (isset($shop->oxshops__oxinfoemail->value)) { + } + elseif(isset($shop->oxshops__oxinfoemail->value)) { $value = $shop->oxshops__oxinfoemail->value; } return $value; @@ -453,8 +453,8 @@ public function save(string $name, $value): void $value = trim($value); } else if ($moduleSetting->getType() === 'bool') { $value = (bool)$value; - } else if ($moduleSetting->getType() === 'float') { - $value = (float)trim($value); + } else if ($moduleSetting->getType() === 'num') { + $value = (float)$value; } $this->moduleSettingBridge->save($name, $value, Module::MODULE_ID); @@ -572,7 +572,6 @@ public function addRequireSession(): void /** * This setting indicates whether settings from the legacy modules have been transferred. - * * @return bool */ public function getLegacySettingsTransferStatus(): bool @@ -585,7 +584,7 @@ public function getLegacySettingsTransferStatus(): bool */ public function isPayPalCheckoutExpressPaymentEnabled(): bool { - if ($this->payPalCheckoutExpressPaymentEnabled === null) { + if (is_null($this->payPalCheckoutExpressPaymentEnabled)) { $expressEnabled = false; $payment = oxNew(Payment::class); $payment->load(PayPalDefinitions::EXPRESS_PAYPAL_PAYMENT_ID); @@ -603,6 +602,65 @@ public function isPayPalCheckoutExpressPaymentEnabled(): bool return $this->payPalCheckoutExpressPaymentEnabled; } + /** check if Vaulting is allowed for PayPal */ + public function isVaultingAllowedForPayPal(): bool + { + if (is_null($this->isVaultingAllowedForPayPal)) { + $this->isVaultingAllowedForPayPal = $this->isVaultingAllowedForPayment( + PayPalDefinitions::STANDARD_PAYPAL_PAYMENT_ID + ); + } + return $this->isVaultingAllowedForPayPal; + } + + /** check if Vaulting is allowed for ACDC */ + public function isVaultingAllowedForACDC(): bool + { + if (is_null($this->isVaultingAllowedForACDC)) { + $this->isVaultingAllowedForACDC = $this->isVaultingAllowedForPayment( + PayPalDefinitions::ACDC_PAYPAL_PAYMENT_ID + ); + } + return $this->isVaultingAllowedForACDC; + } + + /** check if Vaulting is allowed for Payment-Method */ + public function isVaultingAllowedForPayment(string $paymentId): bool + { + $payment = oxNew(Payment::class); + $payment->load($paymentId); + $paymentEnabled = (bool)$payment->oxpayments__oxactive->value; + $paymentType = PayPalDefinitions::getPayPalDefinitions()[$paymentId]["vaultingtype"]; + + $session = Registry::getSession(); + $actShipSet = $session->getVariable('sShipSet'); + $basket = $session->getBasket(); + $user = $session->getUser(); + $payPalDefinitions = PayPalDefinitions::getPayPalDefinitions(); + $actShopCurrency = Registry::getConfig()->getActShopCurrencyObject(); + $userCountryIso = $this->userRepository->getUserCountryIso(); + + [, , $paymentList] = + Registry::get(DeliverySetList::class)->getDeliverySetData( + $actShipSet, + $user, + $basket + ); + + return $paymentEnabled && + $this->getIsVaultingActive() && + PayPalDefinitions::isPayPalVaultingPossible($paymentId, $paymentType) && + array_key_exists($paymentId, $paymentList) && + ( + empty($payPalDefinitions[$paymentId]['currencies']) || + in_array($actShopCurrency->name, $payPalDefinitions[$paymentId]['currencies'], true) + ) && + ( + empty($payPalDefinitions[$paymentId]['countries']) || + in_array($userCountryIso, $payPalDefinitions[$paymentId]['countries'], true) + ); + } + /** * Returns comma seperated String with the Country Restriction for PayPal Express */ @@ -645,11 +703,17 @@ public function getIsVaultingActive(): bool { return (bool)$this->getSettingValue('oscPayPalSetVaulting'); } + public function getIsGooglePayDeliveryAddressActive(): bool { return (bool)$this->getSettingValue('oscPayPalUseGooglePayAddress'); } + public function isCustomIdSchemaStructural(): bool + { + return (bool)$this->getSettingValue('oscPayPalUseStructuralCustomIdSchema'); + } + /** * @return mixed */ diff --git a/src/Service/OrderRepository.php b/src/Service/OrderRepository.php index 3e9f40192..2fe3bcb75 100644 --- a/src/Service/OrderRepository.php +++ b/src/Service/OrderRepository.php @@ -20,14 +20,10 @@ class OrderRepository { - /** - * @var QueryBuilderFactoryInterface - */ + /** @var QueryBuilderFactoryInterface */ private $queryBuilderFactory; - /** - * @var EshopCoreConfig - */ + /** @var EshopCoreConfig */ private $config; public function __construct( @@ -118,9 +114,7 @@ public function getShopOrderByPayPalTransactionId(string $paypalTransactionId): public function getPayPalOrderIdByShopOrderId(string $shopOrderId): string { - /** - * @var QueryBuilder $queryBuilder -*/ + /** @var QueryBuilder $queryBuilder */ $queryBuilder = $this->queryBuilderFactory->create(); $parameters = [ @@ -161,12 +155,10 @@ public function cleanUpNotFinishedOrders(): void ->from('oxorder') ->where('oxtransstatus = :oxtransstatus') ->andWhere('oxshopid = :oxshopid') - ->andWhere( - $queryBuilder->expr()->like( - 'oxpaymenttype', - $queryBuilder->expr()->literal('%' . $parameters['oxpaymenttype'] . '%') - ) - ) + ->andWhere($queryBuilder->expr()->like( + 'oxpaymenttype', + $queryBuilder->expr()->literal('%' . $parameters['oxpaymenttype'] . '%') + )) ->andWhere('oxorderdate < now() - interval :sessiontime MINUTE'); $ids = $queryBuilder->setParameters($parameters) @@ -188,9 +180,7 @@ private function getId( string $payPalTransactionId = '', string $payPalTransactionType = '' ): string { - /** - * @var QueryBuilder $queryBuilder -*/ + /** @var QueryBuilder $queryBuilder */ $queryBuilder = $this->queryBuilderFactory->create(); $parameters = [ @@ -233,9 +223,7 @@ private function getId( private function getShopOrderIdByPaypalOrderId(string $paypalOrderId): string { - /** - * @var QueryBuilder $queryBuilder -*/ + /** @var QueryBuilder $queryBuilder */ $queryBuilder = $this->queryBuilderFactory->create(); $parameters = [ @@ -257,9 +245,7 @@ private function getShopOrderIdByPaypalOrderId(string $paypalOrderId): string private function getShopOrderIdByPaypalTransactionId(string $paypalTransactionId): string { - /** - * @var QueryBuilder $queryBuilder -*/ + /** @var QueryBuilder $queryBuilder */ $queryBuilder = $this->queryBuilderFactory->create(); $parameters = [ diff --git a/src/Service/Payment.php b/src/Service/Payment.php index d41c30924..36aab5013 100644 --- a/src/Service/Payment.php +++ b/src/Service/Payment.php @@ -14,7 +14,8 @@ use OxidEsales\Eshop\Core\Field; use OxidEsales\Eshop\Core\Registry; use OxidEsales\Eshop\Core\Session as EshopSession; -use OxidSolutionCatalysts\PayPal\Core\Config; +use OxidEsales\Eshop\Core\ShopVersion; +use OxidSolutionCatalysts\PayPal\Controller\PaymentController; use OxidSolutionCatalysts\PayPal\Core\ConfirmOrderRequestFactory; use OxidSolutionCatalysts\PayPal\Core\Constants; use OxidSolutionCatalysts\PayPal\Core\OrderRequestFactory; @@ -23,17 +24,13 @@ use OxidSolutionCatalysts\PayPal\Core\PayPalSession; use OxidSolutionCatalysts\PayPal\Core\ServiceFactory; use OxidSolutionCatalysts\PayPal\Exception\PayPalException; -use OxidSolutionCatalysts\PayPal\Exception\UserPhone as UserPhoneException; use OxidSolutionCatalysts\PayPal\Model\PayPalOrder as PayPalOrderModel; -use OxidSolutionCatalysts\PayPal\Service\ModuleSettings as ModuleSettingsService; +use OxidSolutionCatalysts\PayPal\Module; use OxidSolutionCatalysts\PayPal\Traits\ServiceContainer; use OxidSolutionCatalysts\PayPalApi\Exception\ApiException; use OxidSolutionCatalysts\PayPalApi\Model\Orders\AuthorizationWithAdditionalData; use OxidSolutionCatalysts\PayPalApi\Model\Orders\ConfirmOrderRequest; use OxidSolutionCatalysts\PayPalApi\Model\Orders\Order; -use OxidSolutionCatalysts\PayPalApi\Model\Orders\Order as ApiModelOrder; -use OxidSolutionCatalysts\PayPalApi\Model\Orders\Order as ApiOrderModel; -use OxidSolutionCatalysts\PayPalApi\Model\Orders\Order as OrderResponse; use OxidSolutionCatalysts\PayPalApi\Model\Orders\OrderAuthorizeRequest; use OxidSolutionCatalysts\PayPalApi\Model\Orders\OrderCaptureRequest; use OxidSolutionCatalysts\PayPalApi\Model\Payments\CaptureRequest; @@ -68,29 +65,19 @@ class Payment */ private $orderRepository; - /** - * @var ServiceFactory - */ + /** @var ServiceFactory */ private $serviceFactory; - /** - * @var PatchRequestFactory - */ + /** @var PatchRequestFactory */ private $patchRequestFactory; - /** - * @var OrderRequestFactory - */ + /** @var OrderRequestFactory */ private $orderRequestFactory; - /** - * @var SCAValidatorInterface - */ + /** @var SCAValidatorInterface */ private $scaValidator; - /** - * @var ModuleSettingsService - */ + /** @var ModuleSettings */ private $moduleSettingsService; private $logger; @@ -99,7 +86,7 @@ public function __construct( EshopSession $eshopSession, OrderRepository $orderRepository, SCAValidatorInterface $scaValidator, - ModuleSettingsService $moduleSettingsService, + ModuleSettings $moduleSettingsService, Logger $logger, ServiceFactory $serviceFactory = null, PatchRequestFactory $patchRequestFactory = null, @@ -125,29 +112,24 @@ public function doCreatePayPalOrder( string $payPalPartnerAttributionId = '', string $returnUrl = null, string $cancelUrl = null, - bool $setProvidedAddress = true, - ?EshopModelOrder $order = null - // ): ?ApiModelOrder + bool $setProvidedAddress = true ) { //TODO return value $this->setPaymentExecutionError(self::PAYMENT_ERROR_NONE); - $order instanceof EshopModelOrder ?? $order->setOrderNumber(); - /** - * @var ApiOrderService $orderService -*/ + + /** @var ApiOrderService $orderService */ $orderService = $this->serviceFactory->getOrderService(); $request = $this->orderRequestFactory->getRequest( $basket, $intent, $userAction, - $order instanceof EshopModelOrder ? $order->getFieldData('oxordernr') : null, + null, //customId is patched in doCapturePayPalOrder (ordernr is unavailable at this point) $processingInstruction, $paymentSource, null, $returnUrl, $cancelUrl, - true, $setProvidedAddress ); @@ -157,7 +139,8 @@ public function doCreatePayPalOrder( $response = $orderService->createOrder( $request, $payPalPartnerAttributionId, - $payPalClientMetadataId + $payPalClientMetadataId, + 'return=minimal' ); } catch (ApiException $exception) { $this->logger->log('error', 'API Error.', [$exception]); @@ -172,8 +155,7 @@ public function doCreatePayPalOrder( } public function doCreatePatchedOrder( - EshopModelBasket $basket, - EshopModelOrder $order + EshopModelBasket $basket ): array { // PatchOrders access an OrderCall that has taken place before. // For this reason, the payPalPartnerAttributionId does not have @@ -188,9 +170,7 @@ public function doCreatePatchedOrder( Constants::PAYPAL_PARTNER_ATTRIBUTION_ID_PPCP, null, null, - true, - $order, - $order + false ); $paypalOrderId = $response->id ?: ''; @@ -206,8 +186,7 @@ public function doCreatePatchedOrder( $return = [ 'id' => $paypalOrderId, - 'status' => $status, - 'hateoasLinks' => $response?->links ?? [], + 'status' => $status ]; return $return; @@ -218,9 +197,7 @@ public function doPatchPayPalOrder( string $checkoutOrderId, string $shopOrderId = '' ): void { - /** - * @var ApiOrderService $orderService -*/ + /** @var ApiOrderService $orderService */ $orderService = $this->serviceFactory->getOrderService(); $request = $this->patchRequestFactory @@ -243,12 +220,10 @@ public function doCapturePayPalOrder( EshopModelOrder $order, string $checkoutOrderId, string $paymentId, - ApiOrderModel $payPalOrder = null - ): ApiOrderModel { + Order $payPalOrder = null + ): Order { - /** - * @var ApiOrderModel $payPalOrder -*/ + /** @var Order $payPalOrder */ if (is_null($payPalOrder) || !isset($payPalOrder->payment_source)) { $payPalOrder = $this->fetchOrderFields($checkoutOrderId); } @@ -258,13 +233,9 @@ public function doCapturePayPalOrder( throw oxNew(StandardException::class, 'OSC_PAYPAL_3DSECURITY_ERROR'); } - /** - * @var ApiPaymentService $paymentService -*/ + /** @var ApiPaymentService $paymentService */ $paymentService = Registry::get(ServiceFactory::class)->getPaymentService(); - /** - * @var ApiOrderService $orderService -*/ + /** @var ApiOrderService $orderService */ $orderService = $this->serviceFactory->getOrderService(); // Capture Order @@ -272,7 +243,7 @@ public function doCapturePayPalOrder( //TODO: split into multiple methods if ($payPalOrder->intent === Constants::PAYPAL_ORDER_INTENT_AUTHORIZE) { // if order approved then authorize - if ($payPalOrder->status === ApiOrderModel::STATUS_APPROVED) { + if ($payPalOrder->status === Order::STATUS_APPROVED) { $request = new OrderAuthorizeRequest(); $payPalOrder = $orderService->authorizePaymentForOrder( '', @@ -283,9 +254,7 @@ public function doCapturePayPalOrder( ); } - /** - * @var AuthorizationWithAdditionalData $authorization -*/ + /** @var AuthorizationWithAdditionalData $authorization */ $authorization = $payPalOrder->purchase_units[0]->payments->authorizations[0]; $authorizationId = $authorization->id; @@ -336,25 +305,19 @@ public function doCapturePayPalOrder( } elseif ($payPalOrder->status !== Constants::PAYPAL_STATUS_COMPLETED) { $request = new OrderCaptureRequest(); //order number must be resolved before order patching - $shopOrderId = $order->getFieldData('oxordernr'); - if (!$shopOrderId) { + if (!$order->hasOrderNumber()){ $order->setOrderNumber(); - $shopOrderId = $order->getFieldData('oxordernr'); } - $order->setOrderNumber(); - try { //Patching the order with OXID order number as custom value $this->doPatchPayPalOrder( Registry::getSession()->getBasket(), $checkoutOrderId, - $shopOrderId + $this->getCustomIdParameter($order) ); - /** - * @var $result ApiOrderModel -*/ + /** @var $result Order */ $result = $orderService->capturePaymentForOrder( '', $checkoutOrderId, @@ -367,13 +330,6 @@ public function doCapturePayPalOrder( $issue = $exception->getErrorIssue(); $this->displayErrorIfInstrumentDeclined($issue); - /** - * @var Config $payPalConfig -*/ - $payPalConfig = oxNew(Config::class); - if ($payPalConfig->isLogLevel('debug')) { - $this->logger->log('debug', $exception->getMessage(), [$exception]); - } throw oxNew(StandardException::class, 'OSC_PAYPAL_ORDEREXECUTION_ERROR'); } } else { @@ -386,11 +342,9 @@ public function doCapturePayPalOrder( $result->purchase_units[0]->payments->captures[0]->id : ''; $status = $result && $result->purchase_units[0]->payments->captures[0]->status ? - $result->purchase_units[0]->payments->captures[0]->status : ApiOrderModel::STATUS_SAVED; + $result->purchase_units[0]->payments->captures[0]->status : Order::STATUS_SAVED; - /** - * @var PayPalOrderModel $paypalOrder -*/ + /** @var PayPalOrderModel $paypalOrder */ $this->trackPayPalOrder( $order->getId(), $checkoutOrderId, @@ -452,13 +406,9 @@ public function doConfirmUAPM( ): string { $redirectLink = ''; - /** - * @var OrderRequestFactory $requestFactory -*/ + /** @var OrderRequestFactory $requestFactory */ $requestFactory = Registry::get(ConfirmOrderRequestFactory::class); - /** - * @var ConfirmOrderRequest $request -*/ + /** @var ConfirmOrderRequest $request */ $request = $requestFactory->getRequest( $basket, $uapmName @@ -469,14 +419,10 @@ public function doConfirmUAPM( // Transactions that do not include a client metadata ID are not eligible for PayPal Seller Protection. $payPalClientMetadataId = ''; - /** - * @var ApiOrderService $orderService -*/ + /** @var ApiOrderService $orderService */ $orderService = $this->serviceFactory->getOrderService(); - /** - * @var ApiModelOrder $response -*/ + /** @var Order $response */ $response = $orderService->confirmTheOrder( $payPalClientMetadataId, $checkoutOrderId, @@ -538,22 +484,16 @@ public function removeTemporaryOrder(): void $orderModel->isLoaded() ) { $orderModel->cancelOrder(); - $this->logger->log( - 'debug', - sprintf( - 'Temporary order with id %s was canceled', - $sessionOrderId - ) - ); + $this->logger->log('debug', sprintf( + 'Temporary order with id %s was canceled', + $sessionOrderId + )); if (!$orderModel->hasOrderNumber()) { $orderModel->delete(); - $this->logger->log( - 'debug', - sprintf( - 'Temporary order without Order number and with id %s was deleted', - $sessionOrderId - ) - ); + $this->logger->log('debug', sprintf( + 'Temporary order without Order number and with id %s was deleted', + $sessionOrderId + )); } } @@ -598,13 +538,6 @@ public function doExecuteUAPMPayment(EshopModelOrder $order, EshopModelBasket $b $redirectLink = ''; try { - //sent Order OXID as custom_id to PayPal - $this->doPatchPayPalOrder( - Registry::getSession()->getBasket(), - $uapmOrderId, - (string)$order->getFieldData('oxordernr') - ); - $redirectLink = $this->doConfirmUAPM( $order, $basket, @@ -649,8 +582,7 @@ public function doExecuteStandardPayment( Constants::PAYPAL_PARTNER_ATTRIBUTION_ID_PPCP, $returnUrl, $cancelUrl, - false, - $order + false ); $orderId = $response->id ?: ''; @@ -699,9 +631,7 @@ public function doCreateUAPMOrder(EshopModelBasket $basket): string Constants::PAYPAL_PARTNER_ATTRIBUTION_ID_PPCP, null, null, - false, - true, - null + false ); return $response->id ?: ''; @@ -722,24 +652,17 @@ public function doExecutePuiPayment( Constants::PAYPAL_PUI_PROCESSING_INSTRUCTIONS, PayPalDefinitions::PUI_REQUEST_PAYMENT_SOURCE_NAME, $payPalClientMetadataId, - Constants::PAYPAL_PARTNER_ATTRIBUTION_ID_PPCP, - null, - null, - true, - $order + Constants::PAYPAL_PARTNER_ATTRIBUTION_ID_PPCP ); $payPalOrderId = $result->id; - } catch (UserPhoneException $e) { - //mistyped phone in last order step - $this->setPaymentExecutionError(self::PAYMENT_ERROR_PUI_PHONE); } catch (Exception $exception) { $this->setPaymentExecutionError(self::PAYMENT_ERROR_PUI_GENERIC); $this->logger->log('error', 'Error on pui order creation call.', [$exception]); } - // TODO: check what we created, ensure it is a pui order - // $paymentSource = $this->fetchOrderFields((string) $payPalOrderId, 'payment_source'); - // $this->logger->log('error', serialize($paymentSource)); + # TODO: check what we created, ensure it is a pui order + # $paymentSource = $this->fetchOrderFields((string) $payPalOrderId, 'payment_source'); + # $this->logger->log('error', serialize($paymentSource)); if (!$payPalOrderId) { return false; @@ -775,9 +698,7 @@ public function trackPayPalOrder( string $payPalTransactionId = '', string $transactionType = Constants::PAYPAL_TRANSACTION_TYPE_CAPTURE ): PayPalOrderModel { - /** - * @var PayPalOrderModel $payPalOrder -*/ + /** @var PayPalOrderModel $payPalOrder */ $payPalOrder = $this->getPayPalCheckoutOrder($shopOrderId, $payPalOrderId, $payPalTransactionId); $payPalOrder->setPaymentMethodId($paymentMethodId); @@ -794,9 +715,7 @@ public function getPayPalCheckoutOrder( string $payPalOrderId, string $payPalTransactionId = '' ) { - /** - * @var PayPalOrderModel $payPalOrder -*/ + /** @var PayPalOrderModel $payPalOrder */ return $this->orderRepository->paypalOrderByOrderIdAndPayPalId( $shopOrderId, $payPalOrderId, @@ -804,7 +723,7 @@ public function getPayPalCheckoutOrder( ); } - public function fetchOrderFields(string $paypalOrderId, string $fields = ''): ApiOrderModel + public function fetchOrderFields(string $paypalOrderId, string $fields = ''): Order { return $this->serviceFactory ->getOrderService() @@ -818,7 +737,7 @@ public function fetchOrderFields(string $paypalOrderId, string $fields = ''): Ap /** * @throws StandardException */ - public function verify3D(string $paymentId, ApiOrderModel $payPalOrder): bool + public function verify3D(string $paymentId, Order $payPalOrder): bool { //no ACDC payment if ($paymentId != PayPalDefinitions::ACDC_PAYPAL_PAYMENT_ID) { @@ -830,8 +749,8 @@ public function verify3D(string $paymentId, ApiOrderModel $payPalOrder): bool } //case check is to be done automatic but we have no result to check if ( - (Constants::PAYPAL_SCA_WHEN_REQUIRED === $this->moduleSettingsService->getPayPalSCAContingency()) - && is_null($this->scaValidator->getCardAuthenticationResult($payPalOrder)) + (Constants::PAYPAL_SCA_WHEN_REQUIRED === $this->moduleSettingsService->getPayPalSCAContingency()) && + is_null($this->scaValidator->getCardAuthenticationResult($payPalOrder)) ) { return true; } @@ -876,4 +795,29 @@ private function displayErrorIfInstrumentDeclined(?string $issue): void ); } } + + /** + * @param \OxidEsales\Eshop\Application\Model\Order|null $order + * @return mixed|null + */ + public function getCustomIdParameter(?EshopModelOrder $order): string + { + /** @var ModuleSettings $moduleSettings */ + $moduleSettings = $this->getServiceFromContainer(ModuleSettings::class); + $module = oxNew(\OxidEsales\Eshop\Core\Module\Module::class); + $module->load(Module::MODULE_ID); + $orderNumber = $order instanceof EshopModelOrder ? $order->getFieldData('oxordernr') : null; + + if($moduleSettings->isCustomIdSchemaStructural()){ + $customID = [ + 'oxordernr' => $orderNumber, + 'moduleVersion' => $module->getInfo('version'), + 'oxidVersion' => ShopVersion::getVersion() + ]; + + return json_encode($customID); + } + + return $orderNumber; + } } diff --git a/src/Service/StaticContent.php b/src/Service/StaticContent.php index 4bafcbbfe..41f49d21c 100644 --- a/src/Service/StaticContent.php +++ b/src/Service/StaticContent.php @@ -9,7 +9,6 @@ namespace OxidSolutionCatalysts\PayPal\Service; -use OxidEsales\Eshop\Core\Registry; use PDO; use Doctrine\DBAL\Query\QueryBuilder; use OxidEsales\Eshop\Core\Registry as EshopRegistry; @@ -23,21 +22,24 @@ //NOTE: later we will do this on module installation, for now on first activation class StaticContent { - /** - * @var QueryBuilderFactoryInterface - */ + /** @var QueryBuilderFactoryInterface */ private $queryBuilderFactory; + /** @var ModuleSettings */ + private $moduleSettings; + public function __construct( - QueryBuilderFactoryInterface $queryBuilderFactory + QueryBuilderFactoryInterface $queryBuilderFactory, + ModuleSettings $moduleSettings ) { $this->queryBuilderFactory = $queryBuilderFactory; + $this->moduleSettings = $moduleSettings; } public function ensurePayPalPaymentMethods(): void { foreach (PayPalDefinitions::getPayPalDefinitions() as $paymentId => $paymentDefinitions) { - // skip creation and activation of deprecated payments + //skip creation and activation of deprecated payments if (PayPalDefinitions::isDeprecatedPayment($paymentId)) { $this->deactivatePaymentMethod($paymentId); continue; @@ -75,9 +77,7 @@ protected function assignPaymentToDelivery(string $paymentId, string $deliverySe protected function createPaymentMethod(string $paymentId, array $definitions): void { - /** - * @var EshopModelPayment $paymentModel -*/ + /** @var EshopModelPayment $paymentModel */ $paymentModel = oxNew(EshopModelPayment::class); $paymentModel->setId($paymentId); @@ -108,33 +108,14 @@ protected function createPaymentMethod(string $paymentId, array $definitions): v } } - protected function reActivatePaymentMethod(string $paymentId): void - { - $activePayments = Registry::get(ModuleSettings::class)->getActivePayments(); - if (!in_array($paymentId, $activePayments, true)) { - return; - } - - /** - * @var EshopModelPayment $paymentModel - */ - $paymentModel = oxNew(EshopModelPayment::class); - $paymentModel->load($paymentId); - - $paymentModel->oxpayments__oxactive = new Field(true); - - $paymentModel->save(); - } - /** * Try to load payment model based on given id an set payment inactive * - * @param string $paymentId + * @param string $paymentId * @return void * @throws \Exception */ - protected function deactivatePaymentMethod(string $paymentId): void - { + protected function deactivatePaymentMethod(string $paymentId) : void { $paymentModel = oxNew(EshopModelPayment::class); if ($paymentModel->load($paymentId)) { $paymentModel->oxpayments__oxactive = new Field(false); @@ -186,9 +167,7 @@ protected function getContentModel(string $ident, int $languageId): EshopModelCo protected function getActiveDeliverySetIds(): array { - /** - * @var QueryBuilder $queryBuilder -*/ + /** @var QueryBuilder $queryBuilder */ $queryBuilder = $this->queryBuilderFactory->create(); $fromDb = $queryBuilder ->select('oxid') diff --git a/src/Service/UserRepository.php b/src/Service/UserRepository.php index bb7a3f58c..046c86a6b 100644 --- a/src/Service/UserRepository.php +++ b/src/Service/UserRepository.php @@ -20,24 +20,16 @@ class UserRepository { - /** - * @var QueryBuilderFactoryInterface - */ + /** @var QueryBuilderFactoryInterface */ private $queryBuilderFactory; - /** - * @var ContextInterface - */ + /** @var ContextInterface */ private $context; - /** - * @var EshopCoreConfig - */ + /** @var EshopCoreConfig */ private $config; - /** - * @var EshopCoreSession - */ + /** @var EshopCoreSession */ private $session; public function __construct( @@ -74,9 +66,7 @@ public function guestAccountExists(string $userEmail): bool private function getUserId(string $userEmail, bool $hasPassword = true): string { - /** - * @var QueryBuilder $queryBuilder -*/ + /** @var QueryBuilder $queryBuilder */ $queryBuilder = $this->queryBuilderFactory->create(); $parameters = [ diff --git a/src/Traits/AccountControllerTrait.php b/src/Traits/AccountControllerTrait.php new file mode 100644 index 000000000..51dfea570 --- /dev/null +++ b/src/Traits/AccountControllerTrait.php @@ -0,0 +1,30 @@ +getRequestEscapedParameter("paymentTokenId"); + $vaultingService = Registry::get(ServiceFactory::class)->getVaultingService(); + + if (!$vaultingService->deleteVaultedPayment($paymentTokenId)) { + Registry::getUtilsView()->addErrorToDisplay( + Registry::getLang()->translateString('OSC_PAYPAL_DELETE_FAILED'), + false, + true + ); + } + } +} diff --git a/src/Traits/AdminOrderTrait.php b/src/Traits/AdminOrderTrait.php index 623da8d4f..25d54c02c 100644 --- a/src/Traits/AdminOrderTrait.php +++ b/src/Traits/AdminOrderTrait.php @@ -25,29 +25,19 @@ trait AdminOrderTrait { use ServiceContainer; - /** - * @var Order|null - */ + /** @var Order|null */ protected $order = null; - /** - * @var bool|null - */ + /** @var bool|null */ protected $isPayPalStandardManuallyCapture = null; - /** - * @var bool|null - */ + /** @var bool|null */ protected $isPayPalStandardOnDeliveryCapture = null; - /** - * @var bool|null - */ + /** @var bool|null */ protected $isPayPalStandardOrder = null; - /** - * @var bool|null - */ + /** @var bool|null */ protected $isAuthorizedPayPalStandardOrder = null; /** @@ -74,9 +64,7 @@ public function capturePayPalStandard(): void $orderId = $paypalOrder->id; $service = $this->getServiceFromContainer(PaymentService::class); - /** - * @var PayPalOrder $result -*/ + /** @var PayPalOrder $result */ $result = $service->doCapturePayPalOrder( $order, $orderId, @@ -163,8 +151,8 @@ protected function isPayPalStandardOrder() if (is_null($this->isPayPalStandardOrder)) { $this->isPayPalStandardOrder = false; if ( - ($order = $this->getOrder()) - && ($order->oxorder__oxpaymenttype->value === PayPalDefinitions::STANDARD_PAYPAL_PAYMENT_ID) + ($order = $this->getOrder()) && + ($order->oxorder__oxpaymenttype->value === PayPalDefinitions::STANDARD_PAYPAL_PAYMENT_ID) ) { $this->isPayPalStandardOrder = true; } @@ -180,9 +168,7 @@ protected function isPayPalStandardOrder() protected function getPayPalCheckoutOrder(): PayPalOrder { $order = $this->getOrder(); - /** - * @var PayPalOrder $payPalOrder -*/ + /** @var PayPalOrder $payPalOrder */ $payPalOrder = $order->getPayPalCheckoutOrder(); return $payPalOrder; } diff --git a/src/Traits/ServiceContainer.php b/src/Traits/ServiceContainer.php index fa322d57d..237e7c086 100644 --- a/src/Traits/ServiceContainer.php +++ b/src/Traits/ServiceContainer.php @@ -15,7 +15,6 @@ trait ServiceContainer { protected $serviceArray = []; - /** * Used in Unit-Tests to mock services * There might be a cleaner way, but haven't found it yet @@ -28,11 +27,10 @@ public function addServiceMock(string $serviceName, MockObject $serviceMock) { $this->serviceArray[$serviceName] = $serviceMock; } - /** - * @template T + * @template T * @psalm-param class-string $serviceName - * @return T + * @return T */ protected function getServiceFromContainer(string $serviceName) { diff --git a/translations/de/oscpaypal_de_lang.php b/translations/de/oscpaypal_de_lang.php index 53f8f332c..a7309e028 100644 --- a/translations/de/oscpaypal_de_lang.php +++ b/translations/de/oscpaypal_de_lang.php @@ -33,20 +33,16 @@ 'OSC_PAYPAL_PUI_PHONENUMBER_PLACEHOLDER' => '+49 30 123456789', 'OSC_PAYPAL_PUI_PLEASE_RETRY' => 'Bitte geben Sie ihre Daten erneut ein.', 'PAYPAL_PAYMENT_ERROR_PUI_GENRIC' => 'Validierung der Kundendaten für PayPal Rechnungskauf mit Ratepay fehlgeschlagen.', - 'PUI_PAYMENT_SOURCE_INFO_CANNOT_BE_VERIFIED' => 'Die Kombination aus Ihrem Namen und Ihrer Anschrift konnte nicht für PayPal Rechnungskauf validiert werden. Bitte korrigieren Sie Ihre Daten und versuchen Sie es erneut. Weitere Informationen finden Sie in den Ratepay Datenschutzbestimmungen oder nutzen Sie das Ratepay Kontaktformular.', + 'PUI_PAYMENT_SOURCE_INFO_CANNOT_BE_VERIFIED' => 'Die Kombination aus Ihrem Namen und Ihrer Anschrift konnte nicht für PayPal Rechnungskauf validiert werden. Bitte korrigieren Sie Ihre Daten und versuchen Sie es erneut. Weitere Informationen finden Sie in den Ratepay Datenschutzbestimmungen oder nutzen Sie das Ratepay Kontaktformular.', 'PUI_PAYMENT_SOURCE_DECLINED_BY_PROCESSOR' => 'Die gewählte Zahlungsart PayPal Rechnungskauf kann nicht genutzt werden. Diese Entscheidung basiert auf einem automatisierten Datenverarbeitungsverfahren. Weitere Informationen finden Sie in den Ratepay Datenschutzbestimmungen oder nutzen Sie das Ratepay Kontaktformular.', 'PAYMENT_ERROR_INSTRUMENT_DECLINED' => 'Die gewählte Zahlart steht Ihnen bei PayPal nicht zur Verfügung.', 'OSC_PAYPAL_ORDER_NOT_APPROVED' => 'Die Bestellung wurde nicht genehmigt. Bitte versuchen Sie es später oder mit einer anderen Zahlart.', - 'OSC_PAYPAL_ORDER_EXECUTION_IN_PROGRESS' => 'Ihre Bestellung wird geprüft, das kann bis zu 60 Sekunden dauern. Bitte kurz warten und dann erneut auf "zahlungspflichtig bestellen" klicken.', - 'OSC_PAYPAL_LOG_IN_TO_CONTINUE' => 'Bitte loggen Sie sich ein, um die Bestellung abzuschliessen.', - 'OSC_PAYPAL_3DSECURITY_ERROR' => 'Die Sicherheitsüberprüfung ist fehlgeschlagen, bitte erneut versuchen.', - 'OSC_PAYPAL_ORDEREXECUTION_ERROR' => 'Der Bezahlvorgang wurde abgebrochen.', - 'OSCPAYPAL_KILL_EXPRESS_SESSION_REASON' => 'Der Warenkorb wurde geändert. Aus diesem Grund wurde der aktive PayPal-Zahlvorgang automatisch abgebrochen. Bitte starten Sie die Zahlung mit PayPal erneut. Es wurde noch kein Geld von PayPal eingezogen.', 'OSC_PAYPAL_ORDER_EXECUTION_IN_PROGRESS' => 'Ihre Bestellung wird geprüft, das kann bis zu 60 Sekunden dauern. Bitte kurz warten und dann erneut auf "zahlungspflichtig bestellen" klicken.', 'OSC_PAYPAL_LOG_IN_TO_CONTINUE' => 'Bitte loggen Sie sich ein, um die Bestellung abzuschliessen.', 'OSC_PAYPAL_3DSECURITY_ERROR' => 'Die Sicherheitsüberprüfung ist fehlgeschlagen, bitte erneut versuchen.', 'OSC_PAYPAL_ORDEREXECUTION_ERROR' => 'Der Bezahlvorgang wurde abgebrochen.', + 'OSCPAYPAL_KILL_EXPRESS_SESSION_REASON' => 'Der Warenkorb wurde geändert. Aus diesem Grund wurde der aktive PayPal-Zahlvorgang automatisch abgebrochen. Bitte starten Sie die Zahlung mit PayPal erneut. Es wurde noch kein Geld von PayPal eingezogen.', 'OSC_PAYPAL_VAULTING_MENU' => 'PayPal Zahlart speichern', 'OSC_PAYPAL_VAULTING_MENU_CARD' => 'PayPal Kreditkarte speichern', @@ -62,5 +58,4 @@ 'OSC_PAYPAL_CARD_ENDING_IN' => 'endet mit ●●●', 'OSC_PAYPAL_CARD_PAYPAL_PAYMENT' => 'PayPal Zahlung mit', 'OSC_PAYPAL_DELETE_FAILED' => 'Beim Löschen Ihrer Zahlart ist etwas schiefgelaufen.', - 'OSCPAYPAL_KILL_EXPRESS_SESSION_REASON' => 'Der Warenkorb wurde geändert. Aus diesem Grund wurde der aktive PayPal-Zahlvorgang automatisch abgebrochen. Bitte starten Sie die Zahlung mit PayPal erneut. Es wurde noch kein Geld von PayPal eingezogen.', ]; diff --git a/translations/en/oscpaypal_en_lang.php b/translations/en/oscpaypal_en_lang.php index 1abbba0d3..b9369f481 100644 --- a/translations/en/oscpaypal_en_lang.php +++ b/translations/en/oscpaypal_en_lang.php @@ -42,7 +42,6 @@ 'OSC_PAYPAL_LOG_IN_TO_CONTINUE' => 'Please log in to continue checking out.', 'OSC_PAYPAL_3DSECURITY_ERROR' => 'Security check failed, please retry.', - 'OSC_PAYPAL_ORDEREXECUTION_ERROR' => 'Payment process could not be completed.', 'OSCPAYPAL_KILL_EXPRESS_SESSION_REASON' => 'The shopping cart has been changed. For this reason, the active PayPal payment process was automatically canceled. Please restart the payment with PayPal. No money has been collected from PayPal yet.', 'OSC_PAYPAL_ORDEREXECUTION_ERROR' => 'Payment process could not be completed.', @@ -60,5 +59,4 @@ 'OSC_PAYPAL_CARD_ENDING_IN' => 'ending in ●●●', 'OSC_PAYPAL_CARD_PAYPAL_PAYMENT' => 'PayPal payment with', 'OSC_PAYPAL_DELETE_FAILED' => 'There was an error deleting your payment method.', - 'OSCPAYPAL_KILL_EXPRESS_SESSION_REASON' => 'The shopping cart has been changed. For this reason, the active PayPal payment process was automatically canceled. Please restart the payment with PayPal. No money has been collected from PayPal yet.', ]; diff --git a/views/admin/tpl/oscpaypalorder.tpl b/views/admin/tpl/oscpaypalorder.tpl deleted file mode 100644 index 1d25d4229..000000000 --- a/views/admin/tpl/oscpaypalorder.tpl +++ /dev/null @@ -1,243 +0,0 @@ -[{include file="headitem.tpl" title="GENERAL_ADMIN_TITLE"|oxmultilangassign}] - -
- [{$oViewConf->getHiddenSid()}] - - -
- -[{if $error}] -
[{$error}]
-[{/if}] - -[{if $order && $payPalOrder}] - - [{assign var="currency" value=$oView->getPayPalCurrency()}] - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - -
[{oxmultilang ident="OSC_PAYPAL_SHOP_PAYMENT_STATUS" suffix="COLON"}] - [{oxmultilang ident='OSC_PAYPAL_STATUS_'|cat:$oView->getPayPalPaymentStatus()}] -
[{oxmultilang ident="OSC_PAYPAL_ORDER_PRICE" suffix="COLON"}] - [{$oView->formatPrice($oView->getPayPalTotalOrderSum())}] [{$currency}] -
[{oxmultilang ident="OSC_PAYPAL_AUTHORIZED_AMOUNT" suffix="COLON"}] - [{$oView->formatPrice($oView->getPayPalAuthorizationAmount())}] [{$currency}] -
[{oxmultilang ident="OSC_PAYPAL_CAPTURED_AMOUNT" suffix="COLON"}] - [{$oView->formatPrice($oView->getPayPalCapturedAmount())}] [{$currency}] -
[{oxmultilang ident="OSC_PAYPAL_REFUNDED_AMOUNT" suffix="COLON"}] - [{$oView->formatPrice($oView->getPayPalRefundedAmount())}] [{$currency}] -
[{oxmultilang ident="OSC_PAYPAL_CAPTURED_NET" suffix="COLON"}] - [{$oView->formatPrice($oView->getPayPalResultedAmount())}] [{$currency}] -
-
- [{if $payPalOrderDetails->oscpaypal_order__oscpaypalpuipaymentreference->value}] - [{oxmultilang ident="OSC_PAYPAL_PAYMENT_PUI" suffix="COLON"}] - - - - - - - - - - - - - - - - - - - - - -
[{oxmultilang ident="OSC_PAYPAL_PAYMENT_PUI_REFERENCE" suffix="COLON"}] - [{$payPalOrderDetails->oscpaypal_order__oscpaypalpuipaymentreference->value}] -
[{oxmultilang ident="OSC_PAYPAL_PAYMENT_PUI_BIC" suffix="COLON"}] - [{$payPalOrderDetails->oscpaypal_order__oscpaypalpuibic->value}] -
[{oxmultilang ident="OSC_PAYPAL_PAYMENT_PUI_IBAN" suffix="COLON"}] - [{$payPalOrderDetails->oscpaypal_order__oscpaypalpuiiban->value}] -
[{oxmultilang ident="OSC_PAYPAL_PAYMENT_PUI_BANKNAME" suffix="COLON"}] - [{$payPalOrderDetails->oscpaypal_order__oscpaypalpuibankname->value}] -
[{oxmultilang ident="OSC_PAYPAL_PAYMENT_PUI_ACCOUNTHOLDER" suffix="COLON"}] - [{$payPalOrderDetails->oscpaypal_order__oscpaypalpuiaccountholdername->value}] -
- [{/if}] -
-

[{oxmultilang ident="OSC_PAYPAL_ORDER_PRODUCTS" suffix="COLON"}]

- - - - - - [{if $order->isNettoMode()}] - - [{else}] - - [{/if}] - - - - [{assign var="blWhite" value=""}] - [{foreach from=$order->getOrderArticles() item=listitem name=orderArticles}] - [{if $listitem->oxorderarticles__oxstorno->value == 1}] - [{assign var="listclass" value=listitem3}] - [{else}] - [{assign var="listclass" value=listitem$blWhite}] - [{/if}] - - - - - [{if $order->isNettoMode()}] - - - [{else}] - - - [{/if}] - - - [{if $blWhite == "2"}] - [{assign var="blWhite" value=""}] - [{else}] - [{assign var="blWhite" value="2"}] - [{/if}] - [{/foreach}] -
[{oxmultilang ident="GENERAL_SUM"}]   [{oxmultilang ident="GENERAL_ITEMNR"}]   [{oxmultilang ident="GENERAL_TITLE"}][{oxmultilang ident="ORDER_ARTICLE_ENETTO"}][{oxmultilang ident="ORDER_ARTICLE_EBRUTTO"}][{oxmultilang ident="GENERAL_ATALL"}][{oxmultilang ident="ORDER_ARTICLE_MWST"}]
[{$listitem->oxorderarticles__oxamount->value}][{$listitem->oxorderarticles__oxartnum->value}] - [{$listitem->oxorderarticles__oxtitle->value|oxtruncate:20:""|strip_tags}] - [{$listitem->getNetPriceFormated()}] - [{$order->oxorder__oxcurrency->value}] - [{$listitem->getTotalNetPriceFormated()}] - [{$order->oxorder__oxcurrency->value}] - [{$listitem->getBrutPriceFormated()}] - [{$order->oxorder__oxcurrency->value}] - [{$listitem->getTotalBrutPriceFormated()}] - [{$order->oxorder__oxcurrency->value}] - [{$listitem->oxorderarticles__oxvat->value}]
-
- [{oxmultilang ident="OSC_PAYPAL_PAYMENT_HISTORY" suffix="COLON"}] - - - - - - - - - - - - - - - - - - [{foreach from=$oView->getPayPalHistory() item=listitem name=paypalHistory}] - [{cycle values='listitem,listitem2' assign='class'}] - - - - - - - - - - [{/foreach}] -
[{oxmultilang ident="OSC_PAYPAL_HISTORY_DATE"}][{oxmultilang ident="OSC_PAYPAL_HISTORY_ACTION"}][{oxmultilang ident="OSC_PAYPAL_AMOUNT"}] - [{oxmultilang ident="OSC_PAYPAL_HISTORY_PAYPAL_STATUS"}] - [{oxinputhelp ident="OSC_PAYPAL_HISTORY_PAYPAL_STATUS_HELP"}] - [{oxmultilang ident="OSC_PAYPAL_TRANSACTIONID"}][{oxmultilang ident="OSC_PAYPAL_INVOICE_ID"}][{oxmultilang ident="OSC_PAYPAL_COMMENT"}]
[{$listitem.date}][{oxmultilang ident='OSC_PAYPAL_'|cat:$listitem.action}] - [{$oView->formatPrice($listitem.amount)}] - [{$currency}] - [{oxmultilang ident='OSC_PAYPAL_STATUS_'|cat:$listitem.status}][{$listitem.transactionid}][{$listitem.invoiceid}][{$listitem.comment}]
-
- [{if $oView->getPayPalPaymentStatus() == 'COMPLETED' && $oView->getPayPalRemainingRefundAmount()}] -
-

[{oxmultilang ident="OSC_PAYPAL_ISSUE_REFUND"}]

-
- [{$oViewConf->getHiddenSid()}] - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
- [{elseif $oView->getPayPalPaymentStatus() !== 'COMPLETED'}] -
-

[{oxmultilang ident="OSC_PAYPAL_ACTIONS" suffix="COLON"}]

-
- [{$oViewConf->getHiddenSid()}] - - - - - -
-

[{oxmultilang ident="OSC_PAYPAL_CAPTURE_DAYS_LEFT" args=$oView->getTimeLeftForPayPalCapture()}]

-
- [{/if}] -[{/if}] -[{include file="bottomnaviitem.tpl"}] -[{include file="bottomitem.tpl"}] diff --git a/views/de/admin_translations.php b/views/admin_de/admin_translations.php similarity index 98% rename from views/de/admin_translations.php rename to views/admin_de/admin_translations.php index f68bfcac9..c360c3762 100755 --- a/views/de/admin_translations.php +++ b/views/admin_de/admin_translations.php @@ -76,8 +76,6 @@ 'OSC_PAYPAL_SPECIAL_PAYMENTS_VAULTING' => 'Vaulting', 'OSC_PAYPAL_SPECIAL_PAYMENTS_APPLEPAY' => 'Applepay', - - 'OSC_PAYPAL_SPECIAL_PAYMENTS_VAULTING' => 'Vaulting', 'OSC_PAYPAL_SPECIAL_PAYMENTS_GOOGLEPAY' => 'GooglePay', 'OSC_PAYPAL_LOCALISATIONS' => 'Spracheinstellungen', @@ -271,8 +269,6 @@ händisch stornieren.', 'OSC_PAYPAL_STARTTIME_CLEANUP_ORDERS' => 'Startzeit für automatisches Stornieren', 'HELP_OSC_PAYPAL_STARTTIME_CLEANUP_ORDERS' => 'Wie alt müssen nicht beendete Bestellungen sein, damit sie frühestens automatisch storniert werden (in Minuten)?', - 'OSC_PAYPAL_EXPRESS_SHIPPING_TITLE' => 'Pseudoversandkosten für PayPal Express', - 'OSC_PAYPAL_EXPRESS_SHIPPING_DESC' => 'PayPal Express benötigt für die Autorisierung des Warenkorbbetrages Versandkosten. Wenn ein Kunde sich im Shop weder eingeloggt noch seine Versandadresse angegeben hat, kann der Shop standardmäßig noch keine Versandkosten berechen. In den Shopeinstellungen (Stammdaten > Grundeinstellungen > Reiter Einstellungen > Abschnitt weitere Einstellungen) gibt es eine Option "Versandkosten auch dann berechnen, wenn der Kunde noch nicht eingeloggt ist". Damit kann OXID versuchen die Versandkosten für die Standardfälle zu ermitteln. Wenn man diese Option nicht nutzen möchte, besteht hier als letzte Möglichkeit Pseudoversandkosten zu hinterlegen. Die sollten Ihren meißt genutzten Versandkosten am nächsten kommen. Sobald sich der Kunde im Checkout befindet und seine Lieferadresse sowie seine gewünschte Versandart dem Shop bekannt sind, werden die tatsächlichen Versandkosten berechnet. Diese überschreiben alle vorher genutzten "Hilfs-"Versandkosten.', 'OSC_PAYPAL_ORDER_MAIN_TRACKCARRIER_COUNTRY' => 'Versanddienstleister (Land)', 'OSC_PAYPAL_ORDER_MAIN_TRACKCARRIER_PROVIDER' => 'Versanddienstleister (Anbieter)', @@ -285,7 +281,7 @@ eine höhere Checkout-Conversion bedeuten.', 'OSC_PAYPAL_GOOGLEPAY_TITLE' => 'Google Pay Adresse', 'OSC_PAYPAL_EXPRESS_SHIPPING_TITLE' => 'Pseudoversandkosten für PayPal Express', - 'OSC_PAYPAL_EXPRESS_SHIPPING_DESC' => 'Die hier eingegebenen Pseudeversandkosten werden verwendet, wenn die Shopoption “Versandkosten auch dann berechnen, wenn der Kunde noch nicht eingeloggt ist” nicht aktiviert ist.', + 'OSC_PAYPAL_EXPRESS_SHIPPING_DESC' => 'PayPal Express benötigt für die Autorisierung des Warenkorbbetrages Versandkosten. Wenn ein Kunde sich im Shop weder eingeloggt noch seine Versandadresse angegeben hat, kann der Shop standardmäßig noch keine Versandkosten berechen. In den Shopeinstellungen (Stammdaten > Grundeinstellungen > Reiter Einstellungen > Abschnitt weitere Einstellungen) gibt es eine Option "Versandkosten auch dann berechnen, wenn der Kunde noch nicht eingeloggt ist". Damit kann OXID versuchen die Versandkosten für die Standardfälle zu ermitteln. Wenn man diese Option nicht nutzen möchte, besteht hier als letzte Möglichkeit Pseudoversandkosten zu hinterlegen. Die sollten Ihren meißt genutzten Versandkosten am nächsten kommen. Sobald sich der Kunde im Checkout befindet und seine Lieferadresse sowie seine gewünschte Versandart dem Shop bekannt sind, werden die tatsächlichen Versandkosten berechnet. Diese überschreiben alle vorher genutzten "Hilfs-"Versandkosten.', 'OSC_PAYPAL_GOOGLEPAY_ADDRESS_ACTIVATE' => 'Speicherung der Adresse aktivieren', 'HELP_OSC_OSC_PAYPAL_GOOGLEPAY_ADRESS_ACTIVATE' => 'Übernahme der Lieferadresse von GooglePay', @@ -293,4 +289,6 @@ // PayPal Payment 'OSC_PAYPAL_PAYMENT_DEPRECATED' => 'Diese PayPal Zahlungsart kann nicht mehr aktiviert werden, da diese demnächst entfernt wird!', + 'OSC_PAYPAL_CUSTOM_ID_CONTENTS_TITLE' => 'PayPal Inhalte des benutzerdefinierten ID-Feldes', + 'OSC_PAYPAL_CUSTOM_ID_CONTENTS_DESC' => 'Das benutzerdefinierte PayPal-ID-Feld kann entweder nur den Bestellnummernwert oder ein JSON mit zusätzlichen Daten enthalten.', ]; diff --git a/views/de/transaction_type_codes_translations.php b/views/admin_de/transaction_type_codes_translations.php similarity index 100% rename from views/de/transaction_type_codes_translations.php rename to views/admin_de/transaction_type_codes_translations.php diff --git a/views/en/admin_translations.php b/views/admin_en/admin_translations.php similarity index 99% rename from views/en/admin_translations.php rename to views/admin_en/admin_translations.php index 6ad85088e..b17d2dc9b 100755 --- a/views/en/admin_translations.php +++ b/views/admin_en/admin_translations.php @@ -76,8 +76,6 @@ 'OSC_PAYPAL_SPECIAL_PAYMENTS_VAULTING' => 'Vaulting', 'OSC_PAYPAL_SPECIAL_PAYMENTS_APPLEPAY' => 'Applepay', - - 'OSC_PAYPAL_SPECIAL_PAYMENTS_VAULTING' => 'Vaulting', 'OSC_PAYPAL_SPECIAL_PAYMENTS_GOOGLEPAY' => 'GooglePay', 'OSC_PAYPAL_LOCALISATIONS' => 'Locals', @@ -272,8 +270,6 @@ cancel manually.', 'OSC_PAYPAL_STARTTIME_CLEANUP_ORDERS' => 'Start time for automatic cancellation', 'HELP_OSC_PAYPAL_STARTTIME_CLEANUP_ORDERS' => 'How old do not finished orders have to be before they are automatically canceled (in minutes)?', - 'OSC_PAYPAL_EXPRESS_SHIPPING_TITLE' => 'Pseudo shipping costs for PayPal Express', - 'OSC_PAYPAL_EXPRESS_SHIPPING_DESC' => 'PayPal Express requires shipping costs to authorize the shopping cart amount. If a customer has neither logged in to the shop nor provided their shipping address, the shop cannot calculate shipping costs by default. In the shop settings (Master Settings > Core Settings > Tab Settings > Section Other Settings ) there is an option "Calculate default Shipping costs when User is not logged in yet". This allows OXID to try to calculate the shipping costs for standard cases. If you do not want to use this option, the last option is to enter pseudo shipping costs. These should be as close to the shipping costs you use most often. As soon as the customer is in the checkout and their delivery address and desired shipping method are known to the shop, the actual shipping costs are calculated. These overwrite all previously used "auxiliary" shipping costs.', 'OSC_PAYPAL_ORDER_MAIN_TRACKCARRIER_COUNTRY' => 'Tracking Carrier (Country)', 'OSC_PAYPAL_ORDER_MAIN_TRACKCARRIER_PROVIDER' => 'Tracking Carrier (Provider)', @@ -284,15 +280,17 @@ 'HELP_OSC_PAYPAL_VAULTING_ACTIVATE_VAULTING' => 'Repeat purchases made easy: With PayPal you can securely store your customers preferred payment methods, making it quick and easy Enable purchase processing. With their saved payment details, customers can make repeat purchases with just a few clicks. This can be for you mean higher checkout conversion.', + 'OSC_PAYPAL_EXPRESS_SHIPPING_TITLE' => 'Pseudo shipping costs for PayPal Express', + 'OSC_PAYPAL_EXPRESS_SHIPPING_DESC' => 'PayPal Express requires shipping costs to authorize the shopping cart amount. If a customer has neither logged in to the shop nor provided their shipping address, the shop cannot calculate shipping costs by default. In the shop settings (Master Settings > Core Settings > Tab Settings > Section Other Settings ) there is an option "Calculate default Shipping costs when User is not logged in yet". This allows OXID to try to calculate the shipping costs for standard cases. If you do not want to use this option, the last option is to enter pseudo shipping costs. These should be as close to the shipping costs you use most often. As soon as the customer is in the checkout and their delivery address and desired shipping method are known to the shop, the actual shipping costs are calculated. These overwrite all previously used "auxiliary" shipping costs.', 'OSC_PAYPAL_GOOGLEPAY_TITLE' => 'Google Pay address', 'OSC_PAYPAL_GOOGLEPAY_ADDRESS_ACTIVATE' => 'Google Pay address active', 'HELP_OSC_OSC_PAYPAL_GOOGLEPAY_ADRESS_ACTIVATE' => 'Takeover delivery address from googlepay', 'OSC_PAYPAL_INSTALLPROCESS_FAILED' => 'Because the module was not installed correctly via Composer, errors occurred during the (de)activation of the module. Please reinstall the module via composer and repeat the process.', - 'OSC_PAYPAL_CUSTOM_ID_CONTENTS_TITLE' => 'PayPal custom id field contents', - 'OSC_PAYPAL_CUSTOM_ID_CONTENTS_DESC' => 'PayPal custom id field will be JSON encoded string with order number, shop version and the PayPal module version.', // PayPal Payment 'OSC_PAYPAL_PAYMENT_DEPRECATED' => 'This PayPal payment method can no longer be activated as it will be removed soon!', + 'OSC_PAYPAL_CUSTOM_ID_CONTENTS_TITLE' => 'PayPal custom id field contents', + 'OSC_PAYPAL_CUSTOM_ID_CONTENTS_DESC' => 'PayPal custom id field will be JSON encoded string with order number, shop version and the PayPal module version.', ]; diff --git a/views/en/transaction_type_codes_translations.php b/views/admin_en/transaction_type_codes_translations.php similarity index 100% rename from views/en/transaction_type_codes_translations.php rename to views/admin_en/transaction_type_codes_translations.php diff --git a/views/admin_smarty/de/admin_lang.php b/views/admin_smarty/de/admin_lang.php index 447f38c4c..0c3eeaa22 100644 --- a/views/admin_smarty/de/admin_lang.php +++ b/views/admin_smarty/de/admin_lang.php @@ -1,10 +1,3 @@ getIsVaultingActive()}] - - [{if $oViewConf->isAcdcEligibility() }] - - [{/if}] -[{/if}] -[{$smarty.block.parent}] diff --git a/views/blocks/page/checkout/change_payment.tpl b/views/blocks/page/checkout/change_payment.tpl deleted file mode 100644 index 578c4ddae..000000000 --- a/views/blocks/page/checkout/change_payment.tpl +++ /dev/null @@ -1,6 +0,0 @@ -[{if $oViewConf->isFlowCompatibleTheme()}] - [{include file='modules/osc/paypal/change_payment_flow.tpl'}] -[{else}] - [{include file='modules/osc/paypal/change_payment_wave.tpl'}] -[{/if}] -[{$smarty.block.parent}] diff --git a/views/smarty/admin/blocks/headitem__admin_headitem_inccss.tpl b/views/smarty/admin/blocks/admin_headitem_inccss.tpl similarity index 100% rename from views/smarty/admin/blocks/headitem__admin_headitem_inccss.tpl rename to views/smarty/admin/blocks/admin_headitem_inccss.tpl diff --git a/views/smarty/admin/blocks/headitem__admin_headitem_incjs.tpl b/views/smarty/admin/blocks/admin_headitem_incjs.tpl similarity index 100% rename from views/smarty/admin/blocks/headitem__admin_headitem_incjs.tpl rename to views/smarty/admin/blocks/admin_headitem_incjs.tpl diff --git a/views/smarty/admin/blocks/order_main__admin_order_main_form_shipping.tpl b/views/smarty/admin/blocks/admin_order_main_form_shipping.tpl similarity index 100% rename from views/smarty/admin/blocks/order_main__admin_order_main_form_shipping.tpl rename to views/smarty/admin/blocks/admin_order_main_form_shipping.tpl diff --git a/views/smarty/admin/blocks/order_main__admin_order_main_send_order.tpl b/views/smarty/admin/blocks/admin_order_main_send_order.tpl similarity index 100% rename from views/smarty/admin/blocks/order_main__admin_order_main_send_order.tpl rename to views/smarty/admin/blocks/admin_order_main_send_order.tpl diff --git a/views/smarty/admin/oscpaypalconfig.tpl b/views/smarty/admin/oscpaypalconfig.tpl old mode 100755 new mode 100644 index 3594fdece..079bc7270 --- a/views/smarty/admin/oscpaypalconfig.tpl +++ b/views/smarty/admin/oscpaypalconfig.tpl @@ -1,7 +1,6 @@ [{include file="headitem.tpl" title="paypal" box="boxpaypal"}] [{assign var="isSandBox" value=$config->isSandbox()}] [{assign var="sSelfLink" value=$oViewConf->getSslSelfLink()|replace:"&":"&"}] - [{capture assign="sPayPalJS"}] [{strip}] window.isSandBox = '[{$isSandBox}]'; @@ -16,9 +15,9 @@

[{oxmultilang ident="paypal"}] [{oxmultilang ident="OSC_PAYPAL_CONFIG"}]

@@ -55,7 +54,6 @@

[{oxmultilang ident="HELP_OSC_PAYPAL_CREDENTIALS_PART1"}]

[{oxmultilang ident="HELP_OSC_PAYPAL_CREDENTIALS_PART2"}]

-

[{oxmultilang ident="HELP_OSC_PAYPAL_CREDENTIALS_PART2"}]

-

[{oxmultilang ident="OSC_PAYPAL_LIVE_CREDENTIALS"}]

+

[{oxmultilang ident="OSC_PAYPAL_LIVE_CREDENTIALS"}]

@@ -109,9 +107,9 @@
[{oxmultilang ident="OSC_PAYPAL_SPECIAL_PAYMENTS_VAULTING" suffix="COLON"}] [{if $config->isLiveVaultingEligibility()}][{oxmultilang ident="GENERAL_YES"}][{else}][{oxmultilang ident="GENERAL_NO"}][{/if}]
- [{oxmultilang ident="OSC_PAYPAL_SPECIAL_PAYMENTS_APPLEPAY" suffix="COLON"}] [{if $config->isLiveApplePayEligibility()}][{oxmultilang ident="GENERAL_YES"}][{else}][{oxmultilang ident="GENERAL_NO"}][{/if}] -
[{oxmultilang ident="OSC_PAYPAL_SPECIAL_PAYMENTS_GOOGLEPAY" suffix="COLON"}] [{if $config->isLiveGooglePayEligibility()}][{oxmultilang ident="GENERAL_YES"}][{else}][{oxmultilang ident="GENERAL_NO"}][{/if}] +
+ [{oxmultilang ident="OSC_PAYPAL_SPECIAL_PAYMENTS_APPLEPAY" suffix="COLON"}] [{if $config->isLiveApplePayEligibility()}][{oxmultilang ident="GENERAL_YES"}][{else}][{oxmultilang ident="GENERAL_NO"}][{/if}]
@@ -360,7 +358,7 @@
[{if $oView->showTransferLegacySettingsButton()}] - [{oxmultilang ident='OSC_PAYPAL_BANNER_TRANSFERLEGACYSETTINGS'}] + [{oxmultilang ident='OSC_PAYPAL_BANNER_TRANSFERLEGACYSETTINGS'}] [{/if}]

[{oxmultilang ident="OSC_PAYPAL_BANNER_INFOTEXT"}]

@@ -449,7 +447,6 @@
[{oxmultilang ident="HELP_OSC_PAYPAL_BANNER_CARTPAGESELECTOR"}] -
@@ -509,6 +506,7 @@ [{oxmultilang ident="OSC_PAYPAL_VAULTING_TITLE"}]
+
@@ -525,44 +523,44 @@
+
-
-
-
-
-
- -
+
+
+
+
+
+ +
- [{oxmultilang ident="OSC_PAYPAL_EXPRESS_SHIPPING_DESC"}] + [{oxmultilang ident="OSC_PAYPAL_EXPRESS_SHIPPING_DESC"}] +
-
-
-
diff --git a/views/tpl/wave/page/checkout/shipping_and_payment_paypal.tpl b/views/smarty/frontend/wave/page/checkout/shipping_and_payment_paypal.tpl similarity index 100% rename from views/tpl/wave/page/checkout/shipping_and_payment_paypal.tpl rename to views/smarty/frontend/wave/page/checkout/shipping_and_payment_paypal.tpl diff --git a/views/tpl/wave/vaulting/vaultedpaymentsources.tpl b/views/smarty/frontend/wave/vaulting/vaultedpaymentsources.tpl similarity index 100% rename from views/tpl/wave/vaulting/vaultedpaymentsources.tpl rename to views/smarty/frontend/wave/vaulting/vaultedpaymentsources.tpl From 4d124819489d53f42ed6eaa1c35edfb6c226900e Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Thu, 9 Jan 2025 14:53:14 +0100 Subject: [PATCH 02/30] codestyle --- src/Controller/OrderController.php | 37 +++++++++++++++--------------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/src/Controller/OrderController.php b/src/Controller/OrderController.php index ae8ff5bf8..8dc278e65 100644 --- a/src/Controller/OrderController.php +++ b/src/Controller/OrderController.php @@ -12,7 +12,6 @@ use OxidEsales\Eshop\Core\DisplayError; use OxidEsales\Eshop\Core\Exception\StandardException; use OxidEsales\Eshop\Core\Registry; -use OxidSolutionCatalysts\PayPal\Service\Logger; use OxidSolutionCatalysts\PayPal\Core\Constants; use OxidSolutionCatalysts\PayPal\Core\PayPalDefinitions; use OxidSolutionCatalysts\PayPal\Core\PayPalSession; @@ -22,6 +21,7 @@ use OxidSolutionCatalysts\PayPal\Exception\Redirect; use OxidSolutionCatalysts\PayPal\Exception\RedirectWithMessage; use OxidSolutionCatalysts\PayPal\Model\Order as PayPalOrderModel; +use OxidSolutionCatalysts\PayPal\Service\Logger; use OxidSolutionCatalysts\PayPal\Service\ModuleSettings; use OxidSolutionCatalysts\PayPal\Service\Payment as PaymentService; use OxidSolutionCatalysts\PayPal\Service\UserRepository; @@ -36,6 +36,7 @@ /** * Class OrderController + * * @package OxidSolutionCatalysts\PayPal\Controller * * @mixin \OxidEsales\Eshop\Application\Controller\OrderController @@ -82,11 +83,11 @@ public function render() } if ( - $paymentService->getSessionPaymentId() === PayPalDefinitions::SEPA_PAYPAL_PAYMENT_ID || - $paymentService->getSessionPaymentId() === PayPalDefinitions::CCALTERNATIVE_PAYPAL_PAYMENT_ID || - $paymentService->getSessionPaymentId() === PayPalDefinitions::STANDARD_PAYPAL_PAYMENT_ID || - $paymentService->getSessionPaymentId() === PayPalDefinitions::PAYLATER_PAYPAL_PAYMENT_ID || - $paymentService->getSessionPaymentId() === PayPalDefinitions::GOOGLEPAY_PAYPAL_PAYMENT_ID + $paymentService->getSessionPaymentId() === PayPalDefinitions::SEPA_PAYPAL_PAYMENT_ID + || $paymentService->getSessionPaymentId() === PayPalDefinitions::CCALTERNATIVE_PAYPAL_PAYMENT_ID + || $paymentService->getSessionPaymentId() === PayPalDefinitions::STANDARD_PAYPAL_PAYMENT_ID + || $paymentService->getSessionPaymentId() === PayPalDefinitions::PAYLATER_PAYPAL_PAYMENT_ID + || $paymentService->getSessionPaymentId() === PayPalDefinitions::GOOGLEPAY_PAYPAL_PAYMENT_ID ) { $paymentService->removeTemporaryOrder(); } @@ -105,9 +106,9 @@ public function render() $selectedVaultPaymentSourceIndex = $session->getVariable("selectedVaultPaymentSourceIndex"); if ( - $isVaultingPossible && - !is_null($selectedVaultPaymentSourceIndex) && - $payPalCustomerId = $user->getFieldData("oscpaypalcustomerid") + $isVaultingPossible + && !is_null($selectedVaultPaymentSourceIndex) + && $payPalCustomerId = $user->getFieldData("oscpaypalcustomerid") ) { $vaultingService = Registry::get(ServiceFactory::class)->getVaultingService(); @@ -143,9 +144,9 @@ protected function renderRetryOrderExecution(): bool $order->load(Registry::getSession()->getVariable('sess_challenge')); if ( - !$order->getFieldData('oxtransid') && - $retryRequest && - isset($this->retryPaymentMessages[$retryRequest]) + !$order->getFieldData('oxtransid') + && $retryRequest + && isset($this->retryPaymentMessages[$retryRequest]) ) { $displayError = oxNew(DisplayError::class); $displayError->setMessage($this->retryPaymentMessages[$retryRequest]); @@ -183,9 +184,9 @@ public function createAcdcOrder(): void $acdcStatus = Registry::getSession()->getVariable(Constants::SESSION_ACDC_PAYPALORDER_STATUS); if ( - $sessionOrderId && - $sessionAcdcOrderId && - $acdcStatus === Constants::PAYPAL_STATUS_COMPLETED + $sessionOrderId + && $sessionAcdcOrderId + && $acdcStatus === Constants::PAYPAL_STATUS_COMPLETED ) { //we already have a completed acdc order $this->outputJson(['acdcerror' => 'shop order already completed']); @@ -303,9 +304,9 @@ public function captureAcdcOrder(): void $logger = $this->getServiceFromContainer(Logger::class); if ( - 'COMPLETED' === $acdcStatus && - $sessionOrderId && - $sessionAcdcOrderId + 'COMPLETED' === $acdcStatus + && $sessionOrderId + && $sessionAcdcOrderId ) { $logger->log( 'debug', From fea6f29e616113d700d943cadaf996a555519323 Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Thu, 9 Jan 2025 15:11:26 +0100 Subject: [PATCH 03/30] rebuild resources --- assets/css/bootstrap.css | 7263 +---------------- assets/css/paypal-admin.css | 109 +- assets/css/paypal.css | 2 +- assets/js/paypal-frontend.min.js | 2 +- .../build/js/paypal-frontend-googlepay.js | 69 +- .../build/js/paypal-frontend-hateoaslinks.js | 28 +- .../paypal-frontend-paypal-vault-checkout.js | 42 + resources/build/scss/paypal.scss | 23 + resources/grunt/concat.js | 4 + resources/grunt/uglify.js | 3 +- 10 files changed, 140 insertions(+), 7405 deletions(-) create mode 100644 resources/build/js/paypal-frontend-paypal-vault-checkout.js diff --git a/assets/css/bootstrap.css b/assets/css/bootstrap.css index d89885291..40fc379ae 100644 --- a/assets/css/bootstrap.css +++ b/assets/css/bootstrap.css @@ -3,7265 +3,4 @@ * Copyright 2011-2021 The Bootstrap Authors * Copyright 2011-2021 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) - */ -:root { - --blue: #007bff; - --indigo: #6610f2; - --purple: #6f42c1; - --pink: #e83e8c; - --red: #dc3545; - --orange: #fd7e14; - --yellow: #ffc107; - --green: #28a745; - --teal: #20c997; - --cyan: #17a2b8; - --white: #fff; - --gray: #6c757d; - --gray-dark: #343a40; - --primary: #007bff; - --secondary: #6c757d; - --success: #28a745; - --info: #17a2b8; - --warning: #ffc107; - --danger: #dc3545; - --light: #f8f9fa; - --dark: #343a40; - --breakpoint-xs: 0; - --breakpoint-sm: 576px; - --breakpoint-md: 768px; - --breakpoint-lg: 992px; - --breakpoint-xl: 1200px; - --font-family-sans-serif: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; - --font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; } - -*, -*::before, -*::after { - box-sizing: border-box; } - -html { - font-family: sans-serif; - line-height: 1.15; - -webkit-text-size-adjust: 100%; - -webkit-tap-highlight-color: rgba(0, 0, 0, 0); } - -article, aside, figcaption, figure, footer, header, hgroup, main, nav, section { - display: block; } - -body { - margin: 0; - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; - font-size: 1rem; - font-weight: 400; - line-height: 1.5; - color: #212529; - text-align: left; - background-color: #fff; } - -[tabindex="-1"]:focus:not(:focus-visible) { - outline: 0 !important; } - -hr { - box-sizing: content-box; - height: 0; - overflow: visible; } - -h1, h2, h3, h4, h5, h6 { - margin-top: 0; - margin-bottom: 0.5rem; } - -p { - margin-top: 0; - margin-bottom: 1rem; } - -abbr[title], -abbr[data-original-title] { - text-decoration: underline; - -webkit-text-decoration: underline dotted; - text-decoration: underline dotted; - cursor: help; - border-bottom: 0; - -webkit-text-decoration-skip-ink: none; - text-decoration-skip-ink: none; } - -address { - margin-bottom: 1rem; - font-style: normal; - line-height: inherit; } - -ol, -ul, -dl { - margin-top: 0; - margin-bottom: 1rem; } - -ol ol, -ul ul, -ol ul, -ul ol { - margin-bottom: 0; } - -dt { - font-weight: 700; } - -dd { - margin-bottom: .5rem; - margin-left: 0; } - -blockquote { - margin: 0 0 1rem; } - -b, -strong { - font-weight: bolder; } - -small { - font-size: 80%; } - -sub, -sup { - position: relative; - font-size: 75%; - line-height: 0; - vertical-align: baseline; } - -sub { - bottom: -.25em; } - -sup { - top: -.5em; } - -a { - color: #007bff; - text-decoration: none; - background-color: transparent; } - a:hover { - color: #0056b3; - text-decoration: underline; } - -a:not([href]):not([class]) { - color: inherit; - text-decoration: none; } - a:not([href]):not([class]):hover { - color: inherit; - text-decoration: none; } - -pre, -code, -kbd, -samp { - font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; - font-size: 1em; } - -pre { - margin-top: 0; - margin-bottom: 1rem; - overflow: auto; - -ms-overflow-style: scrollbar; } - -figure { - margin: 0 0 1rem; } - -img { - vertical-align: middle; - border-style: none; } - -svg { - overflow: hidden; - vertical-align: middle; } - -table { - border-collapse: collapse; } - -caption { - padding-top: 0.75rem; - padding-bottom: 0.75rem; - color: #6c757d; - text-align: left; - caption-side: bottom; } - -th { - text-align: inherit; - text-align: -webkit-match-parent; } - -label { - display: inline-block; - margin-bottom: 0.5rem; } - -button { - border-radius: 0; } - -button:focus:not(:focus-visible) { - outline: 0; } - -input, -button, -select, -optgroup, -textarea { - margin: 0; - font-family: inherit; - font-size: inherit; - line-height: inherit; } - -button, -input { - overflow: visible; } - -button, -select { - text-transform: none; } - -[role="button"] { - cursor: pointer; } - -select { - word-wrap: normal; } - -button, -[type="button"], -[type="reset"], -[type="submit"] { - -webkit-appearance: button; } - -button:not(:disabled), -[type="button"]:not(:disabled), -[type="reset"]:not(:disabled), -[type="submit"]:not(:disabled) { - cursor: pointer; } - -button::-moz-focus-inner, -[type="button"]::-moz-focus-inner, -[type="reset"]::-moz-focus-inner, -[type="submit"]::-moz-focus-inner { - padding: 0; - border-style: none; } - -input[type="radio"], -input[type="checkbox"] { - box-sizing: border-box; - padding: 0; } - -textarea { - overflow: auto; - resize: vertical; } - -fieldset { - min-width: 0; - padding: 0; - margin: 0; - border: 0; } - -legend { - display: block; - width: 100%; - max-width: 100%; - padding: 0; - margin-bottom: .5rem; - font-size: 1.5rem; - line-height: inherit; - color: inherit; - white-space: normal; } - -progress { - vertical-align: baseline; } - -[type="number"]::-webkit-inner-spin-button, -[type="number"]::-webkit-outer-spin-button { - height: auto; } - -[type="search"] { - outline-offset: -2px; - -webkit-appearance: none; } - -[type="search"]::-webkit-search-decoration { - -webkit-appearance: none; } - -::-webkit-file-upload-button { - font: inherit; - -webkit-appearance: button; } - -output { - display: inline-block; } - -summary { - display: list-item; - cursor: pointer; } - -template { - display: none; } - -[hidden] { - display: none !important; } - -h1, h2, h3, h4, h5, h6, -.h1, .h2, .h3, .h4, .h5, .h6 { - margin-bottom: 0.5rem; - font-weight: 500; - line-height: 1.2; } - -h1, .h1 { - font-size: 2.5rem; } - -h2, .h2 { - font-size: 2rem; } - -h3, .h3 { - font-size: 1.75rem; } - -h4, .h4 { - font-size: 1.5rem; } - -h5, .h5 { - font-size: 1.25rem; } - -h6, .h6 { - font-size: 1rem; } - -.lead { - font-size: 1.25rem; - font-weight: 300; } - -.display-1 { - font-size: 6rem; - font-weight: 300; - line-height: 1.2; } - -.display-2 { - font-size: 5.5rem; - font-weight: 300; - line-height: 1.2; } - -.display-3 { - font-size: 4.5rem; - font-weight: 300; - line-height: 1.2; } - -.display-4 { - font-size: 3.5rem; - font-weight: 300; - line-height: 1.2; } - -hr { - margin-top: 1rem; - margin-bottom: 1rem; - border: 0; - border-top: 1px solid rgba(0, 0, 0, 0.1); } - -small, -.small { - font-size: 80%; - font-weight: 400; } - -mark, -.mark { - padding: 0.2em; - background-color: #fcf8e3; } - -.list-unstyled { - padding-left: 0; - list-style: none; } - -.list-inline { - padding-left: 0; - list-style: none; } - -.list-inline-item { - display: inline-block; } - .list-inline-item:not(:last-child) { - margin-right: 0.5rem; } - -.initialism { - font-size: 90%; - text-transform: uppercase; } - -.blockquote { - margin-bottom: 1rem; - font-size: 1.25rem; } - -.blockquote-footer { - display: block; - font-size: 80%; - color: #6c757d; } - .blockquote-footer::before { - content: "\2014\00A0"; } - -.img-fluid { - max-width: 100%; - height: auto; } - -.img-thumbnail { - padding: 0.25rem; - background-color: #fff; - border: 1px solid #dee2e6; - border-radius: 0.25rem; - max-width: 100%; - height: auto; } - -.figure { - display: inline-block; } - -.figure-img { - margin-bottom: 0.5rem; - line-height: 1; } - -.figure-caption { - font-size: 90%; - color: #6c757d; } - -code { - font-size: 87.5%; - color: #e83e8c; - word-wrap: break-word; } - a > code { - color: inherit; } - -kbd { - padding: 0.2rem 0.4rem; - font-size: 87.5%; - color: #fff; - background-color: #212529; - border-radius: 0.2rem; } - kbd kbd { - padding: 0; - font-size: 100%; - font-weight: 700; } - -pre { - display: block; - font-size: 87.5%; - color: #212529; } - pre code { - font-size: inherit; - color: inherit; - word-break: normal; } - -.pre-scrollable { - max-height: 340px; - overflow-y: scroll; } - -.container, -.container-fluid, -.container-sm, -.container-md, -.container-lg, -.container-xl { - width: 100%; - padding-right: 15px; - padding-left: 15px; - margin-right: auto; - margin-left: auto; } - -@media (min-width: 576px) { - .container, .container-sm { - max-width: 540px; } } - -@media (min-width: 768px) { - .container, .container-sm, .container-md { - max-width: 720px; } } - -@media (min-width: 992px) { - .container, .container-sm, .container-md, .container-lg { - max-width: 960px; } } - -@media (min-width: 1200px) { - .container, .container-sm, .container-md, .container-lg, .container-xl { - max-width: 1140px; } } - -.row { - display: flex; - flex-wrap: wrap; - margin-right: -15px; - margin-left: -15px; } - -.no-gutters { - margin-right: 0; - margin-left: 0; } - .no-gutters > .col, - .no-gutters > [class*="col-"] { - padding-right: 0; - padding-left: 0; } - -.col-1, .col-2, .col-3, .col-4, .col-5, .col-6, .col-7, .col-8, .col-9, .col-10, .col-11, .col-12, .col, -.col-auto, .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12, .col-sm, -.col-sm-auto, .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12, .col-md, -.col-md-auto, .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12, .col-lg, -.col-lg-auto, .col-xl-1, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-10, .col-xl-11, .col-xl-12, .col-xl, -.col-xl-auto { - position: relative; - width: 100%; - padding-right: 15px; - padding-left: 15px; } - -.col { - flex-basis: 0; - flex-grow: 1; - max-width: 100%; } - -.row-cols-1 > * { - flex: 0 0 100%; - max-width: 100%; } - -.row-cols-2 > * { - flex: 0 0 50%; - max-width: 50%; } - -.row-cols-3 > * { - flex: 0 0 33.3333333333%; - max-width: 33.3333333333%; } - -.row-cols-4 > * { - flex: 0 0 25%; - max-width: 25%; } - -.row-cols-5 > * { - flex: 0 0 20%; - max-width: 20%; } - -.row-cols-6 > * { - flex: 0 0 16.6666666667%; - max-width: 16.6666666667%; } - -.col-auto { - flex: 0 0 auto; - width: auto; - max-width: 100%; } - -.col-1 { - flex: 0 0 8.33333333%; - max-width: 8.33333333%; } - -.col-2 { - flex: 0 0 16.66666667%; - max-width: 16.66666667%; } - -.col-3 { - flex: 0 0 25%; - max-width: 25%; } - -.col-4 { - flex: 0 0 33.33333333%; - max-width: 33.33333333%; } - -.col-5 { - flex: 0 0 41.66666667%; - max-width: 41.66666667%; } - -.col-6 { - flex: 0 0 50%; - max-width: 50%; } - -.col-7 { - flex: 0 0 58.33333333%; - max-width: 58.33333333%; } - -.col-8 { - flex: 0 0 66.66666667%; - max-width: 66.66666667%; } - -.col-9 { - flex: 0 0 75%; - max-width: 75%; } - -.col-10 { - flex: 0 0 83.33333333%; - max-width: 83.33333333%; } - -.col-11 { - flex: 0 0 91.66666667%; - max-width: 91.66666667%; } - -.col-12 { - flex: 0 0 100%; - max-width: 100%; } - -.order-first { - order: -1; } - -.order-last { - order: 13; } - -.order-0 { - order: 0; } - -.order-1 { - order: 1; } - -.order-2 { - order: 2; } - -.order-3 { - order: 3; } - -.order-4 { - order: 4; } - -.order-5 { - order: 5; } - -.order-6 { - order: 6; } - -.order-7 { - order: 7; } - -.order-8 { - order: 8; } - -.order-9 { - order: 9; } - -.order-10 { - order: 10; } - -.order-11 { - order: 11; } - -.order-12 { - order: 12; } - -.offset-1 { - margin-left: 8.33333333%; } - -.offset-2 { - margin-left: 16.66666667%; } - -.offset-3 { - margin-left: 25%; } - -.offset-4 { - margin-left: 33.33333333%; } - -.offset-5 { - margin-left: 41.66666667%; } - -.offset-6 { - margin-left: 50%; } - -.offset-7 { - margin-left: 58.33333333%; } - -.offset-8 { - margin-left: 66.66666667%; } - -.offset-9 { - margin-left: 75%; } - -.offset-10 { - margin-left: 83.33333333%; } - -.offset-11 { - margin-left: 91.66666667%; } - -@media (min-width: 576px) { - .col-sm { - flex-basis: 0; - flex-grow: 1; - max-width: 100%; } - .row-cols-sm-1 > * { - flex: 0 0 100%; - max-width: 100%; } - .row-cols-sm-2 > * { - flex: 0 0 50%; - max-width: 50%; } - .row-cols-sm-3 > * { - flex: 0 0 33.3333333333%; - max-width: 33.3333333333%; } - .row-cols-sm-4 > * { - flex: 0 0 25%; - max-width: 25%; } - .row-cols-sm-5 > * { - flex: 0 0 20%; - max-width: 20%; } - .row-cols-sm-6 > * { - flex: 0 0 16.6666666667%; - max-width: 16.6666666667%; } - .col-sm-auto { - flex: 0 0 auto; - width: auto; - max-width: 100%; } - .col-sm-1 { - flex: 0 0 8.33333333%; - max-width: 8.33333333%; } - .col-sm-2 { - flex: 0 0 16.66666667%; - max-width: 16.66666667%; } - .col-sm-3 { - flex: 0 0 25%; - max-width: 25%; } - .col-sm-4 { - flex: 0 0 33.33333333%; - max-width: 33.33333333%; } - .col-sm-5 { - flex: 0 0 41.66666667%; - max-width: 41.66666667%; } - .col-sm-6 { - flex: 0 0 50%; - max-width: 50%; } - .col-sm-7 { - flex: 0 0 58.33333333%; - max-width: 58.33333333%; } - .col-sm-8 { - flex: 0 0 66.66666667%; - max-width: 66.66666667%; } - .col-sm-9 { - flex: 0 0 75%; - max-width: 75%; } - .col-sm-10 { - flex: 0 0 83.33333333%; - max-width: 83.33333333%; } - .col-sm-11 { - flex: 0 0 91.66666667%; - max-width: 91.66666667%; } - .col-sm-12 { - flex: 0 0 100%; - max-width: 100%; } - .order-sm-first { - order: -1; } - .order-sm-last { - order: 13; } - .order-sm-0 { - order: 0; } - .order-sm-1 { - order: 1; } - .order-sm-2 { - order: 2; } - .order-sm-3 { - order: 3; } - .order-sm-4 { - order: 4; } - .order-sm-5 { - order: 5; } - .order-sm-6 { - order: 6; } - .order-sm-7 { - order: 7; } - .order-sm-8 { - order: 8; } - .order-sm-9 { - order: 9; } - .order-sm-10 { - order: 10; } - .order-sm-11 { - order: 11; } - .order-sm-12 { - order: 12; } - .offset-sm-0 { - margin-left: 0; } - .offset-sm-1 { - margin-left: 8.33333333%; } - .offset-sm-2 { - margin-left: 16.66666667%; } - .offset-sm-3 { - margin-left: 25%; } - .offset-sm-4 { - margin-left: 33.33333333%; } - .offset-sm-5 { - margin-left: 41.66666667%; } - .offset-sm-6 { - margin-left: 50%; } - .offset-sm-7 { - margin-left: 58.33333333%; } - .offset-sm-8 { - margin-left: 66.66666667%; } - .offset-sm-9 { - margin-left: 75%; } - .offset-sm-10 { - margin-left: 83.33333333%; } - .offset-sm-11 { - margin-left: 91.66666667%; } } - -@media (min-width: 768px) { - .col-md { - flex-basis: 0; - flex-grow: 1; - max-width: 100%; } - .row-cols-md-1 > * { - flex: 0 0 100%; - max-width: 100%; } - .row-cols-md-2 > * { - flex: 0 0 50%; - max-width: 50%; } - .row-cols-md-3 > * { - flex: 0 0 33.3333333333%; - max-width: 33.3333333333%; } - .row-cols-md-4 > * { - flex: 0 0 25%; - max-width: 25%; } - .row-cols-md-5 > * { - flex: 0 0 20%; - max-width: 20%; } - .row-cols-md-6 > * { - flex: 0 0 16.6666666667%; - max-width: 16.6666666667%; } - .col-md-auto { - flex: 0 0 auto; - width: auto; - max-width: 100%; } - .col-md-1 { - flex: 0 0 8.33333333%; - max-width: 8.33333333%; } - .col-md-2 { - flex: 0 0 16.66666667%; - max-width: 16.66666667%; } - .col-md-3 { - flex: 0 0 25%; - max-width: 25%; } - .col-md-4 { - flex: 0 0 33.33333333%; - max-width: 33.33333333%; } - .col-md-5 { - flex: 0 0 41.66666667%; - max-width: 41.66666667%; } - .col-md-6 { - flex: 0 0 50%; - max-width: 50%; } - .col-md-7 { - flex: 0 0 58.33333333%; - max-width: 58.33333333%; } - .col-md-8 { - flex: 0 0 66.66666667%; - max-width: 66.66666667%; } - .col-md-9 { - flex: 0 0 75%; - max-width: 75%; } - .col-md-10 { - flex: 0 0 83.33333333%; - max-width: 83.33333333%; } - .col-md-11 { - flex: 0 0 91.66666667%; - max-width: 91.66666667%; } - .col-md-12 { - flex: 0 0 100%; - max-width: 100%; } - .order-md-first { - order: -1; } - .order-md-last { - order: 13; } - .order-md-0 { - order: 0; } - .order-md-1 { - order: 1; } - .order-md-2 { - order: 2; } - .order-md-3 { - order: 3; } - .order-md-4 { - order: 4; } - .order-md-5 { - order: 5; } - .order-md-6 { - order: 6; } - .order-md-7 { - order: 7; } - .order-md-8 { - order: 8; } - .order-md-9 { - order: 9; } - .order-md-10 { - order: 10; } - .order-md-11 { - order: 11; } - .order-md-12 { - order: 12; } - .offset-md-0 { - margin-left: 0; } - .offset-md-1 { - margin-left: 8.33333333%; } - .offset-md-2 { - margin-left: 16.66666667%; } - .offset-md-3 { - margin-left: 25%; } - .offset-md-4 { - margin-left: 33.33333333%; } - .offset-md-5 { - margin-left: 41.66666667%; } - .offset-md-6 { - margin-left: 50%; } - .offset-md-7 { - margin-left: 58.33333333%; } - .offset-md-8 { - margin-left: 66.66666667%; } - .offset-md-9 { - margin-left: 75%; } - .offset-md-10 { - margin-left: 83.33333333%; } - .offset-md-11 { - margin-left: 91.66666667%; } } - -@media (min-width: 992px) { - .col-lg { - flex-basis: 0; - flex-grow: 1; - max-width: 100%; } - .row-cols-lg-1 > * { - flex: 0 0 100%; - max-width: 100%; } - .row-cols-lg-2 > * { - flex: 0 0 50%; - max-width: 50%; } - .row-cols-lg-3 > * { - flex: 0 0 33.3333333333%; - max-width: 33.3333333333%; } - .row-cols-lg-4 > * { - flex: 0 0 25%; - max-width: 25%; } - .row-cols-lg-5 > * { - flex: 0 0 20%; - max-width: 20%; } - .row-cols-lg-6 > * { - flex: 0 0 16.6666666667%; - max-width: 16.6666666667%; } - .col-lg-auto { - flex: 0 0 auto; - width: auto; - max-width: 100%; } - .col-lg-1 { - flex: 0 0 8.33333333%; - max-width: 8.33333333%; } - .col-lg-2 { - flex: 0 0 16.66666667%; - max-width: 16.66666667%; } - .col-lg-3 { - flex: 0 0 25%; - max-width: 25%; } - .col-lg-4 { - flex: 0 0 33.33333333%; - max-width: 33.33333333%; } - .col-lg-5 { - flex: 0 0 41.66666667%; - max-width: 41.66666667%; } - .col-lg-6 { - flex: 0 0 50%; - max-width: 50%; } - .col-lg-7 { - flex: 0 0 58.33333333%; - max-width: 58.33333333%; } - .col-lg-8 { - flex: 0 0 66.66666667%; - max-width: 66.66666667%; } - .col-lg-9 { - flex: 0 0 75%; - max-width: 75%; } - .col-lg-10 { - flex: 0 0 83.33333333%; - max-width: 83.33333333%; } - .col-lg-11 { - flex: 0 0 91.66666667%; - max-width: 91.66666667%; } - .col-lg-12 { - flex: 0 0 100%; - max-width: 100%; } - .order-lg-first { - order: -1; } - .order-lg-last { - order: 13; } - .order-lg-0 { - order: 0; } - .order-lg-1 { - order: 1; } - .order-lg-2 { - order: 2; } - .order-lg-3 { - order: 3; } - .order-lg-4 { - order: 4; } - .order-lg-5 { - order: 5; } - .order-lg-6 { - order: 6; } - .order-lg-7 { - order: 7; } - .order-lg-8 { - order: 8; } - .order-lg-9 { - order: 9; } - .order-lg-10 { - order: 10; } - .order-lg-11 { - order: 11; } - .order-lg-12 { - order: 12; } - .offset-lg-0 { - margin-left: 0; } - .offset-lg-1 { - margin-left: 8.33333333%; } - .offset-lg-2 { - margin-left: 16.66666667%; } - .offset-lg-3 { - margin-left: 25%; } - .offset-lg-4 { - margin-left: 33.33333333%; } - .offset-lg-5 { - margin-left: 41.66666667%; } - .offset-lg-6 { - margin-left: 50%; } - .offset-lg-7 { - margin-left: 58.33333333%; } - .offset-lg-8 { - margin-left: 66.66666667%; } - .offset-lg-9 { - margin-left: 75%; } - .offset-lg-10 { - margin-left: 83.33333333%; } - .offset-lg-11 { - margin-left: 91.66666667%; } } - -@media (min-width: 1200px) { - .col-xl { - flex-basis: 0; - flex-grow: 1; - max-width: 100%; } - .row-cols-xl-1 > * { - flex: 0 0 100%; - max-width: 100%; } - .row-cols-xl-2 > * { - flex: 0 0 50%; - max-width: 50%; } - .row-cols-xl-3 > * { - flex: 0 0 33.3333333333%; - max-width: 33.3333333333%; } - .row-cols-xl-4 > * { - flex: 0 0 25%; - max-width: 25%; } - .row-cols-xl-5 > * { - flex: 0 0 20%; - max-width: 20%; } - .row-cols-xl-6 > * { - flex: 0 0 16.6666666667%; - max-width: 16.6666666667%; } - .col-xl-auto { - flex: 0 0 auto; - width: auto; - max-width: 100%; } - .col-xl-1 { - flex: 0 0 8.33333333%; - max-width: 8.33333333%; } - .col-xl-2 { - flex: 0 0 16.66666667%; - max-width: 16.66666667%; } - .col-xl-3 { - flex: 0 0 25%; - max-width: 25%; } - .col-xl-4 { - flex: 0 0 33.33333333%; - max-width: 33.33333333%; } - .col-xl-5 { - flex: 0 0 41.66666667%; - max-width: 41.66666667%; } - .col-xl-6 { - flex: 0 0 50%; - max-width: 50%; } - .col-xl-7 { - flex: 0 0 58.33333333%; - max-width: 58.33333333%; } - .col-xl-8 { - flex: 0 0 66.66666667%; - max-width: 66.66666667%; } - .col-xl-9 { - flex: 0 0 75%; - max-width: 75%; } - .col-xl-10 { - flex: 0 0 83.33333333%; - max-width: 83.33333333%; } - .col-xl-11 { - flex: 0 0 91.66666667%; - max-width: 91.66666667%; } - .col-xl-12 { - flex: 0 0 100%; - max-width: 100%; } - .order-xl-first { - order: -1; } - .order-xl-last { - order: 13; } - .order-xl-0 { - order: 0; } - .order-xl-1 { - order: 1; } - .order-xl-2 { - order: 2; } - .order-xl-3 { - order: 3; } - .order-xl-4 { - order: 4; } - .order-xl-5 { - order: 5; } - .order-xl-6 { - order: 6; } - .order-xl-7 { - order: 7; } - .order-xl-8 { - order: 8; } - .order-xl-9 { - order: 9; } - .order-xl-10 { - order: 10; } - .order-xl-11 { - order: 11; } - .order-xl-12 { - order: 12; } - .offset-xl-0 { - margin-left: 0; } - .offset-xl-1 { - margin-left: 8.33333333%; } - .offset-xl-2 { - margin-left: 16.66666667%; } - .offset-xl-3 { - margin-left: 25%; } - .offset-xl-4 { - margin-left: 33.33333333%; } - .offset-xl-5 { - margin-left: 41.66666667%; } - .offset-xl-6 { - margin-left: 50%; } - .offset-xl-7 { - margin-left: 58.33333333%; } - .offset-xl-8 { - margin-left: 66.66666667%; } - .offset-xl-9 { - margin-left: 75%; } - .offset-xl-10 { - margin-left: 83.33333333%; } - .offset-xl-11 { - margin-left: 91.66666667%; } } - -.table { - width: 100%; - margin-bottom: 1rem; - color: #212529; } - .table th, - .table td { - padding: 0.75rem; - vertical-align: top; - border-top: 1px solid #dee2e6; } - .table thead th { - vertical-align: bottom; - border-bottom: 2px solid #dee2e6; } - .table tbody + tbody { - border-top: 2px solid #dee2e6; } - -.table-sm th, -.table-sm td { - padding: 0.3rem; } - -.table-bordered { - border: 1px solid #dee2e6; } - .table-bordered th, - .table-bordered td { - border: 1px solid #dee2e6; } - .table-bordered thead th, - .table-bordered thead td { - border-bottom-width: 2px; } - -.table-borderless th, -.table-borderless td, -.table-borderless thead th, -.table-borderless tbody + tbody { - border: 0; } - -.table-striped tbody tr:nth-of-type(odd) { - background-color: rgba(0, 0, 0, 0.05); } - -.table-hover tbody tr:hover { - color: #212529; - background-color: rgba(0, 0, 0, 0.075); } - -.table-primary, -.table-primary > th, -.table-primary > td { - background-color: #b8daff; } - -.table-primary th, -.table-primary td, -.table-primary thead th, -.table-primary tbody + tbody { - border-color: #7abaff; } - -.table-hover .table-primary:hover { - background-color: #9fcdff; } - .table-hover .table-primary:hover > td, - .table-hover .table-primary:hover > th { - background-color: #9fcdff; } - -.table-secondary, -.table-secondary > th, -.table-secondary > td { - background-color: #d6d8db; } - -.table-secondary th, -.table-secondary td, -.table-secondary thead th, -.table-secondary tbody + tbody { - border-color: #b3b7bb; } - -.table-hover .table-secondary:hover { - background-color: #c8cbcf; } - .table-hover .table-secondary:hover > td, - .table-hover .table-secondary:hover > th { - background-color: #c8cbcf; } - -.table-success, -.table-success > th, -.table-success > td { - background-color: #c3e6cb; } - -.table-success th, -.table-success td, -.table-success thead th, -.table-success tbody + tbody { - border-color: #8fd19e; } - -.table-hover .table-success:hover { - background-color: #b1dfbb; } - .table-hover .table-success:hover > td, - .table-hover .table-success:hover > th { - background-color: #b1dfbb; } - -.table-info, -.table-info > th, -.table-info > td { - background-color: #bee5eb; } - -.table-info th, -.table-info td, -.table-info thead th, -.table-info tbody + tbody { - border-color: #86cfda; } - -.table-hover .table-info:hover { - background-color: #abdde5; } - .table-hover .table-info:hover > td, - .table-hover .table-info:hover > th { - background-color: #abdde5; } - -.table-warning, -.table-warning > th, -.table-warning > td { - background-color: #ffeeba; } - -.table-warning th, -.table-warning td, -.table-warning thead th, -.table-warning tbody + tbody { - border-color: #ffdf7e; } - -.table-hover .table-warning:hover { - background-color: #ffe8a1; } - .table-hover .table-warning:hover > td, - .table-hover .table-warning:hover > th { - background-color: #ffe8a1; } - -.table-danger, -.table-danger > th, -.table-danger > td { - background-color: #f5c6cb; } - -.table-danger th, -.table-danger td, -.table-danger thead th, -.table-danger tbody + tbody { - border-color: #ed969e; } - -.table-hover .table-danger:hover { - background-color: #f1b0b7; } - .table-hover .table-danger:hover > td, - .table-hover .table-danger:hover > th { - background-color: #f1b0b7; } - -.table-light, -.table-light > th, -.table-light > td { - background-color: #fdfdfe; } - -.table-light th, -.table-light td, -.table-light thead th, -.table-light tbody + tbody { - border-color: #fbfcfc; } - -.table-hover .table-light:hover { - background-color: #ececf6; } - .table-hover .table-light:hover > td, - .table-hover .table-light:hover > th { - background-color: #ececf6; } - -.table-dark, -.table-dark > th, -.table-dark > td { - background-color: #c6c8ca; } - -.table-dark th, -.table-dark td, -.table-dark thead th, -.table-dark tbody + tbody { - border-color: #95999c; } - -.table-hover .table-dark:hover { - background-color: #b9bbbe; } - .table-hover .table-dark:hover > td, - .table-hover .table-dark:hover > th { - background-color: #b9bbbe; } - -.table-active, -.table-active > th, -.table-active > td { - background-color: rgba(0, 0, 0, 0.075); } - -.table-hover .table-active:hover { - background-color: rgba(0, 0, 0, 0.075); } - .table-hover .table-active:hover > td, - .table-hover .table-active:hover > th { - background-color: rgba(0, 0, 0, 0.075); } - -.table .thead-dark th { - color: #fff; - background-color: #343a40; - border-color: #454d55; } - -.table .thead-light th { - color: #495057; - background-color: #e9ecef; - border-color: #dee2e6; } - -.table-dark { - color: #fff; - background-color: #343a40; } - .table-dark th, - .table-dark td, - .table-dark thead th { - border-color: #454d55; } - .table-dark.table-bordered { - border: 0; } - .table-dark.table-striped tbody tr:nth-of-type(odd) { - background-color: rgba(255, 255, 255, 0.05); } - .table-dark.table-hover tbody tr:hover { - color: #fff; - background-color: rgba(255, 255, 255, 0.075); } - -@media (max-width: 575.98px) { - .table-responsive-sm { - display: block; - width: 100%; - overflow-x: auto; - -webkit-overflow-scrolling: touch; } - .table-responsive-sm > .table-bordered { - border: 0; } } - -@media (max-width: 767.98px) { - .table-responsive-md { - display: block; - width: 100%; - overflow-x: auto; - -webkit-overflow-scrolling: touch; } - .table-responsive-md > .table-bordered { - border: 0; } } - -@media (max-width: 991.98px) { - .table-responsive-lg { - display: block; - width: 100%; - overflow-x: auto; - -webkit-overflow-scrolling: touch; } - .table-responsive-lg > .table-bordered { - border: 0; } } - -@media (max-width: 1199.98px) { - .table-responsive-xl { - display: block; - width: 100%; - overflow-x: auto; - -webkit-overflow-scrolling: touch; } - .table-responsive-xl > .table-bordered { - border: 0; } } - -.table-responsive { - display: block; - width: 100%; - overflow-x: auto; - -webkit-overflow-scrolling: touch; } - .table-responsive > .table-bordered { - border: 0; } - -.form-control { - display: block; - width: 100%; - height: calc(1.5em + 0.75rem + 2px); - padding: 0.375rem 0.75rem; - font-size: 1rem; - font-weight: 400; - line-height: 1.5; - color: #495057; - background-color: #fff; - background-clip: padding-box; - border: 1px solid #ced4da; - border-radius: 0.25rem; - transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; } - @media (prefers-reduced-motion: reduce) { - .form-control { - transition: none; } } - .form-control::-ms-expand { - background-color: transparent; - border: 0; } - .form-control:focus { - color: #495057; - background-color: #fff; - border-color: #80bdff; - outline: 0; - box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25); } - .form-control::-moz-placeholder { - color: #6c757d; - opacity: 1; } - .form-control:-ms-input-placeholder { - color: #6c757d; - opacity: 1; } - .form-control::placeholder { - color: #6c757d; - opacity: 1; } - .form-control:disabled, .form-control[readonly] { - background-color: #e9ecef; - opacity: 1; } - -input[type="date"].form-control, -input[type="time"].form-control, -input[type="datetime-local"].form-control, -input[type="month"].form-control { - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; } - -select.form-control:-moz-focusring { - color: transparent; - text-shadow: 0 0 0 #495057; } - -select.form-control:focus::-ms-value { - color: #495057; - background-color: #fff; } - -.form-control-file, -.form-control-range { - display: block; - width: 100%; } - -.col-form-label { - padding-top: calc(0.375rem + 1px); - padding-bottom: calc(0.375rem + 1px); - margin-bottom: 0; - font-size: inherit; - line-height: 1.5; } - -.col-form-label-lg { - padding-top: calc(0.5rem + 1px); - padding-bottom: calc(0.5rem + 1px); - font-size: 1.25rem; - line-height: 1.5; } - -.col-form-label-sm { - padding-top: calc(0.25rem + 1px); - padding-bottom: calc(0.25rem + 1px); - font-size: 0.875rem; - line-height: 1.5; } - -.form-control-plaintext { - display: block; - width: 100%; - padding: 0.375rem 0; - margin-bottom: 0; - font-size: 1rem; - line-height: 1.5; - color: #212529; - background-color: transparent; - border: solid transparent; - border-width: 1px 0; } - .form-control-plaintext.form-control-sm, .form-control-plaintext.form-control-lg { - padding-right: 0; - padding-left: 0; } - -.form-control-sm { - height: calc(1.5em + 0.5rem + 2px); - padding: 0.25rem 0.5rem; - font-size: 0.875rem; - line-height: 1.5; - border-radius: 0.2rem; } - -.form-control-lg { - height: calc(1.5em + 1rem + 2px); - padding: 0.5rem 1rem; - font-size: 1.25rem; - line-height: 1.5; - border-radius: 0.3rem; } - -select.form-control[size], select.form-control[multiple] { - height: auto; } - -textarea.form-control { - height: auto; } - -.form-group { - margin-bottom: 1rem; } - -.form-text { - display: block; - margin-top: 0.25rem; } - -.form-row { - display: flex; - flex-wrap: wrap; - margin-right: -5px; - margin-left: -5px; } - .form-row > .col, - .form-row > [class*="col-"] { - padding-right: 5px; - padding-left: 5px; } - -.form-check { - position: relative; - display: block; - padding-left: 1.25rem; } - -.form-check-input { - position: absolute; - margin-top: 0.3rem; - margin-left: -1.25rem; } - .form-check-input[disabled] ~ .form-check-label, - .form-check-input:disabled ~ .form-check-label { - color: #6c757d; } - -.form-check-label { - margin-bottom: 0; } - -.form-check-inline { - display: inline-flex; - align-items: center; - padding-left: 0; - margin-right: 0.75rem; } - .form-check-inline .form-check-input { - position: static; - margin-top: 0; - margin-right: 0.3125rem; - margin-left: 0; } - -.valid-feedback { - display: none; - width: 100%; - margin-top: 0.25rem; - font-size: 80%; - color: #28a745; } - -.valid-tooltip { - position: absolute; - top: 100%; - left: 0; - z-index: 5; - display: none; - max-width: 100%; - padding: 0.25rem 0.5rem; - margin-top: .1rem; - font-size: 0.875rem; - line-height: 1.5; - color: #fff; - background-color: rgba(40, 167, 69, 0.9); - border-radius: 0.25rem; } - .form-row > .col > .valid-tooltip, - .form-row > [class*="col-"] > .valid-tooltip { - left: 5px; } - -.was-validated :valid ~ .valid-feedback, -.was-validated :valid ~ .valid-tooltip, -.is-valid ~ .valid-feedback, -.is-valid ~ .valid-tooltip { - display: block; } - -.was-validated .form-control:valid, .form-control.is-valid { - border-color: #28a745; - padding-right: calc(1.5em + 0.75rem) !important; - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e"); - background-repeat: no-repeat; - background-position: right calc(0.375em + 0.1875rem) center; - background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); } - .was-validated .form-control:valid:focus, .form-control.is-valid:focus { - border-color: #28a745; - box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25); } - -.was-validated select.form-control:valid, select.form-control.is-valid { - padding-right: 3rem !important; - background-position: right 1.5rem center; } - -.was-validated textarea.form-control:valid, textarea.form-control.is-valid { - padding-right: calc(1.5em + 0.75rem); - background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem); } - -.was-validated .custom-select:valid, .custom-select.is-valid { - border-color: #28a745; - padding-right: calc(0.75em + 2.3125rem) !important; - background: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") right 0.75rem center/8px 10px no-repeat, #fff url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e") center right 1.75rem/calc(0.75em + 0.375rem) calc(0.75em + 0.375rem) no-repeat; } - .was-validated .custom-select:valid:focus, .custom-select.is-valid:focus { - border-color: #28a745; - box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25); } - -.was-validated .form-check-input:valid ~ .form-check-label, .form-check-input.is-valid ~ .form-check-label { - color: #28a745; } - -.was-validated .form-check-input:valid ~ .valid-feedback, -.was-validated .form-check-input:valid ~ .valid-tooltip, .form-check-input.is-valid ~ .valid-feedback, -.form-check-input.is-valid ~ .valid-tooltip { - display: block; } - -.was-validated .custom-control-input:valid ~ .custom-control-label, .custom-control-input.is-valid ~ .custom-control-label { - color: #28a745; } - .was-validated .custom-control-input:valid ~ .custom-control-label::before, .custom-control-input.is-valid ~ .custom-control-label::before { - border-color: #28a745; } - -.was-validated .custom-control-input:valid:checked ~ .custom-control-label::before, .custom-control-input.is-valid:checked ~ .custom-control-label::before { - border-color: #34ce57; - background-color: #34ce57; } - -.was-validated .custom-control-input:valid:focus ~ .custom-control-label::before, .custom-control-input.is-valid:focus ~ .custom-control-label::before { - box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25); } - -.was-validated .custom-control-input:valid:focus:not(:checked) ~ .custom-control-label::before, .custom-control-input.is-valid:focus:not(:checked) ~ .custom-control-label::before { - border-color: #28a745; } - -.was-validated .custom-file-input:valid ~ .custom-file-label, .custom-file-input.is-valid ~ .custom-file-label { - border-color: #28a745; } - -.was-validated .custom-file-input:valid:focus ~ .custom-file-label, .custom-file-input.is-valid:focus ~ .custom-file-label { - border-color: #28a745; - box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25); } - -.invalid-feedback { - display: none; - width: 100%; - margin-top: 0.25rem; - font-size: 80%; - color: #dc3545; } - -.invalid-tooltip { - position: absolute; - top: 100%; - left: 0; - z-index: 5; - display: none; - max-width: 100%; - padding: 0.25rem 0.5rem; - margin-top: .1rem; - font-size: 0.875rem; - line-height: 1.5; - color: #fff; - background-color: rgba(220, 53, 69, 0.9); - border-radius: 0.25rem; } - .form-row > .col > .invalid-tooltip, - .form-row > [class*="col-"] > .invalid-tooltip { - left: 5px; } - -.was-validated :invalid ~ .invalid-feedback, -.was-validated :invalid ~ .invalid-tooltip, -.is-invalid ~ .invalid-feedback, -.is-invalid ~ .invalid-tooltip { - display: block; } - -.was-validated .form-control:invalid, .form-control.is-invalid { - border-color: #dc3545; - padding-right: calc(1.5em + 0.75rem) !important; - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e"); - background-repeat: no-repeat; - background-position: right calc(0.375em + 0.1875rem) center; - background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); } - .was-validated .form-control:invalid:focus, .form-control.is-invalid:focus { - border-color: #dc3545; - box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25); } - -.was-validated select.form-control:invalid, select.form-control.is-invalid { - padding-right: 3rem !important; - background-position: right 1.5rem center; } - -.was-validated textarea.form-control:invalid, textarea.form-control.is-invalid { - padding-right: calc(1.5em + 0.75rem); - background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem); } - -.was-validated .custom-select:invalid, .custom-select.is-invalid { - border-color: #dc3545; - padding-right: calc(0.75em + 2.3125rem) !important; - background: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") right 0.75rem center/8px 10px no-repeat, #fff url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e") center right 1.75rem/calc(0.75em + 0.375rem) calc(0.75em + 0.375rem) no-repeat; } - .was-validated .custom-select:invalid:focus, .custom-select.is-invalid:focus { - border-color: #dc3545; - box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25); } - -.was-validated .form-check-input:invalid ~ .form-check-label, .form-check-input.is-invalid ~ .form-check-label { - color: #dc3545; } - -.was-validated .form-check-input:invalid ~ .invalid-feedback, -.was-validated .form-check-input:invalid ~ .invalid-tooltip, .form-check-input.is-invalid ~ .invalid-feedback, -.form-check-input.is-invalid ~ .invalid-tooltip { - display: block; } - -.was-validated .custom-control-input:invalid ~ .custom-control-label, .custom-control-input.is-invalid ~ .custom-control-label { - color: #dc3545; } - .was-validated .custom-control-input:invalid ~ .custom-control-label::before, .custom-control-input.is-invalid ~ .custom-control-label::before { - border-color: #dc3545; } - -.was-validated .custom-control-input:invalid:checked ~ .custom-control-label::before, .custom-control-input.is-invalid:checked ~ .custom-control-label::before { - border-color: #e4606d; - background-color: #e4606d; } - -.was-validated .custom-control-input:invalid:focus ~ .custom-control-label::before, .custom-control-input.is-invalid:focus ~ .custom-control-label::before { - box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25); } - -.was-validated .custom-control-input:invalid:focus:not(:checked) ~ .custom-control-label::before, .custom-control-input.is-invalid:focus:not(:checked) ~ .custom-control-label::before { - border-color: #dc3545; } - -.was-validated .custom-file-input:invalid ~ .custom-file-label, .custom-file-input.is-invalid ~ .custom-file-label { - border-color: #dc3545; } - -.was-validated .custom-file-input:invalid:focus ~ .custom-file-label, .custom-file-input.is-invalid:focus ~ .custom-file-label { - border-color: #dc3545; - box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25); } - -.form-inline { - display: flex; - flex-flow: row wrap; - align-items: center; } - .form-inline .form-check { - width: 100%; } - @media (min-width: 576px) { - .form-inline label { - display: flex; - align-items: center; - justify-content: center; - margin-bottom: 0; } - .form-inline .form-group { - display: flex; - flex: 0 0 auto; - flex-flow: row wrap; - align-items: center; - margin-bottom: 0; } - .form-inline .form-control { - display: inline-block; - width: auto; - vertical-align: middle; } - .form-inline .form-control-plaintext { - display: inline-block; } - .form-inline .input-group, - .form-inline .custom-select { - width: auto; } - .form-inline .form-check { - display: flex; - align-items: center; - justify-content: center; - width: auto; - padding-left: 0; } - .form-inline .form-check-input { - position: relative; - flex-shrink: 0; - margin-top: 0; - margin-right: 0.25rem; - margin-left: 0; } - .form-inline .custom-control { - align-items: center; - justify-content: center; } - .form-inline .custom-control-label { - margin-bottom: 0; } } - -.btn { - display: inline-block; - font-weight: 400; - color: #212529; - text-align: center; - vertical-align: middle; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - background-color: transparent; - border: 1px solid transparent; - padding: 0.375rem 0.75rem; - font-size: 1rem; - line-height: 1.5; - border-radius: 0.25rem; - transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; } - @media (prefers-reduced-motion: reduce) { - .btn { - transition: none; } } - .btn:hover { - color: #212529; - text-decoration: none; } - .btn:focus, .btn.focus { - outline: 0; - box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25); } - .btn.disabled, .btn:disabled { - opacity: 0.65; } - .btn:not(:disabled):not(.disabled) { - cursor: pointer; } - -a.btn.disabled, -fieldset:disabled a.btn { - pointer-events: none; } - -.btn-primary { - color: #fff; - background-color: #007bff; - border-color: #007bff; } - .btn-primary:hover { - color: #fff; - background-color: #0069d9; - border-color: #0062cc; } - .btn-primary:focus, .btn-primary.focus { - color: #fff; - background-color: #0069d9; - border-color: #0062cc; - box-shadow: 0 0 0 0.2rem rgba(38, 143, 255, 0.5); } - .btn-primary.disabled, .btn-primary:disabled { - color: #fff; - background-color: #007bff; - border-color: #007bff; } - .btn-primary:not(:disabled):not(.disabled):active, .btn-primary:not(:disabled):not(.disabled).active, - .show > .btn-primary.dropdown-toggle { - color: #fff; - background-color: #0062cc; - border-color: #005cbf; } - .btn-primary:not(:disabled):not(.disabled):active:focus, .btn-primary:not(:disabled):not(.disabled).active:focus, - .show > .btn-primary.dropdown-toggle:focus { - box-shadow: 0 0 0 0.2rem rgba(38, 143, 255, 0.5); } - -.btn-secondary { - color: #fff; - background-color: #6c757d; - border-color: #6c757d; } - .btn-secondary:hover { - color: #fff; - background-color: #5a6268; - border-color: #545b62; } - .btn-secondary:focus, .btn-secondary.focus { - color: #fff; - background-color: #5a6268; - border-color: #545b62; - box-shadow: 0 0 0 0.2rem rgba(130, 138, 145, 0.5); } - .btn-secondary.disabled, .btn-secondary:disabled { - color: #fff; - background-color: #6c757d; - border-color: #6c757d; } - .btn-secondary:not(:disabled):not(.disabled):active, .btn-secondary:not(:disabled):not(.disabled).active, - .show > .btn-secondary.dropdown-toggle { - color: #fff; - background-color: #545b62; - border-color: #4e555b; } - .btn-secondary:not(:disabled):not(.disabled):active:focus, .btn-secondary:not(:disabled):not(.disabled).active:focus, - .show > .btn-secondary.dropdown-toggle:focus { - box-shadow: 0 0 0 0.2rem rgba(130, 138, 145, 0.5); } - -.btn-success { - color: #fff; - background-color: #28a745; - border-color: #28a745; } - .btn-success:hover { - color: #fff; - background-color: #218838; - border-color: #1e7e34; } - .btn-success:focus, .btn-success.focus { - color: #fff; - background-color: #218838; - border-color: #1e7e34; - box-shadow: 0 0 0 0.2rem rgba(72, 180, 97, 0.5); } - .btn-success.disabled, .btn-success:disabled { - color: #fff; - background-color: #28a745; - border-color: #28a745; } - .btn-success:not(:disabled):not(.disabled):active, .btn-success:not(:disabled):not(.disabled).active, - .show > .btn-success.dropdown-toggle { - color: #fff; - background-color: #1e7e34; - border-color: #1c7430; } - .btn-success:not(:disabled):not(.disabled):active:focus, .btn-success:not(:disabled):not(.disabled).active:focus, - .show > .btn-success.dropdown-toggle:focus { - box-shadow: 0 0 0 0.2rem rgba(72, 180, 97, 0.5); } - -.btn-info { - color: #fff; - background-color: #17a2b8; - border-color: #17a2b8; } - .btn-info:hover { - color: #fff; - background-color: #138496; - border-color: #117a8b; } - .btn-info:focus, .btn-info.focus { - color: #fff; - background-color: #138496; - border-color: #117a8b; - box-shadow: 0 0 0 0.2rem rgba(58, 176, 195, 0.5); } - .btn-info.disabled, .btn-info:disabled { - color: #fff; - background-color: #17a2b8; - border-color: #17a2b8; } - .btn-info:not(:disabled):not(.disabled):active, .btn-info:not(:disabled):not(.disabled).active, - .show > .btn-info.dropdown-toggle { - color: #fff; - background-color: #117a8b; - border-color: #10707f; } - .btn-info:not(:disabled):not(.disabled):active:focus, .btn-info:not(:disabled):not(.disabled).active:focus, - .show > .btn-info.dropdown-toggle:focus { - box-shadow: 0 0 0 0.2rem rgba(58, 176, 195, 0.5); } - -.btn-warning { - color: #212529; - background-color: #ffc107; - border-color: #ffc107; } - .btn-warning:hover { - color: #212529; - background-color: #e0a800; - border-color: #d39e00; } - .btn-warning:focus, .btn-warning.focus { - color: #212529; - background-color: #e0a800; - border-color: #d39e00; - box-shadow: 0 0 0 0.2rem rgba(222, 170, 12, 0.5); } - .btn-warning.disabled, .btn-warning:disabled { - color: #212529; - background-color: #ffc107; - border-color: #ffc107; } - .btn-warning:not(:disabled):not(.disabled):active, .btn-warning:not(:disabled):not(.disabled).active, - .show > .btn-warning.dropdown-toggle { - color: #212529; - background-color: #d39e00; - border-color: #c69500; } - .btn-warning:not(:disabled):not(.disabled):active:focus, .btn-warning:not(:disabled):not(.disabled).active:focus, - .show > .btn-warning.dropdown-toggle:focus { - box-shadow: 0 0 0 0.2rem rgba(222, 170, 12, 0.5); } - -.btn-danger { - color: #fff; - background-color: #dc3545; - border-color: #dc3545; } - .btn-danger:hover { - color: #fff; - background-color: #c82333; - border-color: #bd2130; } - .btn-danger:focus, .btn-danger.focus { - color: #fff; - background-color: #c82333; - border-color: #bd2130; - box-shadow: 0 0 0 0.2rem rgba(225, 83, 97, 0.5); } - .btn-danger.disabled, .btn-danger:disabled { - color: #fff; - background-color: #dc3545; - border-color: #dc3545; } - .btn-danger:not(:disabled):not(.disabled):active, .btn-danger:not(:disabled):not(.disabled).active, - .show > .btn-danger.dropdown-toggle { - color: #fff; - background-color: #bd2130; - border-color: #b21f2d; } - .btn-danger:not(:disabled):not(.disabled):active:focus, .btn-danger:not(:disabled):not(.disabled).active:focus, - .show > .btn-danger.dropdown-toggle:focus { - box-shadow: 0 0 0 0.2rem rgba(225, 83, 97, 0.5); } - -.btn-light { - color: #212529; - background-color: #f8f9fa; - border-color: #f8f9fa; } - .btn-light:hover { - color: #212529; - background-color: #e2e6ea; - border-color: #dae0e5; } - .btn-light:focus, .btn-light.focus { - color: #212529; - background-color: #e2e6ea; - border-color: #dae0e5; - box-shadow: 0 0 0 0.2rem rgba(216, 217, 219, 0.5); } - .btn-light.disabled, .btn-light:disabled { - color: #212529; - background-color: #f8f9fa; - border-color: #f8f9fa; } - .btn-light:not(:disabled):not(.disabled):active, .btn-light:not(:disabled):not(.disabled).active, - .show > .btn-light.dropdown-toggle { - color: #212529; - background-color: #dae0e5; - border-color: #d3d9df; } - .btn-light:not(:disabled):not(.disabled):active:focus, .btn-light:not(:disabled):not(.disabled).active:focus, - .show > .btn-light.dropdown-toggle:focus { - box-shadow: 0 0 0 0.2rem rgba(216, 217, 219, 0.5); } - -.btn-dark { - color: #fff; - background-color: #343a40; - border-color: #343a40; } - .btn-dark:hover { - color: #fff; - background-color: #23272b; - border-color: #1d2124; } - .btn-dark:focus, .btn-dark.focus { - color: #fff; - background-color: #23272b; - border-color: #1d2124; - box-shadow: 0 0 0 0.2rem rgba(82, 88, 93, 0.5); } - .btn-dark.disabled, .btn-dark:disabled { - color: #fff; - background-color: #343a40; - border-color: #343a40; } - .btn-dark:not(:disabled):not(.disabled):active, .btn-dark:not(:disabled):not(.disabled).active, - .show > .btn-dark.dropdown-toggle { - color: #fff; - background-color: #1d2124; - border-color: #171a1d; } - .btn-dark:not(:disabled):not(.disabled):active:focus, .btn-dark:not(:disabled):not(.disabled).active:focus, - .show > .btn-dark.dropdown-toggle:focus { - box-shadow: 0 0 0 0.2rem rgba(82, 88, 93, 0.5); } - -.btn-outline-primary { - color: #007bff; - border-color: #007bff; } - .btn-outline-primary:hover { - color: #fff; - background-color: #007bff; - border-color: #007bff; } - .btn-outline-primary:focus, .btn-outline-primary.focus { - box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5); } - .btn-outline-primary.disabled, .btn-outline-primary:disabled { - color: #007bff; - background-color: transparent; } - .btn-outline-primary:not(:disabled):not(.disabled):active, .btn-outline-primary:not(:disabled):not(.disabled).active, - .show > .btn-outline-primary.dropdown-toggle { - color: #fff; - background-color: #007bff; - border-color: #007bff; } - .btn-outline-primary:not(:disabled):not(.disabled):active:focus, .btn-outline-primary:not(:disabled):not(.disabled).active:focus, - .show > .btn-outline-primary.dropdown-toggle:focus { - box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5); } - -.btn-outline-secondary { - color: #6c757d; - border-color: #6c757d; } - .btn-outline-secondary:hover { - color: #fff; - background-color: #6c757d; - border-color: #6c757d; } - .btn-outline-secondary:focus, .btn-outline-secondary.focus { - box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5); } - .btn-outline-secondary.disabled, .btn-outline-secondary:disabled { - color: #6c757d; - background-color: transparent; } - .btn-outline-secondary:not(:disabled):not(.disabled):active, .btn-outline-secondary:not(:disabled):not(.disabled).active, - .show > .btn-outline-secondary.dropdown-toggle { - color: #fff; - background-color: #6c757d; - border-color: #6c757d; } - .btn-outline-secondary:not(:disabled):not(.disabled):active:focus, .btn-outline-secondary:not(:disabled):not(.disabled).active:focus, - .show > .btn-outline-secondary.dropdown-toggle:focus { - box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5); } - -.btn-outline-success { - color: #28a745; - border-color: #28a745; } - .btn-outline-success:hover { - color: #fff; - background-color: #28a745; - border-color: #28a745; } - .btn-outline-success:focus, .btn-outline-success.focus { - box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5); } - .btn-outline-success.disabled, .btn-outline-success:disabled { - color: #28a745; - background-color: transparent; } - .btn-outline-success:not(:disabled):not(.disabled):active, .btn-outline-success:not(:disabled):not(.disabled).active, - .show > .btn-outline-success.dropdown-toggle { - color: #fff; - background-color: #28a745; - border-color: #28a745; } - .btn-outline-success:not(:disabled):not(.disabled):active:focus, .btn-outline-success:not(:disabled):not(.disabled).active:focus, - .show > .btn-outline-success.dropdown-toggle:focus { - box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5); } - -.btn-outline-info { - color: #17a2b8; - border-color: #17a2b8; } - .btn-outline-info:hover { - color: #fff; - background-color: #17a2b8; - border-color: #17a2b8; } - .btn-outline-info:focus, .btn-outline-info.focus { - box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5); } - .btn-outline-info.disabled, .btn-outline-info:disabled { - color: #17a2b8; - background-color: transparent; } - .btn-outline-info:not(:disabled):not(.disabled):active, .btn-outline-info:not(:disabled):not(.disabled).active, - .show > .btn-outline-info.dropdown-toggle { - color: #fff; - background-color: #17a2b8; - border-color: #17a2b8; } - .btn-outline-info:not(:disabled):not(.disabled):active:focus, .btn-outline-info:not(:disabled):not(.disabled).active:focus, - .show > .btn-outline-info.dropdown-toggle:focus { - box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5); } - -.btn-outline-warning { - color: #ffc107; - border-color: #ffc107; } - .btn-outline-warning:hover { - color: #212529; - background-color: #ffc107; - border-color: #ffc107; } - .btn-outline-warning:focus, .btn-outline-warning.focus { - box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5); } - .btn-outline-warning.disabled, .btn-outline-warning:disabled { - color: #ffc107; - background-color: transparent; } - .btn-outline-warning:not(:disabled):not(.disabled):active, .btn-outline-warning:not(:disabled):not(.disabled).active, - .show > .btn-outline-warning.dropdown-toggle { - color: #212529; - background-color: #ffc107; - border-color: #ffc107; } - .btn-outline-warning:not(:disabled):not(.disabled):active:focus, .btn-outline-warning:not(:disabled):not(.disabled).active:focus, - .show > .btn-outline-warning.dropdown-toggle:focus { - box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5); } - -.btn-outline-danger { - color: #dc3545; - border-color: #dc3545; } - .btn-outline-danger:hover { - color: #fff; - background-color: #dc3545; - border-color: #dc3545; } - .btn-outline-danger:focus, .btn-outline-danger.focus { - box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5); } - .btn-outline-danger.disabled, .btn-outline-danger:disabled { - color: #dc3545; - background-color: transparent; } - .btn-outline-danger:not(:disabled):not(.disabled):active, .btn-outline-danger:not(:disabled):not(.disabled).active, - .show > .btn-outline-danger.dropdown-toggle { - color: #fff; - background-color: #dc3545; - border-color: #dc3545; } - .btn-outline-danger:not(:disabled):not(.disabled):active:focus, .btn-outline-danger:not(:disabled):not(.disabled).active:focus, - .show > .btn-outline-danger.dropdown-toggle:focus { - box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5); } - -.btn-outline-light { - color: #f8f9fa; - border-color: #f8f9fa; } - .btn-outline-light:hover { - color: #212529; - background-color: #f8f9fa; - border-color: #f8f9fa; } - .btn-outline-light:focus, .btn-outline-light.focus { - box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5); } - .btn-outline-light.disabled, .btn-outline-light:disabled { - color: #f8f9fa; - background-color: transparent; } - .btn-outline-light:not(:disabled):not(.disabled):active, .btn-outline-light:not(:disabled):not(.disabled).active, - .show > .btn-outline-light.dropdown-toggle { - color: #212529; - background-color: #f8f9fa; - border-color: #f8f9fa; } - .btn-outline-light:not(:disabled):not(.disabled):active:focus, .btn-outline-light:not(:disabled):not(.disabled).active:focus, - .show > .btn-outline-light.dropdown-toggle:focus { - box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5); } - -.btn-outline-dark { - color: #343a40; - border-color: #343a40; } - .btn-outline-dark:hover { - color: #fff; - background-color: #343a40; - border-color: #343a40; } - .btn-outline-dark:focus, .btn-outline-dark.focus { - box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5); } - .btn-outline-dark.disabled, .btn-outline-dark:disabled { - color: #343a40; - background-color: transparent; } - .btn-outline-dark:not(:disabled):not(.disabled):active, .btn-outline-dark:not(:disabled):not(.disabled).active, - .show > .btn-outline-dark.dropdown-toggle { - color: #fff; - background-color: #343a40; - border-color: #343a40; } - .btn-outline-dark:not(:disabled):not(.disabled):active:focus, .btn-outline-dark:not(:disabled):not(.disabled).active:focus, - .show > .btn-outline-dark.dropdown-toggle:focus { - box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5); } - -.btn-link { - font-weight: 400; - color: #007bff; - text-decoration: none; } - .btn-link:hover { - color: #0056b3; - text-decoration: underline; } - .btn-link:focus, .btn-link.focus { - text-decoration: underline; } - .btn-link:disabled, .btn-link.disabled { - color: #6c757d; - pointer-events: none; } - -.btn-lg, .btn-group-lg > .btn { - padding: 0.5rem 1rem; - font-size: 1.25rem; - line-height: 1.5; - border-radius: 0.3rem; } - -.btn-sm, .btn-group-sm > .btn { - padding: 0.25rem 0.5rem; - font-size: 0.875rem; - line-height: 1.5; - border-radius: 0.2rem; } - -.btn-block { - display: block; - width: 100%; } - .btn-block + .btn-block { - margin-top: 0.5rem; } - -input[type="submit"].btn-block, -input[type="reset"].btn-block, -input[type="button"].btn-block { - width: 100%; } - -.fade { - transition: opacity 0.15s linear; } - @media (prefers-reduced-motion: reduce) { - .fade { - transition: none; } } - .fade:not(.show) { - opacity: 0; } - -.collapse:not(.show) { - display: none; } - -.collapsing { - position: relative; - height: 0; - overflow: hidden; - transition: height 0.35s ease; } - @media (prefers-reduced-motion: reduce) { - .collapsing { - transition: none; } } - -.dropup, -.dropright, -.dropdown, -.dropleft { - position: relative; } - -.dropdown-toggle { - white-space: nowrap; } - .dropdown-toggle::after { - display: inline-block; - margin-left: 0.255em; - vertical-align: 0.255em; - content: ""; - border-top: 0.3em solid; - border-right: 0.3em solid transparent; - border-bottom: 0; - border-left: 0.3em solid transparent; } - .dropdown-toggle:empty::after { - margin-left: 0; } - -.dropdown-menu { - position: absolute; - top: 100%; - left: 0; - z-index: 1000; - display: none; - float: left; - min-width: 10rem; - padding: 0.5rem 0; - margin: 0.125rem 0 0; - font-size: 1rem; - color: #212529; - text-align: left; - list-style: none; - background-color: #fff; - background-clip: padding-box; - border: 1px solid rgba(0, 0, 0, 0.15); - border-radius: 0.25rem; } - -.dropdown-menu-left { - right: auto; - left: 0; } - -.dropdown-menu-right { - right: 0; - left: auto; } - -@media (min-width: 576px) { - .dropdown-menu-sm-left { - right: auto; - left: 0; } - .dropdown-menu-sm-right { - right: 0; - left: auto; } } - -@media (min-width: 768px) { - .dropdown-menu-md-left { - right: auto; - left: 0; } - .dropdown-menu-md-right { - right: 0; - left: auto; } } - -@media (min-width: 992px) { - .dropdown-menu-lg-left { - right: auto; - left: 0; } - .dropdown-menu-lg-right { - right: 0; - left: auto; } } - -@media (min-width: 1200px) { - .dropdown-menu-xl-left { - right: auto; - left: 0; } - .dropdown-menu-xl-right { - right: 0; - left: auto; } } - -.dropup .dropdown-menu { - top: auto; - bottom: 100%; - margin-top: 0; - margin-bottom: 0.125rem; } - -.dropup .dropdown-toggle::after { - display: inline-block; - margin-left: 0.255em; - vertical-align: 0.255em; - content: ""; - border-top: 0; - border-right: 0.3em solid transparent; - border-bottom: 0.3em solid; - border-left: 0.3em solid transparent; } - -.dropup .dropdown-toggle:empty::after { - margin-left: 0; } - -.dropright .dropdown-menu { - top: 0; - right: auto; - left: 100%; - margin-top: 0; - margin-left: 0.125rem; } - -.dropright .dropdown-toggle::after { - display: inline-block; - margin-left: 0.255em; - vertical-align: 0.255em; - content: ""; - border-top: 0.3em solid transparent; - border-right: 0; - border-bottom: 0.3em solid transparent; - border-left: 0.3em solid; } - -.dropright .dropdown-toggle:empty::after { - margin-left: 0; } - -.dropright .dropdown-toggle::after { - vertical-align: 0; } - -.dropleft .dropdown-menu { - top: 0; - right: 100%; - left: auto; - margin-top: 0; - margin-right: 0.125rem; } - -.dropleft .dropdown-toggle::after { - display: inline-block; - margin-left: 0.255em; - vertical-align: 0.255em; - content: ""; } - -.dropleft .dropdown-toggle::after { - display: none; } - -.dropleft .dropdown-toggle::before { - display: inline-block; - margin-right: 0.255em; - vertical-align: 0.255em; - content: ""; - border-top: 0.3em solid transparent; - border-right: 0.3em solid; - border-bottom: 0.3em solid transparent; } - -.dropleft .dropdown-toggle:empty::after { - margin-left: 0; } - -.dropleft .dropdown-toggle::before { - vertical-align: 0; } - -.dropdown-menu[x-placement^="top"], .dropdown-menu[x-placement^="right"], .dropdown-menu[x-placement^="bottom"], .dropdown-menu[x-placement^="left"] { - right: auto; - bottom: auto; } - -.dropdown-divider { - height: 0; - margin: 0.5rem 0; - overflow: hidden; - border-top: 1px solid #e9ecef; } - -.dropdown-item { - display: block; - width: 100%; - padding: 0.25rem 1.5rem; - clear: both; - font-weight: 400; - color: #212529; - text-align: inherit; - white-space: nowrap; - background-color: transparent; - border: 0; } - .dropdown-item:hover, .dropdown-item:focus { - color: #16181b; - text-decoration: none; - background-color: #e9ecef; } - .dropdown-item.active, .dropdown-item:active { - color: #fff; - text-decoration: none; - background-color: #007bff; } - .dropdown-item.disabled, .dropdown-item:disabled { - color: #adb5bd; - pointer-events: none; - background-color: transparent; } - -.dropdown-menu.show { - display: block; } - -.dropdown-header { - display: block; - padding: 0.5rem 1.5rem; - margin-bottom: 0; - font-size: 0.875rem; - color: #6c757d; - white-space: nowrap; } - -.dropdown-item-text { - display: block; - padding: 0.25rem 1.5rem; - color: #212529; } - -.btn-group, -.btn-group-vertical { - position: relative; - display: inline-flex; - vertical-align: middle; } - .btn-group > .btn, - .btn-group-vertical > .btn { - position: relative; - flex: 1 1 auto; } - .btn-group > .btn:hover, - .btn-group-vertical > .btn:hover { - z-index: 1; } - .btn-group > .btn:focus, .btn-group > .btn:active, .btn-group > .btn.active, - .btn-group-vertical > .btn:focus, - .btn-group-vertical > .btn:active, - .btn-group-vertical > .btn.active { - z-index: 1; } - -.btn-toolbar { - display: flex; - flex-wrap: wrap; - justify-content: flex-start; } - .btn-toolbar .input-group { - width: auto; } - -.btn-group > .btn:not(:first-child), -.btn-group > .btn-group:not(:first-child) { - margin-left: -1px; } - -.btn-group > .btn:not(:last-child):not(.dropdown-toggle), -.btn-group > .btn-group:not(:last-child) > .btn { - border-top-right-radius: 0; - border-bottom-right-radius: 0; } - -.btn-group > .btn:not(:first-child), -.btn-group > .btn-group:not(:first-child) > .btn { - border-top-left-radius: 0; - border-bottom-left-radius: 0; } - -.dropdown-toggle-split { - padding-right: 0.5625rem; - padding-left: 0.5625rem; } - .dropdown-toggle-split::after, - .dropup .dropdown-toggle-split::after, - .dropright .dropdown-toggle-split::after { - margin-left: 0; } - .dropleft .dropdown-toggle-split::before { - margin-right: 0; } - -.btn-sm + .dropdown-toggle-split, .btn-group-sm > .btn + .dropdown-toggle-split { - padding-right: 0.375rem; - padding-left: 0.375rem; } - -.btn-lg + .dropdown-toggle-split, .btn-group-lg > .btn + .dropdown-toggle-split { - padding-right: 0.75rem; - padding-left: 0.75rem; } - -.btn-group-vertical { - flex-direction: column; - align-items: flex-start; - justify-content: center; } - .btn-group-vertical > .btn, - .btn-group-vertical > .btn-group { - width: 100%; } - .btn-group-vertical > .btn:not(:first-child), - .btn-group-vertical > .btn-group:not(:first-child) { - margin-top: -1px; } - .btn-group-vertical > .btn:not(:last-child):not(.dropdown-toggle), - .btn-group-vertical > .btn-group:not(:last-child) > .btn { - border-bottom-right-radius: 0; - border-bottom-left-radius: 0; } - .btn-group-vertical > .btn:not(:first-child), - .btn-group-vertical > .btn-group:not(:first-child) > .btn { - border-top-left-radius: 0; - border-top-right-radius: 0; } - -.btn-group-toggle > .btn, -.btn-group-toggle > .btn-group > .btn { - margin-bottom: 0; } - .btn-group-toggle > .btn input[type="radio"], - .btn-group-toggle > .btn input[type="checkbox"], - .btn-group-toggle > .btn-group > .btn input[type="radio"], - .btn-group-toggle > .btn-group > .btn input[type="checkbox"] { - position: absolute; - clip: rect(0, 0, 0, 0); - pointer-events: none; } - -.input-group { - position: relative; - display: flex; - flex-wrap: wrap; - align-items: stretch; - width: 100%; } - .input-group > .form-control, - .input-group > .form-control-plaintext, - .input-group > .custom-select, - .input-group > .custom-file { - position: relative; - flex: 1 1 auto; - width: 1%; - min-width: 0; - margin-bottom: 0; } - .input-group > .form-control + .form-control, - .input-group > .form-control + .custom-select, - .input-group > .form-control + .custom-file, - .input-group > .form-control-plaintext + .form-control, - .input-group > .form-control-plaintext + .custom-select, - .input-group > .form-control-plaintext + .custom-file, - .input-group > .custom-select + .form-control, - .input-group > .custom-select + .custom-select, - .input-group > .custom-select + .custom-file, - .input-group > .custom-file + .form-control, - .input-group > .custom-file + .custom-select, - .input-group > .custom-file + .custom-file { - margin-left: -1px; } - .input-group > .form-control:focus, - .input-group > .custom-select:focus, - .input-group > .custom-file .custom-file-input:focus ~ .custom-file-label { - z-index: 3; } - .input-group > .custom-file .custom-file-input:focus { - z-index: 4; } - .input-group > .form-control:not(:first-child), - .input-group > .custom-select:not(:first-child) { - border-top-left-radius: 0; - border-bottom-left-radius: 0; } - .input-group > .custom-file { - display: flex; - align-items: center; } - .input-group > .custom-file:not(:last-child) .custom-file-label, - .input-group > .custom-file:not(:last-child) .custom-file-label::after { - border-top-right-radius: 0; - border-bottom-right-radius: 0; } - .input-group > .custom-file:not(:first-child) .custom-file-label { - border-top-left-radius: 0; - border-bottom-left-radius: 0; } - .input-group:not(.has-validation) > .form-control:not(:last-child), - .input-group:not(.has-validation) > .custom-select:not(:last-child), - .input-group:not(.has-validation) > .custom-file:not(:last-child) .custom-file-label, - .input-group:not(.has-validation) > .custom-file:not(:last-child) .custom-file-label::after { - border-top-right-radius: 0; - border-bottom-right-radius: 0; } - .input-group.has-validation > .form-control:nth-last-child(n + 3), - .input-group.has-validation > .custom-select:nth-last-child(n + 3), - .input-group.has-validation > .custom-file:nth-last-child(n + 3) .custom-file-label, - .input-group.has-validation > .custom-file:nth-last-child(n + 3) .custom-file-label::after { - border-top-right-radius: 0; - border-bottom-right-radius: 0; } - -.input-group-prepend, -.input-group-append { - display: flex; } - .input-group-prepend .btn, - .input-group-append .btn { - position: relative; - z-index: 2; } - .input-group-prepend .btn:focus, - .input-group-append .btn:focus { - z-index: 3; } - .input-group-prepend .btn + .btn, - .input-group-prepend .btn + .input-group-text, - .input-group-prepend .input-group-text + .input-group-text, - .input-group-prepend .input-group-text + .btn, - .input-group-append .btn + .btn, - .input-group-append .btn + .input-group-text, - .input-group-append .input-group-text + .input-group-text, - .input-group-append .input-group-text + .btn { - margin-left: -1px; } - -.input-group-prepend { - margin-right: -1px; } - -.input-group-append { - margin-left: -1px; } - -.input-group-text { - display: flex; - align-items: center; - padding: 0.375rem 0.75rem; - margin-bottom: 0; - font-size: 1rem; - font-weight: 400; - line-height: 1.5; - color: #495057; - text-align: center; - white-space: nowrap; - background-color: #e9ecef; - border: 1px solid #ced4da; - border-radius: 0.25rem; } - .input-group-text input[type="radio"], - .input-group-text input[type="checkbox"] { - margin-top: 0; } - -.input-group-lg > .form-control:not(textarea), -.input-group-lg > .custom-select { - height: calc(1.5em + 1rem + 2px); } - -.input-group-lg > .form-control, -.input-group-lg > .custom-select, -.input-group-lg > .input-group-prepend > .input-group-text, -.input-group-lg > .input-group-append > .input-group-text, -.input-group-lg > .input-group-prepend > .btn, -.input-group-lg > .input-group-append > .btn { - padding: 0.5rem 1rem; - font-size: 1.25rem; - line-height: 1.5; - border-radius: 0.3rem; } - -.input-group-sm > .form-control:not(textarea), -.input-group-sm > .custom-select { - height: calc(1.5em + 0.5rem + 2px); } - -.input-group-sm > .form-control, -.input-group-sm > .custom-select, -.input-group-sm > .input-group-prepend > .input-group-text, -.input-group-sm > .input-group-append > .input-group-text, -.input-group-sm > .input-group-prepend > .btn, -.input-group-sm > .input-group-append > .btn { - padding: 0.25rem 0.5rem; - font-size: 0.875rem; - line-height: 1.5; - border-radius: 0.2rem; } - -.input-group-lg > .custom-select, -.input-group-sm > .custom-select { - padding-right: 1.75rem; } - -.input-group > .input-group-prepend > .btn, -.input-group > .input-group-prepend > .input-group-text, -.input-group:not(.has-validation) > .input-group-append:not(:last-child) > .btn, -.input-group:not(.has-validation) > .input-group-append:not(:last-child) > .input-group-text, -.input-group.has-validation > .input-group-append:nth-last-child(n + 3) > .btn, -.input-group.has-validation > .input-group-append:nth-last-child(n + 3) > .input-group-text, -.input-group > .input-group-append:last-child > .btn:not(:last-child):not(.dropdown-toggle), -.input-group > .input-group-append:last-child > .input-group-text:not(:last-child) { - border-top-right-radius: 0; - border-bottom-right-radius: 0; } - -.input-group > .input-group-append > .btn, -.input-group > .input-group-append > .input-group-text, -.input-group > .input-group-prepend:not(:first-child) > .btn, -.input-group > .input-group-prepend:not(:first-child) > .input-group-text, -.input-group > .input-group-prepend:first-child > .btn:not(:first-child), -.input-group > .input-group-prepend:first-child > .input-group-text:not(:first-child) { - border-top-left-radius: 0; - border-bottom-left-radius: 0; } - -.custom-control { - position: relative; - z-index: 1; - display: block; - min-height: 1.5rem; - padding-left: 1.5rem; - -webkit-print-color-adjust: exact; - color-adjust: exact; } - -.custom-control-inline { - display: inline-flex; - margin-right: 1rem; } - -.custom-control-input { - position: absolute; - left: 0; - z-index: -1; - width: 1rem; - height: 1.25rem; - opacity: 0; } - .custom-control-input:checked ~ .custom-control-label::before { - color: #fff; - border-color: #007bff; - background-color: #007bff; } - .custom-control-input:focus ~ .custom-control-label::before { - box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25); } - .custom-control-input:focus:not(:checked) ~ .custom-control-label::before { - border-color: #80bdff; } - .custom-control-input:not(:disabled):active ~ .custom-control-label::before { - color: #fff; - background-color: #b3d7ff; - border-color: #b3d7ff; } - .custom-control-input[disabled] ~ .custom-control-label, .custom-control-input:disabled ~ .custom-control-label { - color: #6c757d; } - .custom-control-input[disabled] ~ .custom-control-label::before, .custom-control-input:disabled ~ .custom-control-label::before { - background-color: #e9ecef; } - -.custom-control-label { - position: relative; - margin-bottom: 0; - vertical-align: top; } - .custom-control-label::before { - position: absolute; - top: 0.25rem; - left: -1.5rem; - display: block; - width: 1rem; - height: 1rem; - pointer-events: none; - content: ""; - background-color: #fff; - border: #adb5bd solid 1px; } - .custom-control-label::after { - position: absolute; - top: 0.25rem; - left: -1.5rem; - display: block; - width: 1rem; - height: 1rem; - content: ""; - background: 50% / 50% 50% no-repeat; } - -.custom-checkbox .custom-control-label::before { - border-radius: 0.25rem; } - -.custom-checkbox .custom-control-input:checked ~ .custom-control-label::after { - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26l2.974 2.99L8 2.193z'/%3e%3c/svg%3e"); } - -.custom-checkbox .custom-control-input:indeterminate ~ .custom-control-label::before { - border-color: #007bff; - background-color: #007bff; } - -.custom-checkbox .custom-control-input:indeterminate ~ .custom-control-label::after { - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4' viewBox='0 0 4 4'%3e%3cpath stroke='%23fff' d='M0 2h4'/%3e%3c/svg%3e"); } - -.custom-checkbox .custom-control-input:disabled:checked ~ .custom-control-label::before { - background-color: rgba(0, 123, 255, 0.5); } - -.custom-checkbox .custom-control-input:disabled:indeterminate ~ .custom-control-label::before { - background-color: rgba(0, 123, 255, 0.5); } - -.custom-radio .custom-control-label::before { - border-radius: 50%; } - -.custom-radio .custom-control-input:checked ~ .custom-control-label::after { - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e"); } - -.custom-radio .custom-control-input:disabled:checked ~ .custom-control-label::before { - background-color: rgba(0, 123, 255, 0.5); } - -.custom-switch { - padding-left: 2.25rem; } - .custom-switch .custom-control-label::before { - left: -2.25rem; - width: 1.75rem; - pointer-events: all; - border-radius: 0.5rem; } - .custom-switch .custom-control-label::after { - top: calc(0.25rem + 2px); - left: calc(-2.25rem + 2px); - width: calc(1rem - 4px); - height: calc(1rem - 4px); - background-color: #adb5bd; - border-radius: 0.5rem; - transition: transform 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; } - @media (prefers-reduced-motion: reduce) { - .custom-switch .custom-control-label::after { - transition: none; } } - .custom-switch .custom-control-input:checked ~ .custom-control-label::after { - background-color: #fff; - transform: translateX(0.75rem); } - .custom-switch .custom-control-input:disabled:checked ~ .custom-control-label::before { - background-color: rgba(0, 123, 255, 0.5); } - -.custom-select { - display: inline-block; - width: 100%; - height: calc(1.5em + 0.75rem + 2px); - padding: 0.375rem 1.75rem 0.375rem 0.75rem; - font-size: 1rem; - font-weight: 400; - line-height: 1.5; - color: #495057; - vertical-align: middle; - background: #fff url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") right 0.75rem center/8px 10px no-repeat; - border: 1px solid #ced4da; - border-radius: 0.25rem; - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; } - .custom-select:focus { - border-color: #80bdff; - outline: 0; - box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25); } - .custom-select:focus::-ms-value { - color: #495057; - background-color: #fff; } - .custom-select[multiple], .custom-select[size]:not([size="1"]) { - height: auto; - padding-right: 0.75rem; - background-image: none; } - .custom-select:disabled { - color: #6c757d; - background-color: #e9ecef; } - .custom-select::-ms-expand { - display: none; } - .custom-select:-moz-focusring { - color: transparent; - text-shadow: 0 0 0 #495057; } - -.custom-select-sm { - height: calc(1.5em + 0.5rem + 2px); - padding-top: 0.25rem; - padding-bottom: 0.25rem; - padding-left: 0.5rem; - font-size: 0.875rem; } - -.custom-select-lg { - height: calc(1.5em + 1rem + 2px); - padding-top: 0.5rem; - padding-bottom: 0.5rem; - padding-left: 1rem; - font-size: 1.25rem; } - -.custom-file { - position: relative; - display: inline-block; - width: 100%; - height: calc(1.5em + 0.75rem + 2px); - margin-bottom: 0; } - -.custom-file-input { - position: relative; - z-index: 2; - width: 100%; - height: calc(1.5em + 0.75rem + 2px); - margin: 0; - overflow: hidden; - opacity: 0; } - .custom-file-input:focus ~ .custom-file-label { - border-color: #80bdff; - box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25); } - .custom-file-input[disabled] ~ .custom-file-label, - .custom-file-input:disabled ~ .custom-file-label { - background-color: #e9ecef; } - .custom-file-input:lang(en) ~ .custom-file-label::after { - content: "Browse"; } - .custom-file-input ~ .custom-file-label[data-browse]::after { - content: attr(data-browse); } - -.custom-file-label { - position: absolute; - top: 0; - right: 0; - left: 0; - z-index: 1; - height: calc(1.5em + 0.75rem + 2px); - padding: 0.375rem 0.75rem; - overflow: hidden; - font-weight: 400; - line-height: 1.5; - color: #495057; - background-color: #fff; - border: 1px solid #ced4da; - border-radius: 0.25rem; } - .custom-file-label::after { - position: absolute; - top: 0; - right: 0; - bottom: 0; - z-index: 3; - display: block; - height: calc(1.5em + 0.75rem); - padding: 0.375rem 0.75rem; - line-height: 1.5; - color: #495057; - content: "Browse"; - background-color: #e9ecef; - border-left: inherit; - border-radius: 0 0.25rem 0.25rem 0; } - -.custom-range { - width: 100%; - height: 1.4rem; - padding: 0; - background-color: transparent; - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; } - .custom-range:focus { - outline: 0; } - .custom-range:focus::-webkit-slider-thumb { - box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(0, 123, 255, 0.25); } - .custom-range:focus::-moz-range-thumb { - box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(0, 123, 255, 0.25); } - .custom-range:focus::-ms-thumb { - box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(0, 123, 255, 0.25); } - .custom-range::-moz-focus-outer { - border: 0; } - .custom-range::-webkit-slider-thumb { - width: 1rem; - height: 1rem; - margin-top: -0.25rem; - background-color: #007bff; - border: 0; - border-radius: 1rem; - -webkit-transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; - transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; - -webkit-appearance: none; - appearance: none; } - @media (prefers-reduced-motion: reduce) { - .custom-range::-webkit-slider-thumb { - -webkit-transition: none; - transition: none; } } - .custom-range::-webkit-slider-thumb:active { - background-color: #b3d7ff; } - .custom-range::-webkit-slider-runnable-track { - width: 100%; - height: 0.5rem; - color: transparent; - cursor: pointer; - background-color: #dee2e6; - border-color: transparent; - border-radius: 1rem; } - .custom-range::-moz-range-thumb { - width: 1rem; - height: 1rem; - background-color: #007bff; - border: 0; - border-radius: 1rem; - -moz-transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; - transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; - -moz-appearance: none; - appearance: none; } - @media (prefers-reduced-motion: reduce) { - .custom-range::-moz-range-thumb { - -moz-transition: none; - transition: none; } } - .custom-range::-moz-range-thumb:active { - background-color: #b3d7ff; } - .custom-range::-moz-range-track { - width: 100%; - height: 0.5rem; - color: transparent; - cursor: pointer; - background-color: #dee2e6; - border-color: transparent; - border-radius: 1rem; } - .custom-range::-ms-thumb { - width: 1rem; - height: 1rem; - margin-top: 0; - margin-right: 0.2rem; - margin-left: 0.2rem; - background-color: #007bff; - border: 0; - border-radius: 1rem; - -ms-transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; - transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; - appearance: none; } - @media (prefers-reduced-motion: reduce) { - .custom-range::-ms-thumb { - -ms-transition: none; - transition: none; } } - .custom-range::-ms-thumb:active { - background-color: #b3d7ff; } - .custom-range::-ms-track { - width: 100%; - height: 0.5rem; - color: transparent; - cursor: pointer; - background-color: transparent; - border-color: transparent; - border-width: 0.5rem; } - .custom-range::-ms-fill-lower { - background-color: #dee2e6; - border-radius: 1rem; } - .custom-range::-ms-fill-upper { - margin-right: 15px; - background-color: #dee2e6; - border-radius: 1rem; } - .custom-range:disabled::-webkit-slider-thumb { - background-color: #adb5bd; } - .custom-range:disabled::-webkit-slider-runnable-track { - cursor: default; } - .custom-range:disabled::-moz-range-thumb { - background-color: #adb5bd; } - .custom-range:disabled::-moz-range-track { - cursor: default; } - .custom-range:disabled::-ms-thumb { - background-color: #adb5bd; } - -.custom-control-label::before, -.custom-file-label, -.custom-select { - transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; } - @media (prefers-reduced-motion: reduce) { - .custom-control-label::before, - .custom-file-label, - .custom-select { - transition: none; } } - -.nav { - display: flex; - flex-wrap: wrap; - padding-left: 0; - margin-bottom: 0; - list-style: none; } - -.nav-link { - display: block; - padding: 0.5rem 1rem; } - .nav-link:hover, .nav-link:focus { - text-decoration: none; } - .nav-link.disabled { - color: #6c757d; - pointer-events: none; - cursor: default; } - -.nav-tabs { - border-bottom: 1px solid #dee2e6; } - .nav-tabs .nav-link { - margin-bottom: -1px; - border: 1px solid transparent; - border-top-left-radius: 0.25rem; - border-top-right-radius: 0.25rem; } - .nav-tabs .nav-link:hover, .nav-tabs .nav-link:focus { - border-color: #e9ecef #e9ecef #dee2e6; } - .nav-tabs .nav-link.disabled { - color: #6c757d; - background-color: transparent; - border-color: transparent; } - .nav-tabs .nav-link.active, - .nav-tabs .nav-item.show .nav-link { - color: #495057; - background-color: #fff; - border-color: #dee2e6 #dee2e6 #fff; } - .nav-tabs .dropdown-menu { - margin-top: -1px; - border-top-left-radius: 0; - border-top-right-radius: 0; } - -.nav-pills .nav-link { - border-radius: 0.25rem; } - -.nav-pills .nav-link.active, -.nav-pills .show > .nav-link { - color: #fff; - background-color: #007bff; } - -.nav-fill > .nav-link, -.nav-fill .nav-item { - flex: 1 1 auto; - text-align: center; } - -.nav-justified > .nav-link, -.nav-justified .nav-item { - flex-basis: 0; - flex-grow: 1; - text-align: center; } - -.tab-content > .tab-pane { - display: none; } - -.tab-content > .active { - display: block; } - -.navbar { - position: relative; - display: flex; - flex-wrap: wrap; - align-items: center; - justify-content: space-between; - padding: 0.5rem 1rem; } - .navbar .container, - .navbar .container-fluid, .navbar .container-sm, .navbar .container-md, .navbar .container-lg, .navbar .container-xl { - display: flex; - flex-wrap: wrap; - align-items: center; - justify-content: space-between; } - -.navbar-brand { - display: inline-block; - padding-top: 0.3125rem; - padding-bottom: 0.3125rem; - margin-right: 1rem; - font-size: 1.25rem; - line-height: inherit; - white-space: nowrap; } - .navbar-brand:hover, .navbar-brand:focus { - text-decoration: none; } - -.navbar-nav { - display: flex; - flex-direction: column; - padding-left: 0; - margin-bottom: 0; - list-style: none; } - .navbar-nav .nav-link { - padding-right: 0; - padding-left: 0; } - .navbar-nav .dropdown-menu { - position: static; - float: none; } - -.navbar-text { - display: inline-block; - padding-top: 0.5rem; - padding-bottom: 0.5rem; } - -.navbar-collapse { - flex-basis: 100%; - flex-grow: 1; - align-items: center; } - -.navbar-toggler { - padding: 0.25rem 0.75rem; - font-size: 1.25rem; - line-height: 1; - background-color: transparent; - border: 1px solid transparent; - border-radius: 0.25rem; } - .navbar-toggler:hover, .navbar-toggler:focus { - text-decoration: none; } - -.navbar-toggler-icon { - display: inline-block; - width: 1.5em; - height: 1.5em; - vertical-align: middle; - content: ""; - background: 50% / 100% 100% no-repeat; } - -.navbar-nav-scroll { - max-height: 75vh; - overflow-y: auto; } - -@media (max-width: 575.98px) { - .navbar-expand-sm > .container, - .navbar-expand-sm > .container-fluid, .navbar-expand-sm > .container-sm, .navbar-expand-sm > .container-md, .navbar-expand-sm > .container-lg, .navbar-expand-sm > .container-xl { - padding-right: 0; - padding-left: 0; } } - -@media (min-width: 576px) { - .navbar-expand-sm { - flex-flow: row nowrap; - justify-content: flex-start; } - .navbar-expand-sm .navbar-nav { - flex-direction: row; } - .navbar-expand-sm .navbar-nav .dropdown-menu { - position: absolute; } - .navbar-expand-sm .navbar-nav .nav-link { - padding-right: 0.5rem; - padding-left: 0.5rem; } - .navbar-expand-sm > .container, - .navbar-expand-sm > .container-fluid, .navbar-expand-sm > .container-sm, .navbar-expand-sm > .container-md, .navbar-expand-sm > .container-lg, .navbar-expand-sm > .container-xl { - flex-wrap: nowrap; } - .navbar-expand-sm .navbar-nav-scroll { - overflow: visible; } - .navbar-expand-sm .navbar-collapse { - display: flex !important; - flex-basis: auto; } - .navbar-expand-sm .navbar-toggler { - display: none; } } - -@media (max-width: 767.98px) { - .navbar-expand-md > .container, - .navbar-expand-md > .container-fluid, .navbar-expand-md > .container-sm, .navbar-expand-md > .container-md, .navbar-expand-md > .container-lg, .navbar-expand-md > .container-xl { - padding-right: 0; - padding-left: 0; } } - -@media (min-width: 768px) { - .navbar-expand-md { - flex-flow: row nowrap; - justify-content: flex-start; } - .navbar-expand-md .navbar-nav { - flex-direction: row; } - .navbar-expand-md .navbar-nav .dropdown-menu { - position: absolute; } - .navbar-expand-md .navbar-nav .nav-link { - padding-right: 0.5rem; - padding-left: 0.5rem; } - .navbar-expand-md > .container, - .navbar-expand-md > .container-fluid, .navbar-expand-md > .container-sm, .navbar-expand-md > .container-md, .navbar-expand-md > .container-lg, .navbar-expand-md > .container-xl { - flex-wrap: nowrap; } - .navbar-expand-md .navbar-nav-scroll { - overflow: visible; } - .navbar-expand-md .navbar-collapse { - display: flex !important; - flex-basis: auto; } - .navbar-expand-md .navbar-toggler { - display: none; } } - -@media (max-width: 991.98px) { - .navbar-expand-lg > .container, - .navbar-expand-lg > .container-fluid, .navbar-expand-lg > .container-sm, .navbar-expand-lg > .container-md, .navbar-expand-lg > .container-lg, .navbar-expand-lg > .container-xl { - padding-right: 0; - padding-left: 0; } } - -@media (min-width: 992px) { - .navbar-expand-lg { - flex-flow: row nowrap; - justify-content: flex-start; } - .navbar-expand-lg .navbar-nav { - flex-direction: row; } - .navbar-expand-lg .navbar-nav .dropdown-menu { - position: absolute; } - .navbar-expand-lg .navbar-nav .nav-link { - padding-right: 0.5rem; - padding-left: 0.5rem; } - .navbar-expand-lg > .container, - .navbar-expand-lg > .container-fluid, .navbar-expand-lg > .container-sm, .navbar-expand-lg > .container-md, .navbar-expand-lg > .container-lg, .navbar-expand-lg > .container-xl { - flex-wrap: nowrap; } - .navbar-expand-lg .navbar-nav-scroll { - overflow: visible; } - .navbar-expand-lg .navbar-collapse { - display: flex !important; - flex-basis: auto; } - .navbar-expand-lg .navbar-toggler { - display: none; } } - -@media (max-width: 1199.98px) { - .navbar-expand-xl > .container, - .navbar-expand-xl > .container-fluid, .navbar-expand-xl > .container-sm, .navbar-expand-xl > .container-md, .navbar-expand-xl > .container-lg, .navbar-expand-xl > .container-xl { - padding-right: 0; - padding-left: 0; } } - -@media (min-width: 1200px) { - .navbar-expand-xl { - flex-flow: row nowrap; - justify-content: flex-start; } - .navbar-expand-xl .navbar-nav { - flex-direction: row; } - .navbar-expand-xl .navbar-nav .dropdown-menu { - position: absolute; } - .navbar-expand-xl .navbar-nav .nav-link { - padding-right: 0.5rem; - padding-left: 0.5rem; } - .navbar-expand-xl > .container, - .navbar-expand-xl > .container-fluid, .navbar-expand-xl > .container-sm, .navbar-expand-xl > .container-md, .navbar-expand-xl > .container-lg, .navbar-expand-xl > .container-xl { - flex-wrap: nowrap; } - .navbar-expand-xl .navbar-nav-scroll { - overflow: visible; } - .navbar-expand-xl .navbar-collapse { - display: flex !important; - flex-basis: auto; } - .navbar-expand-xl .navbar-toggler { - display: none; } } - -.navbar-expand { - flex-flow: row nowrap; - justify-content: flex-start; } - .navbar-expand > .container, - .navbar-expand > .container-fluid, .navbar-expand > .container-sm, .navbar-expand > .container-md, .navbar-expand > .container-lg, .navbar-expand > .container-xl { - padding-right: 0; - padding-left: 0; } - .navbar-expand .navbar-nav { - flex-direction: row; } - .navbar-expand .navbar-nav .dropdown-menu { - position: absolute; } - .navbar-expand .navbar-nav .nav-link { - padding-right: 0.5rem; - padding-left: 0.5rem; } - .navbar-expand > .container, - .navbar-expand > .container-fluid, .navbar-expand > .container-sm, .navbar-expand > .container-md, .navbar-expand > .container-lg, .navbar-expand > .container-xl { - flex-wrap: nowrap; } - .navbar-expand .navbar-nav-scroll { - overflow: visible; } - .navbar-expand .navbar-collapse { - display: flex !important; - flex-basis: auto; } - .navbar-expand .navbar-toggler { - display: none; } - -.navbar-light .navbar-brand { - color: rgba(0, 0, 0, 0.9); } - .navbar-light .navbar-brand:hover, .navbar-light .navbar-brand:focus { - color: rgba(0, 0, 0, 0.9); } - -.navbar-light .navbar-nav .nav-link { - color: rgba(0, 0, 0, 0.5); } - .navbar-light .navbar-nav .nav-link:hover, .navbar-light .navbar-nav .nav-link:focus { - color: rgba(0, 0, 0, 0.7); } - .navbar-light .navbar-nav .nav-link.disabled { - color: rgba(0, 0, 0, 0.3); } - -.navbar-light .navbar-nav .show > .nav-link, -.navbar-light .navbar-nav .active > .nav-link, -.navbar-light .navbar-nav .nav-link.show, -.navbar-light .navbar-nav .nav-link.active { - color: rgba(0, 0, 0, 0.9); } - -.navbar-light .navbar-toggler { - color: rgba(0, 0, 0, 0.5); - border-color: rgba(0, 0, 0, 0.1); } - -.navbar-light .navbar-toggler-icon { - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%280, 0, 0, 0.5%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e"); } - -.navbar-light .navbar-text { - color: rgba(0, 0, 0, 0.5); } - .navbar-light .navbar-text a { - color: rgba(0, 0, 0, 0.9); } - .navbar-light .navbar-text a:hover, .navbar-light .navbar-text a:focus { - color: rgba(0, 0, 0, 0.9); } - -.navbar-dark .navbar-brand { - color: #fff; } - .navbar-dark .navbar-brand:hover, .navbar-dark .navbar-brand:focus { - color: #fff; } - -.navbar-dark .navbar-nav .nav-link { - color: rgba(255, 255, 255, 0.5); } - .navbar-dark .navbar-nav .nav-link:hover, .navbar-dark .navbar-nav .nav-link:focus { - color: rgba(255, 255, 255, 0.75); } - .navbar-dark .navbar-nav .nav-link.disabled { - color: rgba(255, 255, 255, 0.25); } - -.navbar-dark .navbar-nav .show > .nav-link, -.navbar-dark .navbar-nav .active > .nav-link, -.navbar-dark .navbar-nav .nav-link.show, -.navbar-dark .navbar-nav .nav-link.active { - color: #fff; } - -.navbar-dark .navbar-toggler { - color: rgba(255, 255, 255, 0.5); - border-color: rgba(255, 255, 255, 0.1); } - -.navbar-dark .navbar-toggler-icon { - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.5%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e"); } - -.navbar-dark .navbar-text { - color: rgba(255, 255, 255, 0.5); } - .navbar-dark .navbar-text a { - color: #fff; } - .navbar-dark .navbar-text a:hover, .navbar-dark .navbar-text a:focus { - color: #fff; } - -.card { - position: relative; - display: flex; - flex-direction: column; - min-width: 0; - word-wrap: break-word; - background-color: #fff; - background-clip: border-box; - border: 1px solid rgba(0, 0, 0, 0.125); - border-radius: 0.25rem; } - .card > hr { - margin-right: 0; - margin-left: 0; } - .card > .list-group { - border-top: inherit; - border-bottom: inherit; } - .card > .list-group:first-child { - border-top-width: 0; - border-top-left-radius: calc(0.25rem - 1px); - border-top-right-radius: calc(0.25rem - 1px); } - .card > .list-group:last-child { - border-bottom-width: 0; - border-bottom-right-radius: calc(0.25rem - 1px); - border-bottom-left-radius: calc(0.25rem - 1px); } - .card > .card-header + .list-group, - .card > .list-group + .card-footer { - border-top: 0; } - -.card-body { - flex: 1 1 auto; - min-height: 1px; - padding: 1.25rem; } - -.card-title { - margin-bottom: 0.75rem; } - -.card-subtitle { - margin-top: -0.375rem; - margin-bottom: 0; } - -.card-text:last-child { - margin-bottom: 0; } - -.card-link:hover { - text-decoration: none; } - -.card-link + .card-link { - margin-left: 1.25rem; } - -.card-header { - padding: 0.75rem 1.25rem; - margin-bottom: 0; - background-color: rgba(0, 0, 0, 0.03); - border-bottom: 1px solid rgba(0, 0, 0, 0.125); } - .card-header:first-child { - border-radius: calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0; } - -.card-footer { - padding: 0.75rem 1.25rem; - background-color: rgba(0, 0, 0, 0.03); - border-top: 1px solid rgba(0, 0, 0, 0.125); } - .card-footer:last-child { - border-radius: 0 0 calc(0.25rem - 1px) calc(0.25rem - 1px); } - -.card-header-tabs { - margin-right: -0.625rem; - margin-bottom: -0.75rem; - margin-left: -0.625rem; - border-bottom: 0; } - -.card-header-pills { - margin-right: -0.625rem; - margin-left: -0.625rem; } - -.card-img-overlay { - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; - padding: 1.25rem; - border-radius: calc(0.25rem - 1px); } - -.card-img, -.card-img-top, -.card-img-bottom { - flex-shrink: 0; - width: 100%; } - -.card-img, -.card-img-top { - border-top-left-radius: calc(0.25rem - 1px); - border-top-right-radius: calc(0.25rem - 1px); } - -.card-img, -.card-img-bottom { - border-bottom-right-radius: calc(0.25rem - 1px); - border-bottom-left-radius: calc(0.25rem - 1px); } - -.card-deck .card { - margin-bottom: 15px; } - -@media (min-width: 576px) { - .card-deck { - display: flex; - flex-flow: row wrap; - margin-right: -15px; - margin-left: -15px; } - .card-deck .card { - flex: 1 0 0%; - margin-right: 15px; - margin-bottom: 0; - margin-left: 15px; } } - -.card-group > .card { - margin-bottom: 15px; } - -@media (min-width: 576px) { - .card-group { - display: flex; - flex-flow: row wrap; } - .card-group > .card { - flex: 1 0 0%; - margin-bottom: 0; } - .card-group > .card + .card { - margin-left: 0; - border-left: 0; } - .card-group > .card:not(:last-child) { - border-top-right-radius: 0; - border-bottom-right-radius: 0; } - .card-group > .card:not(:last-child) .card-img-top, - .card-group > .card:not(:last-child) .card-header { - border-top-right-radius: 0; } - .card-group > .card:not(:last-child) .card-img-bottom, - .card-group > .card:not(:last-child) .card-footer { - border-bottom-right-radius: 0; } - .card-group > .card:not(:first-child) { - border-top-left-radius: 0; - border-bottom-left-radius: 0; } - .card-group > .card:not(:first-child) .card-img-top, - .card-group > .card:not(:first-child) .card-header { - border-top-left-radius: 0; } - .card-group > .card:not(:first-child) .card-img-bottom, - .card-group > .card:not(:first-child) .card-footer { - border-bottom-left-radius: 0; } } - -.card-columns .card { - margin-bottom: 0.75rem; } - -@media (min-width: 576px) { - .card-columns { - -moz-column-count: 3; - column-count: 3; - -moz-column-gap: 1.25rem; - column-gap: 1.25rem; - orphans: 1; - widows: 1; } - .card-columns .card { - display: inline-block; - width: 100%; } } - -.accordion { - overflow-anchor: none; } - .accordion > .card { - overflow: hidden; } - .accordion > .card:not(:last-of-type) { - border-bottom: 0; - border-bottom-right-radius: 0; - border-bottom-left-radius: 0; } - .accordion > .card:not(:first-of-type) { - border-top-left-radius: 0; - border-top-right-radius: 0; } - .accordion > .card > .card-header { - border-radius: 0; - margin-bottom: -1px; } - -.breadcrumb { - display: flex; - flex-wrap: wrap; - padding: 0.75rem 1rem; - margin-bottom: 1rem; - list-style: none; - background-color: #e9ecef; - border-radius: 0.25rem; } - -.breadcrumb-item + .breadcrumb-item { - padding-left: 0.5rem; } - .breadcrumb-item + .breadcrumb-item::before { - float: left; - padding-right: 0.5rem; - color: #6c757d; - content: "/"; } - -.breadcrumb-item + .breadcrumb-item:hover::before { - text-decoration: underline; } - -.breadcrumb-item + .breadcrumb-item:hover::before { - text-decoration: none; } - -.breadcrumb-item.active { - color: #6c757d; } - -.pagination { - display: flex; - padding-left: 0; - list-style: none; - border-radius: 0.25rem; } - -.page-link { - position: relative; - display: block; - padding: 0.5rem 0.75rem; - margin-left: -1px; - line-height: 1.25; - color: #007bff; - background-color: #fff; - border: 1px solid #dee2e6; } - .page-link:hover { - z-index: 2; - color: #0056b3; - text-decoration: none; - background-color: #e9ecef; - border-color: #dee2e6; } - .page-link:focus { - z-index: 3; - outline: 0; - box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25); } - -.page-item:first-child .page-link { - margin-left: 0; - border-top-left-radius: 0.25rem; - border-bottom-left-radius: 0.25rem; } - -.page-item:last-child .page-link { - border-top-right-radius: 0.25rem; - border-bottom-right-radius: 0.25rem; } - -.page-item.active .page-link { - z-index: 3; - color: #fff; - background-color: #007bff; - border-color: #007bff; } - -.page-item.disabled .page-link { - color: #6c757d; - pointer-events: none; - cursor: auto; - background-color: #fff; - border-color: #dee2e6; } - -.pagination-lg .page-link { - padding: 0.75rem 1.5rem; - font-size: 1.25rem; - line-height: 1.5; } - -.pagination-lg .page-item:first-child .page-link { - border-top-left-radius: 0.3rem; - border-bottom-left-radius: 0.3rem; } - -.pagination-lg .page-item:last-child .page-link { - border-top-right-radius: 0.3rem; - border-bottom-right-radius: 0.3rem; } - -.pagination-sm .page-link { - padding: 0.25rem 0.5rem; - font-size: 0.875rem; - line-height: 1.5; } - -.pagination-sm .page-item:first-child .page-link { - border-top-left-radius: 0.2rem; - border-bottom-left-radius: 0.2rem; } - -.pagination-sm .page-item:last-child .page-link { - border-top-right-radius: 0.2rem; - border-bottom-right-radius: 0.2rem; } - -.badge { - display: inline-block; - padding: 0.25em 0.4em; - font-size: 75%; - font-weight: 700; - line-height: 1; - text-align: center; - white-space: nowrap; - vertical-align: baseline; - border-radius: 0.25rem; - transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; } - @media (prefers-reduced-motion: reduce) { - .badge { - transition: none; } } - a.badge:hover, a.badge:focus { - text-decoration: none; } - .badge:empty { - display: none; } - -.btn .badge { - position: relative; - top: -1px; } - -.badge-pill { - padding-right: 0.6em; - padding-left: 0.6em; - border-radius: 10rem; } - -.badge-primary { - color: #fff; - background-color: #007bff; } - a.badge-primary:hover, a.badge-primary:focus { - color: #fff; - background-color: #0062cc; } - a.badge-primary:focus, a.badge-primary.focus { - outline: 0; - box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5); } - -.badge-secondary { - color: #fff; - background-color: #6c757d; } - a.badge-secondary:hover, a.badge-secondary:focus { - color: #fff; - background-color: #545b62; } - a.badge-secondary:focus, a.badge-secondary.focus { - outline: 0; - box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5); } - -.badge-success { - color: #fff; - background-color: #28a745; } - a.badge-success:hover, a.badge-success:focus { - color: #fff; - background-color: #1e7e34; } - a.badge-success:focus, a.badge-success.focus { - outline: 0; - box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5); } - -.badge-info { - color: #fff; - background-color: #17a2b8; } - a.badge-info:hover, a.badge-info:focus { - color: #fff; - background-color: #117a8b; } - a.badge-info:focus, a.badge-info.focus { - outline: 0; - box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5); } - -.badge-warning { - color: #212529; - background-color: #ffc107; } - a.badge-warning:hover, a.badge-warning:focus { - color: #212529; - background-color: #d39e00; } - a.badge-warning:focus, a.badge-warning.focus { - outline: 0; - box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5); } - -.badge-danger { - color: #fff; - background-color: #dc3545; } - a.badge-danger:hover, a.badge-danger:focus { - color: #fff; - background-color: #bd2130; } - a.badge-danger:focus, a.badge-danger.focus { - outline: 0; - box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5); } - -.badge-light { - color: #212529; - background-color: #f8f9fa; } - a.badge-light:hover, a.badge-light:focus { - color: #212529; - background-color: #dae0e5; } - a.badge-light:focus, a.badge-light.focus { - outline: 0; - box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5); } - -.badge-dark { - color: #fff; - background-color: #343a40; } - a.badge-dark:hover, a.badge-dark:focus { - color: #fff; - background-color: #1d2124; } - a.badge-dark:focus, a.badge-dark.focus { - outline: 0; - box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5); } - -.jumbotron { - padding: 2rem 1rem; - margin-bottom: 2rem; - background-color: #e9ecef; - border-radius: 0.3rem; } - @media (min-width: 576px) { - .jumbotron { - padding: 4rem 2rem; } } - -.jumbotron-fluid { - padding-right: 0; - padding-left: 0; - border-radius: 0; } - -.alert { - position: relative; - padding: 0.75rem 1.25rem; - margin-bottom: 1rem; - border: 1px solid transparent; - border-radius: 0.25rem; } - -.alert-heading { - color: inherit; } - -.alert-link { - font-weight: 700; } - -.alert-dismissible { - padding-right: 4rem; } - .alert-dismissible .close { - position: absolute; - top: 0; - right: 0; - z-index: 2; - padding: 0.75rem 1.25rem; - color: inherit; } - -.alert-primary { - color: #004085; - background-color: #cce5ff; - border-color: #b8daff; } - .alert-primary hr { - border-top-color: #9fcdff; } - .alert-primary .alert-link { - color: #002752; } - -.alert-secondary { - color: #383d41; - background-color: #e2e3e5; - border-color: #d6d8db; } - .alert-secondary hr { - border-top-color: #c8cbcf; } - .alert-secondary .alert-link { - color: #202326; } - -.alert-success { - color: #155724; - background-color: #d4edda; - border-color: #c3e6cb; } - .alert-success hr { - border-top-color: #b1dfbb; } - .alert-success .alert-link { - color: #0b2e13; } - -.alert-info { - color: #0c5460; - background-color: #d1ecf1; - border-color: #bee5eb; } - .alert-info hr { - border-top-color: #abdde5; } - .alert-info .alert-link { - color: #062c33; } - -.alert-warning { - color: #856404; - background-color: #fff3cd; - border-color: #ffeeba; } - .alert-warning hr { - border-top-color: #ffe8a1; } - .alert-warning .alert-link { - color: #533f03; } - -.alert-danger { - color: #721c24; - background-color: #f8d7da; - border-color: #f5c6cb; } - .alert-danger hr { - border-top-color: #f1b0b7; } - .alert-danger .alert-link { - color: #491217; } - -.alert-light { - color: #818182; - background-color: #fefefe; - border-color: #fdfdfe; } - .alert-light hr { - border-top-color: #ececf6; } - .alert-light .alert-link { - color: #686868; } - -.alert-dark { - color: #1b1e21; - background-color: #d6d8d9; - border-color: #c6c8ca; } - .alert-dark hr { - border-top-color: #b9bbbe; } - .alert-dark .alert-link { - color: #040505; } - -@-webkit-keyframes progress-bar-stripes { - from { - background-position: 1rem 0; } - to { - background-position: 0 0; } } - -@keyframes progress-bar-stripes { - from { - background-position: 1rem 0; } - to { - background-position: 0 0; } } - -.progress { - display: flex; - height: 1rem; - overflow: hidden; - line-height: 0; - font-size: 0.75rem; - background-color: #e9ecef; - border-radius: 0.25rem; } - -.progress-bar { - display: flex; - flex-direction: column; - justify-content: center; - overflow: hidden; - color: #fff; - text-align: center; - white-space: nowrap; - background-color: #007bff; - transition: width 0.6s ease; } - @media (prefers-reduced-motion: reduce) { - .progress-bar { - transition: none; } } - -.progress-bar-striped { - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-size: 1rem 1rem; } - -.progress-bar-animated { - -webkit-animation: 1s linear infinite progress-bar-stripes; - animation: 1s linear infinite progress-bar-stripes; } - @media (prefers-reduced-motion: reduce) { - .progress-bar-animated { - -webkit-animation: none; - animation: none; } } - -.media { - display: flex; - align-items: flex-start; } - -.media-body { - flex: 1; } - -.list-group { - display: flex; - flex-direction: column; - padding-left: 0; - margin-bottom: 0; - border-radius: 0.25rem; } - -.list-group-item-action { - width: 100%; - color: #495057; - text-align: inherit; } - .list-group-item-action:hover, .list-group-item-action:focus { - z-index: 1; - color: #495057; - text-decoration: none; - background-color: #f8f9fa; } - .list-group-item-action:active { - color: #212529; - background-color: #e9ecef; } - -.list-group-item { - position: relative; - display: block; - padding: 0.75rem 1.25rem; - background-color: #fff; - border: 1px solid rgba(0, 0, 0, 0.125); } - .list-group-item:first-child { - border-top-left-radius: inherit; - border-top-right-radius: inherit; } - .list-group-item:last-child { - border-bottom-right-radius: inherit; - border-bottom-left-radius: inherit; } - .list-group-item.disabled, .list-group-item:disabled { - color: #6c757d; - pointer-events: none; - background-color: #fff; } - .list-group-item.active { - z-index: 2; - color: #fff; - background-color: #007bff; - border-color: #007bff; } - .list-group-item + .list-group-item { - border-top-width: 0; } - .list-group-item + .list-group-item.active { - margin-top: -1px; - border-top-width: 1px; } - -.list-group-horizontal { - flex-direction: row; } - .list-group-horizontal > .list-group-item:first-child { - border-bottom-left-radius: 0.25rem; - border-top-right-radius: 0; } - .list-group-horizontal > .list-group-item:last-child { - border-top-right-radius: 0.25rem; - border-bottom-left-radius: 0; } - .list-group-horizontal > .list-group-item.active { - margin-top: 0; } - .list-group-horizontal > .list-group-item + .list-group-item { - border-top-width: 1px; - border-left-width: 0; } - .list-group-horizontal > .list-group-item + .list-group-item.active { - margin-left: -1px; - border-left-width: 1px; } - -@media (min-width: 576px) { - .list-group-horizontal-sm { - flex-direction: row; } - .list-group-horizontal-sm > .list-group-item:first-child { - border-bottom-left-radius: 0.25rem; - border-top-right-radius: 0; } - .list-group-horizontal-sm > .list-group-item:last-child { - border-top-right-radius: 0.25rem; - border-bottom-left-radius: 0; } - .list-group-horizontal-sm > .list-group-item.active { - margin-top: 0; } - .list-group-horizontal-sm > .list-group-item + .list-group-item { - border-top-width: 1px; - border-left-width: 0; } - .list-group-horizontal-sm > .list-group-item + .list-group-item.active { - margin-left: -1px; - border-left-width: 1px; } } - -@media (min-width: 768px) { - .list-group-horizontal-md { - flex-direction: row; } - .list-group-horizontal-md > .list-group-item:first-child { - border-bottom-left-radius: 0.25rem; - border-top-right-radius: 0; } - .list-group-horizontal-md > .list-group-item:last-child { - border-top-right-radius: 0.25rem; - border-bottom-left-radius: 0; } - .list-group-horizontal-md > .list-group-item.active { - margin-top: 0; } - .list-group-horizontal-md > .list-group-item + .list-group-item { - border-top-width: 1px; - border-left-width: 0; } - .list-group-horizontal-md > .list-group-item + .list-group-item.active { - margin-left: -1px; - border-left-width: 1px; } } - -@media (min-width: 992px) { - .list-group-horizontal-lg { - flex-direction: row; } - .list-group-horizontal-lg > .list-group-item:first-child { - border-bottom-left-radius: 0.25rem; - border-top-right-radius: 0; } - .list-group-horizontal-lg > .list-group-item:last-child { - border-top-right-radius: 0.25rem; - border-bottom-left-radius: 0; } - .list-group-horizontal-lg > .list-group-item.active { - margin-top: 0; } - .list-group-horizontal-lg > .list-group-item + .list-group-item { - border-top-width: 1px; - border-left-width: 0; } - .list-group-horizontal-lg > .list-group-item + .list-group-item.active { - margin-left: -1px; - border-left-width: 1px; } } - -@media (min-width: 1200px) { - .list-group-horizontal-xl { - flex-direction: row; } - .list-group-horizontal-xl > .list-group-item:first-child { - border-bottom-left-radius: 0.25rem; - border-top-right-radius: 0; } - .list-group-horizontal-xl > .list-group-item:last-child { - border-top-right-radius: 0.25rem; - border-bottom-left-radius: 0; } - .list-group-horizontal-xl > .list-group-item.active { - margin-top: 0; } - .list-group-horizontal-xl > .list-group-item + .list-group-item { - border-top-width: 1px; - border-left-width: 0; } - .list-group-horizontal-xl > .list-group-item + .list-group-item.active { - margin-left: -1px; - border-left-width: 1px; } } - -.list-group-flush { - border-radius: 0; } - .list-group-flush > .list-group-item { - border-width: 0 0 1px; } - .list-group-flush > .list-group-item:last-child { - border-bottom-width: 0; } - -.list-group-item-primary { - color: #004085; - background-color: #b8daff; } - .list-group-item-primary.list-group-item-action:hover, .list-group-item-primary.list-group-item-action:focus { - color: #004085; - background-color: #9fcdff; } - .list-group-item-primary.list-group-item-action.active { - color: #fff; - background-color: #004085; - border-color: #004085; } - -.list-group-item-secondary { - color: #383d41; - background-color: #d6d8db; } - .list-group-item-secondary.list-group-item-action:hover, .list-group-item-secondary.list-group-item-action:focus { - color: #383d41; - background-color: #c8cbcf; } - .list-group-item-secondary.list-group-item-action.active { - color: #fff; - background-color: #383d41; - border-color: #383d41; } - -.list-group-item-success { - color: #155724; - background-color: #c3e6cb; } - .list-group-item-success.list-group-item-action:hover, .list-group-item-success.list-group-item-action:focus { - color: #155724; - background-color: #b1dfbb; } - .list-group-item-success.list-group-item-action.active { - color: #fff; - background-color: #155724; - border-color: #155724; } - -.list-group-item-info { - color: #0c5460; - background-color: #bee5eb; } - .list-group-item-info.list-group-item-action:hover, .list-group-item-info.list-group-item-action:focus { - color: #0c5460; - background-color: #abdde5; } - .list-group-item-info.list-group-item-action.active { - color: #fff; - background-color: #0c5460; - border-color: #0c5460; } - -.list-group-item-warning { - color: #856404; - background-color: #ffeeba; } - .list-group-item-warning.list-group-item-action:hover, .list-group-item-warning.list-group-item-action:focus { - color: #856404; - background-color: #ffe8a1; } - .list-group-item-warning.list-group-item-action.active { - color: #fff; - background-color: #856404; - border-color: #856404; } - -.list-group-item-danger { - color: #721c24; - background-color: #f5c6cb; } - .list-group-item-danger.list-group-item-action:hover, .list-group-item-danger.list-group-item-action:focus { - color: #721c24; - background-color: #f1b0b7; } - .list-group-item-danger.list-group-item-action.active { - color: #fff; - background-color: #721c24; - border-color: #721c24; } - -.list-group-item-light { - color: #818182; - background-color: #fdfdfe; } - .list-group-item-light.list-group-item-action:hover, .list-group-item-light.list-group-item-action:focus { - color: #818182; - background-color: #ececf6; } - .list-group-item-light.list-group-item-action.active { - color: #fff; - background-color: #818182; - border-color: #818182; } - -.list-group-item-dark { - color: #1b1e21; - background-color: #c6c8ca; } - .list-group-item-dark.list-group-item-action:hover, .list-group-item-dark.list-group-item-action:focus { - color: #1b1e21; - background-color: #b9bbbe; } - .list-group-item-dark.list-group-item-action.active { - color: #fff; - background-color: #1b1e21; - border-color: #1b1e21; } - -.close { - float: right; - font-size: 1.5rem; - font-weight: 700; - line-height: 1; - color: #000; - text-shadow: 0 1px 0 #fff; - opacity: .5; } - .close:hover { - color: #000; - text-decoration: none; } - .close:not(:disabled):not(.disabled):hover, .close:not(:disabled):not(.disabled):focus { - opacity: .75; } - -button.close { - padding: 0; - background-color: transparent; - border: 0; } - -a.close.disabled { - pointer-events: none; } - -.toast { - flex-basis: 350px; - max-width: 350px; - font-size: 0.875rem; - background-color: rgba(255, 255, 255, 0.85); - background-clip: padding-box; - border: 1px solid rgba(0, 0, 0, 0.1); - box-shadow: 0 0.25rem 0.75rem rgba(0, 0, 0, 0.1); - opacity: 0; - border-radius: 0.25rem; } - .toast:not(:last-child) { - margin-bottom: 0.75rem; } - .toast.showing { - opacity: 1; } - .toast.show { - display: block; - opacity: 1; } - .toast.hide { - display: none; } - -.toast-header { - display: flex; - align-items: center; - padding: 0.25rem 0.75rem; - color: #6c757d; - background-color: rgba(255, 255, 255, 0.85); - background-clip: padding-box; - border-bottom: 1px solid rgba(0, 0, 0, 0.05); - border-top-left-radius: calc(0.25rem - 1px); - border-top-right-radius: calc(0.25rem - 1px); } - -.toast-body { - padding: 0.75rem; } - -.modal-open { - overflow: hidden; } - .modal-open .modal { - overflow-x: hidden; - overflow-y: auto; } - -.modal { - position: fixed; - top: 0; - left: 0; - z-index: 1050; - display: none; - width: 100%; - height: 100%; - overflow: hidden; - outline: 0; } - -.modal-dialog { - position: relative; - width: auto; - margin: 0.5rem; - pointer-events: none; } - .modal.fade .modal-dialog { - transition: transform 0.3s ease-out; - transform: translate(0, -50px); } - @media (prefers-reduced-motion: reduce) { - .modal.fade .modal-dialog { - transition: none; } } - .modal.show .modal-dialog { - transform: none; } - .modal.modal-static .modal-dialog { - transform: scale(1.02); } - -.modal-dialog-scrollable { - display: flex; - max-height: calc(100% - 1rem); } - .modal-dialog-scrollable .modal-content { - max-height: calc(100vh - 1rem); - overflow: hidden; } - .modal-dialog-scrollable .modal-header, - .modal-dialog-scrollable .modal-footer { - flex-shrink: 0; } - .modal-dialog-scrollable .modal-body { - overflow-y: auto; } - -.modal-dialog-centered { - display: flex; - align-items: center; - min-height: calc(100% - 1rem); } - .modal-dialog-centered::before { - display: block; - height: calc(100vh - 1rem); - height: -webkit-min-content; - height: -moz-min-content; - height: min-content; - content: ""; } - .modal-dialog-centered.modal-dialog-scrollable { - flex-direction: column; - justify-content: center; - height: 100%; } - .modal-dialog-centered.modal-dialog-scrollable .modal-content { - max-height: none; } - .modal-dialog-centered.modal-dialog-scrollable::before { - content: none; } - -.modal-content { - position: relative; - display: flex; - flex-direction: column; - width: 100%; - pointer-events: auto; - background-color: #fff; - background-clip: padding-box; - border: 1px solid rgba(0, 0, 0, 0.2); - border-radius: 0.3rem; - outline: 0; } - -.modal-backdrop { - position: fixed; - top: 0; - left: 0; - z-index: 1040; - width: 100vw; - height: 100vh; - background-color: #000; } - .modal-backdrop.fade { - opacity: 0; } - .modal-backdrop.show { - opacity: 0.5; } - -.modal-header { - display: flex; - align-items: flex-start; - justify-content: space-between; - padding: 1rem 1rem; - border-bottom: 1px solid #dee2e6; - border-top-left-radius: calc(0.3rem - 1px); - border-top-right-radius: calc(0.3rem - 1px); } - .modal-header .close { - padding: 1rem 1rem; - margin: -1rem -1rem -1rem auto; } - -.modal-title { - margin-bottom: 0; - line-height: 1.5; } - -.modal-body { - position: relative; - flex: 1 1 auto; - padding: 1rem; } - -.modal-footer { - display: flex; - flex-wrap: wrap; - align-items: center; - justify-content: flex-end; - padding: 0.75rem; - border-top: 1px solid #dee2e6; - border-bottom-right-radius: calc(0.3rem - 1px); - border-bottom-left-radius: calc(0.3rem - 1px); } - .modal-footer > * { - margin: 0.25rem; } - -.modal-scrollbar-measure { - position: absolute; - top: -9999px; - width: 50px; - height: 50px; - overflow: scroll; } - -@media (min-width: 576px) { - .modal-dialog { - max-width: 500px; - margin: 1.75rem auto; } - .modal-dialog-scrollable { - max-height: calc(100% - 3.5rem); } - .modal-dialog-scrollable .modal-content { - max-height: calc(100vh - 3.5rem); } - .modal-dialog-centered { - min-height: calc(100% - 3.5rem); } - .modal-dialog-centered::before { - height: calc(100vh - 3.5rem); - height: -webkit-min-content; - height: -moz-min-content; - height: min-content; } - .modal-sm { - max-width: 300px; } } - -@media (min-width: 992px) { - .modal-lg, - .modal-xl { - max-width: 800px; } } - -@media (min-width: 1200px) { - .modal-xl { - max-width: 1140px; } } - -.tooltip { - position: absolute; - z-index: 1070; - display: block; - margin: 0; - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; - font-style: normal; - font-weight: 400; - line-height: 1.5; - text-align: left; - text-align: start; - text-decoration: none; - text-shadow: none; - text-transform: none; - letter-spacing: normal; - word-break: normal; - word-spacing: normal; - white-space: normal; - line-break: auto; - font-size: 0.875rem; - word-wrap: break-word; - opacity: 0; } - .tooltip.show { - opacity: 0.9; } - .tooltip .arrow { - position: absolute; - display: block; - width: 0.8rem; - height: 0.4rem; } - .tooltip .arrow::before { - position: absolute; - content: ""; - border-color: transparent; - border-style: solid; } - -.bs-tooltip-top, .bs-tooltip-auto[x-placement^="top"] { - padding: 0.4rem 0; } - .bs-tooltip-top .arrow, .bs-tooltip-auto[x-placement^="top"] .arrow { - bottom: 0; } - .bs-tooltip-top .arrow::before, .bs-tooltip-auto[x-placement^="top"] .arrow::before { - top: 0; - border-width: 0.4rem 0.4rem 0; - border-top-color: #000; } - -.bs-tooltip-right, .bs-tooltip-auto[x-placement^="right"] { - padding: 0 0.4rem; } - .bs-tooltip-right .arrow, .bs-tooltip-auto[x-placement^="right"] .arrow { - left: 0; - width: 0.4rem; - height: 0.8rem; } - .bs-tooltip-right .arrow::before, .bs-tooltip-auto[x-placement^="right"] .arrow::before { - right: 0; - border-width: 0.4rem 0.4rem 0.4rem 0; - border-right-color: #000; } - -.bs-tooltip-bottom, .bs-tooltip-auto[x-placement^="bottom"] { - padding: 0.4rem 0; } - .bs-tooltip-bottom .arrow, .bs-tooltip-auto[x-placement^="bottom"] .arrow { - top: 0; } - .bs-tooltip-bottom .arrow::before, .bs-tooltip-auto[x-placement^="bottom"] .arrow::before { - bottom: 0; - border-width: 0 0.4rem 0.4rem; - border-bottom-color: #000; } - -.bs-tooltip-left, .bs-tooltip-auto[x-placement^="left"] { - padding: 0 0.4rem; } - .bs-tooltip-left .arrow, .bs-tooltip-auto[x-placement^="left"] .arrow { - right: 0; - width: 0.4rem; - height: 0.8rem; } - .bs-tooltip-left .arrow::before, .bs-tooltip-auto[x-placement^="left"] .arrow::before { - left: 0; - border-width: 0.4rem 0 0.4rem 0.4rem; - border-left-color: #000; } - -.tooltip-inner { - max-width: 200px; - padding: 0.25rem 0.5rem; - color: #fff; - text-align: center; - background-color: #000; - border-radius: 0.25rem; } - -.popover { - position: absolute; - top: 0; - left: 0; - z-index: 1060; - display: block; - max-width: 276px; - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; - font-style: normal; - font-weight: 400; - line-height: 1.5; - text-align: left; - text-align: start; - text-decoration: none; - text-shadow: none; - text-transform: none; - letter-spacing: normal; - word-break: normal; - word-spacing: normal; - white-space: normal; - line-break: auto; - font-size: 0.875rem; - word-wrap: break-word; - background-color: #fff; - background-clip: padding-box; - border: 1px solid rgba(0, 0, 0, 0.2); - border-radius: 0.3rem; } - .popover .arrow { - position: absolute; - display: block; - width: 1rem; - height: 0.5rem; - margin: 0 0.3rem; } - .popover .arrow::before, .popover .arrow::after { - position: absolute; - display: block; - content: ""; - border-color: transparent; - border-style: solid; } - -.bs-popover-top, .bs-popover-auto[x-placement^="top"] { - margin-bottom: 0.5rem; } - .bs-popover-top > .arrow, .bs-popover-auto[x-placement^="top"] > .arrow { - bottom: calc(-0.5rem - 1px); } - .bs-popover-top > .arrow::before, .bs-popover-auto[x-placement^="top"] > .arrow::before { - bottom: 0; - border-width: 0.5rem 0.5rem 0; - border-top-color: rgba(0, 0, 0, 0.25); } - .bs-popover-top > .arrow::after, .bs-popover-auto[x-placement^="top"] > .arrow::after { - bottom: 1px; - border-width: 0.5rem 0.5rem 0; - border-top-color: #fff; } - -.bs-popover-right, .bs-popover-auto[x-placement^="right"] { - margin-left: 0.5rem; } - .bs-popover-right > .arrow, .bs-popover-auto[x-placement^="right"] > .arrow { - left: calc(-0.5rem - 1px); - width: 0.5rem; - height: 1rem; - margin: 0.3rem 0; } - .bs-popover-right > .arrow::before, .bs-popover-auto[x-placement^="right"] > .arrow::before { - left: 0; - border-width: 0.5rem 0.5rem 0.5rem 0; - border-right-color: rgba(0, 0, 0, 0.25); } - .bs-popover-right > .arrow::after, .bs-popover-auto[x-placement^="right"] > .arrow::after { - left: 1px; - border-width: 0.5rem 0.5rem 0.5rem 0; - border-right-color: #fff; } - -.bs-popover-bottom, .bs-popover-auto[x-placement^="bottom"] { - margin-top: 0.5rem; } - .bs-popover-bottom > .arrow, .bs-popover-auto[x-placement^="bottom"] > .arrow { - top: calc(-0.5rem - 1px); } - .bs-popover-bottom > .arrow::before, .bs-popover-auto[x-placement^="bottom"] > .arrow::before { - top: 0; - border-width: 0 0.5rem 0.5rem 0.5rem; - border-bottom-color: rgba(0, 0, 0, 0.25); } - .bs-popover-bottom > .arrow::after, .bs-popover-auto[x-placement^="bottom"] > .arrow::after { - top: 1px; - border-width: 0 0.5rem 0.5rem 0.5rem; - border-bottom-color: #fff; } - .bs-popover-bottom .popover-header::before, .bs-popover-auto[x-placement^="bottom"] .popover-header::before { - position: absolute; - top: 0; - left: 50%; - display: block; - width: 1rem; - margin-left: -0.5rem; - content: ""; - border-bottom: 1px solid #f7f7f7; } - -.bs-popover-left, .bs-popover-auto[x-placement^="left"] { - margin-right: 0.5rem; } - .bs-popover-left > .arrow, .bs-popover-auto[x-placement^="left"] > .arrow { - right: calc(-0.5rem - 1px); - width: 0.5rem; - height: 1rem; - margin: 0.3rem 0; } - .bs-popover-left > .arrow::before, .bs-popover-auto[x-placement^="left"] > .arrow::before { - right: 0; - border-width: 0.5rem 0 0.5rem 0.5rem; - border-left-color: rgba(0, 0, 0, 0.25); } - .bs-popover-left > .arrow::after, .bs-popover-auto[x-placement^="left"] > .arrow::after { - right: 1px; - border-width: 0.5rem 0 0.5rem 0.5rem; - border-left-color: #fff; } - -.popover-header { - padding: 0.5rem 0.75rem; - margin-bottom: 0; - font-size: 1rem; - background-color: #f7f7f7; - border-bottom: 1px solid #ebebeb; - border-top-left-radius: calc(0.3rem - 1px); - border-top-right-radius: calc(0.3rem - 1px); } - .popover-header:empty { - display: none; } - -.popover-body { - padding: 0.5rem 0.75rem; - color: #212529; } - -.carousel { - position: relative; } - -.carousel.pointer-event { - touch-action: pan-y; } - -.carousel-inner { - position: relative; - width: 100%; - overflow: hidden; } - .carousel-inner::after { - display: block; - clear: both; - content: ""; } - -.carousel-item { - position: relative; - display: none; - float: left; - width: 100%; - margin-right: -100%; - -webkit-backface-visibility: hidden; - backface-visibility: hidden; - transition: transform 0.6s ease-in-out; } - @media (prefers-reduced-motion: reduce) { - .carousel-item { - transition: none; } } - -.carousel-item.active, -.carousel-item-next, -.carousel-item-prev { - display: block; } - -.carousel-item-next:not(.carousel-item-left), -.active.carousel-item-right { - transform: translateX(100%); } - -.carousel-item-prev:not(.carousel-item-right), -.active.carousel-item-left { - transform: translateX(-100%); } - -.carousel-fade .carousel-item { - opacity: 0; - transition-property: opacity; - transform: none; } - -.carousel-fade .carousel-item.active, -.carousel-fade .carousel-item-next.carousel-item-left, -.carousel-fade .carousel-item-prev.carousel-item-right { - z-index: 1; - opacity: 1; } - -.carousel-fade .active.carousel-item-left, -.carousel-fade .active.carousel-item-right { - z-index: 0; - opacity: 0; - transition: opacity 0s 0.6s; } - @media (prefers-reduced-motion: reduce) { - .carousel-fade .active.carousel-item-left, - .carousel-fade .active.carousel-item-right { - transition: none; } } - -.carousel-control-prev, -.carousel-control-next { - position: absolute; - top: 0; - bottom: 0; - z-index: 1; - display: flex; - align-items: center; - justify-content: center; - width: 15%; - padding: 0; - color: #fff; - text-align: center; - background: none; - border: 0; - opacity: 0.5; - transition: opacity 0.15s ease; } - @media (prefers-reduced-motion: reduce) { - .carousel-control-prev, - .carousel-control-next { - transition: none; } } - .carousel-control-prev:hover, .carousel-control-prev:focus, - .carousel-control-next:hover, - .carousel-control-next:focus { - color: #fff; - text-decoration: none; - outline: 0; - opacity: 0.9; } - -.carousel-control-prev { - left: 0; } - -.carousel-control-next { - right: 0; } - -.carousel-control-prev-icon, -.carousel-control-next-icon { - display: inline-block; - width: 20px; - height: 20px; - background: 50% / 100% 100% no-repeat; } - -.carousel-control-prev-icon { - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M5.25 0l-4 4 4 4 1.5-1.5L4.25 4l2.5-2.5L5.25 0z'/%3e%3c/svg%3e"); } - -.carousel-control-next-icon { - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M2.75 0l-1.5 1.5L3.75 4l-2.5 2.5L2.75 8l4-4-4-4z'/%3e%3c/svg%3e"); } - -.carousel-indicators { - position: absolute; - right: 0; - bottom: 0; - left: 0; - z-index: 15; - display: flex; - justify-content: center; - padding-left: 0; - margin-right: 15%; - margin-left: 15%; - list-style: none; } - .carousel-indicators li { - box-sizing: content-box; - flex: 0 1 auto; - width: 30px; - height: 3px; - margin-right: 3px; - margin-left: 3px; - text-indent: -999px; - cursor: pointer; - background-color: #fff; - background-clip: padding-box; - border-top: 10px solid transparent; - border-bottom: 10px solid transparent; - opacity: .5; - transition: opacity 0.6s ease; } - @media (prefers-reduced-motion: reduce) { - .carousel-indicators li { - transition: none; } } - .carousel-indicators .active { - opacity: 1; } - -.carousel-caption { - position: absolute; - right: 15%; - bottom: 20px; - left: 15%; - z-index: 10; - padding-top: 20px; - padding-bottom: 20px; - color: #fff; - text-align: center; } - -@-webkit-keyframes spinner-border { - to { - transform: rotate(360deg); } } - -@keyframes spinner-border { - to { - transform: rotate(360deg); } } - -.spinner-border { - display: inline-block; - width: 2rem; - height: 2rem; - vertical-align: -0.125em; - border: 0.25em solid currentColor; - border-right-color: transparent; - border-radius: 50%; - -webkit-animation: .75s linear infinite spinner-border; - animation: .75s linear infinite spinner-border; } - -.spinner-border-sm { - width: 1rem; - height: 1rem; - border-width: 0.2em; } - -@-webkit-keyframes spinner-grow { - 0% { - transform: scale(0); } - 50% { - opacity: 1; - transform: none; } } - -@keyframes spinner-grow { - 0% { - transform: scale(0); } - 50% { - opacity: 1; - transform: none; } } - -.spinner-grow { - display: inline-block; - width: 2rem; - height: 2rem; - vertical-align: -0.125em; - background-color: currentColor; - border-radius: 50%; - opacity: 0; - -webkit-animation: .75s linear infinite spinner-grow; - animation: .75s linear infinite spinner-grow; } - -.spinner-grow-sm { - width: 1rem; - height: 1rem; } - -@media (prefers-reduced-motion: reduce) { - .spinner-border, - .spinner-grow { - -webkit-animation-duration: 1.5s; - animation-duration: 1.5s; } } - -.align-baseline { - vertical-align: baseline !important; } - -.align-top { - vertical-align: top !important; } - -.align-middle { - vertical-align: middle !important; } - -.align-bottom { - vertical-align: bottom !important; } - -.align-text-bottom { - vertical-align: text-bottom !important; } - -.align-text-top { - vertical-align: text-top !important; } - -.bg-primary { - background-color: #007bff !important; } - -a.bg-primary:hover, a.bg-primary:focus, -button.bg-primary:hover, -button.bg-primary:focus { - background-color: #0062cc !important; } - -.bg-secondary { - background-color: #6c757d !important; } - -a.bg-secondary:hover, a.bg-secondary:focus, -button.bg-secondary:hover, -button.bg-secondary:focus { - background-color: #545b62 !important; } - -.bg-success { - background-color: #28a745 !important; } - -a.bg-success:hover, a.bg-success:focus, -button.bg-success:hover, -button.bg-success:focus { - background-color: #1e7e34 !important; } - -.bg-info { - background-color: #17a2b8 !important; } - -a.bg-info:hover, a.bg-info:focus, -button.bg-info:hover, -button.bg-info:focus { - background-color: #117a8b !important; } - -.bg-warning { - background-color: #ffc107 !important; } - -a.bg-warning:hover, a.bg-warning:focus, -button.bg-warning:hover, -button.bg-warning:focus { - background-color: #d39e00 !important; } - -.bg-danger { - background-color: #dc3545 !important; } - -a.bg-danger:hover, a.bg-danger:focus, -button.bg-danger:hover, -button.bg-danger:focus { - background-color: #bd2130 !important; } - -.bg-light { - background-color: #f8f9fa !important; } - -a.bg-light:hover, a.bg-light:focus, -button.bg-light:hover, -button.bg-light:focus { - background-color: #dae0e5 !important; } - -.bg-dark { - background-color: #343a40 !important; } - -a.bg-dark:hover, a.bg-dark:focus, -button.bg-dark:hover, -button.bg-dark:focus { - background-color: #1d2124 !important; } - -.bg-white { - background-color: #fff !important; } - -.bg-transparent { - background-color: transparent !important; } - -.border { - border: 1px solid #dee2e6 !important; } - -.border-top { - border-top: 1px solid #dee2e6 !important; } - -.border-right { - border-right: 1px solid #dee2e6 !important; } - -.border-bottom { - border-bottom: 1px solid #dee2e6 !important; } - -.border-left { - border-left: 1px solid #dee2e6 !important; } - -.border-0 { - border: 0 !important; } - -.border-top-0 { - border-top: 0 !important; } - -.border-right-0 { - border-right: 0 !important; } - -.border-bottom-0 { - border-bottom: 0 !important; } - -.border-left-0 { - border-left: 0 !important; } - -.border-primary { - border-color: #007bff !important; } - -.border-secondary { - border-color: #6c757d !important; } - -.border-success { - border-color: #28a745 !important; } - -.border-info { - border-color: #17a2b8 !important; } - -.border-warning { - border-color: #ffc107 !important; } - -.border-danger { - border-color: #dc3545 !important; } - -.border-light { - border-color: #f8f9fa !important; } - -.border-dark { - border-color: #343a40 !important; } - -.border-white { - border-color: #fff !important; } - -.rounded-sm { - border-radius: 0.2rem !important; } - -.rounded { - border-radius: 0.25rem !important; } - -.rounded-top { - border-top-left-radius: 0.25rem !important; - border-top-right-radius: 0.25rem !important; } - -.rounded-right { - border-top-right-radius: 0.25rem !important; - border-bottom-right-radius: 0.25rem !important; } - -.rounded-bottom { - border-bottom-right-radius: 0.25rem !important; - border-bottom-left-radius: 0.25rem !important; } - -.rounded-left { - border-top-left-radius: 0.25rem !important; - border-bottom-left-radius: 0.25rem !important; } - -.rounded-lg { - border-radius: 0.3rem !important; } - -.rounded-circle { - border-radius: 50% !important; } - -.rounded-pill { - border-radius: 50rem !important; } - -.rounded-0 { - border-radius: 0 !important; } - -.clearfix::after { - display: block; - clear: both; - content: ""; } - -.d-none { - display: none !important; } - -.d-inline { - display: inline !important; } - -.d-inline-block { - display: inline-block !important; } - -.d-block { - display: block !important; } - -.d-table { - display: table !important; } - -.d-table-row { - display: table-row !important; } - -.d-table-cell { - display: table-cell !important; } - -.d-flex { - display: flex !important; } - -.d-inline-flex { - display: inline-flex !important; } - -@media (min-width: 576px) { - .d-sm-none { - display: none !important; } - .d-sm-inline { - display: inline !important; } - .d-sm-inline-block { - display: inline-block !important; } - .d-sm-block { - display: block !important; } - .d-sm-table { - display: table !important; } - .d-sm-table-row { - display: table-row !important; } - .d-sm-table-cell { - display: table-cell !important; } - .d-sm-flex { - display: flex !important; } - .d-sm-inline-flex { - display: inline-flex !important; } } - -@media (min-width: 768px) { - .d-md-none { - display: none !important; } - .d-md-inline { - display: inline !important; } - .d-md-inline-block { - display: inline-block !important; } - .d-md-block { - display: block !important; } - .d-md-table { - display: table !important; } - .d-md-table-row { - display: table-row !important; } - .d-md-table-cell { - display: table-cell !important; } - .d-md-flex { - display: flex !important; } - .d-md-inline-flex { - display: inline-flex !important; } } - -@media (min-width: 992px) { - .d-lg-none { - display: none !important; } - .d-lg-inline { - display: inline !important; } - .d-lg-inline-block { - display: inline-block !important; } - .d-lg-block { - display: block !important; } - .d-lg-table { - display: table !important; } - .d-lg-table-row { - display: table-row !important; } - .d-lg-table-cell { - display: table-cell !important; } - .d-lg-flex { - display: flex !important; } - .d-lg-inline-flex { - display: inline-flex !important; } } - -@media (min-width: 1200px) { - .d-xl-none { - display: none !important; } - .d-xl-inline { - display: inline !important; } - .d-xl-inline-block { - display: inline-block !important; } - .d-xl-block { - display: block !important; } - .d-xl-table { - display: table !important; } - .d-xl-table-row { - display: table-row !important; } - .d-xl-table-cell { - display: table-cell !important; } - .d-xl-flex { - display: flex !important; } - .d-xl-inline-flex { - display: inline-flex !important; } } - -@media print { - .d-print-none { - display: none !important; } - .d-print-inline { - display: inline !important; } - .d-print-inline-block { - display: inline-block !important; } - .d-print-block { - display: block !important; } - .d-print-table { - display: table !important; } - .d-print-table-row { - display: table-row !important; } - .d-print-table-cell { - display: table-cell !important; } - .d-print-flex { - display: flex !important; } - .d-print-inline-flex { - display: inline-flex !important; } } - -.embed-responsive { - position: relative; - display: block; - width: 100%; - padding: 0; - overflow: hidden; } - .embed-responsive::before { - display: block; - content: ""; } - .embed-responsive .embed-responsive-item, - .embed-responsive iframe, - .embed-responsive embed, - .embed-responsive object, - .embed-responsive video { - position: absolute; - top: 0; - bottom: 0; - left: 0; - width: 100%; - height: 100%; - border: 0; } - -.embed-responsive-21by9::before { - padding-top: 42.85714286%; } - -.embed-responsive-16by9::before { - padding-top: 56.25%; } - -.embed-responsive-4by3::before { - padding-top: 75%; } - -.embed-responsive-1by1::before { - padding-top: 100%; } - -.flex-row { - flex-direction: row !important; } - -.flex-column { - flex-direction: column !important; } - -.flex-row-reverse { - flex-direction: row-reverse !important; } - -.flex-column-reverse { - flex-direction: column-reverse !important; } - -.flex-wrap { - flex-wrap: wrap !important; } - -.flex-nowrap { - flex-wrap: nowrap !important; } - -.flex-wrap-reverse { - flex-wrap: wrap-reverse !important; } - -.flex-fill { - flex: 1 1 auto !important; } - -.flex-grow-0 { - flex-grow: 0 !important; } - -.flex-grow-1 { - flex-grow: 1 !important; } - -.flex-shrink-0 { - flex-shrink: 0 !important; } - -.flex-shrink-1 { - flex-shrink: 1 !important; } - -.justify-content-start { - justify-content: flex-start !important; } - -.justify-content-end { - justify-content: flex-end !important; } - -.justify-content-center { - justify-content: center !important; } - -.justify-content-between { - justify-content: space-between !important; } - -.justify-content-around { - justify-content: space-around !important; } - -.align-items-start { - align-items: flex-start !important; } - -.align-items-end { - align-items: flex-end !important; } - -.align-items-center { - align-items: center !important; } - -.align-items-baseline { - align-items: baseline !important; } - -.align-items-stretch { - align-items: stretch !important; } - -.align-content-start { - align-content: flex-start !important; } - -.align-content-end { - align-content: flex-end !important; } - -.align-content-center { - align-content: center !important; } - -.align-content-between { - align-content: space-between !important; } - -.align-content-around { - align-content: space-around !important; } - -.align-content-stretch { - align-content: stretch !important; } - -.align-self-auto { - align-self: auto !important; } - -.align-self-start { - align-self: flex-start !important; } - -.align-self-end { - align-self: flex-end !important; } - -.align-self-center { - align-self: center !important; } - -.align-self-baseline { - align-self: baseline !important; } - -.align-self-stretch { - align-self: stretch !important; } - -@media (min-width: 576px) { - .flex-sm-row { - flex-direction: row !important; } - .flex-sm-column { - flex-direction: column !important; } - .flex-sm-row-reverse { - flex-direction: row-reverse !important; } - .flex-sm-column-reverse { - flex-direction: column-reverse !important; } - .flex-sm-wrap { - flex-wrap: wrap !important; } - .flex-sm-nowrap { - flex-wrap: nowrap !important; } - .flex-sm-wrap-reverse { - flex-wrap: wrap-reverse !important; } - .flex-sm-fill { - flex: 1 1 auto !important; } - .flex-sm-grow-0 { - flex-grow: 0 !important; } - .flex-sm-grow-1 { - flex-grow: 1 !important; } - .flex-sm-shrink-0 { - flex-shrink: 0 !important; } - .flex-sm-shrink-1 { - flex-shrink: 1 !important; } - .justify-content-sm-start { - justify-content: flex-start !important; } - .justify-content-sm-end { - justify-content: flex-end !important; } - .justify-content-sm-center { - justify-content: center !important; } - .justify-content-sm-between { - justify-content: space-between !important; } - .justify-content-sm-around { - justify-content: space-around !important; } - .align-items-sm-start { - align-items: flex-start !important; } - .align-items-sm-end { - align-items: flex-end !important; } - .align-items-sm-center { - align-items: center !important; } - .align-items-sm-baseline { - align-items: baseline !important; } - .align-items-sm-stretch { - align-items: stretch !important; } - .align-content-sm-start { - align-content: flex-start !important; } - .align-content-sm-end { - align-content: flex-end !important; } - .align-content-sm-center { - align-content: center !important; } - .align-content-sm-between { - align-content: space-between !important; } - .align-content-sm-around { - align-content: space-around !important; } - .align-content-sm-stretch { - align-content: stretch !important; } - .align-self-sm-auto { - align-self: auto !important; } - .align-self-sm-start { - align-self: flex-start !important; } - .align-self-sm-end { - align-self: flex-end !important; } - .align-self-sm-center { - align-self: center !important; } - .align-self-sm-baseline { - align-self: baseline !important; } - .align-self-sm-stretch { - align-self: stretch !important; } } - -@media (min-width: 768px) { - .flex-md-row { - flex-direction: row !important; } - .flex-md-column { - flex-direction: column !important; } - .flex-md-row-reverse { - flex-direction: row-reverse !important; } - .flex-md-column-reverse { - flex-direction: column-reverse !important; } - .flex-md-wrap { - flex-wrap: wrap !important; } - .flex-md-nowrap { - flex-wrap: nowrap !important; } - .flex-md-wrap-reverse { - flex-wrap: wrap-reverse !important; } - .flex-md-fill { - flex: 1 1 auto !important; } - .flex-md-grow-0 { - flex-grow: 0 !important; } - .flex-md-grow-1 { - flex-grow: 1 !important; } - .flex-md-shrink-0 { - flex-shrink: 0 !important; } - .flex-md-shrink-1 { - flex-shrink: 1 !important; } - .justify-content-md-start { - justify-content: flex-start !important; } - .justify-content-md-end { - justify-content: flex-end !important; } - .justify-content-md-center { - justify-content: center !important; } - .justify-content-md-between { - justify-content: space-between !important; } - .justify-content-md-around { - justify-content: space-around !important; } - .align-items-md-start { - align-items: flex-start !important; } - .align-items-md-end { - align-items: flex-end !important; } - .align-items-md-center { - align-items: center !important; } - .align-items-md-baseline { - align-items: baseline !important; } - .align-items-md-stretch { - align-items: stretch !important; } - .align-content-md-start { - align-content: flex-start !important; } - .align-content-md-end { - align-content: flex-end !important; } - .align-content-md-center { - align-content: center !important; } - .align-content-md-between { - align-content: space-between !important; } - .align-content-md-around { - align-content: space-around !important; } - .align-content-md-stretch { - align-content: stretch !important; } - .align-self-md-auto { - align-self: auto !important; } - .align-self-md-start { - align-self: flex-start !important; } - .align-self-md-end { - align-self: flex-end !important; } - .align-self-md-center { - align-self: center !important; } - .align-self-md-baseline { - align-self: baseline !important; } - .align-self-md-stretch { - align-self: stretch !important; } } - -@media (min-width: 992px) { - .flex-lg-row { - flex-direction: row !important; } - .flex-lg-column { - flex-direction: column !important; } - .flex-lg-row-reverse { - flex-direction: row-reverse !important; } - .flex-lg-column-reverse { - flex-direction: column-reverse !important; } - .flex-lg-wrap { - flex-wrap: wrap !important; } - .flex-lg-nowrap { - flex-wrap: nowrap !important; } - .flex-lg-wrap-reverse { - flex-wrap: wrap-reverse !important; } - .flex-lg-fill { - flex: 1 1 auto !important; } - .flex-lg-grow-0 { - flex-grow: 0 !important; } - .flex-lg-grow-1 { - flex-grow: 1 !important; } - .flex-lg-shrink-0 { - flex-shrink: 0 !important; } - .flex-lg-shrink-1 { - flex-shrink: 1 !important; } - .justify-content-lg-start { - justify-content: flex-start !important; } - .justify-content-lg-end { - justify-content: flex-end !important; } - .justify-content-lg-center { - justify-content: center !important; } - .justify-content-lg-between { - justify-content: space-between !important; } - .justify-content-lg-around { - justify-content: space-around !important; } - .align-items-lg-start { - align-items: flex-start !important; } - .align-items-lg-end { - align-items: flex-end !important; } - .align-items-lg-center { - align-items: center !important; } - .align-items-lg-baseline { - align-items: baseline !important; } - .align-items-lg-stretch { - align-items: stretch !important; } - .align-content-lg-start { - align-content: flex-start !important; } - .align-content-lg-end { - align-content: flex-end !important; } - .align-content-lg-center { - align-content: center !important; } - .align-content-lg-between { - align-content: space-between !important; } - .align-content-lg-around { - align-content: space-around !important; } - .align-content-lg-stretch { - align-content: stretch !important; } - .align-self-lg-auto { - align-self: auto !important; } - .align-self-lg-start { - align-self: flex-start !important; } - .align-self-lg-end { - align-self: flex-end !important; } - .align-self-lg-center { - align-self: center !important; } - .align-self-lg-baseline { - align-self: baseline !important; } - .align-self-lg-stretch { - align-self: stretch !important; } } - -@media (min-width: 1200px) { - .flex-xl-row { - flex-direction: row !important; } - .flex-xl-column { - flex-direction: column !important; } - .flex-xl-row-reverse { - flex-direction: row-reverse !important; } - .flex-xl-column-reverse { - flex-direction: column-reverse !important; } - .flex-xl-wrap { - flex-wrap: wrap !important; } - .flex-xl-nowrap { - flex-wrap: nowrap !important; } - .flex-xl-wrap-reverse { - flex-wrap: wrap-reverse !important; } - .flex-xl-fill { - flex: 1 1 auto !important; } - .flex-xl-grow-0 { - flex-grow: 0 !important; } - .flex-xl-grow-1 { - flex-grow: 1 !important; } - .flex-xl-shrink-0 { - flex-shrink: 0 !important; } - .flex-xl-shrink-1 { - flex-shrink: 1 !important; } - .justify-content-xl-start { - justify-content: flex-start !important; } - .justify-content-xl-end { - justify-content: flex-end !important; } - .justify-content-xl-center { - justify-content: center !important; } - .justify-content-xl-between { - justify-content: space-between !important; } - .justify-content-xl-around { - justify-content: space-around !important; } - .align-items-xl-start { - align-items: flex-start !important; } - .align-items-xl-end { - align-items: flex-end !important; } - .align-items-xl-center { - align-items: center !important; } - .align-items-xl-baseline { - align-items: baseline !important; } - .align-items-xl-stretch { - align-items: stretch !important; } - .align-content-xl-start { - align-content: flex-start !important; } - .align-content-xl-end { - align-content: flex-end !important; } - .align-content-xl-center { - align-content: center !important; } - .align-content-xl-between { - align-content: space-between !important; } - .align-content-xl-around { - align-content: space-around !important; } - .align-content-xl-stretch { - align-content: stretch !important; } - .align-self-xl-auto { - align-self: auto !important; } - .align-self-xl-start { - align-self: flex-start !important; } - .align-self-xl-end { - align-self: flex-end !important; } - .align-self-xl-center { - align-self: center !important; } - .align-self-xl-baseline { - align-self: baseline !important; } - .align-self-xl-stretch { - align-self: stretch !important; } } - -.float-left { - float: left !important; } - -.float-right { - float: right !important; } - -.float-none { - float: none !important; } - -@media (min-width: 576px) { - .float-sm-left { - float: left !important; } - .float-sm-right { - float: right !important; } - .float-sm-none { - float: none !important; } } - -@media (min-width: 768px) { - .float-md-left { - float: left !important; } - .float-md-right { - float: right !important; } - .float-md-none { - float: none !important; } } - -@media (min-width: 992px) { - .float-lg-left { - float: left !important; } - .float-lg-right { - float: right !important; } - .float-lg-none { - float: none !important; } } - -@media (min-width: 1200px) { - .float-xl-left { - float: left !important; } - .float-xl-right { - float: right !important; } - .float-xl-none { - float: none !important; } } - -.user-select-all { - -webkit-user-select: all !important; - -moz-user-select: all !important; - user-select: all !important; } - -.user-select-auto { - -webkit-user-select: auto !important; - -moz-user-select: auto !important; - -ms-user-select: auto !important; - user-select: auto !important; } - -.user-select-none { - -webkit-user-select: none !important; - -moz-user-select: none !important; - -ms-user-select: none !important; - user-select: none !important; } - -.overflow-auto { - overflow: auto !important; } - -.overflow-hidden { - overflow: hidden !important; } - -.position-static { - position: static !important; } - -.position-relative { - position: relative !important; } - -.position-absolute { - position: absolute !important; } - -.position-fixed { - position: fixed !important; } - -.position-sticky { - position: -webkit-sticky !important; - position: sticky !important; } - -.fixed-top { - position: fixed; - top: 0; - right: 0; - left: 0; - z-index: 1030; } - -.fixed-bottom { - position: fixed; - right: 0; - bottom: 0; - left: 0; - z-index: 1030; } - -@supports ((position: -webkit-sticky) or (position: sticky)) { - .sticky-top { - position: -webkit-sticky; - position: sticky; - top: 0; - z-index: 1020; } } - -.sr-only { - position: absolute; - width: 1px; - height: 1px; - padding: 0; - margin: -1px; - overflow: hidden; - clip: rect(0, 0, 0, 0); - white-space: nowrap; - border: 0; } - -.sr-only-focusable:active, .sr-only-focusable:focus { - position: static; - width: auto; - height: auto; - overflow: visible; - clip: auto; - white-space: normal; } - -.shadow-sm { - box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075) !important; } - -.shadow { - box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15) !important; } - -.shadow-lg { - box-shadow: 0 1rem 3rem rgba(0, 0, 0, 0.175) !important; } - -.shadow-none { - box-shadow: none !important; } - -.w-25 { - width: 25% !important; } - -.w-50 { - width: 50% !important; } - -.w-75 { - width: 75% !important; } - -.w-100 { - width: 100% !important; } - -.w-auto { - width: auto !important; } - -.h-25 { - height: 25% !important; } - -.h-50 { - height: 50% !important; } - -.h-75 { - height: 75% !important; } - -.h-100 { - height: 100% !important; } - -.h-auto { - height: auto !important; } - -.mw-100 { - max-width: 100% !important; } - -.mh-100 { - max-height: 100% !important; } - -.min-vw-100 { - min-width: 100vw !important; } - -.min-vh-100 { - min-height: 100vh !important; } - -.vw-100 { - width: 100vw !important; } - -.vh-100 { - height: 100vh !important; } - -.m-0 { - margin: 0 !important; } - -.mt-0, -.my-0 { - margin-top: 0 !important; } - -.mr-0, -.mx-0 { - margin-right: 0 !important; } - -.mb-0, -.my-0 { - margin-bottom: 0 !important; } - -.ml-0, -.mx-0 { - margin-left: 0 !important; } - -.m-1 { - margin: 0.25rem !important; } - -.mt-1, -.my-1 { - margin-top: 0.25rem !important; } - -.mr-1, -.mx-1 { - margin-right: 0.25rem !important; } - -.mb-1, -.my-1 { - margin-bottom: 0.25rem !important; } - -.ml-1, -.mx-1 { - margin-left: 0.25rem !important; } - -.m-2 { - margin: 0.5rem !important; } - -.mt-2, -.my-2 { - margin-top: 0.5rem !important; } - -.mr-2, -.mx-2 { - margin-right: 0.5rem !important; } - -.mb-2, -.my-2 { - margin-bottom: 0.5rem !important; } - -.ml-2, -.mx-2 { - margin-left: 0.5rem !important; } - -.m-3 { - margin: 1rem !important; } - -.mt-3, -.my-3 { - margin-top: 1rem !important; } - -.mr-3, -.mx-3 { - margin-right: 1rem !important; } - -.mb-3, -.my-3 { - margin-bottom: 1rem !important; } - -.ml-3, -.mx-3 { - margin-left: 1rem !important; } - -.m-4 { - margin: 1.5rem !important; } - -.mt-4, -.my-4 { - margin-top: 1.5rem !important; } - -.mr-4, -.mx-4 { - margin-right: 1.5rem !important; } - -.mb-4, -.my-4 { - margin-bottom: 1.5rem !important; } - -.ml-4, -.mx-4 { - margin-left: 1.5rem !important; } - -.m-5 { - margin: 3rem !important; } - -.mt-5, -.my-5 { - margin-top: 3rem !important; } - -.mr-5, -.mx-5 { - margin-right: 3rem !important; } - -.mb-5, -.my-5 { - margin-bottom: 3rem !important; } - -.ml-5, -.mx-5 { - margin-left: 3rem !important; } - -.p-0 { - padding: 0 !important; } - -.pt-0, -.py-0 { - padding-top: 0 !important; } - -.pr-0, -.px-0 { - padding-right: 0 !important; } - -.pb-0, -.py-0 { - padding-bottom: 0 !important; } - -.pl-0, -.px-0 { - padding-left: 0 !important; } - -.p-1 { - padding: 0.25rem !important; } - -.pt-1, -.py-1 { - padding-top: 0.25rem !important; } - -.pr-1, -.px-1 { - padding-right: 0.25rem !important; } - -.pb-1, -.py-1 { - padding-bottom: 0.25rem !important; } - -.pl-1, -.px-1 { - padding-left: 0.25rem !important; } - -.p-2 { - padding: 0.5rem !important; } - -.pt-2, -.py-2 { - padding-top: 0.5rem !important; } - -.pr-2, -.px-2 { - padding-right: 0.5rem !important; } - -.pb-2, -.py-2 { - padding-bottom: 0.5rem !important; } - -.pl-2, -.px-2 { - padding-left: 0.5rem !important; } - -.p-3 { - padding: 1rem !important; } - -.pt-3, -.py-3 { - padding-top: 1rem !important; } - -.pr-3, -.px-3 { - padding-right: 1rem !important; } - -.pb-3, -.py-3 { - padding-bottom: 1rem !important; } - -.pl-3, -.px-3 { - padding-left: 1rem !important; } - -.p-4 { - padding: 1.5rem !important; } - -.pt-4, -.py-4 { - padding-top: 1.5rem !important; } - -.pr-4, -.px-4 { - padding-right: 1.5rem !important; } - -.pb-4, -.py-4 { - padding-bottom: 1.5rem !important; } - -.pl-4, -.px-4 { - padding-left: 1.5rem !important; } - -.p-5 { - padding: 3rem !important; } - -.pt-5, -.py-5 { - padding-top: 3rem !important; } - -.pr-5, -.px-5 { - padding-right: 3rem !important; } - -.pb-5, -.py-5 { - padding-bottom: 3rem !important; } - -.pl-5, -.px-5 { - padding-left: 3rem !important; } - -.m-n1 { - margin: -0.25rem !important; } - -.mt-n1, -.my-n1 { - margin-top: -0.25rem !important; } - -.mr-n1, -.mx-n1 { - margin-right: -0.25rem !important; } - -.mb-n1, -.my-n1 { - margin-bottom: -0.25rem !important; } - -.ml-n1, -.mx-n1 { - margin-left: -0.25rem !important; } - -.m-n2 { - margin: -0.5rem !important; } - -.mt-n2, -.my-n2 { - margin-top: -0.5rem !important; } - -.mr-n2, -.mx-n2 { - margin-right: -0.5rem !important; } - -.mb-n2, -.my-n2 { - margin-bottom: -0.5rem !important; } - -.ml-n2, -.mx-n2 { - margin-left: -0.5rem !important; } - -.m-n3 { - margin: -1rem !important; } - -.mt-n3, -.my-n3 { - margin-top: -1rem !important; } - -.mr-n3, -.mx-n3 { - margin-right: -1rem !important; } - -.mb-n3, -.my-n3 { - margin-bottom: -1rem !important; } - -.ml-n3, -.mx-n3 { - margin-left: -1rem !important; } - -.m-n4 { - margin: -1.5rem !important; } - -.mt-n4, -.my-n4 { - margin-top: -1.5rem !important; } - -.mr-n4, -.mx-n4 { - margin-right: -1.5rem !important; } - -.mb-n4, -.my-n4 { - margin-bottom: -1.5rem !important; } - -.ml-n4, -.mx-n4 { - margin-left: -1.5rem !important; } - -.m-n5 { - margin: -3rem !important; } - -.mt-n5, -.my-n5 { - margin-top: -3rem !important; } - -.mr-n5, -.mx-n5 { - margin-right: -3rem !important; } - -.mb-n5, -.my-n5 { - margin-bottom: -3rem !important; } - -.ml-n5, -.mx-n5 { - margin-left: -3rem !important; } - -.m-auto { - margin: auto !important; } - -.mt-auto, -.my-auto { - margin-top: auto !important; } - -.mr-auto, -.mx-auto { - margin-right: auto !important; } - -.mb-auto, -.my-auto { - margin-bottom: auto !important; } - -.ml-auto, -.mx-auto { - margin-left: auto !important; } - -@media (min-width: 576px) { - .m-sm-0 { - margin: 0 !important; } - .mt-sm-0, - .my-sm-0 { - margin-top: 0 !important; } - .mr-sm-0, - .mx-sm-0 { - margin-right: 0 !important; } - .mb-sm-0, - .my-sm-0 { - margin-bottom: 0 !important; } - .ml-sm-0, - .mx-sm-0 { - margin-left: 0 !important; } - .m-sm-1 { - margin: 0.25rem !important; } - .mt-sm-1, - .my-sm-1 { - margin-top: 0.25rem !important; } - .mr-sm-1, - .mx-sm-1 { - margin-right: 0.25rem !important; } - .mb-sm-1, - .my-sm-1 { - margin-bottom: 0.25rem !important; } - .ml-sm-1, - .mx-sm-1 { - margin-left: 0.25rem !important; } - .m-sm-2 { - margin: 0.5rem !important; } - .mt-sm-2, - .my-sm-2 { - margin-top: 0.5rem !important; } - .mr-sm-2, - .mx-sm-2 { - margin-right: 0.5rem !important; } - .mb-sm-2, - .my-sm-2 { - margin-bottom: 0.5rem !important; } - .ml-sm-2, - .mx-sm-2 { - margin-left: 0.5rem !important; } - .m-sm-3 { - margin: 1rem !important; } - .mt-sm-3, - .my-sm-3 { - margin-top: 1rem !important; } - .mr-sm-3, - .mx-sm-3 { - margin-right: 1rem !important; } - .mb-sm-3, - .my-sm-3 { - margin-bottom: 1rem !important; } - .ml-sm-3, - .mx-sm-3 { - margin-left: 1rem !important; } - .m-sm-4 { - margin: 1.5rem !important; } - .mt-sm-4, - .my-sm-4 { - margin-top: 1.5rem !important; } - .mr-sm-4, - .mx-sm-4 { - margin-right: 1.5rem !important; } - .mb-sm-4, - .my-sm-4 { - margin-bottom: 1.5rem !important; } - .ml-sm-4, - .mx-sm-4 { - margin-left: 1.5rem !important; } - .m-sm-5 { - margin: 3rem !important; } - .mt-sm-5, - .my-sm-5 { - margin-top: 3rem !important; } - .mr-sm-5, - .mx-sm-5 { - margin-right: 3rem !important; } - .mb-sm-5, - .my-sm-5 { - margin-bottom: 3rem !important; } - .ml-sm-5, - .mx-sm-5 { - margin-left: 3rem !important; } - .p-sm-0 { - padding: 0 !important; } - .pt-sm-0, - .py-sm-0 { - padding-top: 0 !important; } - .pr-sm-0, - .px-sm-0 { - padding-right: 0 !important; } - .pb-sm-0, - .py-sm-0 { - padding-bottom: 0 !important; } - .pl-sm-0, - .px-sm-0 { - padding-left: 0 !important; } - .p-sm-1 { - padding: 0.25rem !important; } - .pt-sm-1, - .py-sm-1 { - padding-top: 0.25rem !important; } - .pr-sm-1, - .px-sm-1 { - padding-right: 0.25rem !important; } - .pb-sm-1, - .py-sm-1 { - padding-bottom: 0.25rem !important; } - .pl-sm-1, - .px-sm-1 { - padding-left: 0.25rem !important; } - .p-sm-2 { - padding: 0.5rem !important; } - .pt-sm-2, - .py-sm-2 { - padding-top: 0.5rem !important; } - .pr-sm-2, - .px-sm-2 { - padding-right: 0.5rem !important; } - .pb-sm-2, - .py-sm-2 { - padding-bottom: 0.5rem !important; } - .pl-sm-2, - .px-sm-2 { - padding-left: 0.5rem !important; } - .p-sm-3 { - padding: 1rem !important; } - .pt-sm-3, - .py-sm-3 { - padding-top: 1rem !important; } - .pr-sm-3, - .px-sm-3 { - padding-right: 1rem !important; } - .pb-sm-3, - .py-sm-3 { - padding-bottom: 1rem !important; } - .pl-sm-3, - .px-sm-3 { - padding-left: 1rem !important; } - .p-sm-4 { - padding: 1.5rem !important; } - .pt-sm-4, - .py-sm-4 { - padding-top: 1.5rem !important; } - .pr-sm-4, - .px-sm-4 { - padding-right: 1.5rem !important; } - .pb-sm-4, - .py-sm-4 { - padding-bottom: 1.5rem !important; } - .pl-sm-4, - .px-sm-4 { - padding-left: 1.5rem !important; } - .p-sm-5 { - padding: 3rem !important; } - .pt-sm-5, - .py-sm-5 { - padding-top: 3rem !important; } - .pr-sm-5, - .px-sm-5 { - padding-right: 3rem !important; } - .pb-sm-5, - .py-sm-5 { - padding-bottom: 3rem !important; } - .pl-sm-5, - .px-sm-5 { - padding-left: 3rem !important; } - .m-sm-n1 { - margin: -0.25rem !important; } - .mt-sm-n1, - .my-sm-n1 { - margin-top: -0.25rem !important; } - .mr-sm-n1, - .mx-sm-n1 { - margin-right: -0.25rem !important; } - .mb-sm-n1, - .my-sm-n1 { - margin-bottom: -0.25rem !important; } - .ml-sm-n1, - .mx-sm-n1 { - margin-left: -0.25rem !important; } - .m-sm-n2 { - margin: -0.5rem !important; } - .mt-sm-n2, - .my-sm-n2 { - margin-top: -0.5rem !important; } - .mr-sm-n2, - .mx-sm-n2 { - margin-right: -0.5rem !important; } - .mb-sm-n2, - .my-sm-n2 { - margin-bottom: -0.5rem !important; } - .ml-sm-n2, - .mx-sm-n2 { - margin-left: -0.5rem !important; } - .m-sm-n3 { - margin: -1rem !important; } - .mt-sm-n3, - .my-sm-n3 { - margin-top: -1rem !important; } - .mr-sm-n3, - .mx-sm-n3 { - margin-right: -1rem !important; } - .mb-sm-n3, - .my-sm-n3 { - margin-bottom: -1rem !important; } - .ml-sm-n3, - .mx-sm-n3 { - margin-left: -1rem !important; } - .m-sm-n4 { - margin: -1.5rem !important; } - .mt-sm-n4, - .my-sm-n4 { - margin-top: -1.5rem !important; } - .mr-sm-n4, - .mx-sm-n4 { - margin-right: -1.5rem !important; } - .mb-sm-n4, - .my-sm-n4 { - margin-bottom: -1.5rem !important; } - .ml-sm-n4, - .mx-sm-n4 { - margin-left: -1.5rem !important; } - .m-sm-n5 { - margin: -3rem !important; } - .mt-sm-n5, - .my-sm-n5 { - margin-top: -3rem !important; } - .mr-sm-n5, - .mx-sm-n5 { - margin-right: -3rem !important; } - .mb-sm-n5, - .my-sm-n5 { - margin-bottom: -3rem !important; } - .ml-sm-n5, - .mx-sm-n5 { - margin-left: -3rem !important; } - .m-sm-auto { - margin: auto !important; } - .mt-sm-auto, - .my-sm-auto { - margin-top: auto !important; } - .mr-sm-auto, - .mx-sm-auto { - margin-right: auto !important; } - .mb-sm-auto, - .my-sm-auto { - margin-bottom: auto !important; } - .ml-sm-auto, - .mx-sm-auto { - margin-left: auto !important; } } - -@media (min-width: 768px) { - .m-md-0 { - margin: 0 !important; } - .mt-md-0, - .my-md-0 { - margin-top: 0 !important; } - .mr-md-0, - .mx-md-0 { - margin-right: 0 !important; } - .mb-md-0, - .my-md-0 { - margin-bottom: 0 !important; } - .ml-md-0, - .mx-md-0 { - margin-left: 0 !important; } - .m-md-1 { - margin: 0.25rem !important; } - .mt-md-1, - .my-md-1 { - margin-top: 0.25rem !important; } - .mr-md-1, - .mx-md-1 { - margin-right: 0.25rem !important; } - .mb-md-1, - .my-md-1 { - margin-bottom: 0.25rem !important; } - .ml-md-1, - .mx-md-1 { - margin-left: 0.25rem !important; } - .m-md-2 { - margin: 0.5rem !important; } - .mt-md-2, - .my-md-2 { - margin-top: 0.5rem !important; } - .mr-md-2, - .mx-md-2 { - margin-right: 0.5rem !important; } - .mb-md-2, - .my-md-2 { - margin-bottom: 0.5rem !important; } - .ml-md-2, - .mx-md-2 { - margin-left: 0.5rem !important; } - .m-md-3 { - margin: 1rem !important; } - .mt-md-3, - .my-md-3 { - margin-top: 1rem !important; } - .mr-md-3, - .mx-md-3 { - margin-right: 1rem !important; } - .mb-md-3, - .my-md-3 { - margin-bottom: 1rem !important; } - .ml-md-3, - .mx-md-3 { - margin-left: 1rem !important; } - .m-md-4 { - margin: 1.5rem !important; } - .mt-md-4, - .my-md-4 { - margin-top: 1.5rem !important; } - .mr-md-4, - .mx-md-4 { - margin-right: 1.5rem !important; } - .mb-md-4, - .my-md-4 { - margin-bottom: 1.5rem !important; } - .ml-md-4, - .mx-md-4 { - margin-left: 1.5rem !important; } - .m-md-5 { - margin: 3rem !important; } - .mt-md-5, - .my-md-5 { - margin-top: 3rem !important; } - .mr-md-5, - .mx-md-5 { - margin-right: 3rem !important; } - .mb-md-5, - .my-md-5 { - margin-bottom: 3rem !important; } - .ml-md-5, - .mx-md-5 { - margin-left: 3rem !important; } - .p-md-0 { - padding: 0 !important; } - .pt-md-0, - .py-md-0 { - padding-top: 0 !important; } - .pr-md-0, - .px-md-0 { - padding-right: 0 !important; } - .pb-md-0, - .py-md-0 { - padding-bottom: 0 !important; } - .pl-md-0, - .px-md-0 { - padding-left: 0 !important; } - .p-md-1 { - padding: 0.25rem !important; } - .pt-md-1, - .py-md-1 { - padding-top: 0.25rem !important; } - .pr-md-1, - .px-md-1 { - padding-right: 0.25rem !important; } - .pb-md-1, - .py-md-1 { - padding-bottom: 0.25rem !important; } - .pl-md-1, - .px-md-1 { - padding-left: 0.25rem !important; } - .p-md-2 { - padding: 0.5rem !important; } - .pt-md-2, - .py-md-2 { - padding-top: 0.5rem !important; } - .pr-md-2, - .px-md-2 { - padding-right: 0.5rem !important; } - .pb-md-2, - .py-md-2 { - padding-bottom: 0.5rem !important; } - .pl-md-2, - .px-md-2 { - padding-left: 0.5rem !important; } - .p-md-3 { - padding: 1rem !important; } - .pt-md-3, - .py-md-3 { - padding-top: 1rem !important; } - .pr-md-3, - .px-md-3 { - padding-right: 1rem !important; } - .pb-md-3, - .py-md-3 { - padding-bottom: 1rem !important; } - .pl-md-3, - .px-md-3 { - padding-left: 1rem !important; } - .p-md-4 { - padding: 1.5rem !important; } - .pt-md-4, - .py-md-4 { - padding-top: 1.5rem !important; } - .pr-md-4, - .px-md-4 { - padding-right: 1.5rem !important; } - .pb-md-4, - .py-md-4 { - padding-bottom: 1.5rem !important; } - .pl-md-4, - .px-md-4 { - padding-left: 1.5rem !important; } - .p-md-5 { - padding: 3rem !important; } - .pt-md-5, - .py-md-5 { - padding-top: 3rem !important; } - .pr-md-5, - .px-md-5 { - padding-right: 3rem !important; } - .pb-md-5, - .py-md-5 { - padding-bottom: 3rem !important; } - .pl-md-5, - .px-md-5 { - padding-left: 3rem !important; } - .m-md-n1 { - margin: -0.25rem !important; } - .mt-md-n1, - .my-md-n1 { - margin-top: -0.25rem !important; } - .mr-md-n1, - .mx-md-n1 { - margin-right: -0.25rem !important; } - .mb-md-n1, - .my-md-n1 { - margin-bottom: -0.25rem !important; } - .ml-md-n1, - .mx-md-n1 { - margin-left: -0.25rem !important; } - .m-md-n2 { - margin: -0.5rem !important; } - .mt-md-n2, - .my-md-n2 { - margin-top: -0.5rem !important; } - .mr-md-n2, - .mx-md-n2 { - margin-right: -0.5rem !important; } - .mb-md-n2, - .my-md-n2 { - margin-bottom: -0.5rem !important; } - .ml-md-n2, - .mx-md-n2 { - margin-left: -0.5rem !important; } - .m-md-n3 { - margin: -1rem !important; } - .mt-md-n3, - .my-md-n3 { - margin-top: -1rem !important; } - .mr-md-n3, - .mx-md-n3 { - margin-right: -1rem !important; } - .mb-md-n3, - .my-md-n3 { - margin-bottom: -1rem !important; } - .ml-md-n3, - .mx-md-n3 { - margin-left: -1rem !important; } - .m-md-n4 { - margin: -1.5rem !important; } - .mt-md-n4, - .my-md-n4 { - margin-top: -1.5rem !important; } - .mr-md-n4, - .mx-md-n4 { - margin-right: -1.5rem !important; } - .mb-md-n4, - .my-md-n4 { - margin-bottom: -1.5rem !important; } - .ml-md-n4, - .mx-md-n4 { - margin-left: -1.5rem !important; } - .m-md-n5 { - margin: -3rem !important; } - .mt-md-n5, - .my-md-n5 { - margin-top: -3rem !important; } - .mr-md-n5, - .mx-md-n5 { - margin-right: -3rem !important; } - .mb-md-n5, - .my-md-n5 { - margin-bottom: -3rem !important; } - .ml-md-n5, - .mx-md-n5 { - margin-left: -3rem !important; } - .m-md-auto { - margin: auto !important; } - .mt-md-auto, - .my-md-auto { - margin-top: auto !important; } - .mr-md-auto, - .mx-md-auto { - margin-right: auto !important; } - .mb-md-auto, - .my-md-auto { - margin-bottom: auto !important; } - .ml-md-auto, - .mx-md-auto { - margin-left: auto !important; } } - -@media (min-width: 992px) { - .m-lg-0 { - margin: 0 !important; } - .mt-lg-0, - .my-lg-0 { - margin-top: 0 !important; } - .mr-lg-0, - .mx-lg-0 { - margin-right: 0 !important; } - .mb-lg-0, - .my-lg-0 { - margin-bottom: 0 !important; } - .ml-lg-0, - .mx-lg-0 { - margin-left: 0 !important; } - .m-lg-1 { - margin: 0.25rem !important; } - .mt-lg-1, - .my-lg-1 { - margin-top: 0.25rem !important; } - .mr-lg-1, - .mx-lg-1 { - margin-right: 0.25rem !important; } - .mb-lg-1, - .my-lg-1 { - margin-bottom: 0.25rem !important; } - .ml-lg-1, - .mx-lg-1 { - margin-left: 0.25rem !important; } - .m-lg-2 { - margin: 0.5rem !important; } - .mt-lg-2, - .my-lg-2 { - margin-top: 0.5rem !important; } - .mr-lg-2, - .mx-lg-2 { - margin-right: 0.5rem !important; } - .mb-lg-2, - .my-lg-2 { - margin-bottom: 0.5rem !important; } - .ml-lg-2, - .mx-lg-2 { - margin-left: 0.5rem !important; } - .m-lg-3 { - margin: 1rem !important; } - .mt-lg-3, - .my-lg-3 { - margin-top: 1rem !important; } - .mr-lg-3, - .mx-lg-3 { - margin-right: 1rem !important; } - .mb-lg-3, - .my-lg-3 { - margin-bottom: 1rem !important; } - .ml-lg-3, - .mx-lg-3 { - margin-left: 1rem !important; } - .m-lg-4 { - margin: 1.5rem !important; } - .mt-lg-4, - .my-lg-4 { - margin-top: 1.5rem !important; } - .mr-lg-4, - .mx-lg-4 { - margin-right: 1.5rem !important; } - .mb-lg-4, - .my-lg-4 { - margin-bottom: 1.5rem !important; } - .ml-lg-4, - .mx-lg-4 { - margin-left: 1.5rem !important; } - .m-lg-5 { - margin: 3rem !important; } - .mt-lg-5, - .my-lg-5 { - margin-top: 3rem !important; } - .mr-lg-5, - .mx-lg-5 { - margin-right: 3rem !important; } - .mb-lg-5, - .my-lg-5 { - margin-bottom: 3rem !important; } - .ml-lg-5, - .mx-lg-5 { - margin-left: 3rem !important; } - .p-lg-0 { - padding: 0 !important; } - .pt-lg-0, - .py-lg-0 { - padding-top: 0 !important; } - .pr-lg-0, - .px-lg-0 { - padding-right: 0 !important; } - .pb-lg-0, - .py-lg-0 { - padding-bottom: 0 !important; } - .pl-lg-0, - .px-lg-0 { - padding-left: 0 !important; } - .p-lg-1 { - padding: 0.25rem !important; } - .pt-lg-1, - .py-lg-1 { - padding-top: 0.25rem !important; } - .pr-lg-1, - .px-lg-1 { - padding-right: 0.25rem !important; } - .pb-lg-1, - .py-lg-1 { - padding-bottom: 0.25rem !important; } - .pl-lg-1, - .px-lg-1 { - padding-left: 0.25rem !important; } - .p-lg-2 { - padding: 0.5rem !important; } - .pt-lg-2, - .py-lg-2 { - padding-top: 0.5rem !important; } - .pr-lg-2, - .px-lg-2 { - padding-right: 0.5rem !important; } - .pb-lg-2, - .py-lg-2 { - padding-bottom: 0.5rem !important; } - .pl-lg-2, - .px-lg-2 { - padding-left: 0.5rem !important; } - .p-lg-3 { - padding: 1rem !important; } - .pt-lg-3, - .py-lg-3 { - padding-top: 1rem !important; } - .pr-lg-3, - .px-lg-3 { - padding-right: 1rem !important; } - .pb-lg-3, - .py-lg-3 { - padding-bottom: 1rem !important; } - .pl-lg-3, - .px-lg-3 { - padding-left: 1rem !important; } - .p-lg-4 { - padding: 1.5rem !important; } - .pt-lg-4, - .py-lg-4 { - padding-top: 1.5rem !important; } - .pr-lg-4, - .px-lg-4 { - padding-right: 1.5rem !important; } - .pb-lg-4, - .py-lg-4 { - padding-bottom: 1.5rem !important; } - .pl-lg-4, - .px-lg-4 { - padding-left: 1.5rem !important; } - .p-lg-5 { - padding: 3rem !important; } - .pt-lg-5, - .py-lg-5 { - padding-top: 3rem !important; } - .pr-lg-5, - .px-lg-5 { - padding-right: 3rem !important; } - .pb-lg-5, - .py-lg-5 { - padding-bottom: 3rem !important; } - .pl-lg-5, - .px-lg-5 { - padding-left: 3rem !important; } - .m-lg-n1 { - margin: -0.25rem !important; } - .mt-lg-n1, - .my-lg-n1 { - margin-top: -0.25rem !important; } - .mr-lg-n1, - .mx-lg-n1 { - margin-right: -0.25rem !important; } - .mb-lg-n1, - .my-lg-n1 { - margin-bottom: -0.25rem !important; } - .ml-lg-n1, - .mx-lg-n1 { - margin-left: -0.25rem !important; } - .m-lg-n2 { - margin: -0.5rem !important; } - .mt-lg-n2, - .my-lg-n2 { - margin-top: -0.5rem !important; } - .mr-lg-n2, - .mx-lg-n2 { - margin-right: -0.5rem !important; } - .mb-lg-n2, - .my-lg-n2 { - margin-bottom: -0.5rem !important; } - .ml-lg-n2, - .mx-lg-n2 { - margin-left: -0.5rem !important; } - .m-lg-n3 { - margin: -1rem !important; } - .mt-lg-n3, - .my-lg-n3 { - margin-top: -1rem !important; } - .mr-lg-n3, - .mx-lg-n3 { - margin-right: -1rem !important; } - .mb-lg-n3, - .my-lg-n3 { - margin-bottom: -1rem !important; } - .ml-lg-n3, - .mx-lg-n3 { - margin-left: -1rem !important; } - .m-lg-n4 { - margin: -1.5rem !important; } - .mt-lg-n4, - .my-lg-n4 { - margin-top: -1.5rem !important; } - .mr-lg-n4, - .mx-lg-n4 { - margin-right: -1.5rem !important; } - .mb-lg-n4, - .my-lg-n4 { - margin-bottom: -1.5rem !important; } - .ml-lg-n4, - .mx-lg-n4 { - margin-left: -1.5rem !important; } - .m-lg-n5 { - margin: -3rem !important; } - .mt-lg-n5, - .my-lg-n5 { - margin-top: -3rem !important; } - .mr-lg-n5, - .mx-lg-n5 { - margin-right: -3rem !important; } - .mb-lg-n5, - .my-lg-n5 { - margin-bottom: -3rem !important; } - .ml-lg-n5, - .mx-lg-n5 { - margin-left: -3rem !important; } - .m-lg-auto { - margin: auto !important; } - .mt-lg-auto, - .my-lg-auto { - margin-top: auto !important; } - .mr-lg-auto, - .mx-lg-auto { - margin-right: auto !important; } - .mb-lg-auto, - .my-lg-auto { - margin-bottom: auto !important; } - .ml-lg-auto, - .mx-lg-auto { - margin-left: auto !important; } } - -@media (min-width: 1200px) { - .m-xl-0 { - margin: 0 !important; } - .mt-xl-0, - .my-xl-0 { - margin-top: 0 !important; } - .mr-xl-0, - .mx-xl-0 { - margin-right: 0 !important; } - .mb-xl-0, - .my-xl-0 { - margin-bottom: 0 !important; } - .ml-xl-0, - .mx-xl-0 { - margin-left: 0 !important; } - .m-xl-1 { - margin: 0.25rem !important; } - .mt-xl-1, - .my-xl-1 { - margin-top: 0.25rem !important; } - .mr-xl-1, - .mx-xl-1 { - margin-right: 0.25rem !important; } - .mb-xl-1, - .my-xl-1 { - margin-bottom: 0.25rem !important; } - .ml-xl-1, - .mx-xl-1 { - margin-left: 0.25rem !important; } - .m-xl-2 { - margin: 0.5rem !important; } - .mt-xl-2, - .my-xl-2 { - margin-top: 0.5rem !important; } - .mr-xl-2, - .mx-xl-2 { - margin-right: 0.5rem !important; } - .mb-xl-2, - .my-xl-2 { - margin-bottom: 0.5rem !important; } - .ml-xl-2, - .mx-xl-2 { - margin-left: 0.5rem !important; } - .m-xl-3 { - margin: 1rem !important; } - .mt-xl-3, - .my-xl-3 { - margin-top: 1rem !important; } - .mr-xl-3, - .mx-xl-3 { - margin-right: 1rem !important; } - .mb-xl-3, - .my-xl-3 { - margin-bottom: 1rem !important; } - .ml-xl-3, - .mx-xl-3 { - margin-left: 1rem !important; } - .m-xl-4 { - margin: 1.5rem !important; } - .mt-xl-4, - .my-xl-4 { - margin-top: 1.5rem !important; } - .mr-xl-4, - .mx-xl-4 { - margin-right: 1.5rem !important; } - .mb-xl-4, - .my-xl-4 { - margin-bottom: 1.5rem !important; } - .ml-xl-4, - .mx-xl-4 { - margin-left: 1.5rem !important; } - .m-xl-5 { - margin: 3rem !important; } - .mt-xl-5, - .my-xl-5 { - margin-top: 3rem !important; } - .mr-xl-5, - .mx-xl-5 { - margin-right: 3rem !important; } - .mb-xl-5, - .my-xl-5 { - margin-bottom: 3rem !important; } - .ml-xl-5, - .mx-xl-5 { - margin-left: 3rem !important; } - .p-xl-0 { - padding: 0 !important; } - .pt-xl-0, - .py-xl-0 { - padding-top: 0 !important; } - .pr-xl-0, - .px-xl-0 { - padding-right: 0 !important; } - .pb-xl-0, - .py-xl-0 { - padding-bottom: 0 !important; } - .pl-xl-0, - .px-xl-0 { - padding-left: 0 !important; } - .p-xl-1 { - padding: 0.25rem !important; } - .pt-xl-1, - .py-xl-1 { - padding-top: 0.25rem !important; } - .pr-xl-1, - .px-xl-1 { - padding-right: 0.25rem !important; } - .pb-xl-1, - .py-xl-1 { - padding-bottom: 0.25rem !important; } - .pl-xl-1, - .px-xl-1 { - padding-left: 0.25rem !important; } - .p-xl-2 { - padding: 0.5rem !important; } - .pt-xl-2, - .py-xl-2 { - padding-top: 0.5rem !important; } - .pr-xl-2, - .px-xl-2 { - padding-right: 0.5rem !important; } - .pb-xl-2, - .py-xl-2 { - padding-bottom: 0.5rem !important; } - .pl-xl-2, - .px-xl-2 { - padding-left: 0.5rem !important; } - .p-xl-3 { - padding: 1rem !important; } - .pt-xl-3, - .py-xl-3 { - padding-top: 1rem !important; } - .pr-xl-3, - .px-xl-3 { - padding-right: 1rem !important; } - .pb-xl-3, - .py-xl-3 { - padding-bottom: 1rem !important; } - .pl-xl-3, - .px-xl-3 { - padding-left: 1rem !important; } - .p-xl-4 { - padding: 1.5rem !important; } - .pt-xl-4, - .py-xl-4 { - padding-top: 1.5rem !important; } - .pr-xl-4, - .px-xl-4 { - padding-right: 1.5rem !important; } - .pb-xl-4, - .py-xl-4 { - padding-bottom: 1.5rem !important; } - .pl-xl-4, - .px-xl-4 { - padding-left: 1.5rem !important; } - .p-xl-5 { - padding: 3rem !important; } - .pt-xl-5, - .py-xl-5 { - padding-top: 3rem !important; } - .pr-xl-5, - .px-xl-5 { - padding-right: 3rem !important; } - .pb-xl-5, - .py-xl-5 { - padding-bottom: 3rem !important; } - .pl-xl-5, - .px-xl-5 { - padding-left: 3rem !important; } - .m-xl-n1 { - margin: -0.25rem !important; } - .mt-xl-n1, - .my-xl-n1 { - margin-top: -0.25rem !important; } - .mr-xl-n1, - .mx-xl-n1 { - margin-right: -0.25rem !important; } - .mb-xl-n1, - .my-xl-n1 { - margin-bottom: -0.25rem !important; } - .ml-xl-n1, - .mx-xl-n1 { - margin-left: -0.25rem !important; } - .m-xl-n2 { - margin: -0.5rem !important; } - .mt-xl-n2, - .my-xl-n2 { - margin-top: -0.5rem !important; } - .mr-xl-n2, - .mx-xl-n2 { - margin-right: -0.5rem !important; } - .mb-xl-n2, - .my-xl-n2 { - margin-bottom: -0.5rem !important; } - .ml-xl-n2, - .mx-xl-n2 { - margin-left: -0.5rem !important; } - .m-xl-n3 { - margin: -1rem !important; } - .mt-xl-n3, - .my-xl-n3 { - margin-top: -1rem !important; } - .mr-xl-n3, - .mx-xl-n3 { - margin-right: -1rem !important; } - .mb-xl-n3, - .my-xl-n3 { - margin-bottom: -1rem !important; } - .ml-xl-n3, - .mx-xl-n3 { - margin-left: -1rem !important; } - .m-xl-n4 { - margin: -1.5rem !important; } - .mt-xl-n4, - .my-xl-n4 { - margin-top: -1.5rem !important; } - .mr-xl-n4, - .mx-xl-n4 { - margin-right: -1.5rem !important; } - .mb-xl-n4, - .my-xl-n4 { - margin-bottom: -1.5rem !important; } - .ml-xl-n4, - .mx-xl-n4 { - margin-left: -1.5rem !important; } - .m-xl-n5 { - margin: -3rem !important; } - .mt-xl-n5, - .my-xl-n5 { - margin-top: -3rem !important; } - .mr-xl-n5, - .mx-xl-n5 { - margin-right: -3rem !important; } - .mb-xl-n5, - .my-xl-n5 { - margin-bottom: -3rem !important; } - .ml-xl-n5, - .mx-xl-n5 { - margin-left: -3rem !important; } - .m-xl-auto { - margin: auto !important; } - .mt-xl-auto, - .my-xl-auto { - margin-top: auto !important; } - .mr-xl-auto, - .mx-xl-auto { - margin-right: auto !important; } - .mb-xl-auto, - .my-xl-auto { - margin-bottom: auto !important; } - .ml-xl-auto, - .mx-xl-auto { - margin-left: auto !important; } } - -.stretched-link::after { - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: 1; - pointer-events: auto; - content: ""; - background-color: rgba(0, 0, 0, 0); } - -.text-monospace { - font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace !important; } - -.text-justify { - text-align: justify !important; } - -.text-wrap { - white-space: normal !important; } - -.text-nowrap { - white-space: nowrap !important; } - -.text-truncate { - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; } - -.text-left { - text-align: left !important; } - -.text-right { - text-align: right !important; } - -.text-center { - text-align: center !important; } - -@media (min-width: 576px) { - .text-sm-left { - text-align: left !important; } - .text-sm-right { - text-align: right !important; } - .text-sm-center { - text-align: center !important; } } - -@media (min-width: 768px) { - .text-md-left { - text-align: left !important; } - .text-md-right { - text-align: right !important; } - .text-md-center { - text-align: center !important; } } - -@media (min-width: 992px) { - .text-lg-left { - text-align: left !important; } - .text-lg-right { - text-align: right !important; } - .text-lg-center { - text-align: center !important; } } - -@media (min-width: 1200px) { - .text-xl-left { - text-align: left !important; } - .text-xl-right { - text-align: right !important; } - .text-xl-center { - text-align: center !important; } } - -.text-lowercase { - text-transform: lowercase !important; } - -.text-uppercase { - text-transform: uppercase !important; } - -.text-capitalize { - text-transform: capitalize !important; } - -.font-weight-light { - font-weight: 300 !important; } - -.font-weight-lighter { - font-weight: lighter !important; } - -.font-weight-normal { - font-weight: 400 !important; } - -.font-weight-bold { - font-weight: 700 !important; } - -.font-weight-bolder { - font-weight: bolder !important; } - -.font-italic { - font-style: italic !important; } - -.text-white { - color: #fff !important; } - -.text-primary { - color: #007bff !important; } - -a.text-primary:hover, a.text-primary:focus { - color: #0056b3 !important; } - -.text-secondary { - color: #6c757d !important; } - -a.text-secondary:hover, a.text-secondary:focus { - color: #494f54 !important; } - -.text-success { - color: #28a745 !important; } - -a.text-success:hover, a.text-success:focus { - color: #19692c !important; } - -.text-info { - color: #17a2b8 !important; } - -a.text-info:hover, a.text-info:focus { - color: #0f6674 !important; } - -.text-warning { - color: #ffc107 !important; } - -a.text-warning:hover, a.text-warning:focus { - color: #ba8b00 !important; } - -.text-danger { - color: #dc3545 !important; } - -a.text-danger:hover, a.text-danger:focus { - color: #a71d2a !important; } - -.text-light { - color: #f8f9fa !important; } - -a.text-light:hover, a.text-light:focus { - color: #cbd3da !important; } - -.text-dark { - color: #343a40 !important; } - -a.text-dark:hover, a.text-dark:focus { - color: #121416 !important; } - -.text-body { - color: #212529 !important; } - -.text-muted { - color: #6c757d !important; } - -.text-black-50 { - color: rgba(0, 0, 0, 0.5) !important; } - -.text-white-50 { - color: rgba(255, 255, 255, 0.5) !important; } - -.text-hide { - font: 0/0 a; - color: transparent; - text-shadow: none; - background-color: transparent; - border: 0; } - -.text-decoration-none { - text-decoration: none !important; } - -.text-break { - word-break: break-word !important; - word-wrap: break-word !important; } - -.text-reset { - color: inherit !important; } - -.visible { - visibility: visible !important; } - -.invisible { - visibility: hidden !important; } - -@media print { - *, - *::before, - *::after { - text-shadow: none !important; - box-shadow: none !important; } - a:not(.btn) { - text-decoration: underline; } - abbr[title]::after { - content: " (" attr(title) ")"; } - pre { - white-space: pre-wrap !important; } - pre, - blockquote { - border: 1px solid #adb5bd; - page-break-inside: avoid; } - tr, - img { - page-break-inside: avoid; } - p, - h2, - h3 { - orphans: 3; - widows: 3; } - h2, - h3 { - page-break-after: avoid; } - @page { - size: a3; } - body { - min-width: 992px !important; } - .container { - min-width: 992px !important; } - .navbar { - display: none; } - .badge { - border: 1px solid #000; } - .table { - border-collapse: collapse !important; } - .table td, - .table th { - background-color: #fff !important; } - .table-bordered th, - .table-bordered td { - border: 1px solid #dee2e6 !important; } - .table-dark { - color: inherit; } - .table-dark th, - .table-dark td, - .table-dark thead th, - .table-dark tbody + tbody { - border-color: #dee2e6; } - .table .thead-dark th { - color: inherit; - border-color: #dee2e6; } } + */:root{--blue: #007bff;--indigo: #6610f2;--purple: #6f42c1;--pink: #e83e8c;--red: #dc3545;--orange: #fd7e14;--yellow: #ffc107;--green: #28a745;--teal: #20c997;--cyan: #17a2b8;--white: #fff;--gray: #6c757d;--gray-dark: #343a40;--primary: #007bff;--secondary: #6c757d;--success: #28a745;--info: #17a2b8;--warning: #ffc107;--danger: #dc3545;--light: #f8f9fa;--dark: #343a40;--breakpoint-xs: 0;--breakpoint-sm: 576px;--breakpoint-md: 768px;--breakpoint-lg: 992px;--breakpoint-xl: 1200px;--font-family-sans-serif: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace}*,*::before,*::after{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:rgba(0,0,0,0)}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus:not(:focus-visible){outline:0 !important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[title],abbr[data-original-title]{text-decoration:underline;text-decoration:underline dotted;cursor:help;border-bottom:0;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul,dl{margin-top:0;margin-bottom:1rem}ol ol,ul ul,ol ul,ul ol{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([class]){color:inherit;text-decoration:none}a:not([href]):not([class]):hover{color:inherit;text-decoration:none}pre,code,kbd,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit;text-align:-webkit-match-parent}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus:not(:focus-visible){outline:0}input,button,select,optgroup,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[role="button"]{cursor:pointer}select{word-wrap:normal}button,[type="button"],[type="reset"],[type="submit"]{-webkit-appearance:button}button:not(:disabled),[type="button"]:not(:disabled),[type="reset"]:not(:disabled),[type="submit"]:not(:disabled){cursor:pointer}button::-moz-focus-inner,[type="button"]::-moz-focus-inner,[type="reset"]::-moz-focus-inner,[type="submit"]::-moz-focus-inner{padding:0;border-style:none}input[type="radio"],input[type="checkbox"]{box-sizing:border-box;padding:0}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type="number"]::-webkit-inner-spin-button,[type="number"]::-webkit-outer-spin-button{height:auto}[type="search"]{outline-offset:-2px;-webkit-appearance:none}[type="search"]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none !important}h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{margin-bottom:.5rem;font-weight:500;line-height:1.2}h1,.h1{font-size:2.5rem}h2,.h2{font-size:2rem}h3,.h3{font-size:1.75rem}h4,.h4{font-size:1.5rem}h5,.h5{font-size:1.25rem}h6,.h6{font-size:1rem}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:6rem;font-weight:300;line-height:1.2}.display-2{font-size:5.5rem;font-weight:300;line-height:1.2}.display-3{font-size:4.5rem;font-weight:300;line-height:1.2}.display-4{font-size:3.5rem;font-weight:300;line-height:1.2}hr{margin-top:1rem;margin-bottom:1rem;border:0;border-top:1px solid rgba(0,0,0,0.1)}small,.small{font-size:80%;font-weight:400}mark,.mark{padding:.2em;background-color:#fcf8e3}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:90%;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote-footer{display:block;font-size:80%;color:#6c757d}.blockquote-footer::before{content:"\2014\00A0"}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:90%;color:#6c757d}code{font-size:87.5%;color:#e83e8c;word-wrap:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:87.5%;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:100%;font-weight:700}pre{display:block;font-size:87.5%;color:#212529}pre code{font-size:inherit;color:inherit;word-break:normal}.pre-scrollable{max-height:340px;overflow-y:scroll}.container,.container-fluid,.container-sm,.container-md,.container-lg,.container-xl{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width: 576px){.container,.container-sm{max-width:540px}}@media (min-width: 768px){.container,.container-sm,.container-md{max-width:720px}}@media (min-width: 992px){.container,.container-sm,.container-md,.container-lg{max-width:960px}}@media (min-width: 1200px){.container,.container-sm,.container-md,.container-lg,.container-xl{max-width:1140px}}.row{display:flex;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*="col-"]{padding-right:0;padding-left:0}.col-1,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-10,.col-11,.col-12,.col,.col-auto,.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm,.col-sm-auto,.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12,.col-md,.col-md-auto,.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg,.col-lg-auto,.col-xl-1,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl,.col-xl-auto{position:relative;width:100%;padding-right:15px;padding-left:15px}.col{flex-basis:0;flex-grow:1;max-width:100%}.row-cols-1>*{flex:0 0 100%;max-width:100%}.row-cols-2>*{flex:0 0 50%;max-width:50%}.row-cols-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.row-cols-4>*{flex:0 0 25%;max-width:25%}.row-cols-5>*{flex:0 0 20%;max-width:20%}.row-cols-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-auto{flex:0 0 auto;width:auto;max-width:100%}.col-1{flex:0 0 8.33333333%;max-width:8.33333333%}.col-2{flex:0 0 16.66666667%;max-width:16.66666667%}.col-3{flex:0 0 25%;max-width:25%}.col-4{flex:0 0 33.33333333%;max-width:33.33333333%}.col-5{flex:0 0 41.66666667%;max-width:41.66666667%}.col-6{flex:0 0 50%;max-width:50%}.col-7{flex:0 0 58.33333333%;max-width:58.33333333%}.col-8{flex:0 0 66.66666667%;max-width:66.66666667%}.col-9{flex:0 0 75%;max-width:75%}.col-10{flex:0 0 83.33333333%;max-width:83.33333333%}.col-11{flex:0 0 91.66666667%;max-width:91.66666667%}.col-12{flex:0 0 100%;max-width:100%}.order-first{order:-1}.order-last{order:13}.order-0{order:0}.order-1{order:1}.order-2{order:2}.order-3{order:3}.order-4{order:4}.order-5{order:5}.order-6{order:6}.order-7{order:7}.order-8{order:8}.order-9{order:9}.order-10{order:10}.order-11{order:11}.order-12{order:12}.offset-1{margin-left:8.33333333%}.offset-2{margin-left:16.66666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.33333333%}.offset-5{margin-left:41.66666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.33333333%}.offset-8{margin-left:66.66666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.33333333%}.offset-11{margin-left:91.66666667%}@media (min-width: 576px){.col-sm{flex-basis:0;flex-grow:1;max-width:100%}.row-cols-sm-1>*{flex:0 0 100%;max-width:100%}.row-cols-sm-2>*{flex:0 0 50%;max-width:50%}.row-cols-sm-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.row-cols-sm-4>*{flex:0 0 25%;max-width:25%}.row-cols-sm-5>*{flex:0 0 20%;max-width:20%}.row-cols-sm-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-sm-auto{flex:0 0 auto;width:auto;max-width:100%}.col-sm-1{flex:0 0 8.33333333%;max-width:8.33333333%}.col-sm-2{flex:0 0 16.66666667%;max-width:16.66666667%}.col-sm-3{flex:0 0 25%;max-width:25%}.col-sm-4{flex:0 0 33.33333333%;max-width:33.33333333%}.col-sm-5{flex:0 0 41.66666667%;max-width:41.66666667%}.col-sm-6{flex:0 0 50%;max-width:50%}.col-sm-7{flex:0 0 58.33333333%;max-width:58.33333333%}.col-sm-8{flex:0 0 66.66666667%;max-width:66.66666667%}.col-sm-9{flex:0 0 75%;max-width:75%}.col-sm-10{flex:0 0 83.33333333%;max-width:83.33333333%}.col-sm-11{flex:0 0 91.66666667%;max-width:91.66666667%}.col-sm-12{flex:0 0 100%;max-width:100%}.order-sm-first{order:-1}.order-sm-last{order:13}.order-sm-0{order:0}.order-sm-1{order:1}.order-sm-2{order:2}.order-sm-3{order:3}.order-sm-4{order:4}.order-sm-5{order:5}.order-sm-6{order:6}.order-sm-7{order:7}.order-sm-8{order:8}.order-sm-9{order:9}.order-sm-10{order:10}.order-sm-11{order:11}.order-sm-12{order:12}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.33333333%}.offset-sm-2{margin-left:16.66666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.33333333%}.offset-sm-5{margin-left:41.66666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.33333333%}.offset-sm-8{margin-left:66.66666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.33333333%}.offset-sm-11{margin-left:91.66666667%}}@media (min-width: 768px){.col-md{flex-basis:0;flex-grow:1;max-width:100%}.row-cols-md-1>*{flex:0 0 100%;max-width:100%}.row-cols-md-2>*{flex:0 0 50%;max-width:50%}.row-cols-md-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.row-cols-md-4>*{flex:0 0 25%;max-width:25%}.row-cols-md-5>*{flex:0 0 20%;max-width:20%}.row-cols-md-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-md-auto{flex:0 0 auto;width:auto;max-width:100%}.col-md-1{flex:0 0 8.33333333%;max-width:8.33333333%}.col-md-2{flex:0 0 16.66666667%;max-width:16.66666667%}.col-md-3{flex:0 0 25%;max-width:25%}.col-md-4{flex:0 0 33.33333333%;max-width:33.33333333%}.col-md-5{flex:0 0 41.66666667%;max-width:41.66666667%}.col-md-6{flex:0 0 50%;max-width:50%}.col-md-7{flex:0 0 58.33333333%;max-width:58.33333333%}.col-md-8{flex:0 0 66.66666667%;max-width:66.66666667%}.col-md-9{flex:0 0 75%;max-width:75%}.col-md-10{flex:0 0 83.33333333%;max-width:83.33333333%}.col-md-11{flex:0 0 91.66666667%;max-width:91.66666667%}.col-md-12{flex:0 0 100%;max-width:100%}.order-md-first{order:-1}.order-md-last{order:13}.order-md-0{order:0}.order-md-1{order:1}.order-md-2{order:2}.order-md-3{order:3}.order-md-4{order:4}.order-md-5{order:5}.order-md-6{order:6}.order-md-7{order:7}.order-md-8{order:8}.order-md-9{order:9}.order-md-10{order:10}.order-md-11{order:11}.order-md-12{order:12}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.33333333%}.offset-md-2{margin-left:16.66666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.33333333%}.offset-md-5{margin-left:41.66666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.33333333%}.offset-md-8{margin-left:66.66666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.33333333%}.offset-md-11{margin-left:91.66666667%}}@media (min-width: 992px){.col-lg{flex-basis:0;flex-grow:1;max-width:100%}.row-cols-lg-1>*{flex:0 0 100%;max-width:100%}.row-cols-lg-2>*{flex:0 0 50%;max-width:50%}.row-cols-lg-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.row-cols-lg-4>*{flex:0 0 25%;max-width:25%}.row-cols-lg-5>*{flex:0 0 20%;max-width:20%}.row-cols-lg-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-lg-auto{flex:0 0 auto;width:auto;max-width:100%}.col-lg-1{flex:0 0 8.33333333%;max-width:8.33333333%}.col-lg-2{flex:0 0 16.66666667%;max-width:16.66666667%}.col-lg-3{flex:0 0 25%;max-width:25%}.col-lg-4{flex:0 0 33.33333333%;max-width:33.33333333%}.col-lg-5{flex:0 0 41.66666667%;max-width:41.66666667%}.col-lg-6{flex:0 0 50%;max-width:50%}.col-lg-7{flex:0 0 58.33333333%;max-width:58.33333333%}.col-lg-8{flex:0 0 66.66666667%;max-width:66.66666667%}.col-lg-9{flex:0 0 75%;max-width:75%}.col-lg-10{flex:0 0 83.33333333%;max-width:83.33333333%}.col-lg-11{flex:0 0 91.66666667%;max-width:91.66666667%}.col-lg-12{flex:0 0 100%;max-width:100%}.order-lg-first{order:-1}.order-lg-last{order:13}.order-lg-0{order:0}.order-lg-1{order:1}.order-lg-2{order:2}.order-lg-3{order:3}.order-lg-4{order:4}.order-lg-5{order:5}.order-lg-6{order:6}.order-lg-7{order:7}.order-lg-8{order:8}.order-lg-9{order:9}.order-lg-10{order:10}.order-lg-11{order:11}.order-lg-12{order:12}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.33333333%}.offset-lg-2{margin-left:16.66666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.33333333%}.offset-lg-5{margin-left:41.66666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.33333333%}.offset-lg-8{margin-left:66.66666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.33333333%}.offset-lg-11{margin-left:91.66666667%}}@media (min-width: 1200px){.col-xl{flex-basis:0;flex-grow:1;max-width:100%}.row-cols-xl-1>*{flex:0 0 100%;max-width:100%}.row-cols-xl-2>*{flex:0 0 50%;max-width:50%}.row-cols-xl-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.row-cols-xl-4>*{flex:0 0 25%;max-width:25%}.row-cols-xl-5>*{flex:0 0 20%;max-width:20%}.row-cols-xl-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-xl-auto{flex:0 0 auto;width:auto;max-width:100%}.col-xl-1{flex:0 0 8.33333333%;max-width:8.33333333%}.col-xl-2{flex:0 0 16.66666667%;max-width:16.66666667%}.col-xl-3{flex:0 0 25%;max-width:25%}.col-xl-4{flex:0 0 33.33333333%;max-width:33.33333333%}.col-xl-5{flex:0 0 41.66666667%;max-width:41.66666667%}.col-xl-6{flex:0 0 50%;max-width:50%}.col-xl-7{flex:0 0 58.33333333%;max-width:58.33333333%}.col-xl-8{flex:0 0 66.66666667%;max-width:66.66666667%}.col-xl-9{flex:0 0 75%;max-width:75%}.col-xl-10{flex:0 0 83.33333333%;max-width:83.33333333%}.col-xl-11{flex:0 0 91.66666667%;max-width:91.66666667%}.col-xl-12{flex:0 0 100%;max-width:100%}.order-xl-first{order:-1}.order-xl-last{order:13}.order-xl-0{order:0}.order-xl-1{order:1}.order-xl-2{order:2}.order-xl-3{order:3}.order-xl-4{order:4}.order-xl-5{order:5}.order-xl-6{order:6}.order-xl-7{order:7}.order-xl-8{order:8}.order-xl-9{order:9}.order-xl-10{order:10}.order-xl-11{order:11}.order-xl-12{order:12}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.33333333%}.offset-xl-2{margin-left:16.66666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.33333333%}.offset-xl-5{margin-left:41.66666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.33333333%}.offset-xl-8{margin-left:66.66666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.33333333%}.offset-xl-11{margin-left:91.66666667%}}.table{width:100%;margin-bottom:1rem;color:#212529}.table th,.table td{padding:.75rem;vertical-align:top;border-top:1px solid #dee2e6}.table thead th{vertical-align:bottom;border-bottom:2px solid #dee2e6}.table tbody+tbody{border-top:2px solid #dee2e6}.table-sm th,.table-sm td{padding:.3rem}.table-bordered{border:1px solid #dee2e6}.table-bordered th,.table-bordered td{border:1px solid #dee2e6}.table-bordered thead th,.table-bordered thead td{border-bottom-width:2px}.table-borderless th,.table-borderless td,.table-borderless thead th,.table-borderless tbody+tbody{border:0}.table-striped tbody tr:nth-of-type(odd){background-color:rgba(0,0,0,0.05)}.table-hover tbody tr:hover{color:#212529;background-color:rgba(0,0,0,0.075)}.table-primary,.table-primary>th,.table-primary>td{background-color:#b8daff}.table-primary th,.table-primary td,.table-primary thead th,.table-primary tbody+tbody{border-color:#7abaff}.table-hover .table-primary:hover{background-color:#9fcdff}.table-hover .table-primary:hover>td,.table-hover .table-primary:hover>th{background-color:#9fcdff}.table-secondary,.table-secondary>th,.table-secondary>td{background-color:#d6d8db}.table-secondary th,.table-secondary td,.table-secondary thead th,.table-secondary tbody+tbody{border-color:#b3b7bb}.table-hover .table-secondary:hover{background-color:#c8cbcf}.table-hover .table-secondary:hover>td,.table-hover .table-secondary:hover>th{background-color:#c8cbcf}.table-success,.table-success>th,.table-success>td{background-color:#c3e6cb}.table-success th,.table-success td,.table-success thead th,.table-success tbody+tbody{border-color:#8fd19e}.table-hover .table-success:hover{background-color:#b1dfbb}.table-hover .table-success:hover>td,.table-hover .table-success:hover>th{background-color:#b1dfbb}.table-info,.table-info>th,.table-info>td{background-color:#bee5eb}.table-info th,.table-info td,.table-info thead th,.table-info tbody+tbody{border-color:#86cfda}.table-hover .table-info:hover{background-color:#abdde5}.table-hover .table-info:hover>td,.table-hover .table-info:hover>th{background-color:#abdde5}.table-warning,.table-warning>th,.table-warning>td{background-color:#ffeeba}.table-warning th,.table-warning td,.table-warning thead th,.table-warning tbody+tbody{border-color:#ffdf7e}.table-hover .table-warning:hover{background-color:#ffe8a1}.table-hover .table-warning:hover>td,.table-hover .table-warning:hover>th{background-color:#ffe8a1}.table-danger,.table-danger>th,.table-danger>td{background-color:#f5c6cb}.table-danger th,.table-danger td,.table-danger thead th,.table-danger tbody+tbody{border-color:#ed969e}.table-hover .table-danger:hover{background-color:#f1b0b7}.table-hover .table-danger:hover>td,.table-hover .table-danger:hover>th{background-color:#f1b0b7}.table-light,.table-light>th,.table-light>td{background-color:#fdfdfe}.table-light th,.table-light td,.table-light thead th,.table-light tbody+tbody{border-color:#fbfcfc}.table-hover .table-light:hover{background-color:#ececf6}.table-hover .table-light:hover>td,.table-hover .table-light:hover>th{background-color:#ececf6}.table-dark,.table-dark>th,.table-dark>td{background-color:#c6c8ca}.table-dark th,.table-dark td,.table-dark thead th,.table-dark tbody+tbody{border-color:#95999c}.table-hover .table-dark:hover{background-color:#b9bbbe}.table-hover .table-dark:hover>td,.table-hover .table-dark:hover>th{background-color:#b9bbbe}.table-active,.table-active>th,.table-active>td{background-color:rgba(0,0,0,0.075)}.table-hover .table-active:hover{background-color:rgba(0,0,0,0.075)}.table-hover .table-active:hover>td,.table-hover .table-active:hover>th{background-color:rgba(0,0,0,0.075)}.table .thead-dark th{color:#fff;background-color:#343a40;border-color:#454d55}.table .thead-light th{color:#495057;background-color:#e9ecef;border-color:#dee2e6}.table-dark{color:#fff;background-color:#343a40}.table-dark th,.table-dark td,.table-dark thead th{border-color:#454d55}.table-dark.table-bordered{border:0}.table-dark.table-striped tbody tr:nth-of-type(odd){background-color:rgba(255,255,255,0.05)}.table-dark.table-hover tbody tr:hover{color:#fff;background-color:rgba(255,255,255,0.075)}@media (max-width: 575.98px){.table-responsive-sm{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-sm>.table-bordered{border:0}}@media (max-width: 767.98px){.table-responsive-md{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-md>.table-bordered{border:0}}@media (max-width: 991.98px){.table-responsive-lg{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-lg>.table-bordered{border:0}}@media (max-width: 1199.98px){.table-responsive-xl{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-xl>.table-bordered{border:0}}.table-responsive{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive>.table-bordered{border:0}.form-control{display:block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;border-radius:.25rem;transition:border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.form-control{transition:none}}.form-control::-ms-expand{background-color:transparent;border:0}.form-control:focus{color:#495057;background-color:#fff;border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,0.25)}.form-control::placeholder{color:#6c757d;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#e9ecef;opacity:1}input[type="date"].form-control,input[type="time"].form-control,input[type="datetime-local"].form-control,input[type="month"].form-control{appearance:none}select.form-control:-moz-focusring{color:transparent;text-shadow:0 0 0 #495057}select.form-control:focus::-ms-value{color:#495057;background-color:#fff}.form-control-file,.form-control-range{display:block;width:100%}.col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.25rem;line-height:1.5}.col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem;line-height:1.5}.form-control-plaintext{display:block;width:100%;padding:.375rem 0;margin-bottom:0;font-size:1rem;line-height:1.5;color:#212529;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-sm,.form-control-plaintext.form-control-lg{padding-right:0;padding-left:0}.form-control-sm{height:calc(1.5em + .5rem + 2px);padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.form-control-lg{height:calc(1.5em + 1rem + 2px);padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}select.form-control[size],select.form-control[multiple]{height:auto}textarea.form-control{height:auto}.form-group{margin-bottom:1rem}.form-text{display:block;margin-top:.25rem}.form-row{display:flex;flex-wrap:wrap;margin-right:-5px;margin-left:-5px}.form-row>.col,.form-row>[class*="col-"]{padding-right:5px;padding-left:5px}.form-check{position:relative;display:block;padding-left:1.25rem}.form-check-input{position:absolute;margin-top:.3rem;margin-left:-1.25rem}.form-check-input[disabled] ~ .form-check-label,.form-check-input:disabled ~ .form-check-label{color:#6c757d}.form-check-label{margin-bottom:0}.form-check-inline{display:inline-flex;align-items:center;padding-left:0;margin-right:.75rem}.form-check-inline .form-check-input{position:static;margin-top:0;margin-right:.3125rem;margin-left:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#28a745}.valid-tooltip{position:absolute;top:100%;left:0;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(40,167,69,0.9);border-radius:.25rem}.form-row>.col>.valid-tooltip,.form-row>[class*="col-"]>.valid-tooltip{left:5px}.was-validated :valid ~ .valid-feedback,.was-validated :valid ~ .valid-tooltip,.is-valid ~ .valid-feedback,.is-valid ~ .valid-tooltip{display:block}.was-validated .form-control:valid,.form-control.is-valid{border-color:#28a745;padding-right:calc(1.5em + .75rem) !important;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.was-validated .form-control:valid:focus,.form-control.is-valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,0.25)}.was-validated select.form-control:valid,select.form-control.is-valid{padding-right:3rem !important;background-position:right 1.5rem center}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.was-validated .custom-select:valid,.custom-select.is-valid{border-color:#28a745;padding-right:calc(.75em + 2.3125rem) !important;background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") right .75rem center/8px 10px no-repeat,#fff url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e") center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem) no-repeat}.was-validated .custom-select:valid:focus,.custom-select.is-valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,0.25)}.was-validated .form-check-input:valid ~ .form-check-label,.form-check-input.is-valid ~ .form-check-label{color:#28a745}.was-validated .form-check-input:valid ~ .valid-feedback,.was-validated .form-check-input:valid ~ .valid-tooltip,.form-check-input.is-valid ~ .valid-feedback,.form-check-input.is-valid ~ .valid-tooltip{display:block}.was-validated .custom-control-input:valid ~ .custom-control-label,.custom-control-input.is-valid ~ .custom-control-label{color:#28a745}.was-validated .custom-control-input:valid ~ .custom-control-label::before,.custom-control-input.is-valid ~ .custom-control-label::before{border-color:#28a745}.was-validated .custom-control-input:valid:checked ~ .custom-control-label::before,.custom-control-input.is-valid:checked ~ .custom-control-label::before{border-color:#34ce57;background-color:#34ce57}.was-validated .custom-control-input:valid:focus ~ .custom-control-label::before,.custom-control-input.is-valid:focus ~ .custom-control-label::before{box-shadow:0 0 0 .2rem rgba(40,167,69,0.25)}.was-validated .custom-control-input:valid:focus:not(:checked) ~ .custom-control-label::before,.custom-control-input.is-valid:focus:not(:checked) ~ .custom-control-label::before{border-color:#28a745}.was-validated .custom-file-input:valid ~ .custom-file-label,.custom-file-input.is-valid ~ .custom-file-label{border-color:#28a745}.was-validated .custom-file-input:valid:focus ~ .custom-file-label,.custom-file-input.is-valid:focus ~ .custom-file-label{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,0.25)}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#dc3545}.invalid-tooltip{position:absolute;top:100%;left:0;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(220,53,69,0.9);border-radius:.25rem}.form-row>.col>.invalid-tooltip,.form-row>[class*="col-"]>.invalid-tooltip{left:5px}.was-validated :invalid ~ .invalid-feedback,.was-validated :invalid ~ .invalid-tooltip,.is-invalid ~ .invalid-feedback,.is-invalid ~ .invalid-tooltip{display:block}.was-validated .form-control:invalid,.form-control.is-invalid{border-color:#dc3545;padding-right:calc(1.5em + .75rem) !important;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.was-validated .form-control:invalid:focus,.form-control.is-invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,0.25)}.was-validated select.form-control:invalid,select.form-control.is-invalid{padding-right:3rem !important;background-position:right 1.5rem center}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.was-validated .custom-select:invalid,.custom-select.is-invalid{border-color:#dc3545;padding-right:calc(.75em + 2.3125rem) !important;background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") right .75rem center/8px 10px no-repeat,#fff url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e") center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem) no-repeat}.was-validated .custom-select:invalid:focus,.custom-select.is-invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,0.25)}.was-validated .form-check-input:invalid ~ .form-check-label,.form-check-input.is-invalid ~ .form-check-label{color:#dc3545}.was-validated .form-check-input:invalid ~ .invalid-feedback,.was-validated .form-check-input:invalid ~ .invalid-tooltip,.form-check-input.is-invalid ~ .invalid-feedback,.form-check-input.is-invalid ~ .invalid-tooltip{display:block}.was-validated .custom-control-input:invalid ~ .custom-control-label,.custom-control-input.is-invalid ~ .custom-control-label{color:#dc3545}.was-validated .custom-control-input:invalid ~ .custom-control-label::before,.custom-control-input.is-invalid ~ .custom-control-label::before{border-color:#dc3545}.was-validated .custom-control-input:invalid:checked ~ .custom-control-label::before,.custom-control-input.is-invalid:checked ~ .custom-control-label::before{border-color:#e4606d;background-color:#e4606d}.was-validated .custom-control-input:invalid:focus ~ .custom-control-label::before,.custom-control-input.is-invalid:focus ~ .custom-control-label::before{box-shadow:0 0 0 .2rem rgba(220,53,69,0.25)}.was-validated .custom-control-input:invalid:focus:not(:checked) ~ .custom-control-label::before,.custom-control-input.is-invalid:focus:not(:checked) ~ .custom-control-label::before{border-color:#dc3545}.was-validated .custom-file-input:invalid ~ .custom-file-label,.custom-file-input.is-invalid ~ .custom-file-label{border-color:#dc3545}.was-validated .custom-file-input:invalid:focus ~ .custom-file-label,.custom-file-input.is-invalid:focus ~ .custom-file-label{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,0.25)}.form-inline{display:flex;flex-flow:row wrap;align-items:center}.form-inline .form-check{width:100%}@media (min-width: 576px){.form-inline label{display:flex;align-items:center;justify-content:center;margin-bottom:0}.form-inline .form-group{display:flex;flex:0 0 auto;flex-flow:row wrap;align-items:center;margin-bottom:0}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-plaintext{display:inline-block}.form-inline .input-group,.form-inline .custom-select{width:auto}.form-inline .form-check{display:flex;align-items:center;justify-content:center;width:auto;padding-left:0}.form-inline .form-check-input{position:relative;flex-shrink:0;margin-top:0;margin-right:.25rem;margin-left:0}.form-inline .custom-control{align-items:center;justify-content:center}.form-inline .custom-control-label{margin-bottom:0}}.btn{display:inline-block;font-weight:400;color:#212529;text-align:center;vertical-align:middle;user-select:none;background-color:transparent;border:1px solid transparent;padding:.375rem .75rem;font-size:1rem;line-height:1.5;border-radius:.25rem;transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.btn{transition:none}}.btn:hover{color:#212529;text-decoration:none}.btn:focus,.btn.focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,0.25)}.btn.disabled,.btn:disabled{opacity:.65}.btn:not(:disabled):not(.disabled){cursor:pointer}a.btn.disabled,fieldset:disabled a.btn{pointer-events:none}.btn-primary{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:hover{color:#fff;background-color:#0069d9;border-color:#0062cc}.btn-primary:focus,.btn-primary.focus{color:#fff;background-color:#0069d9;border-color:#0062cc;box-shadow:0 0 0 .2rem rgba(38,143,255,0.5)}.btn-primary.disabled,.btn-primary:disabled{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:not(:disabled):not(.disabled):active,.btn-primary:not(:disabled):not(.disabled).active,.show>.btn-primary.dropdown-toggle{color:#fff;background-color:#0062cc;border-color:#005cbf}.btn-primary:not(:disabled):not(.disabled):active:focus,.btn-primary:not(:disabled):not(.disabled).active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(38,143,255,0.5)}.btn-secondary{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:hover{color:#fff;background-color:#5a6268;border-color:#545b62}.btn-secondary:focus,.btn-secondary.focus{color:#fff;background-color:#5a6268;border-color:#545b62;box-shadow:0 0 0 .2rem rgba(130,138,145,0.5)}.btn-secondary.disabled,.btn-secondary:disabled{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:not(:disabled):not(.disabled):active,.btn-secondary:not(:disabled):not(.disabled).active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#545b62;border-color:#4e555b}.btn-secondary:not(:disabled):not(.disabled):active:focus,.btn-secondary:not(:disabled):not(.disabled).active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(130,138,145,0.5)}.btn-success{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:hover{color:#fff;background-color:#218838;border-color:#1e7e34}.btn-success:focus,.btn-success.focus{color:#fff;background-color:#218838;border-color:#1e7e34;box-shadow:0 0 0 .2rem rgba(72,180,97,0.5)}.btn-success.disabled,.btn-success:disabled{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:not(:disabled):not(.disabled):active,.btn-success:not(:disabled):not(.disabled).active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#1e7e34;border-color:#1c7430}.btn-success:not(:disabled):not(.disabled):active:focus,.btn-success:not(:disabled):not(.disabled).active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(72,180,97,0.5)}.btn-info{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:hover{color:#fff;background-color:#138496;border-color:#117a8b}.btn-info:focus,.btn-info.focus{color:#fff;background-color:#138496;border-color:#117a8b;box-shadow:0 0 0 .2rem rgba(58,176,195,0.5)}.btn-info.disabled,.btn-info:disabled{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:not(:disabled):not(.disabled):active,.btn-info:not(:disabled):not(.disabled).active,.show>.btn-info.dropdown-toggle{color:#fff;background-color:#117a8b;border-color:#10707f}.btn-info:not(:disabled):not(.disabled):active:focus,.btn-info:not(:disabled):not(.disabled).active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(58,176,195,0.5)}.btn-warning{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:hover{color:#212529;background-color:#e0a800;border-color:#d39e00}.btn-warning:focus,.btn-warning.focus{color:#212529;background-color:#e0a800;border-color:#d39e00;box-shadow:0 0 0 .2rem rgba(222,170,12,0.5)}.btn-warning.disabled,.btn-warning:disabled{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:not(:disabled):not(.disabled):active,.btn-warning:not(:disabled):not(.disabled).active,.show>.btn-warning.dropdown-toggle{color:#212529;background-color:#d39e00;border-color:#c69500}.btn-warning:not(:disabled):not(.disabled):active:focus,.btn-warning:not(:disabled):not(.disabled).active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(222,170,12,0.5)}.btn-danger{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:hover{color:#fff;background-color:#c82333;border-color:#bd2130}.btn-danger:focus,.btn-danger.focus{color:#fff;background-color:#c82333;border-color:#bd2130;box-shadow:0 0 0 .2rem rgba(225,83,97,0.5)}.btn-danger.disabled,.btn-danger:disabled{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:not(:disabled):not(.disabled):active,.btn-danger:not(:disabled):not(.disabled).active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#bd2130;border-color:#b21f2d}.btn-danger:not(:disabled):not(.disabled):active:focus,.btn-danger:not(:disabled):not(.disabled).active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(225,83,97,0.5)}.btn-light{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:hover{color:#212529;background-color:#e2e6ea;border-color:#dae0e5}.btn-light:focus,.btn-light.focus{color:#212529;background-color:#e2e6ea;border-color:#dae0e5;box-shadow:0 0 0 .2rem rgba(216,217,219,0.5)}.btn-light.disabled,.btn-light:disabled{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:not(:disabled):not(.disabled):active,.btn-light:not(:disabled):not(.disabled).active,.show>.btn-light.dropdown-toggle{color:#212529;background-color:#dae0e5;border-color:#d3d9df}.btn-light:not(:disabled):not(.disabled):active:focus,.btn-light:not(:disabled):not(.disabled).active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(216,217,219,0.5)}.btn-dark{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:hover{color:#fff;background-color:#23272b;border-color:#1d2124}.btn-dark:focus,.btn-dark.focus{color:#fff;background-color:#23272b;border-color:#1d2124;box-shadow:0 0 0 .2rem rgba(82,88,93,0.5)}.btn-dark.disabled,.btn-dark:disabled{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:not(:disabled):not(.disabled):active,.btn-dark:not(:disabled):not(.disabled).active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#1d2124;border-color:#171a1d}.btn-dark:not(:disabled):not(.disabled):active:focus,.btn-dark:not(:disabled):not(.disabled).active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(82,88,93,0.5)}.btn-outline-primary{color:#007bff;border-color:#007bff}.btn-outline-primary:hover{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary:focus,.btn-outline-primary.focus{box-shadow:0 0 0 .2rem rgba(0,123,255,0.5)}.btn-outline-primary.disabled,.btn-outline-primary:disabled{color:#007bff;background-color:transparent}.btn-outline-primary:not(:disabled):not(.disabled):active,.btn-outline-primary:not(:disabled):not(.disabled).active,.show>.btn-outline-primary.dropdown-toggle{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary:not(:disabled):not(.disabled):active:focus,.btn-outline-primary:not(:disabled):not(.disabled).active:focus,.show>.btn-outline-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,0.5)}.btn-outline-secondary{color:#6c757d;border-color:#6c757d}.btn-outline-secondary:hover{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary:focus,.btn-outline-secondary.focus{box-shadow:0 0 0 .2rem rgba(108,117,125,0.5)}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{color:#6c757d;background-color:transparent}.btn-outline-secondary:not(:disabled):not(.disabled):active,.btn-outline-secondary:not(:disabled):not(.disabled).active,.show>.btn-outline-secondary.dropdown-toggle{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary:not(:disabled):not(.disabled):active:focus,.btn-outline-secondary:not(:disabled):not(.disabled).active:focus,.show>.btn-outline-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,0.5)}.btn-outline-success{color:#28a745;border-color:#28a745}.btn-outline-success:hover{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success:focus,.btn-outline-success.focus{box-shadow:0 0 0 .2rem rgba(40,167,69,0.5)}.btn-outline-success.disabled,.btn-outline-success:disabled{color:#28a745;background-color:transparent}.btn-outline-success:not(:disabled):not(.disabled):active,.btn-outline-success:not(:disabled):not(.disabled).active,.show>.btn-outline-success.dropdown-toggle{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success:not(:disabled):not(.disabled):active:focus,.btn-outline-success:not(:disabled):not(.disabled).active:focus,.show>.btn-outline-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,0.5)}.btn-outline-info{color:#17a2b8;border-color:#17a2b8}.btn-outline-info:hover{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info:focus,.btn-outline-info.focus{box-shadow:0 0 0 .2rem rgba(23,162,184,0.5)}.btn-outline-info.disabled,.btn-outline-info:disabled{color:#17a2b8;background-color:transparent}.btn-outline-info:not(:disabled):not(.disabled):active,.btn-outline-info:not(:disabled):not(.disabled).active,.show>.btn-outline-info.dropdown-toggle{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info:not(:disabled):not(.disabled):active:focus,.btn-outline-info:not(:disabled):not(.disabled).active:focus,.show>.btn-outline-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,0.5)}.btn-outline-warning{color:#ffc107;border-color:#ffc107}.btn-outline-warning:hover{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning:focus,.btn-outline-warning.focus{box-shadow:0 0 0 .2rem rgba(255,193,7,0.5)}.btn-outline-warning.disabled,.btn-outline-warning:disabled{color:#ffc107;background-color:transparent}.btn-outline-warning:not(:disabled):not(.disabled):active,.btn-outline-warning:not(:disabled):not(.disabled).active,.show>.btn-outline-warning.dropdown-toggle{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning:not(:disabled):not(.disabled):active:focus,.btn-outline-warning:not(:disabled):not(.disabled).active:focus,.show>.btn-outline-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,0.5)}.btn-outline-danger{color:#dc3545;border-color:#dc3545}.btn-outline-danger:hover{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger:focus,.btn-outline-danger.focus{box-shadow:0 0 0 .2rem rgba(220,53,69,0.5)}.btn-outline-danger.disabled,.btn-outline-danger:disabled{color:#dc3545;background-color:transparent}.btn-outline-danger:not(:disabled):not(.disabled):active,.btn-outline-danger:not(:disabled):not(.disabled).active,.show>.btn-outline-danger.dropdown-toggle{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger:not(:disabled):not(.disabled):active:focus,.btn-outline-danger:not(:disabled):not(.disabled).active:focus,.show>.btn-outline-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,0.5)}.btn-outline-light{color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:hover{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:focus,.btn-outline-light.focus{box-shadow:0 0 0 .2rem rgba(248,249,250,0.5)}.btn-outline-light.disabled,.btn-outline-light:disabled{color:#f8f9fa;background-color:transparent}.btn-outline-light:not(:disabled):not(.disabled):active,.btn-outline-light:not(:disabled):not(.disabled).active,.show>.btn-outline-light.dropdown-toggle{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:not(:disabled):not(.disabled):active:focus,.btn-outline-light:not(:disabled):not(.disabled).active:focus,.show>.btn-outline-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,0.5)}.btn-outline-dark{color:#343a40;border-color:#343a40}.btn-outline-dark:hover{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark:focus,.btn-outline-dark.focus{box-shadow:0 0 0 .2rem rgba(52,58,64,0.5)}.btn-outline-dark.disabled,.btn-outline-dark:disabled{color:#343a40;background-color:transparent}.btn-outline-dark:not(:disabled):not(.disabled):active,.btn-outline-dark:not(:disabled):not(.disabled).active,.show>.btn-outline-dark.dropdown-toggle{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark:not(:disabled):not(.disabled):active:focus,.btn-outline-dark:not(:disabled):not(.disabled).active:focus,.show>.btn-outline-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,0.5)}.btn-link{font-weight:400;color:#007bff;text-decoration:none}.btn-link:hover{color:#0056b3;text-decoration:underline}.btn-link:focus,.btn-link.focus{text-decoration:underline}.btn-link:disabled,.btn-link.disabled{color:#6c757d;pointer-events:none}.btn-lg,.btn-group-lg>.btn{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.btn-sm,.btn-group-sm>.btn{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:.5rem}input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%}.fade{transition:opacity 0.15s linear}@media (prefers-reduced-motion: reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{position:relative;height:0;overflow:hidden;transition:height 0.35s ease}@media (prefers-reduced-motion: reduce){.collapsing{transition:none}}.dropup,.dropright,.dropdown,.dropleft{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:10rem;padding:.5rem 0;margin:.125rem 0 0;font-size:1rem;color:#212529;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,0.15);border-radius:.25rem}.dropdown-menu-left{right:auto;left:0}.dropdown-menu-right{right:0;left:auto}@media (min-width: 576px){.dropdown-menu-sm-left{right:auto;left:0}.dropdown-menu-sm-right{right:0;left:auto}}@media (min-width: 768px){.dropdown-menu-md-left{right:auto;left:0}.dropdown-menu-md-right{right:0;left:auto}}@media (min-width: 992px){.dropdown-menu-lg-left{right:auto;left:0}.dropdown-menu-lg-right{right:0;left:auto}}@media (min-width: 1200px){.dropdown-menu-xl-left{right:auto;left:0}.dropdown-menu-xl-right{right:0;left:auto}}.dropup .dropdown-menu{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-menu{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem}.dropright .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropright .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-toggle::after{vertical-align:0}.dropleft .dropdown-menu{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem}.dropleft .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}.dropleft .dropdown-toggle::after{display:none}.dropleft .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropleft .dropdown-toggle:empty::after{margin-left:0}.dropleft .dropdown-toggle::before{vertical-align:0}.dropdown-menu[x-placement^="top"],.dropdown-menu[x-placement^="right"],.dropdown-menu[x-placement^="bottom"],.dropdown-menu[x-placement^="left"]{right:auto;bottom:auto}.dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid #e9ecef}.dropdown-item{display:block;width:100%;padding:.25rem 1.5rem;clear:both;font-weight:400;color:#212529;text-align:inherit;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:hover,.dropdown-item:focus{color:#16181b;text-decoration:none;background-color:#e9ecef}.dropdown-item.active,.dropdown-item:active{color:#fff;text-decoration:none;background-color:#007bff}.dropdown-item.disabled,.dropdown-item:disabled{color:#adb5bd;pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:.5rem 1.5rem;margin-bottom:0;font-size:.875rem;color:#6c757d;white-space:nowrap}.dropdown-item-text{display:block;padding:.25rem 1.5rem;color:#212529}.btn-group,.btn-group-vertical{position:relative;display:inline-flex;vertical-align:middle}.btn-group>.btn,.btn-group-vertical>.btn{position:relative;flex:1 1 auto}.btn-group>.btn:hover,.btn-group-vertical>.btn:hover{z-index:1}.btn-group>.btn:focus,.btn-group>.btn:active,.btn-group>.btn.active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn.active{z-index:1}.btn-toolbar{display:flex;flex-wrap:wrap;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn:not(:first-child),.btn-group>.btn-group:not(:first-child){margin-left:-1px}.btn-group>.btn:not(:last-child):not(.dropdown-toggle),.btn-group>.btn-group:not(:last-child)>.btn{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:not(:first-child),.btn-group>.btn-group:not(:first-child)>.btn{border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after,.dropright .dropdown-toggle-split::after{margin-left:0}.dropleft .dropdown-toggle-split::before{margin-right:0}.btn-sm+.dropdown-toggle-split,.btn-group-sm>.btn+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-lg+.dropdown-toggle-split,.btn-group-lg>.btn+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{flex-direction:column;align-items:flex-start;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn:not(:first-child),.btn-group-vertical>.btn-group:not(:first-child){margin-top:-1px}.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle),.btn-group-vertical>.btn-group:not(:last-child)>.btn{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:not(:first-child),.btn-group-vertical>.btn-group:not(:first-child)>.btn{border-top-left-radius:0;border-top-right-radius:0}.btn-group-toggle>.btn,.btn-group-toggle>.btn-group>.btn{margin-bottom:0}.btn-group-toggle>.btn input[type="radio"],.btn-group-toggle>.btn input[type="checkbox"],.btn-group-toggle>.btn-group>.btn input[type="radio"],.btn-group-toggle>.btn-group>.btn input[type="checkbox"]{position:absolute;clip:rect(0, 0, 0, 0);pointer-events:none}.input-group{position:relative;display:flex;flex-wrap:wrap;align-items:stretch;width:100%}.input-group>.form-control,.input-group>.form-control-plaintext,.input-group>.custom-select,.input-group>.custom-file{position:relative;flex:1 1 auto;width:1%;min-width:0;margin-bottom:0}.input-group>.form-control+.form-control,.input-group>.form-control+.custom-select,.input-group>.form-control+.custom-file,.input-group>.form-control-plaintext+.form-control,.input-group>.form-control-plaintext+.custom-select,.input-group>.form-control-plaintext+.custom-file,.input-group>.custom-select+.form-control,.input-group>.custom-select+.custom-select,.input-group>.custom-select+.custom-file,.input-group>.custom-file+.form-control,.input-group>.custom-file+.custom-select,.input-group>.custom-file+.custom-file{margin-left:-1px}.input-group>.form-control:focus,.input-group>.custom-select:focus,.input-group>.custom-file .custom-file-input:focus ~ .custom-file-label{z-index:3}.input-group>.custom-file .custom-file-input:focus{z-index:4}.input-group>.form-control:not(:first-child),.input-group>.custom-select:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.custom-file{display:flex;align-items:center}.input-group>.custom-file:not(:last-child) .custom-file-label,.input-group>.custom-file:not(:last-child) .custom-file-label::after{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-file:not(:first-child) .custom-file-label{border-top-left-radius:0;border-bottom-left-radius:0}.input-group:not(.has-validation)>.form-control:not(:last-child),.input-group:not(.has-validation)>.custom-select:not(:last-child),.input-group:not(.has-validation)>.custom-file:not(:last-child) .custom-file-label,.input-group:not(.has-validation)>.custom-file:not(:last-child) .custom-file-label::after{border-top-right-radius:0;border-bottom-right-radius:0}.input-group.has-validation>.form-control:nth-last-child(n+3),.input-group.has-validation>.custom-select:nth-last-child(n+3),.input-group.has-validation>.custom-file:nth-last-child(n+3) .custom-file-label,.input-group.has-validation>.custom-file:nth-last-child(n+3) .custom-file-label::after{border-top-right-radius:0;border-bottom-right-radius:0}.input-group-prepend,.input-group-append{display:flex}.input-group-prepend .btn,.input-group-append .btn{position:relative;z-index:2}.input-group-prepend .btn:focus,.input-group-append .btn:focus{z-index:3}.input-group-prepend .btn+.btn,.input-group-prepend .btn+.input-group-text,.input-group-prepend .input-group-text+.input-group-text,.input-group-prepend .input-group-text+.btn,.input-group-append .btn+.btn,.input-group-append .btn+.input-group-text,.input-group-append .input-group-text+.input-group-text,.input-group-append .input-group-text+.btn{margin-left:-1px}.input-group-prepend{margin-right:-1px}.input-group-append{margin-left:-1px}.input-group-text{display:flex;align-items:center;padding:.375rem .75rem;margin-bottom:0;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid #ced4da;border-radius:.25rem}.input-group-text input[type="radio"],.input-group-text input[type="checkbox"]{margin-top:0}.input-group-lg>.form-control:not(textarea),.input-group-lg>.custom-select{height:calc(1.5em + 1rem + 2px)}.input-group-lg>.form-control,.input-group-lg>.custom-select,.input-group-lg>.input-group-prepend>.input-group-text,.input-group-lg>.input-group-append>.input-group-text,.input-group-lg>.input-group-prepend>.btn,.input-group-lg>.input-group-append>.btn{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.input-group-sm>.form-control:not(textarea),.input-group-sm>.custom-select{height:calc(1.5em + .5rem + 2px)}.input-group-sm>.form-control,.input-group-sm>.custom-select,.input-group-sm>.input-group-prepend>.input-group-text,.input-group-sm>.input-group-append>.input-group-text,.input-group-sm>.input-group-prepend>.btn,.input-group-sm>.input-group-append>.btn{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.input-group-lg>.custom-select,.input-group-sm>.custom-select{padding-right:1.75rem}.input-group>.input-group-prepend>.btn,.input-group>.input-group-prepend>.input-group-text,.input-group:not(.has-validation)>.input-group-append:not(:last-child)>.btn,.input-group:not(.has-validation)>.input-group-append:not(:last-child)>.input-group-text,.input-group.has-validation>.input-group-append:nth-last-child(n+3)>.btn,.input-group.has-validation>.input-group-append:nth-last-child(n+3)>.input-group-text,.input-group>.input-group-append:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group>.input-group-append:last-child>.input-group-text:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.input-group-append>.btn,.input-group>.input-group-append>.input-group-text,.input-group>.input-group-prepend:not(:first-child)>.btn,.input-group>.input-group-prepend:not(:first-child)>.input-group-text,.input-group>.input-group-prepend:first-child>.btn:not(:first-child),.input-group>.input-group-prepend:first-child>.input-group-text:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.custom-control{position:relative;z-index:1;display:block;min-height:1.5rem;padding-left:1.5rem;color-adjust:exact}.custom-control-inline{display:inline-flex;margin-right:1rem}.custom-control-input{position:absolute;left:0;z-index:-1;width:1rem;height:1.25rem;opacity:0}.custom-control-input:checked ~ .custom-control-label::before{color:#fff;border-color:#007bff;background-color:#007bff}.custom-control-input:focus ~ .custom-control-label::before{box-shadow:0 0 0 .2rem rgba(0,123,255,0.25)}.custom-control-input:focus:not(:checked) ~ .custom-control-label::before{border-color:#80bdff}.custom-control-input:not(:disabled):active ~ .custom-control-label::before{color:#fff;background-color:#b3d7ff;border-color:#b3d7ff}.custom-control-input[disabled] ~ .custom-control-label,.custom-control-input:disabled ~ .custom-control-label{color:#6c757d}.custom-control-input[disabled] ~ .custom-control-label::before,.custom-control-input:disabled ~ .custom-control-label::before{background-color:#e9ecef}.custom-control-label{position:relative;margin-bottom:0;vertical-align:top}.custom-control-label::before{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;pointer-events:none;content:"";background-color:#fff;border:#adb5bd solid 1px}.custom-control-label::after{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;content:"";background:50% / 50% 50% no-repeat}.custom-checkbox .custom-control-label::before{border-radius:.25rem}.custom-checkbox .custom-control-input:checked ~ .custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26l2.974 2.99L8 2.193z'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:indeterminate ~ .custom-control-label::before{border-color:#007bff;background-color:#007bff}.custom-checkbox .custom-control-input:indeterminate ~ .custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4' viewBox='0 0 4 4'%3e%3cpath stroke='%23fff' d='M0 2h4'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:disabled:checked ~ .custom-control-label::before{background-color:rgba(0,123,255,0.5)}.custom-checkbox .custom-control-input:disabled:indeterminate ~ .custom-control-label::before{background-color:rgba(0,123,255,0.5)}.custom-radio .custom-control-label::before{border-radius:50%}.custom-radio .custom-control-input:checked ~ .custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")}.custom-radio .custom-control-input:disabled:checked ~ .custom-control-label::before{background-color:rgba(0,123,255,0.5)}.custom-switch{padding-left:2.25rem}.custom-switch .custom-control-label::before{left:-2.25rem;width:1.75rem;pointer-events:all;border-radius:.5rem}.custom-switch .custom-control-label::after{top:calc(.25rem + 2px);left:calc(-2.25rem + 2px);width:calc(1rem - 4px);height:calc(1rem - 4px);background-color:#adb5bd;border-radius:.5rem;transition:transform 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.custom-switch .custom-control-label::after{transition:none}}.custom-switch .custom-control-input:checked ~ .custom-control-label::after{background-color:#fff;transform:translateX(.75rem)}.custom-switch .custom-control-input:disabled:checked ~ .custom-control-label::before{background-color:rgba(0,123,255,0.5)}.custom-select{display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem 1.75rem .375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;vertical-align:middle;background:#fff url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") right .75rem center/8px 10px no-repeat;border:1px solid #ced4da;border-radius:.25rem;appearance:none}.custom-select:focus{border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,0.25)}.custom-select:focus::-ms-value{color:#495057;background-color:#fff}.custom-select[multiple],.custom-select[size]:not([size="1"]){height:auto;padding-right:.75rem;background-image:none}.custom-select:disabled{color:#6c757d;background-color:#e9ecef}.custom-select::-ms-expand{display:none}.custom-select:-moz-focusring{color:transparent;text-shadow:0 0 0 #495057}.custom-select-sm{height:calc(1.5em + .5rem + 2px);padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:.875rem}.custom-select-lg{height:calc(1.5em + 1rem + 2px);padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem}.custom-file{position:relative;display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);margin-bottom:0}.custom-file-input{position:relative;z-index:2;width:100%;height:calc(1.5em + .75rem + 2px);margin:0;overflow:hidden;opacity:0}.custom-file-input:focus ~ .custom-file-label{border-color:#80bdff;box-shadow:0 0 0 .2rem rgba(0,123,255,0.25)}.custom-file-input[disabled] ~ .custom-file-label,.custom-file-input:disabled ~ .custom-file-label{background-color:#e9ecef}.custom-file-input:lang(en) ~ .custom-file-label::after{content:"Browse"}.custom-file-input ~ .custom-file-label[data-browse]::after{content:attr(data-browse)}.custom-file-label{position:absolute;top:0;right:0;left:0;z-index:1;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;overflow:hidden;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;border:1px solid #ced4da;border-radius:.25rem}.custom-file-label::after{position:absolute;top:0;right:0;bottom:0;z-index:3;display:block;height:calc(1.5em + .75rem);padding:.375rem .75rem;line-height:1.5;color:#495057;content:"Browse";background-color:#e9ecef;border-left:inherit;border-radius:0 .25rem .25rem 0}.custom-range{width:100%;height:1.4rem;padding:0;background-color:transparent;appearance:none}.custom-range:focus{outline:0}.custom-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,0.25)}.custom-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,0.25)}.custom-range:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,0.25)}.custom-range::-moz-focus-outer{border:0}.custom-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#007bff;border:0;border-radius:1rem;transition:background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out;appearance:none}@media (prefers-reduced-motion: reduce){.custom-range::-webkit-slider-thumb{transition:none}}.custom-range::-webkit-slider-thumb:active{background-color:#b3d7ff}.custom-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#007bff;border:0;border-radius:1rem;transition:background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out;appearance:none}@media (prefers-reduced-motion: reduce){.custom-range::-moz-range-thumb{transition:none}}.custom-range::-moz-range-thumb:active{background-color:#b3d7ff}.custom-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-ms-thumb{width:1rem;height:1rem;margin-top:0;margin-right:.2rem;margin-left:.2rem;background-color:#007bff;border:0;border-radius:1rem;transition:background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out;appearance:none}@media (prefers-reduced-motion: reduce){.custom-range::-ms-thumb{transition:none}}.custom-range::-ms-thumb:active{background-color:#b3d7ff}.custom-range::-ms-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:transparent;border-color:transparent;border-width:.5rem}.custom-range::-ms-fill-lower{background-color:#dee2e6;border-radius:1rem}.custom-range::-ms-fill-upper{margin-right:15px;background-color:#dee2e6;border-radius:1rem}.custom-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.custom-range:disabled::-webkit-slider-runnable-track{cursor:default}.custom-range:disabled::-moz-range-thumb{background-color:#adb5bd}.custom-range:disabled::-moz-range-track{cursor:default}.custom-range:disabled::-ms-thumb{background-color:#adb5bd}.custom-control-label::before,.custom-file-label,.custom-select{transition:background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.custom-control-label::before,.custom-file-label,.custom-select{transition:none}}.nav{display:flex;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.5rem 1rem}.nav-link:hover,.nav-link:focus{text-decoration:none}.nav-link.disabled{color:#6c757d;pointer-events:none;cursor:default}.nav-tabs{border-bottom:1px solid #dee2e6}.nav-tabs .nav-link{margin-bottom:-1px;border:1px solid transparent;border-top-left-radius:.25rem;border-top-right-radius:.25rem}.nav-tabs .nav-link:hover,.nav-tabs .nav-link:focus{border-color:#e9ecef #e9ecef #dee2e6}.nav-tabs .nav-link.disabled{color:#6c757d;background-color:transparent;border-color:transparent}.nav-tabs .nav-link.active,.nav-tabs .nav-item.show .nav-link{color:#495057;background-color:#fff;border-color:#dee2e6 #dee2e6 #fff}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:#fff;background-color:#007bff}.nav-fill>.nav-link,.nav-fill .nav-item{flex:1 1 auto;text-align:center}.nav-justified>.nav-link,.nav-justified .nav-item{flex-basis:0;flex-grow:1;text-align:center}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{position:relative;display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;padding:.5rem 1rem}.navbar .container,.navbar .container-fluid,.navbar .container-sm,.navbar .container-md,.navbar .container-lg,.navbar .container-xl{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between}.navbar-brand{display:inline-block;padding-top:.3125rem;padding-bottom:.3125rem;margin-right:1rem;font-size:1.25rem;line-height:inherit;white-space:nowrap}.navbar-brand:hover,.navbar-brand:focus{text-decoration:none}.navbar-nav{display:flex;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static;float:none}.navbar-text{display:inline-block;padding-top:.5rem;padding-bottom:.5rem}.navbar-collapse{flex-basis:100%;flex-grow:1;align-items:center}.navbar-toggler{padding:.25rem .75rem;font-size:1.25rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:.25rem}.navbar-toggler:hover,.navbar-toggler:focus{text-decoration:none}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;content:"";background:50% / 100% 100% no-repeat}.navbar-nav-scroll{max-height:75vh;overflow-y:auto}@media (max-width: 575.98px){.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid,.navbar-expand-sm>.container-sm,.navbar-expand-sm>.container-md,.navbar-expand-sm>.container-lg,.navbar-expand-sm>.container-xl{padding-right:0;padding-left:0}}@media (min-width: 576px){.navbar-expand-sm{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid,.navbar-expand-sm>.container-sm,.navbar-expand-sm>.container-md,.navbar-expand-sm>.container-lg,.navbar-expand-sm>.container-xl{flex-wrap:nowrap}.navbar-expand-sm .navbar-nav-scroll{overflow:visible}.navbar-expand-sm .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}}@media (max-width: 767.98px){.navbar-expand-md>.container,.navbar-expand-md>.container-fluid,.navbar-expand-md>.container-sm,.navbar-expand-md>.container-md,.navbar-expand-md>.container-lg,.navbar-expand-md>.container-xl{padding-right:0;padding-left:0}}@media (min-width: 768px){.navbar-expand-md{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-md .navbar-nav{flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-md>.container,.navbar-expand-md>.container-fluid,.navbar-expand-md>.container-sm,.navbar-expand-md>.container-md,.navbar-expand-md>.container-lg,.navbar-expand-md>.container-xl{flex-wrap:nowrap}.navbar-expand-md .navbar-nav-scroll{overflow:visible}.navbar-expand-md .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}}@media (max-width: 991.98px){.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid,.navbar-expand-lg>.container-sm,.navbar-expand-lg>.container-md,.navbar-expand-lg>.container-lg,.navbar-expand-lg>.container-xl{padding-right:0;padding-left:0}}@media (min-width: 992px){.navbar-expand-lg{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid,.navbar-expand-lg>.container-sm,.navbar-expand-lg>.container-md,.navbar-expand-lg>.container-lg,.navbar-expand-lg>.container-xl{flex-wrap:nowrap}.navbar-expand-lg .navbar-nav-scroll{overflow:visible}.navbar-expand-lg .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}}@media (max-width: 1199.98px){.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid,.navbar-expand-xl>.container-sm,.navbar-expand-xl>.container-md,.navbar-expand-xl>.container-lg,.navbar-expand-xl>.container-xl{padding-right:0;padding-left:0}}@media (min-width: 1200px){.navbar-expand-xl{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-xl .navbar-nav{flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid,.navbar-expand-xl>.container-sm,.navbar-expand-xl>.container-md,.navbar-expand-xl>.container-lg,.navbar-expand-xl>.container-xl{flex-wrap:nowrap}.navbar-expand-xl .navbar-nav-scroll{overflow:visible}.navbar-expand-xl .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}}.navbar-expand{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand>.container,.navbar-expand>.container-fluid,.navbar-expand>.container-sm,.navbar-expand>.container-md,.navbar-expand>.container-lg,.navbar-expand>.container-xl{padding-right:0;padding-left:0}.navbar-expand .navbar-nav{flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand>.container,.navbar-expand>.container-fluid,.navbar-expand>.container-sm,.navbar-expand>.container-md,.navbar-expand>.container-lg,.navbar-expand>.container-xl{flex-wrap:nowrap}.navbar-expand .navbar-nav-scroll{overflow:visible}.navbar-expand .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-light .navbar-brand{color:rgba(0,0,0,0.9)}.navbar-light .navbar-brand:hover,.navbar-light .navbar-brand:focus{color:rgba(0,0,0,0.9)}.navbar-light .navbar-nav .nav-link{color:rgba(0,0,0,0.5)}.navbar-light .navbar-nav .nav-link:hover,.navbar-light .navbar-nav .nav-link:focus{color:rgba(0,0,0,0.7)}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(0,0,0,0.3)}.navbar-light .navbar-nav .show>.nav-link,.navbar-light .navbar-nav .active>.nav-link,.navbar-light .navbar-nav .nav-link.show,.navbar-light .navbar-nav .nav-link.active{color:rgba(0,0,0,0.9)}.navbar-light .navbar-toggler{color:rgba(0,0,0,0.5);border-color:rgba(0,0,0,0.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%280,0,0,0.5%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-light .navbar-text{color:rgba(0,0,0,0.5)}.navbar-light .navbar-text a{color:rgba(0,0,0,0.9)}.navbar-light .navbar-text a:hover,.navbar-light .navbar-text a:focus{color:rgba(0,0,0,0.9)}.navbar-dark .navbar-brand{color:#fff}.navbar-dark .navbar-brand:hover,.navbar-dark .navbar-brand:focus{color:#fff}.navbar-dark .navbar-nav .nav-link{color:rgba(255,255,255,0.5)}.navbar-dark .navbar-nav .nav-link:hover,.navbar-dark .navbar-nav .nav-link:focus{color:rgba(255,255,255,0.75)}.navbar-dark .navbar-nav .nav-link.disabled{color:rgba(255,255,255,0.25)}.navbar-dark .navbar-nav .show>.nav-link,.navbar-dark .navbar-nav .active>.nav-link,.navbar-dark .navbar-nav .nav-link.show,.navbar-dark .navbar-nav .nav-link.active{color:#fff}.navbar-dark .navbar-toggler{color:rgba(255,255,255,0.5);border-color:rgba(255,255,255,0.1)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255,255,255,0.5%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-dark .navbar-text{color:rgba(255,255,255,0.5)}.navbar-dark .navbar-text a{color:#fff}.navbar-dark .navbar-text a:hover,.navbar-dark .navbar-text a:focus{color:#fff}.card{position:relative;display:flex;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid rgba(0,0,0,0.125);border-radius:.25rem}.card>hr{margin-right:0;margin-left:0}.card>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child{border-top-width:0;border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card>.card-header+.list-group,.card>.list-group+.card-footer{border-top:0}.card-body{flex:1 1 auto;min-height:1px;padding:1.25rem}.card-title{margin-bottom:.75rem}.card-subtitle{margin-top:-.375rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-left:1.25rem}.card-header{padding:.75rem 1.25rem;margin-bottom:0;background-color:rgba(0,0,0,0.03);border-bottom:1px solid rgba(0,0,0,0.125)}.card-header:first-child{border-radius:calc(.25rem - 1px) calc(.25rem - 1px) 0 0}.card-footer{padding:.75rem 1.25rem;background-color:rgba(0,0,0,0.03);border-top:1px solid rgba(0,0,0,0.125)}.card-footer:last-child{border-radius:0 0 calc(.25rem - 1px) calc(.25rem - 1px)}.card-header-tabs{margin-right:-.625rem;margin-bottom:-.75rem;margin-left:-.625rem;border-bottom:0}.card-header-pills{margin-right:-.625rem;margin-left:-.625rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1.25rem;border-radius:calc(.25rem - 1px)}.card-img,.card-img-top,.card-img-bottom{flex-shrink:0;width:100%}.card-img,.card-img-top{border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card-img,.card-img-bottom{border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card-deck .card{margin-bottom:15px}@media (min-width: 576px){.card-deck{display:flex;flex-flow:row wrap;margin-right:-15px;margin-left:-15px}.card-deck .card{flex:1 0 0%;margin-right:15px;margin-bottom:0;margin-left:15px}}.card-group>.card{margin-bottom:15px}@media (min-width: 576px){.card-group{display:flex;flex-flow:row wrap}.card-group>.card{flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-img-top,.card-group>.card:not(:last-child) .card-header{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-img-bottom,.card-group>.card:not(:last-child) .card-footer{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-img-top,.card-group>.card:not(:first-child) .card-header{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-img-bottom,.card-group>.card:not(:first-child) .card-footer{border-bottom-left-radius:0}}.card-columns .card{margin-bottom:.75rem}@media (min-width: 576px){.card-columns{column-count:3;column-gap:1.25rem;orphans:1;widows:1}.card-columns .card{display:inline-block;width:100%}}.accordion{overflow-anchor:none}.accordion>.card{overflow:hidden}.accordion>.card:not(:last-of-type){border-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion>.card:not(:first-of-type){border-top-left-radius:0;border-top-right-radius:0}.accordion>.card>.card-header{border-radius:0;margin-bottom:-1px}.breadcrumb{display:flex;flex-wrap:wrap;padding:.75rem 1rem;margin-bottom:1rem;list-style:none;background-color:#e9ecef;border-radius:.25rem}.breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.breadcrumb-item+.breadcrumb-item::before{float:left;padding-right:.5rem;color:#6c757d;content:"/"}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:underline}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:none}.breadcrumb-item.active{color:#6c757d}.pagination{display:flex;padding-left:0;list-style:none;border-radius:.25rem}.page-link{position:relative;display:block;padding:.5rem .75rem;margin-left:-1px;line-height:1.25;color:#007bff;background-color:#fff;border:1px solid #dee2e6}.page-link:hover{z-index:2;color:#0056b3;text-decoration:none;background-color:#e9ecef;border-color:#dee2e6}.page-link:focus{z-index:3;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,0.25)}.page-item:first-child .page-link{margin-left:0;border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.page-item.active .page-link{z-index:3;color:#fff;background-color:#007bff;border-color:#007bff}.page-item.disabled .page-link{color:#6c757d;pointer-events:none;cursor:auto;background-color:#fff;border-color:#dee2e6}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:1.25rem;line-height:1.5}.pagination-lg .page-item:first-child .page-link{border-top-left-radius:.3rem;border-bottom-left-radius:.3rem}.pagination-lg .page-item:last-child .page-link{border-top-right-radius:.3rem;border-bottom-right-radius:.3rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:.875rem;line-height:1.5}.pagination-sm .page-item:first-child .page-link{border-top-left-radius:.2rem;border-bottom-left-radius:.2rem}.pagination-sm .page-item:last-child .page-link{border-top-right-radius:.2rem;border-bottom-right-radius:.2rem}.badge{display:inline-block;padding:.25em .4em;font-size:75%;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem;transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.badge{transition:none}}a.badge:hover,a.badge:focus{text-decoration:none}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.badge-pill{padding-right:.6em;padding-left:.6em;border-radius:10rem}.badge-primary{color:#fff;background-color:#007bff}a.badge-primary:hover,a.badge-primary:focus{color:#fff;background-color:#0062cc}a.badge-primary:focus,a.badge-primary.focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,0.5)}.badge-secondary{color:#fff;background-color:#6c757d}a.badge-secondary:hover,a.badge-secondary:focus{color:#fff;background-color:#545b62}a.badge-secondary:focus,a.badge-secondary.focus{outline:0;box-shadow:0 0 0 .2rem rgba(108,117,125,0.5)}.badge-success{color:#fff;background-color:#28a745}a.badge-success:hover,a.badge-success:focus{color:#fff;background-color:#1e7e34}a.badge-success:focus,a.badge-success.focus{outline:0;box-shadow:0 0 0 .2rem rgba(40,167,69,0.5)}.badge-info{color:#fff;background-color:#17a2b8}a.badge-info:hover,a.badge-info:focus{color:#fff;background-color:#117a8b}a.badge-info:focus,a.badge-info.focus{outline:0;box-shadow:0 0 0 .2rem rgba(23,162,184,0.5)}.badge-warning{color:#212529;background-color:#ffc107}a.badge-warning:hover,a.badge-warning:focus{color:#212529;background-color:#d39e00}a.badge-warning:focus,a.badge-warning.focus{outline:0;box-shadow:0 0 0 .2rem rgba(255,193,7,0.5)}.badge-danger{color:#fff;background-color:#dc3545}a.badge-danger:hover,a.badge-danger:focus{color:#fff;background-color:#bd2130}a.badge-danger:focus,a.badge-danger.focus{outline:0;box-shadow:0 0 0 .2rem rgba(220,53,69,0.5)}.badge-light{color:#212529;background-color:#f8f9fa}a.badge-light:hover,a.badge-light:focus{color:#212529;background-color:#dae0e5}a.badge-light:focus,a.badge-light.focus{outline:0;box-shadow:0 0 0 .2rem rgba(248,249,250,0.5)}.badge-dark{color:#fff;background-color:#343a40}a.badge-dark:hover,a.badge-dark:focus{color:#fff;background-color:#1d2124}a.badge-dark:focus,a.badge-dark.focus{outline:0;box-shadow:0 0 0 .2rem rgba(52,58,64,0.5)}.jumbotron{padding:2rem 1rem;margin-bottom:2rem;background-color:#e9ecef;border-radius:.3rem}@media (min-width: 576px){.jumbotron{padding:4rem 2rem}}.jumbotron-fluid{padding-right:0;padding-left:0;border-radius:0}.alert{position:relative;padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:4rem}.alert-dismissible .close{position:absolute;top:0;right:0;z-index:2;padding:.75rem 1.25rem;color:inherit}.alert-primary{color:#004085;background-color:#cce5ff;border-color:#b8daff}.alert-primary hr{border-top-color:#9fcdff}.alert-primary .alert-link{color:#002752}.alert-secondary{color:#383d41;background-color:#e2e3e5;border-color:#d6d8db}.alert-secondary hr{border-top-color:#c8cbcf}.alert-secondary .alert-link{color:#202326}.alert-success{color:#155724;background-color:#d4edda;border-color:#c3e6cb}.alert-success hr{border-top-color:#b1dfbb}.alert-success .alert-link{color:#0b2e13}.alert-info{color:#0c5460;background-color:#d1ecf1;border-color:#bee5eb}.alert-info hr{border-top-color:#abdde5}.alert-info .alert-link{color:#062c33}.alert-warning{color:#856404;background-color:#fff3cd;border-color:#ffeeba}.alert-warning hr{border-top-color:#ffe8a1}.alert-warning .alert-link{color:#533f03}.alert-danger{color:#721c24;background-color:#f8d7da;border-color:#f5c6cb}.alert-danger hr{border-top-color:#f1b0b7}.alert-danger .alert-link{color:#491217}.alert-light{color:#818182;background-color:#fefefe;border-color:#fdfdfe}.alert-light hr{border-top-color:#ececf6}.alert-light .alert-link{color:#686868}.alert-dark{color:#1b1e21;background-color:#d6d8d9;border-color:#c6c8ca}.alert-dark hr{border-top-color:#b9bbbe}.alert-dark .alert-link{color:#040505}@keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}.progress{display:flex;height:1rem;overflow:hidden;line-height:0;font-size:.75rem;background-color:#e9ecef;border-radius:.25rem}.progress-bar{display:flex;flex-direction:column;justify-content:center;overflow:hidden;color:#fff;text-align:center;white-space:nowrap;background-color:#007bff;transition:width 0.6s ease}@media (prefers-reduced-motion: reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-size:1rem 1rem}.progress-bar-animated{animation:1s linear infinite progress-bar-stripes}@media (prefers-reduced-motion: reduce){.progress-bar-animated{animation:none}}.media{display:flex;align-items:flex-start}.media-body{flex:1}.list-group{display:flex;flex-direction:column;padding-left:0;margin-bottom:0;border-radius:.25rem}.list-group-item-action{width:100%;color:#495057;text-align:inherit}.list-group-item-action:hover,.list-group-item-action:focus{z-index:1;color:#495057;text-decoration:none;background-color:#f8f9fa}.list-group-item-action:active{color:#212529;background-color:#e9ecef}.list-group-item{position:relative;display:block;padding:.75rem 1.25rem;background-color:#fff;border:1px solid rgba(0,0,0,0.125)}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{color:#6c757d;pointer-events:none;background-color:#fff}.list-group-item.active{z-index:2;color:#fff;background-color:#007bff;border-color:#007bff}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:-1px;border-top-width:1px}.list-group-horizontal{flex-direction:row}.list-group-horizontal>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}@media (min-width: 576px){.list-group-horizontal-sm{flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width: 768px){.list-group-horizontal-md{flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width: 992px){.list-group-horizontal-lg{flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width: 1200px){.list-group-horizontal-xl{flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 1px}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{color:#004085;background-color:#b8daff}.list-group-item-primary.list-group-item-action:hover,.list-group-item-primary.list-group-item-action:focus{color:#004085;background-color:#9fcdff}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#004085;border-color:#004085}.list-group-item-secondary{color:#383d41;background-color:#d6d8db}.list-group-item-secondary.list-group-item-action:hover,.list-group-item-secondary.list-group-item-action:focus{color:#383d41;background-color:#c8cbcf}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#383d41;border-color:#383d41}.list-group-item-success{color:#155724;background-color:#c3e6cb}.list-group-item-success.list-group-item-action:hover,.list-group-item-success.list-group-item-action:focus{color:#155724;background-color:#b1dfbb}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#155724;border-color:#155724}.list-group-item-info{color:#0c5460;background-color:#bee5eb}.list-group-item-info.list-group-item-action:hover,.list-group-item-info.list-group-item-action:focus{color:#0c5460;background-color:#abdde5}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#0c5460;border-color:#0c5460}.list-group-item-warning{color:#856404;background-color:#ffeeba}.list-group-item-warning.list-group-item-action:hover,.list-group-item-warning.list-group-item-action:focus{color:#856404;background-color:#ffe8a1}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#856404;border-color:#856404}.list-group-item-danger{color:#721c24;background-color:#f5c6cb}.list-group-item-danger.list-group-item-action:hover,.list-group-item-danger.list-group-item-action:focus{color:#721c24;background-color:#f1b0b7}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#721c24;border-color:#721c24}.list-group-item-light{color:#818182;background-color:#fdfdfe}.list-group-item-light.list-group-item-action:hover,.list-group-item-light.list-group-item-action:focus{color:#818182;background-color:#ececf6}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#818182;border-color:#818182}.list-group-item-dark{color:#1b1e21;background-color:#c6c8ca}.list-group-item-dark.list-group-item-action:hover,.list-group-item-dark.list-group-item-action:focus{color:#1b1e21;background-color:#b9bbbe}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#1b1e21;border-color:#1b1e21}.close{float:right;font-size:1.5rem;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.5}.close:hover{color:#000;text-decoration:none}.close:not(:disabled):not(.disabled):hover,.close:not(:disabled):not(.disabled):focus{opacity:.75}button.close{padding:0;background-color:transparent;border:0}a.close.disabled{pointer-events:none}.toast{flex-basis:350px;max-width:350px;font-size:.875rem;background-color:rgba(255,255,255,0.85);background-clip:padding-box;border:1px solid rgba(0,0,0,0.1);box-shadow:0 0.25rem 0.75rem rgba(0,0,0,0.1);opacity:0;border-radius:.25rem}.toast:not(:last-child){margin-bottom:.75rem}.toast.showing{opacity:1}.toast.show{display:block;opacity:1}.toast.hide{display:none}.toast-header{display:flex;align-items:center;padding:.25rem .75rem;color:#6c757d;background-color:rgba(255,255,255,0.85);background-clip:padding-box;border-bottom:1px solid rgba(0,0,0,0.05);border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.toast-body{padding:.75rem}.modal-open{overflow:hidden}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal{position:fixed;top:0;left:0;z-index:1050;display:none;width:100%;height:100%;overflow:hidden;outline:0}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:transform 0.3s ease-out;transform:translate(0, -50px)}@media (prefers-reduced-motion: reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{transform:none}.modal.modal-static .modal-dialog{transform:scale(1.02)}.modal-dialog-scrollable{display:flex;max-height:calc(100% - 1rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 1rem);overflow:hidden}.modal-dialog-scrollable .modal-header,.modal-dialog-scrollable .modal-footer{flex-shrink:0}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:flex;align-items:center;min-height:calc(100% - 1rem)}.modal-dialog-centered::before{display:block;height:calc(100vh - 1rem);height:min-content;content:""}.modal-dialog-centered.modal-dialog-scrollable{flex-direction:column;justify-content:center;height:100%}.modal-dialog-centered.modal-dialog-scrollable .modal-content{max-height:none}.modal-dialog-centered.modal-dialog-scrollable::before{content:none}.modal-content{position:relative;display:flex;flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,0.2);border-radius:.3rem;outline:0}.modal-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:flex;align-items:flex-start;justify-content:space-between;padding:1rem 1rem;border-bottom:1px solid #dee2e6;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.modal-header .close{padding:1rem 1rem;margin:-1rem -1rem -1rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;flex:1 1 auto;padding:1rem}.modal-footer{display:flex;flex-wrap:wrap;align-items:center;justify-content:flex-end;padding:.75rem;border-top:1px solid #dee2e6;border-bottom-right-radius:calc(.3rem - 1px);border-bottom-left-radius:calc(.3rem - 1px)}.modal-footer>*{margin:.25rem}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width: 576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-scrollable{max-height:calc(100% - 3.5rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 3.5rem)}.modal-dialog-centered{min-height:calc(100% - 3.5rem)}.modal-dialog-centered::before{height:calc(100vh - 3.5rem);height:min-content}.modal-sm{max-width:300px}}@media (min-width: 992px){.modal-lg,.modal-xl{max-width:800px}}@media (min-width: 1200px){.modal-xl{max-width:1140px}}.tooltip{position:absolute;z-index:1070;display:block;margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:.9}.tooltip .arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-top,.bs-tooltip-auto[x-placement^="top"]{padding:.4rem 0}.bs-tooltip-top .arrow,.bs-tooltip-auto[x-placement^="top"] .arrow{bottom:0}.bs-tooltip-top .arrow::before,.bs-tooltip-auto[x-placement^="top"] .arrow::before{top:0;border-width:.4rem .4rem 0;border-top-color:#000}.bs-tooltip-right,.bs-tooltip-auto[x-placement^="right"]{padding:0 .4rem}.bs-tooltip-right .arrow,.bs-tooltip-auto[x-placement^="right"] .arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-right .arrow::before,.bs-tooltip-auto[x-placement^="right"] .arrow::before{right:0;border-width:.4rem .4rem .4rem 0;border-right-color:#000}.bs-tooltip-bottom,.bs-tooltip-auto[x-placement^="bottom"]{padding:.4rem 0}.bs-tooltip-bottom .arrow,.bs-tooltip-auto[x-placement^="bottom"] .arrow{top:0}.bs-tooltip-bottom .arrow::before,.bs-tooltip-auto[x-placement^="bottom"] .arrow::before{bottom:0;border-width:0 .4rem .4rem;border-bottom-color:#000}.bs-tooltip-left,.bs-tooltip-auto[x-placement^="left"]{padding:0 .4rem}.bs-tooltip-left .arrow,.bs-tooltip-auto[x-placement^="left"] .arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-left .arrow::before,.bs-tooltip-auto[x-placement^="left"] .arrow::before{left:0;border-width:.4rem 0 .4rem .4rem;border-left-color:#000}.tooltip-inner{max-width:200px;padding:.25rem .5rem;color:#fff;text-align:center;background-color:#000;border-radius:.25rem}.popover{position:absolute;top:0;left:0;z-index:1060;display:block;max-width:276px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,0.2);border-radius:.3rem}.popover .arrow{position:absolute;display:block;width:1rem;height:.5rem;margin:0 .3rem}.popover .arrow::before,.popover .arrow::after{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.bs-popover-top,.bs-popover-auto[x-placement^="top"]{margin-bottom:.5rem}.bs-popover-top>.arrow,.bs-popover-auto[x-placement^="top"]>.arrow{bottom:calc(-.5rem - 1px)}.bs-popover-top>.arrow::before,.bs-popover-auto[x-placement^="top"]>.arrow::before{bottom:0;border-width:.5rem .5rem 0;border-top-color:rgba(0,0,0,0.25)}.bs-popover-top>.arrow::after,.bs-popover-auto[x-placement^="top"]>.arrow::after{bottom:1px;border-width:.5rem .5rem 0;border-top-color:#fff}.bs-popover-right,.bs-popover-auto[x-placement^="right"]{margin-left:.5rem}.bs-popover-right>.arrow,.bs-popover-auto[x-placement^="right"]>.arrow{left:calc(-.5rem - 1px);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-right>.arrow::before,.bs-popover-auto[x-placement^="right"]>.arrow::before{left:0;border-width:.5rem .5rem .5rem 0;border-right-color:rgba(0,0,0,0.25)}.bs-popover-right>.arrow::after,.bs-popover-auto[x-placement^="right"]>.arrow::after{left:1px;border-width:.5rem .5rem .5rem 0;border-right-color:#fff}.bs-popover-bottom,.bs-popover-auto[x-placement^="bottom"]{margin-top:.5rem}.bs-popover-bottom>.arrow,.bs-popover-auto[x-placement^="bottom"]>.arrow{top:calc(-.5rem - 1px)}.bs-popover-bottom>.arrow::before,.bs-popover-auto[x-placement^="bottom"]>.arrow::before{top:0;border-width:0 .5rem .5rem .5rem;border-bottom-color:rgba(0,0,0,0.25)}.bs-popover-bottom>.arrow::after,.bs-popover-auto[x-placement^="bottom"]>.arrow::after{top:1px;border-width:0 .5rem .5rem .5rem;border-bottom-color:#fff}.bs-popover-bottom .popover-header::before,.bs-popover-auto[x-placement^="bottom"] .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:"";border-bottom:1px solid #f7f7f7}.bs-popover-left,.bs-popover-auto[x-placement^="left"]{margin-right:.5rem}.bs-popover-left>.arrow,.bs-popover-auto[x-placement^="left"]>.arrow{right:calc(-.5rem - 1px);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-left>.arrow::before,.bs-popover-auto[x-placement^="left"]>.arrow::before{right:0;border-width:.5rem 0 .5rem .5rem;border-left-color:rgba(0,0,0,0.25)}.bs-popover-left>.arrow::after,.bs-popover-auto[x-placement^="left"]>.arrow::after{right:1px;border-width:.5rem 0 .5rem .5rem;border-left-color:#fff}.popover-header{padding:.5rem .75rem;margin-bottom:0;font-size:1rem;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.popover-header:empty{display:none}.popover-body{padding:.5rem .75rem;color:#212529}.carousel{position:relative}.carousel.pointer-event{touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner::after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;backface-visibility:hidden;transition:transform .6s ease-in-out}@media (prefers-reduced-motion: reduce){.carousel-item{transition:none}}.carousel-item.active,.carousel-item-next,.carousel-item-prev{display:block}.carousel-item-next:not(.carousel-item-left),.active.carousel-item-right{transform:translateX(100%)}.carousel-item-prev:not(.carousel-item-right),.active.carousel-item-left{transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;transform:none}.carousel-fade .carousel-item.active,.carousel-fade .carousel-item-next.carousel-item-left,.carousel-fade .carousel-item-prev.carousel-item-right{z-index:1;opacity:1}.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{z-index:0;opacity:0;transition:opacity 0s .6s}@media (prefers-reduced-motion: reduce){.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{transition:none}}.carousel-control-prev,.carousel-control-next{position:absolute;top:0;bottom:0;z-index:1;display:flex;align-items:center;justify-content:center;width:15%;padding:0;color:#fff;text-align:center;background:none;border:0;opacity:.5;transition:opacity 0.15s ease}@media (prefers-reduced-motion: reduce){.carousel-control-prev,.carousel-control-next{transition:none}}.carousel-control-prev:hover,.carousel-control-prev:focus,.carousel-control-next:hover,.carousel-control-next:focus{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-prev-icon,.carousel-control-next-icon{display:inline-block;width:20px;height:20px;background:50% / 100% 100% no-repeat}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M5.25 0l-4 4 4 4 1.5-1.5L4.25 4l2.5-2.5L5.25 0z'/%3e%3c/svg%3e")}.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M2.75 0l-1.5 1.5L3.75 4l-2.5 2.5L2.75 8l4-4-4-4z'/%3e%3c/svg%3e")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:15;display:flex;justify-content:center;padding-left:0;margin-right:15%;margin-left:15%;list-style:none}.carousel-indicators li{box-sizing:content-box;flex:0 1 auto;width:30px;height:3px;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:#fff;background-clip:padding-box;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:.5;transition:opacity 0.6s ease}@media (prefers-reduced-motion: reduce){.carousel-indicators li{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center}@keyframes spinner-border{to{transform:rotate(360deg)}}.spinner-border{display:inline-block;width:2rem;height:2rem;vertical-align:-.125em;border:.25em solid currentColor;border-right-color:transparent;border-radius:50%;animation:.75s linear infinite spinner-border}.spinner-border-sm{width:1rem;height:1rem;border-width:.2em}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}.spinner-grow{display:inline-block;width:2rem;height:2rem;vertical-align:-.125em;background-color:currentColor;border-radius:50%;opacity:0;animation:.75s linear infinite spinner-grow}.spinner-grow-sm{width:1rem;height:1rem}@media (prefers-reduced-motion: reduce){.spinner-border,.spinner-grow{animation-duration:1.5s}}.align-baseline{vertical-align:baseline !important}.align-top{vertical-align:top !important}.align-middle{vertical-align:middle !important}.align-bottom{vertical-align:bottom !important}.align-text-bottom{vertical-align:text-bottom !important}.align-text-top{vertical-align:text-top !important}.bg-primary{background-color:#007bff !important}a.bg-primary:hover,a.bg-primary:focus,button.bg-primary:hover,button.bg-primary:focus{background-color:#0062cc !important}.bg-secondary{background-color:#6c757d !important}a.bg-secondary:hover,a.bg-secondary:focus,button.bg-secondary:hover,button.bg-secondary:focus{background-color:#545b62 !important}.bg-success{background-color:#28a745 !important}a.bg-success:hover,a.bg-success:focus,button.bg-success:hover,button.bg-success:focus{background-color:#1e7e34 !important}.bg-info{background-color:#17a2b8 !important}a.bg-info:hover,a.bg-info:focus,button.bg-info:hover,button.bg-info:focus{background-color:#117a8b !important}.bg-warning{background-color:#ffc107 !important}a.bg-warning:hover,a.bg-warning:focus,button.bg-warning:hover,button.bg-warning:focus{background-color:#d39e00 !important}.bg-danger{background-color:#dc3545 !important}a.bg-danger:hover,a.bg-danger:focus,button.bg-danger:hover,button.bg-danger:focus{background-color:#bd2130 !important}.bg-light{background-color:#f8f9fa !important}a.bg-light:hover,a.bg-light:focus,button.bg-light:hover,button.bg-light:focus{background-color:#dae0e5 !important}.bg-dark{background-color:#343a40 !important}a.bg-dark:hover,a.bg-dark:focus,button.bg-dark:hover,button.bg-dark:focus{background-color:#1d2124 !important}.bg-white{background-color:#fff !important}.bg-transparent{background-color:transparent !important}.border{border:1px solid #dee2e6 !important}.border-top{border-top:1px solid #dee2e6 !important}.border-right{border-right:1px solid #dee2e6 !important}.border-bottom{border-bottom:1px solid #dee2e6 !important}.border-left{border-left:1px solid #dee2e6 !important}.border-0{border:0 !important}.border-top-0{border-top:0 !important}.border-right-0{border-right:0 !important}.border-bottom-0{border-bottom:0 !important}.border-left-0{border-left:0 !important}.border-primary{border-color:#007bff !important}.border-secondary{border-color:#6c757d !important}.border-success{border-color:#28a745 !important}.border-info{border-color:#17a2b8 !important}.border-warning{border-color:#ffc107 !important}.border-danger{border-color:#dc3545 !important}.border-light{border-color:#f8f9fa !important}.border-dark{border-color:#343a40 !important}.border-white{border-color:#fff !important}.rounded-sm{border-radius:.2rem !important}.rounded{border-radius:.25rem !important}.rounded-top{border-top-left-radius:.25rem !important;border-top-right-radius:.25rem !important}.rounded-right{border-top-right-radius:.25rem !important;border-bottom-right-radius:.25rem !important}.rounded-bottom{border-bottom-right-radius:.25rem !important;border-bottom-left-radius:.25rem !important}.rounded-left{border-top-left-radius:.25rem !important;border-bottom-left-radius:.25rem !important}.rounded-lg{border-radius:.3rem !important}.rounded-circle{border-radius:50% !important}.rounded-pill{border-radius:50rem !important}.rounded-0{border-radius:0 !important}.clearfix::after{display:block;clear:both;content:""}.d-none{display:none !important}.d-inline{display:inline !important}.d-inline-block{display:inline-block !important}.d-block{display:block !important}.d-table{display:table !important}.d-table-row{display:table-row !important}.d-table-cell{display:table-cell !important}.d-flex{display:flex !important}.d-inline-flex{display:inline-flex !important}@media (min-width: 576px){.d-sm-none{display:none !important}.d-sm-inline{display:inline !important}.d-sm-inline-block{display:inline-block !important}.d-sm-block{display:block !important}.d-sm-table{display:table !important}.d-sm-table-row{display:table-row !important}.d-sm-table-cell{display:table-cell !important}.d-sm-flex{display:flex !important}.d-sm-inline-flex{display:inline-flex !important}}@media (min-width: 768px){.d-md-none{display:none !important}.d-md-inline{display:inline !important}.d-md-inline-block{display:inline-block !important}.d-md-block{display:block !important}.d-md-table{display:table !important}.d-md-table-row{display:table-row !important}.d-md-table-cell{display:table-cell !important}.d-md-flex{display:flex !important}.d-md-inline-flex{display:inline-flex !important}}@media (min-width: 992px){.d-lg-none{display:none !important}.d-lg-inline{display:inline !important}.d-lg-inline-block{display:inline-block !important}.d-lg-block{display:block !important}.d-lg-table{display:table !important}.d-lg-table-row{display:table-row !important}.d-lg-table-cell{display:table-cell !important}.d-lg-flex{display:flex !important}.d-lg-inline-flex{display:inline-flex !important}}@media (min-width: 1200px){.d-xl-none{display:none !important}.d-xl-inline{display:inline !important}.d-xl-inline-block{display:inline-block !important}.d-xl-block{display:block !important}.d-xl-table{display:table !important}.d-xl-table-row{display:table-row !important}.d-xl-table-cell{display:table-cell !important}.d-xl-flex{display:flex !important}.d-xl-inline-flex{display:inline-flex !important}}@media print{.d-print-none{display:none !important}.d-print-inline{display:inline !important}.d-print-inline-block{display:inline-block !important}.d-print-block{display:block !important}.d-print-table{display:table !important}.d-print-table-row{display:table-row !important}.d-print-table-cell{display:table-cell !important}.d-print-flex{display:flex !important}.d-print-inline-flex{display:inline-flex !important}}.embed-responsive{position:relative;display:block;width:100%;padding:0;overflow:hidden}.embed-responsive::before{display:block;content:""}.embed-responsive .embed-responsive-item,.embed-responsive iframe,.embed-responsive embed,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-21by9::before{padding-top:42.85714286%}.embed-responsive-16by9::before{padding-top:56.25%}.embed-responsive-4by3::before{padding-top:75%}.embed-responsive-1by1::before{padding-top:100%}.flex-row{flex-direction:row !important}.flex-column{flex-direction:column !important}.flex-row-reverse{flex-direction:row-reverse !important}.flex-column-reverse{flex-direction:column-reverse !important}.flex-wrap{flex-wrap:wrap !important}.flex-nowrap{flex-wrap:nowrap !important}.flex-wrap-reverse{flex-wrap:wrap-reverse !important}.flex-fill{flex:1 1 auto !important}.flex-grow-0{flex-grow:0 !important}.flex-grow-1{flex-grow:1 !important}.flex-shrink-0{flex-shrink:0 !important}.flex-shrink-1{flex-shrink:1 !important}.justify-content-start{justify-content:flex-start !important}.justify-content-end{justify-content:flex-end !important}.justify-content-center{justify-content:center !important}.justify-content-between{justify-content:space-between !important}.justify-content-around{justify-content:space-around !important}.align-items-start{align-items:flex-start !important}.align-items-end{align-items:flex-end !important}.align-items-center{align-items:center !important}.align-items-baseline{align-items:baseline !important}.align-items-stretch{align-items:stretch !important}.align-content-start{align-content:flex-start !important}.align-content-end{align-content:flex-end !important}.align-content-center{align-content:center !important}.align-content-between{align-content:space-between !important}.align-content-around{align-content:space-around !important}.align-content-stretch{align-content:stretch !important}.align-self-auto{align-self:auto !important}.align-self-start{align-self:flex-start !important}.align-self-end{align-self:flex-end !important}.align-self-center{align-self:center !important}.align-self-baseline{align-self:baseline !important}.align-self-stretch{align-self:stretch !important}@media (min-width: 576px){.flex-sm-row{flex-direction:row !important}.flex-sm-column{flex-direction:column !important}.flex-sm-row-reverse{flex-direction:row-reverse !important}.flex-sm-column-reverse{flex-direction:column-reverse !important}.flex-sm-wrap{flex-wrap:wrap !important}.flex-sm-nowrap{flex-wrap:nowrap !important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse !important}.flex-sm-fill{flex:1 1 auto !important}.flex-sm-grow-0{flex-grow:0 !important}.flex-sm-grow-1{flex-grow:1 !important}.flex-sm-shrink-0{flex-shrink:0 !important}.flex-sm-shrink-1{flex-shrink:1 !important}.justify-content-sm-start{justify-content:flex-start !important}.justify-content-sm-end{justify-content:flex-end !important}.justify-content-sm-center{justify-content:center !important}.justify-content-sm-between{justify-content:space-between !important}.justify-content-sm-around{justify-content:space-around !important}.align-items-sm-start{align-items:flex-start !important}.align-items-sm-end{align-items:flex-end !important}.align-items-sm-center{align-items:center !important}.align-items-sm-baseline{align-items:baseline !important}.align-items-sm-stretch{align-items:stretch !important}.align-content-sm-start{align-content:flex-start !important}.align-content-sm-end{align-content:flex-end !important}.align-content-sm-center{align-content:center !important}.align-content-sm-between{align-content:space-between !important}.align-content-sm-around{align-content:space-around !important}.align-content-sm-stretch{align-content:stretch !important}.align-self-sm-auto{align-self:auto !important}.align-self-sm-start{align-self:flex-start !important}.align-self-sm-end{align-self:flex-end !important}.align-self-sm-center{align-self:center !important}.align-self-sm-baseline{align-self:baseline !important}.align-self-sm-stretch{align-self:stretch !important}}@media (min-width: 768px){.flex-md-row{flex-direction:row !important}.flex-md-column{flex-direction:column !important}.flex-md-row-reverse{flex-direction:row-reverse !important}.flex-md-column-reverse{flex-direction:column-reverse !important}.flex-md-wrap{flex-wrap:wrap !important}.flex-md-nowrap{flex-wrap:nowrap !important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse !important}.flex-md-fill{flex:1 1 auto !important}.flex-md-grow-0{flex-grow:0 !important}.flex-md-grow-1{flex-grow:1 !important}.flex-md-shrink-0{flex-shrink:0 !important}.flex-md-shrink-1{flex-shrink:1 !important}.justify-content-md-start{justify-content:flex-start !important}.justify-content-md-end{justify-content:flex-end !important}.justify-content-md-center{justify-content:center !important}.justify-content-md-between{justify-content:space-between !important}.justify-content-md-around{justify-content:space-around !important}.align-items-md-start{align-items:flex-start !important}.align-items-md-end{align-items:flex-end !important}.align-items-md-center{align-items:center !important}.align-items-md-baseline{align-items:baseline !important}.align-items-md-stretch{align-items:stretch !important}.align-content-md-start{align-content:flex-start !important}.align-content-md-end{align-content:flex-end !important}.align-content-md-center{align-content:center !important}.align-content-md-between{align-content:space-between !important}.align-content-md-around{align-content:space-around !important}.align-content-md-stretch{align-content:stretch !important}.align-self-md-auto{align-self:auto !important}.align-self-md-start{align-self:flex-start !important}.align-self-md-end{align-self:flex-end !important}.align-self-md-center{align-self:center !important}.align-self-md-baseline{align-self:baseline !important}.align-self-md-stretch{align-self:stretch !important}}@media (min-width: 992px){.flex-lg-row{flex-direction:row !important}.flex-lg-column{flex-direction:column !important}.flex-lg-row-reverse{flex-direction:row-reverse !important}.flex-lg-column-reverse{flex-direction:column-reverse !important}.flex-lg-wrap{flex-wrap:wrap !important}.flex-lg-nowrap{flex-wrap:nowrap !important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse !important}.flex-lg-fill{flex:1 1 auto !important}.flex-lg-grow-0{flex-grow:0 !important}.flex-lg-grow-1{flex-grow:1 !important}.flex-lg-shrink-0{flex-shrink:0 !important}.flex-lg-shrink-1{flex-shrink:1 !important}.justify-content-lg-start{justify-content:flex-start !important}.justify-content-lg-end{justify-content:flex-end !important}.justify-content-lg-center{justify-content:center !important}.justify-content-lg-between{justify-content:space-between !important}.justify-content-lg-around{justify-content:space-around !important}.align-items-lg-start{align-items:flex-start !important}.align-items-lg-end{align-items:flex-end !important}.align-items-lg-center{align-items:center !important}.align-items-lg-baseline{align-items:baseline !important}.align-items-lg-stretch{align-items:stretch !important}.align-content-lg-start{align-content:flex-start !important}.align-content-lg-end{align-content:flex-end !important}.align-content-lg-center{align-content:center !important}.align-content-lg-between{align-content:space-between !important}.align-content-lg-around{align-content:space-around !important}.align-content-lg-stretch{align-content:stretch !important}.align-self-lg-auto{align-self:auto !important}.align-self-lg-start{align-self:flex-start !important}.align-self-lg-end{align-self:flex-end !important}.align-self-lg-center{align-self:center !important}.align-self-lg-baseline{align-self:baseline !important}.align-self-lg-stretch{align-self:stretch !important}}@media (min-width: 1200px){.flex-xl-row{flex-direction:row !important}.flex-xl-column{flex-direction:column !important}.flex-xl-row-reverse{flex-direction:row-reverse !important}.flex-xl-column-reverse{flex-direction:column-reverse !important}.flex-xl-wrap{flex-wrap:wrap !important}.flex-xl-nowrap{flex-wrap:nowrap !important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse !important}.flex-xl-fill{flex:1 1 auto !important}.flex-xl-grow-0{flex-grow:0 !important}.flex-xl-grow-1{flex-grow:1 !important}.flex-xl-shrink-0{flex-shrink:0 !important}.flex-xl-shrink-1{flex-shrink:1 !important}.justify-content-xl-start{justify-content:flex-start !important}.justify-content-xl-end{justify-content:flex-end !important}.justify-content-xl-center{justify-content:center !important}.justify-content-xl-between{justify-content:space-between !important}.justify-content-xl-around{justify-content:space-around !important}.align-items-xl-start{align-items:flex-start !important}.align-items-xl-end{align-items:flex-end !important}.align-items-xl-center{align-items:center !important}.align-items-xl-baseline{align-items:baseline !important}.align-items-xl-stretch{align-items:stretch !important}.align-content-xl-start{align-content:flex-start !important}.align-content-xl-end{align-content:flex-end !important}.align-content-xl-center{align-content:center !important}.align-content-xl-between{align-content:space-between !important}.align-content-xl-around{align-content:space-around !important}.align-content-xl-stretch{align-content:stretch !important}.align-self-xl-auto{align-self:auto !important}.align-self-xl-start{align-self:flex-start !important}.align-self-xl-end{align-self:flex-end !important}.align-self-xl-center{align-self:center !important}.align-self-xl-baseline{align-self:baseline !important}.align-self-xl-stretch{align-self:stretch !important}}.float-left{float:left !important}.float-right{float:right !important}.float-none{float:none !important}@media (min-width: 576px){.float-sm-left{float:left !important}.float-sm-right{float:right !important}.float-sm-none{float:none !important}}@media (min-width: 768px){.float-md-left{float:left !important}.float-md-right{float:right !important}.float-md-none{float:none !important}}@media (min-width: 992px){.float-lg-left{float:left !important}.float-lg-right{float:right !important}.float-lg-none{float:none !important}}@media (min-width: 1200px){.float-xl-left{float:left !important}.float-xl-right{float:right !important}.float-xl-none{float:none !important}}.user-select-all{user-select:all !important}.user-select-auto{user-select:auto !important}.user-select-none{user-select:none !important}.overflow-auto{overflow:auto !important}.overflow-hidden{overflow:hidden !important}.position-static{position:static !important}.position-relative{position:relative !important}.position-absolute{position:absolute !important}.position-fixed{position:fixed !important}.position-sticky{position:sticky !important}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}@supports (position: sticky){.sticky-top{position:sticky;top:0;z-index:1020}}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);white-space:nowrap;border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;overflow:visible;clip:auto;white-space:normal}.shadow-sm{box-shadow:0 0.125rem 0.25rem rgba(0,0,0,0.075) !important}.shadow{box-shadow:0 0.5rem 1rem rgba(0,0,0,0.15) !important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,0.175) !important}.shadow-none{box-shadow:none !important}.w-25{width:25% !important}.w-50{width:50% !important}.w-75{width:75% !important}.w-100{width:100% !important}.w-auto{width:auto !important}.h-25{height:25% !important}.h-50{height:50% !important}.h-75{height:75% !important}.h-100{height:100% !important}.h-auto{height:auto !important}.mw-100{max-width:100% !important}.mh-100{max-height:100% !important}.min-vw-100{min-width:100vw !important}.min-vh-100{min-height:100vh !important}.vw-100{width:100vw !important}.vh-100{height:100vh !important}.m-0{margin:0 !important}.mt-0,.my-0{margin-top:0 !important}.mr-0,.mx-0{margin-right:0 !important}.mb-0,.my-0{margin-bottom:0 !important}.ml-0,.mx-0{margin-left:0 !important}.m-1{margin:.25rem !important}.mt-1,.my-1{margin-top:.25rem !important}.mr-1,.mx-1{margin-right:.25rem !important}.mb-1,.my-1{margin-bottom:.25rem !important}.ml-1,.mx-1{margin-left:.25rem !important}.m-2{margin:.5rem !important}.mt-2,.my-2{margin-top:.5rem !important}.mr-2,.mx-2{margin-right:.5rem !important}.mb-2,.my-2{margin-bottom:.5rem !important}.ml-2,.mx-2{margin-left:.5rem !important}.m-3{margin:1rem !important}.mt-3,.my-3{margin-top:1rem !important}.mr-3,.mx-3{margin-right:1rem !important}.mb-3,.my-3{margin-bottom:1rem !important}.ml-3,.mx-3{margin-left:1rem !important}.m-4{margin:1.5rem !important}.mt-4,.my-4{margin-top:1.5rem !important}.mr-4,.mx-4{margin-right:1.5rem !important}.mb-4,.my-4{margin-bottom:1.5rem !important}.ml-4,.mx-4{margin-left:1.5rem !important}.m-5{margin:3rem !important}.mt-5,.my-5{margin-top:3rem !important}.mr-5,.mx-5{margin-right:3rem !important}.mb-5,.my-5{margin-bottom:3rem !important}.ml-5,.mx-5{margin-left:3rem !important}.p-0{padding:0 !important}.pt-0,.py-0{padding-top:0 !important}.pr-0,.px-0{padding-right:0 !important}.pb-0,.py-0{padding-bottom:0 !important}.pl-0,.px-0{padding-left:0 !important}.p-1{padding:.25rem !important}.pt-1,.py-1{padding-top:.25rem !important}.pr-1,.px-1{padding-right:.25rem !important}.pb-1,.py-1{padding-bottom:.25rem !important}.pl-1,.px-1{padding-left:.25rem !important}.p-2{padding:.5rem !important}.pt-2,.py-2{padding-top:.5rem !important}.pr-2,.px-2{padding-right:.5rem !important}.pb-2,.py-2{padding-bottom:.5rem !important}.pl-2,.px-2{padding-left:.5rem !important}.p-3{padding:1rem !important}.pt-3,.py-3{padding-top:1rem !important}.pr-3,.px-3{padding-right:1rem !important}.pb-3,.py-3{padding-bottom:1rem !important}.pl-3,.px-3{padding-left:1rem !important}.p-4{padding:1.5rem !important}.pt-4,.py-4{padding-top:1.5rem !important}.pr-4,.px-4{padding-right:1.5rem !important}.pb-4,.py-4{padding-bottom:1.5rem !important}.pl-4,.px-4{padding-left:1.5rem !important}.p-5{padding:3rem !important}.pt-5,.py-5{padding-top:3rem !important}.pr-5,.px-5{padding-right:3rem !important}.pb-5,.py-5{padding-bottom:3rem !important}.pl-5,.px-5{padding-left:3rem !important}.m-n1{margin:-.25rem !important}.mt-n1,.my-n1{margin-top:-.25rem !important}.mr-n1,.mx-n1{margin-right:-.25rem !important}.mb-n1,.my-n1{margin-bottom:-.25rem !important}.ml-n1,.mx-n1{margin-left:-.25rem !important}.m-n2{margin:-.5rem !important}.mt-n2,.my-n2{margin-top:-.5rem !important}.mr-n2,.mx-n2{margin-right:-.5rem !important}.mb-n2,.my-n2{margin-bottom:-.5rem !important}.ml-n2,.mx-n2{margin-left:-.5rem !important}.m-n3{margin:-1rem !important}.mt-n3,.my-n3{margin-top:-1rem !important}.mr-n3,.mx-n3{margin-right:-1rem !important}.mb-n3,.my-n3{margin-bottom:-1rem !important}.ml-n3,.mx-n3{margin-left:-1rem !important}.m-n4{margin:-1.5rem !important}.mt-n4,.my-n4{margin-top:-1.5rem !important}.mr-n4,.mx-n4{margin-right:-1.5rem !important}.mb-n4,.my-n4{margin-bottom:-1.5rem !important}.ml-n4,.mx-n4{margin-left:-1.5rem !important}.m-n5{margin:-3rem !important}.mt-n5,.my-n5{margin-top:-3rem !important}.mr-n5,.mx-n5{margin-right:-3rem !important}.mb-n5,.my-n5{margin-bottom:-3rem !important}.ml-n5,.mx-n5{margin-left:-3rem !important}.m-auto{margin:auto !important}.mt-auto,.my-auto{margin-top:auto !important}.mr-auto,.mx-auto{margin-right:auto !important}.mb-auto,.my-auto{margin-bottom:auto !important}.ml-auto,.mx-auto{margin-left:auto !important}@media (min-width: 576px){.m-sm-0{margin:0 !important}.mt-sm-0,.my-sm-0{margin-top:0 !important}.mr-sm-0,.mx-sm-0{margin-right:0 !important}.mb-sm-0,.my-sm-0{margin-bottom:0 !important}.ml-sm-0,.mx-sm-0{margin-left:0 !important}.m-sm-1{margin:.25rem !important}.mt-sm-1,.my-sm-1{margin-top:.25rem !important}.mr-sm-1,.mx-sm-1{margin-right:.25rem !important}.mb-sm-1,.my-sm-1{margin-bottom:.25rem !important}.ml-sm-1,.mx-sm-1{margin-left:.25rem !important}.m-sm-2{margin:.5rem !important}.mt-sm-2,.my-sm-2{margin-top:.5rem !important}.mr-sm-2,.mx-sm-2{margin-right:.5rem !important}.mb-sm-2,.my-sm-2{margin-bottom:.5rem !important}.ml-sm-2,.mx-sm-2{margin-left:.5rem !important}.m-sm-3{margin:1rem !important}.mt-sm-3,.my-sm-3{margin-top:1rem !important}.mr-sm-3,.mx-sm-3{margin-right:1rem !important}.mb-sm-3,.my-sm-3{margin-bottom:1rem !important}.ml-sm-3,.mx-sm-3{margin-left:1rem !important}.m-sm-4{margin:1.5rem !important}.mt-sm-4,.my-sm-4{margin-top:1.5rem !important}.mr-sm-4,.mx-sm-4{margin-right:1.5rem !important}.mb-sm-4,.my-sm-4{margin-bottom:1.5rem !important}.ml-sm-4,.mx-sm-4{margin-left:1.5rem !important}.m-sm-5{margin:3rem !important}.mt-sm-5,.my-sm-5{margin-top:3rem !important}.mr-sm-5,.mx-sm-5{margin-right:3rem !important}.mb-sm-5,.my-sm-5{margin-bottom:3rem !important}.ml-sm-5,.mx-sm-5{margin-left:3rem !important}.p-sm-0{padding:0 !important}.pt-sm-0,.py-sm-0{padding-top:0 !important}.pr-sm-0,.px-sm-0{padding-right:0 !important}.pb-sm-0,.py-sm-0{padding-bottom:0 !important}.pl-sm-0,.px-sm-0{padding-left:0 !important}.p-sm-1{padding:.25rem !important}.pt-sm-1,.py-sm-1{padding-top:.25rem !important}.pr-sm-1,.px-sm-1{padding-right:.25rem !important}.pb-sm-1,.py-sm-1{padding-bottom:.25rem !important}.pl-sm-1,.px-sm-1{padding-left:.25rem !important}.p-sm-2{padding:.5rem !important}.pt-sm-2,.py-sm-2{padding-top:.5rem !important}.pr-sm-2,.px-sm-2{padding-right:.5rem !important}.pb-sm-2,.py-sm-2{padding-bottom:.5rem !important}.pl-sm-2,.px-sm-2{padding-left:.5rem !important}.p-sm-3{padding:1rem !important}.pt-sm-3,.py-sm-3{padding-top:1rem !important}.pr-sm-3,.px-sm-3{padding-right:1rem !important}.pb-sm-3,.py-sm-3{padding-bottom:1rem !important}.pl-sm-3,.px-sm-3{padding-left:1rem !important}.p-sm-4{padding:1.5rem !important}.pt-sm-4,.py-sm-4{padding-top:1.5rem !important}.pr-sm-4,.px-sm-4{padding-right:1.5rem !important}.pb-sm-4,.py-sm-4{padding-bottom:1.5rem !important}.pl-sm-4,.px-sm-4{padding-left:1.5rem !important}.p-sm-5{padding:3rem !important}.pt-sm-5,.py-sm-5{padding-top:3rem !important}.pr-sm-5,.px-sm-5{padding-right:3rem !important}.pb-sm-5,.py-sm-5{padding-bottom:3rem !important}.pl-sm-5,.px-sm-5{padding-left:3rem !important}.m-sm-n1{margin:-.25rem !important}.mt-sm-n1,.my-sm-n1{margin-top:-.25rem !important}.mr-sm-n1,.mx-sm-n1{margin-right:-.25rem !important}.mb-sm-n1,.my-sm-n1{margin-bottom:-.25rem !important}.ml-sm-n1,.mx-sm-n1{margin-left:-.25rem !important}.m-sm-n2{margin:-.5rem !important}.mt-sm-n2,.my-sm-n2{margin-top:-.5rem !important}.mr-sm-n2,.mx-sm-n2{margin-right:-.5rem !important}.mb-sm-n2,.my-sm-n2{margin-bottom:-.5rem !important}.ml-sm-n2,.mx-sm-n2{margin-left:-.5rem !important}.m-sm-n3{margin:-1rem !important}.mt-sm-n3,.my-sm-n3{margin-top:-1rem !important}.mr-sm-n3,.mx-sm-n3{margin-right:-1rem !important}.mb-sm-n3,.my-sm-n3{margin-bottom:-1rem !important}.ml-sm-n3,.mx-sm-n3{margin-left:-1rem !important}.m-sm-n4{margin:-1.5rem !important}.mt-sm-n4,.my-sm-n4{margin-top:-1.5rem !important}.mr-sm-n4,.mx-sm-n4{margin-right:-1.5rem !important}.mb-sm-n4,.my-sm-n4{margin-bottom:-1.5rem !important}.ml-sm-n4,.mx-sm-n4{margin-left:-1.5rem !important}.m-sm-n5{margin:-3rem !important}.mt-sm-n5,.my-sm-n5{margin-top:-3rem !important}.mr-sm-n5,.mx-sm-n5{margin-right:-3rem !important}.mb-sm-n5,.my-sm-n5{margin-bottom:-3rem !important}.ml-sm-n5,.mx-sm-n5{margin-left:-3rem !important}.m-sm-auto{margin:auto !important}.mt-sm-auto,.my-sm-auto{margin-top:auto !important}.mr-sm-auto,.mx-sm-auto{margin-right:auto !important}.mb-sm-auto,.my-sm-auto{margin-bottom:auto !important}.ml-sm-auto,.mx-sm-auto{margin-left:auto !important}}@media (min-width: 768px){.m-md-0{margin:0 !important}.mt-md-0,.my-md-0{margin-top:0 !important}.mr-md-0,.mx-md-0{margin-right:0 !important}.mb-md-0,.my-md-0{margin-bottom:0 !important}.ml-md-0,.mx-md-0{margin-left:0 !important}.m-md-1{margin:.25rem !important}.mt-md-1,.my-md-1{margin-top:.25rem !important}.mr-md-1,.mx-md-1{margin-right:.25rem !important}.mb-md-1,.my-md-1{margin-bottom:.25rem !important}.ml-md-1,.mx-md-1{margin-left:.25rem !important}.m-md-2{margin:.5rem !important}.mt-md-2,.my-md-2{margin-top:.5rem !important}.mr-md-2,.mx-md-2{margin-right:.5rem !important}.mb-md-2,.my-md-2{margin-bottom:.5rem !important}.ml-md-2,.mx-md-2{margin-left:.5rem !important}.m-md-3{margin:1rem !important}.mt-md-3,.my-md-3{margin-top:1rem !important}.mr-md-3,.mx-md-3{margin-right:1rem !important}.mb-md-3,.my-md-3{margin-bottom:1rem !important}.ml-md-3,.mx-md-3{margin-left:1rem !important}.m-md-4{margin:1.5rem !important}.mt-md-4,.my-md-4{margin-top:1.5rem !important}.mr-md-4,.mx-md-4{margin-right:1.5rem !important}.mb-md-4,.my-md-4{margin-bottom:1.5rem !important}.ml-md-4,.mx-md-4{margin-left:1.5rem !important}.m-md-5{margin:3rem !important}.mt-md-5,.my-md-5{margin-top:3rem !important}.mr-md-5,.mx-md-5{margin-right:3rem !important}.mb-md-5,.my-md-5{margin-bottom:3rem !important}.ml-md-5,.mx-md-5{margin-left:3rem !important}.p-md-0{padding:0 !important}.pt-md-0,.py-md-0{padding-top:0 !important}.pr-md-0,.px-md-0{padding-right:0 !important}.pb-md-0,.py-md-0{padding-bottom:0 !important}.pl-md-0,.px-md-0{padding-left:0 !important}.p-md-1{padding:.25rem !important}.pt-md-1,.py-md-1{padding-top:.25rem !important}.pr-md-1,.px-md-1{padding-right:.25rem !important}.pb-md-1,.py-md-1{padding-bottom:.25rem !important}.pl-md-1,.px-md-1{padding-left:.25rem !important}.p-md-2{padding:.5rem !important}.pt-md-2,.py-md-2{padding-top:.5rem !important}.pr-md-2,.px-md-2{padding-right:.5rem !important}.pb-md-2,.py-md-2{padding-bottom:.5rem !important}.pl-md-2,.px-md-2{padding-left:.5rem !important}.p-md-3{padding:1rem !important}.pt-md-3,.py-md-3{padding-top:1rem !important}.pr-md-3,.px-md-3{padding-right:1rem !important}.pb-md-3,.py-md-3{padding-bottom:1rem !important}.pl-md-3,.px-md-3{padding-left:1rem !important}.p-md-4{padding:1.5rem !important}.pt-md-4,.py-md-4{padding-top:1.5rem !important}.pr-md-4,.px-md-4{padding-right:1.5rem !important}.pb-md-4,.py-md-4{padding-bottom:1.5rem !important}.pl-md-4,.px-md-4{padding-left:1.5rem !important}.p-md-5{padding:3rem !important}.pt-md-5,.py-md-5{padding-top:3rem !important}.pr-md-5,.px-md-5{padding-right:3rem !important}.pb-md-5,.py-md-5{padding-bottom:3rem !important}.pl-md-5,.px-md-5{padding-left:3rem !important}.m-md-n1{margin:-.25rem !important}.mt-md-n1,.my-md-n1{margin-top:-.25rem !important}.mr-md-n1,.mx-md-n1{margin-right:-.25rem !important}.mb-md-n1,.my-md-n1{margin-bottom:-.25rem !important}.ml-md-n1,.mx-md-n1{margin-left:-.25rem !important}.m-md-n2{margin:-.5rem !important}.mt-md-n2,.my-md-n2{margin-top:-.5rem !important}.mr-md-n2,.mx-md-n2{margin-right:-.5rem !important}.mb-md-n2,.my-md-n2{margin-bottom:-.5rem !important}.ml-md-n2,.mx-md-n2{margin-left:-.5rem !important}.m-md-n3{margin:-1rem !important}.mt-md-n3,.my-md-n3{margin-top:-1rem !important}.mr-md-n3,.mx-md-n3{margin-right:-1rem !important}.mb-md-n3,.my-md-n3{margin-bottom:-1rem !important}.ml-md-n3,.mx-md-n3{margin-left:-1rem !important}.m-md-n4{margin:-1.5rem !important}.mt-md-n4,.my-md-n4{margin-top:-1.5rem !important}.mr-md-n4,.mx-md-n4{margin-right:-1.5rem !important}.mb-md-n4,.my-md-n4{margin-bottom:-1.5rem !important}.ml-md-n4,.mx-md-n4{margin-left:-1.5rem !important}.m-md-n5{margin:-3rem !important}.mt-md-n5,.my-md-n5{margin-top:-3rem !important}.mr-md-n5,.mx-md-n5{margin-right:-3rem !important}.mb-md-n5,.my-md-n5{margin-bottom:-3rem !important}.ml-md-n5,.mx-md-n5{margin-left:-3rem !important}.m-md-auto{margin:auto !important}.mt-md-auto,.my-md-auto{margin-top:auto !important}.mr-md-auto,.mx-md-auto{margin-right:auto !important}.mb-md-auto,.my-md-auto{margin-bottom:auto !important}.ml-md-auto,.mx-md-auto{margin-left:auto !important}}@media (min-width: 992px){.m-lg-0{margin:0 !important}.mt-lg-0,.my-lg-0{margin-top:0 !important}.mr-lg-0,.mx-lg-0{margin-right:0 !important}.mb-lg-0,.my-lg-0{margin-bottom:0 !important}.ml-lg-0,.mx-lg-0{margin-left:0 !important}.m-lg-1{margin:.25rem !important}.mt-lg-1,.my-lg-1{margin-top:.25rem !important}.mr-lg-1,.mx-lg-1{margin-right:.25rem !important}.mb-lg-1,.my-lg-1{margin-bottom:.25rem !important}.ml-lg-1,.mx-lg-1{margin-left:.25rem !important}.m-lg-2{margin:.5rem !important}.mt-lg-2,.my-lg-2{margin-top:.5rem !important}.mr-lg-2,.mx-lg-2{margin-right:.5rem !important}.mb-lg-2,.my-lg-2{margin-bottom:.5rem !important}.ml-lg-2,.mx-lg-2{margin-left:.5rem !important}.m-lg-3{margin:1rem !important}.mt-lg-3,.my-lg-3{margin-top:1rem !important}.mr-lg-3,.mx-lg-3{margin-right:1rem !important}.mb-lg-3,.my-lg-3{margin-bottom:1rem !important}.ml-lg-3,.mx-lg-3{margin-left:1rem !important}.m-lg-4{margin:1.5rem !important}.mt-lg-4,.my-lg-4{margin-top:1.5rem !important}.mr-lg-4,.mx-lg-4{margin-right:1.5rem !important}.mb-lg-4,.my-lg-4{margin-bottom:1.5rem !important}.ml-lg-4,.mx-lg-4{margin-left:1.5rem !important}.m-lg-5{margin:3rem !important}.mt-lg-5,.my-lg-5{margin-top:3rem !important}.mr-lg-5,.mx-lg-5{margin-right:3rem !important}.mb-lg-5,.my-lg-5{margin-bottom:3rem !important}.ml-lg-5,.mx-lg-5{margin-left:3rem !important}.p-lg-0{padding:0 !important}.pt-lg-0,.py-lg-0{padding-top:0 !important}.pr-lg-0,.px-lg-0{padding-right:0 !important}.pb-lg-0,.py-lg-0{padding-bottom:0 !important}.pl-lg-0,.px-lg-0{padding-left:0 !important}.p-lg-1{padding:.25rem !important}.pt-lg-1,.py-lg-1{padding-top:.25rem !important}.pr-lg-1,.px-lg-1{padding-right:.25rem !important}.pb-lg-1,.py-lg-1{padding-bottom:.25rem !important}.pl-lg-1,.px-lg-1{padding-left:.25rem !important}.p-lg-2{padding:.5rem !important}.pt-lg-2,.py-lg-2{padding-top:.5rem !important}.pr-lg-2,.px-lg-2{padding-right:.5rem !important}.pb-lg-2,.py-lg-2{padding-bottom:.5rem !important}.pl-lg-2,.px-lg-2{padding-left:.5rem !important}.p-lg-3{padding:1rem !important}.pt-lg-3,.py-lg-3{padding-top:1rem !important}.pr-lg-3,.px-lg-3{padding-right:1rem !important}.pb-lg-3,.py-lg-3{padding-bottom:1rem !important}.pl-lg-3,.px-lg-3{padding-left:1rem !important}.p-lg-4{padding:1.5rem !important}.pt-lg-4,.py-lg-4{padding-top:1.5rem !important}.pr-lg-4,.px-lg-4{padding-right:1.5rem !important}.pb-lg-4,.py-lg-4{padding-bottom:1.5rem !important}.pl-lg-4,.px-lg-4{padding-left:1.5rem !important}.p-lg-5{padding:3rem !important}.pt-lg-5,.py-lg-5{padding-top:3rem !important}.pr-lg-5,.px-lg-5{padding-right:3rem !important}.pb-lg-5,.py-lg-5{padding-bottom:3rem !important}.pl-lg-5,.px-lg-5{padding-left:3rem !important}.m-lg-n1{margin:-.25rem !important}.mt-lg-n1,.my-lg-n1{margin-top:-.25rem !important}.mr-lg-n1,.mx-lg-n1{margin-right:-.25rem !important}.mb-lg-n1,.my-lg-n1{margin-bottom:-.25rem !important}.ml-lg-n1,.mx-lg-n1{margin-left:-.25rem !important}.m-lg-n2{margin:-.5rem !important}.mt-lg-n2,.my-lg-n2{margin-top:-.5rem !important}.mr-lg-n2,.mx-lg-n2{margin-right:-.5rem !important}.mb-lg-n2,.my-lg-n2{margin-bottom:-.5rem !important}.ml-lg-n2,.mx-lg-n2{margin-left:-.5rem !important}.m-lg-n3{margin:-1rem !important}.mt-lg-n3,.my-lg-n3{margin-top:-1rem !important}.mr-lg-n3,.mx-lg-n3{margin-right:-1rem !important}.mb-lg-n3,.my-lg-n3{margin-bottom:-1rem !important}.ml-lg-n3,.mx-lg-n3{margin-left:-1rem !important}.m-lg-n4{margin:-1.5rem !important}.mt-lg-n4,.my-lg-n4{margin-top:-1.5rem !important}.mr-lg-n4,.mx-lg-n4{margin-right:-1.5rem !important}.mb-lg-n4,.my-lg-n4{margin-bottom:-1.5rem !important}.ml-lg-n4,.mx-lg-n4{margin-left:-1.5rem !important}.m-lg-n5{margin:-3rem !important}.mt-lg-n5,.my-lg-n5{margin-top:-3rem !important}.mr-lg-n5,.mx-lg-n5{margin-right:-3rem !important}.mb-lg-n5,.my-lg-n5{margin-bottom:-3rem !important}.ml-lg-n5,.mx-lg-n5{margin-left:-3rem !important}.m-lg-auto{margin:auto !important}.mt-lg-auto,.my-lg-auto{margin-top:auto !important}.mr-lg-auto,.mx-lg-auto{margin-right:auto !important}.mb-lg-auto,.my-lg-auto{margin-bottom:auto !important}.ml-lg-auto,.mx-lg-auto{margin-left:auto !important}}@media (min-width: 1200px){.m-xl-0{margin:0 !important}.mt-xl-0,.my-xl-0{margin-top:0 !important}.mr-xl-0,.mx-xl-0{margin-right:0 !important}.mb-xl-0,.my-xl-0{margin-bottom:0 !important}.ml-xl-0,.mx-xl-0{margin-left:0 !important}.m-xl-1{margin:.25rem !important}.mt-xl-1,.my-xl-1{margin-top:.25rem !important}.mr-xl-1,.mx-xl-1{margin-right:.25rem !important}.mb-xl-1,.my-xl-1{margin-bottom:.25rem !important}.ml-xl-1,.mx-xl-1{margin-left:.25rem !important}.m-xl-2{margin:.5rem !important}.mt-xl-2,.my-xl-2{margin-top:.5rem !important}.mr-xl-2,.mx-xl-2{margin-right:.5rem !important}.mb-xl-2,.my-xl-2{margin-bottom:.5rem !important}.ml-xl-2,.mx-xl-2{margin-left:.5rem !important}.m-xl-3{margin:1rem !important}.mt-xl-3,.my-xl-3{margin-top:1rem !important}.mr-xl-3,.mx-xl-3{margin-right:1rem !important}.mb-xl-3,.my-xl-3{margin-bottom:1rem !important}.ml-xl-3,.mx-xl-3{margin-left:1rem !important}.m-xl-4{margin:1.5rem !important}.mt-xl-4,.my-xl-4{margin-top:1.5rem !important}.mr-xl-4,.mx-xl-4{margin-right:1.5rem !important}.mb-xl-4,.my-xl-4{margin-bottom:1.5rem !important}.ml-xl-4,.mx-xl-4{margin-left:1.5rem !important}.m-xl-5{margin:3rem !important}.mt-xl-5,.my-xl-5{margin-top:3rem !important}.mr-xl-5,.mx-xl-5{margin-right:3rem !important}.mb-xl-5,.my-xl-5{margin-bottom:3rem !important}.ml-xl-5,.mx-xl-5{margin-left:3rem !important}.p-xl-0{padding:0 !important}.pt-xl-0,.py-xl-0{padding-top:0 !important}.pr-xl-0,.px-xl-0{padding-right:0 !important}.pb-xl-0,.py-xl-0{padding-bottom:0 !important}.pl-xl-0,.px-xl-0{padding-left:0 !important}.p-xl-1{padding:.25rem !important}.pt-xl-1,.py-xl-1{padding-top:.25rem !important}.pr-xl-1,.px-xl-1{padding-right:.25rem !important}.pb-xl-1,.py-xl-1{padding-bottom:.25rem !important}.pl-xl-1,.px-xl-1{padding-left:.25rem !important}.p-xl-2{padding:.5rem !important}.pt-xl-2,.py-xl-2{padding-top:.5rem !important}.pr-xl-2,.px-xl-2{padding-right:.5rem !important}.pb-xl-2,.py-xl-2{padding-bottom:.5rem !important}.pl-xl-2,.px-xl-2{padding-left:.5rem !important}.p-xl-3{padding:1rem !important}.pt-xl-3,.py-xl-3{padding-top:1rem !important}.pr-xl-3,.px-xl-3{padding-right:1rem !important}.pb-xl-3,.py-xl-3{padding-bottom:1rem !important}.pl-xl-3,.px-xl-3{padding-left:1rem !important}.p-xl-4{padding:1.5rem !important}.pt-xl-4,.py-xl-4{padding-top:1.5rem !important}.pr-xl-4,.px-xl-4{padding-right:1.5rem !important}.pb-xl-4,.py-xl-4{padding-bottom:1.5rem !important}.pl-xl-4,.px-xl-4{padding-left:1.5rem !important}.p-xl-5{padding:3rem !important}.pt-xl-5,.py-xl-5{padding-top:3rem !important}.pr-xl-5,.px-xl-5{padding-right:3rem !important}.pb-xl-5,.py-xl-5{padding-bottom:3rem !important}.pl-xl-5,.px-xl-5{padding-left:3rem !important}.m-xl-n1{margin:-.25rem !important}.mt-xl-n1,.my-xl-n1{margin-top:-.25rem !important}.mr-xl-n1,.mx-xl-n1{margin-right:-.25rem !important}.mb-xl-n1,.my-xl-n1{margin-bottom:-.25rem !important}.ml-xl-n1,.mx-xl-n1{margin-left:-.25rem !important}.m-xl-n2{margin:-.5rem !important}.mt-xl-n2,.my-xl-n2{margin-top:-.5rem !important}.mr-xl-n2,.mx-xl-n2{margin-right:-.5rem !important}.mb-xl-n2,.my-xl-n2{margin-bottom:-.5rem !important}.ml-xl-n2,.mx-xl-n2{margin-left:-.5rem !important}.m-xl-n3{margin:-1rem !important}.mt-xl-n3,.my-xl-n3{margin-top:-1rem !important}.mr-xl-n3,.mx-xl-n3{margin-right:-1rem !important}.mb-xl-n3,.my-xl-n3{margin-bottom:-1rem !important}.ml-xl-n3,.mx-xl-n3{margin-left:-1rem !important}.m-xl-n4{margin:-1.5rem !important}.mt-xl-n4,.my-xl-n4{margin-top:-1.5rem !important}.mr-xl-n4,.mx-xl-n4{margin-right:-1.5rem !important}.mb-xl-n4,.my-xl-n4{margin-bottom:-1.5rem !important}.ml-xl-n4,.mx-xl-n4{margin-left:-1.5rem !important}.m-xl-n5{margin:-3rem !important}.mt-xl-n5,.my-xl-n5{margin-top:-3rem !important}.mr-xl-n5,.mx-xl-n5{margin-right:-3rem !important}.mb-xl-n5,.my-xl-n5{margin-bottom:-3rem !important}.ml-xl-n5,.mx-xl-n5{margin-left:-3rem !important}.m-xl-auto{margin:auto !important}.mt-xl-auto,.my-xl-auto{margin-top:auto !important}.mr-xl-auto,.mx-xl-auto{margin-right:auto !important}.mb-xl-auto,.my-xl-auto{margin-bottom:auto !important}.ml-xl-auto,.mx-xl-auto{margin-left:auto !important}}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;pointer-events:auto;content:"";background-color:rgba(0,0,0,0)}.text-monospace{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace !important}.text-justify{text-align:justify !important}.text-wrap{white-space:normal !important}.text-nowrap{white-space:nowrap !important}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text-left{text-align:left !important}.text-right{text-align:right !important}.text-center{text-align:center !important}@media (min-width: 576px){.text-sm-left{text-align:left !important}.text-sm-right{text-align:right !important}.text-sm-center{text-align:center !important}}@media (min-width: 768px){.text-md-left{text-align:left !important}.text-md-right{text-align:right !important}.text-md-center{text-align:center !important}}@media (min-width: 992px){.text-lg-left{text-align:left !important}.text-lg-right{text-align:right !important}.text-lg-center{text-align:center !important}}@media (min-width: 1200px){.text-xl-left{text-align:left !important}.text-xl-right{text-align:right !important}.text-xl-center{text-align:center !important}}.text-lowercase{text-transform:lowercase !important}.text-uppercase{text-transform:uppercase !important}.text-capitalize{text-transform:capitalize !important}.font-weight-light{font-weight:300 !important}.font-weight-lighter{font-weight:lighter !important}.font-weight-normal{font-weight:400 !important}.font-weight-bold{font-weight:700 !important}.font-weight-bolder{font-weight:bolder !important}.font-italic{font-style:italic !important}.text-white{color:#fff !important}.text-primary{color:#007bff !important}a.text-primary:hover,a.text-primary:focus{color:#0056b3 !important}.text-secondary{color:#6c757d !important}a.text-secondary:hover,a.text-secondary:focus{color:#494f54 !important}.text-success{color:#28a745 !important}a.text-success:hover,a.text-success:focus{color:#19692c !important}.text-info{color:#17a2b8 !important}a.text-info:hover,a.text-info:focus{color:#0f6674 !important}.text-warning{color:#ffc107 !important}a.text-warning:hover,a.text-warning:focus{color:#ba8b00 !important}.text-danger{color:#dc3545 !important}a.text-danger:hover,a.text-danger:focus{color:#a71d2a !important}.text-light{color:#f8f9fa !important}a.text-light:hover,a.text-light:focus{color:#cbd3da !important}.text-dark{color:#343a40 !important}a.text-dark:hover,a.text-dark:focus{color:#121416 !important}.text-body{color:#212529 !important}.text-muted{color:#6c757d !important}.text-black-50{color:rgba(0,0,0,0.5) !important}.text-white-50{color:rgba(255,255,255,0.5) !important}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.text-decoration-none{text-decoration:none !important}.text-break{word-break:break-word !important;word-wrap:break-word !important}.text-reset{color:inherit !important}.visible{visibility:visible !important}.invisible{visibility:hidden !important}@media print{*,*::before,*::after{text-shadow:none !important;box-shadow:none !important}a:not(.btn){text-decoration:underline}abbr[title]::after{content:" (" attr(title) ")"}pre{white-space:pre-wrap !important}pre,blockquote{border:1px solid #adb5bd;page-break-inside:avoid}tr,img{page-break-inside:avoid}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}@page{size:a3}body{min-width:992px !important}.container{min-width:992px !important}.navbar{display:none}.badge{border:1px solid #000}.table{border-collapse:collapse !important}.table td,.table th{background-color:#fff !important}.table-bordered th,.table-bordered td{border:1px solid #dee2e6 !important}.table-dark{color:inherit}.table-dark th,.table-dark td,.table-dark thead th,.table-dark tbody+tbody{border-color:#dee2e6}.table .thead-dark th{color:inherit;border-color:#dee2e6}} diff --git a/assets/css/paypal-admin.css b/assets/css/paypal-admin.css index c709d6692..5299647c5 100644 --- a/assets/css/paypal-admin.css +++ b/assets/css/paypal-admin.css @@ -1,108 +1 @@ -#overlay { - position: fixed; - display: none; - width: 100%; - height: 100%; - top: 0; - left: 0; - right: 0; - bottom: 0; - background-color: rgba(0, 0, 0, 0.9); - z-index: 20000; - cursor: pointer; } - -.loader { - margin: 20% auto; - font-size: 25px; - width: 1em; - height: 1em; - border-radius: 50%; - position: relative; - text-indent: -9999em; - -webkit-animation: load5 1.1s infinite ease; - animation: load5 1.1s infinite ease; - transform: translateZ(0); } - -@-webkit-keyframes load5 { - 0%, - 100% { - box-shadow: 0em -2.6em 0em 0em #ffffff, 1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2), 2.5em 0em 0 0em rgba(255, 255, 255, 0.2), 1.75em 1.75em 0 0em rgba(255, 255, 255, 0.2), 0em 2.5em 0 0em rgba(255, 255, 255, 0.2), -1.8em 1.8em 0 0em rgba(255, 255, 255, 0.2), -2.6em 0em 0 0em rgba(255, 255, 255, 0.5), -1.8em -1.8em 0 0em rgba(255, 255, 255, 0.7); } - 12.5% { - box-shadow: 0em -2.6em 0em 0em rgba(255, 255, 255, 0.7), 1.8em -1.8em 0 0em #ffffff, 2.5em 0em 0 0em rgba(255, 255, 255, 0.2), 1.75em 1.75em 0 0em rgba(255, 255, 255, 0.2), 0em 2.5em 0 0em rgba(255, 255, 255, 0.2), -1.8em 1.8em 0 0em rgba(255, 255, 255, 0.2), -2.6em 0em 0 0em rgba(255, 255, 255, 0.2), -1.8em -1.8em 0 0em rgba(255, 255, 255, 0.5); } - 25% { - box-shadow: 0em -2.6em 0em 0em rgba(255, 255, 255, 0.5), 1.8em -1.8em 0 0em rgba(255, 255, 255, 0.7), 2.5em 0em 0 0em #ffffff, 1.75em 1.75em 0 0em rgba(255, 255, 255, 0.2), 0em 2.5em 0 0em rgba(255, 255, 255, 0.2), -1.8em 1.8em 0 0em rgba(255, 255, 255, 0.2), -2.6em 0em 0 0em rgba(255, 255, 255, 0.2), -1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2); } - 37.5% { - box-shadow: 0em -2.6em 0em 0em rgba(255, 255, 255, 0.2), 1.8em -1.8em 0 0em rgba(255, 255, 255, 0.5), 2.5em 0em 0 0em rgba(255, 255, 255, 0.7), 1.75em 1.75em 0 0em #ffffff, 0em 2.5em 0 0em rgba(255, 255, 255, 0.2), -1.8em 1.8em 0 0em rgba(255, 255, 255, 0.2), -2.6em 0em 0 0em rgba(255, 255, 255, 0.2), -1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2); } - 50% { - box-shadow: 0em -2.6em 0em 0em rgba(255, 255, 255, 0.2), 1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2), 2.5em 0em 0 0em rgba(255, 255, 255, 0.5), 1.75em 1.75em 0 0em rgba(255, 255, 255, 0.7), 0em 2.5em 0 0em #ffffff, -1.8em 1.8em 0 0em rgba(255, 255, 255, 0.2), -2.6em 0em 0 0em rgba(255, 255, 255, 0.2), -1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2); } - 62.5% { - box-shadow: 0em -2.6em 0em 0em rgba(255, 255, 255, 0.2), 1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2), 2.5em 0em 0 0em rgba(255, 255, 255, 0.2), 1.75em 1.75em 0 0em rgba(255, 255, 255, 0.5), 0em 2.5em 0 0em rgba(255, 255, 255, 0.7), -1.8em 1.8em 0 0em #ffffff, -2.6em 0em 0 0em rgba(255, 255, 255, 0.2), -1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2); } - 75% { - box-shadow: 0em -2.6em 0em 0em rgba(255, 255, 255, 0.2), 1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2), 2.5em 0em 0 0em rgba(255, 255, 255, 0.2), 1.75em 1.75em 0 0em rgba(255, 255, 255, 0.2), 0em 2.5em 0 0em rgba(255, 255, 255, 0.5), -1.8em 1.8em 0 0em rgba(255, 255, 255, 0.7), -2.6em 0em 0 0em #ffffff, -1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2); } - 87.5% { - box-shadow: 0em -2.6em 0em 0em rgba(255, 255, 255, 0.2), 1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2), 2.5em 0em 0 0em rgba(255, 255, 255, 0.2), 1.75em 1.75em 0 0em rgba(255, 255, 255, 0.2), 0em 2.5em 0 0em rgba(255, 255, 255, 0.2), -1.8em 1.8em 0 0em rgba(255, 255, 255, 0.5), -2.6em 0em 0 0em rgba(255, 255, 255, 0.7), -1.8em -1.8em 0 0em #ffffff; } } - -@keyframes load5 { - 0%, - 100% { - box-shadow: 0em -2.6em 0em 0em #ffffff, 1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2), 2.5em 0em 0 0em rgba(255, 255, 255, 0.2), 1.75em 1.75em 0 0em rgba(255, 255, 255, 0.2), 0em 2.5em 0 0em rgba(255, 255, 255, 0.2), -1.8em 1.8em 0 0em rgba(255, 255, 255, 0.2), -2.6em 0em 0 0em rgba(255, 255, 255, 0.5), -1.8em -1.8em 0 0em rgba(255, 255, 255, 0.7); } - 12.5% { - box-shadow: 0em -2.6em 0em 0em rgba(255, 255, 255, 0.7), 1.8em -1.8em 0 0em #ffffff, 2.5em 0em 0 0em rgba(255, 255, 255, 0.2), 1.75em 1.75em 0 0em rgba(255, 255, 255, 0.2), 0em 2.5em 0 0em rgba(255, 255, 255, 0.2), -1.8em 1.8em 0 0em rgba(255, 255, 255, 0.2), -2.6em 0em 0 0em rgba(255, 255, 255, 0.2), -1.8em -1.8em 0 0em rgba(255, 255, 255, 0.5); } - 25% { - box-shadow: 0em -2.6em 0em 0em rgba(255, 255, 255, 0.5), 1.8em -1.8em 0 0em rgba(255, 255, 255, 0.7), 2.5em 0em 0 0em #ffffff, 1.75em 1.75em 0 0em rgba(255, 255, 255, 0.2), 0em 2.5em 0 0em rgba(255, 255, 255, 0.2), -1.8em 1.8em 0 0em rgba(255, 255, 255, 0.2), -2.6em 0em 0 0em rgba(255, 255, 255, 0.2), -1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2); } - 37.5% { - box-shadow: 0em -2.6em 0em 0em rgba(255, 255, 255, 0.2), 1.8em -1.8em 0 0em rgba(255, 255, 255, 0.5), 2.5em 0em 0 0em rgba(255, 255, 255, 0.7), 1.75em 1.75em 0 0em #ffffff, 0em 2.5em 0 0em rgba(255, 255, 255, 0.2), -1.8em 1.8em 0 0em rgba(255, 255, 255, 0.2), -2.6em 0em 0 0em rgba(255, 255, 255, 0.2), -1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2); } - 50% { - box-shadow: 0em -2.6em 0em 0em rgba(255, 255, 255, 0.2), 1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2), 2.5em 0em 0 0em rgba(255, 255, 255, 0.5), 1.75em 1.75em 0 0em rgba(255, 255, 255, 0.7), 0em 2.5em 0 0em #ffffff, -1.8em 1.8em 0 0em rgba(255, 255, 255, 0.2), -2.6em 0em 0 0em rgba(255, 255, 255, 0.2), -1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2); } - 62.5% { - box-shadow: 0em -2.6em 0em 0em rgba(255, 255, 255, 0.2), 1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2), 2.5em 0em 0 0em rgba(255, 255, 255, 0.2), 1.75em 1.75em 0 0em rgba(255, 255, 255, 0.5), 0em 2.5em 0 0em rgba(255, 255, 255, 0.7), -1.8em 1.8em 0 0em #ffffff, -2.6em 0em 0 0em rgba(255, 255, 255, 0.2), -1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2); } - 75% { - box-shadow: 0em -2.6em 0em 0em rgba(255, 255, 255, 0.2), 1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2), 2.5em 0em 0 0em rgba(255, 255, 255, 0.2), 1.75em 1.75em 0 0em rgba(255, 255, 255, 0.2), 0em 2.5em 0 0em rgba(255, 255, 255, 0.5), -1.8em 1.8em 0 0em rgba(255, 255, 255, 0.7), -2.6em 0em 0 0em #ffffff, -1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2); } - 87.5% { - box-shadow: 0em -2.6em 0em 0em rgba(255, 255, 255, 0.2), 1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2), 2.5em 0em 0 0em rgba(255, 255, 255, 0.2), 1.75em 1.75em 0 0em rgba(255, 255, 255, 0.2), 0em 2.5em 0 0em rgba(255, 255, 255, 0.2), -1.8em 1.8em 0 0em rgba(255, 255, 255, 0.5), -2.6em 0em 0 0em rgba(255, 255, 255, 0.7), -1.8em -1.8em 0 0em #ffffff; } } - -#PPMiniWin .mask { - display: block; } - -.paypal-config { - width: 600px; - margin: 5em auto; } - .paypal-config fieldset { - padding-left: 10px; - border-left: 1px dotted #eee; } - .paypal-config .helpbox { - margin-top: 10px; - background-color: khaki; - color: gray; - padding: 5px 10px; } - .paypal-config .form-group textarea { - height: 150px; - width: 100%; } - .paypal-config .bottom-space { - margin: 1.5rem 0; } - .paypal-config .card-header { - cursor: pointer; } - .paypal-config .paypal-button-PPLtBlue { - padding-top: 12px; - border-radius: 5px; - border: 1px solid #9DA3A6; - vertical-align: middle; - padding-right: 16px; - display: table-cell; - text-decoration: none; - background-color: #1B9DDb; - color: #fff; - font-size: 15px; - font-family: HelveticaNeueMedium,"Helvetica Neue Medium",Helvetica,Arial,sans-serif; } - .paypal-config .paypal-button-PPLtBlue:before { - content: ""; - background: url(https://www.paypalobjects.com/images/shared/monogram@2x.png) 12px no-repeat #FFF; - background-size: 18.34px; - display: table-cell; - width: 40px; - height: 42px; - float: left; - margin-right: 16px; - border-bottom-left-radius: 5px; - border-top-left-radius: 5px; - margin-top: -12px; } +#overlay{position:fixed;display:none;width:100%;height:100%;top:0;left:0;right:0;bottom:0;background-color:rgba(0,0,0,0.9);z-index:20000;cursor:pointer}.loader{margin:20% auto;font-size:25px;width:1em;height:1em;border-radius:50%;position:relative;text-indent:-9999em;animation:load5 1.1s infinite ease;transform:translateZ(0)}@keyframes load5{0%,100%{box-shadow:0em -2.6em 0em 0em #fff,1.8em -1.8em 0 0em rgba(255,255,255,0.2),2.5em 0em 0 0em rgba(255,255,255,0.2),1.75em 1.75em 0 0em rgba(255,255,255,0.2),0em 2.5em 0 0em rgba(255,255,255,0.2),-1.8em 1.8em 0 0em rgba(255,255,255,0.2),-2.6em 0em 0 0em rgba(255,255,255,0.5),-1.8em -1.8em 0 0em rgba(255,255,255,0.7)}12.5%{box-shadow:0em -2.6em 0em 0em rgba(255,255,255,0.7),1.8em -1.8em 0 0em #fff,2.5em 0em 0 0em rgba(255,255,255,0.2),1.75em 1.75em 0 0em rgba(255,255,255,0.2),0em 2.5em 0 0em rgba(255,255,255,0.2),-1.8em 1.8em 0 0em rgba(255,255,255,0.2),-2.6em 0em 0 0em rgba(255,255,255,0.2),-1.8em -1.8em 0 0em rgba(255,255,255,0.5)}25%{box-shadow:0em -2.6em 0em 0em rgba(255,255,255,0.5),1.8em -1.8em 0 0em rgba(255,255,255,0.7),2.5em 0em 0 0em #fff,1.75em 1.75em 0 0em rgba(255,255,255,0.2),0em 2.5em 0 0em rgba(255,255,255,0.2),-1.8em 1.8em 0 0em rgba(255,255,255,0.2),-2.6em 0em 0 0em rgba(255,255,255,0.2),-1.8em -1.8em 0 0em rgba(255,255,255,0.2)}37.5%{box-shadow:0em -2.6em 0em 0em rgba(255,255,255,0.2),1.8em -1.8em 0 0em rgba(255,255,255,0.5),2.5em 0em 0 0em rgba(255,255,255,0.7),1.75em 1.75em 0 0em #fff,0em 2.5em 0 0em rgba(255,255,255,0.2),-1.8em 1.8em 0 0em rgba(255,255,255,0.2),-2.6em 0em 0 0em rgba(255,255,255,0.2),-1.8em -1.8em 0 0em rgba(255,255,255,0.2)}50%{box-shadow:0em -2.6em 0em 0em rgba(255,255,255,0.2),1.8em -1.8em 0 0em rgba(255,255,255,0.2),2.5em 0em 0 0em rgba(255,255,255,0.5),1.75em 1.75em 0 0em rgba(255,255,255,0.7),0em 2.5em 0 0em #fff,-1.8em 1.8em 0 0em rgba(255,255,255,0.2),-2.6em 0em 0 0em rgba(255,255,255,0.2),-1.8em -1.8em 0 0em rgba(255,255,255,0.2)}62.5%{box-shadow:0em -2.6em 0em 0em rgba(255,255,255,0.2),1.8em -1.8em 0 0em rgba(255,255,255,0.2),2.5em 0em 0 0em rgba(255,255,255,0.2),1.75em 1.75em 0 0em rgba(255,255,255,0.5),0em 2.5em 0 0em rgba(255,255,255,0.7),-1.8em 1.8em 0 0em #fff,-2.6em 0em 0 0em rgba(255,255,255,0.2),-1.8em -1.8em 0 0em rgba(255,255,255,0.2)}75%{box-shadow:0em -2.6em 0em 0em rgba(255,255,255,0.2),1.8em -1.8em 0 0em rgba(255,255,255,0.2),2.5em 0em 0 0em rgba(255,255,255,0.2),1.75em 1.75em 0 0em rgba(255,255,255,0.2),0em 2.5em 0 0em rgba(255,255,255,0.5),-1.8em 1.8em 0 0em rgba(255,255,255,0.7),-2.6em 0em 0 0em #fff,-1.8em -1.8em 0 0em rgba(255,255,255,0.2)}87.5%{box-shadow:0em -2.6em 0em 0em rgba(255,255,255,0.2),1.8em -1.8em 0 0em rgba(255,255,255,0.2),2.5em 0em 0 0em rgba(255,255,255,0.2),1.75em 1.75em 0 0em rgba(255,255,255,0.2),0em 2.5em 0 0em rgba(255,255,255,0.2),-1.8em 1.8em 0 0em rgba(255,255,255,0.5),-2.6em 0em 0 0em rgba(255,255,255,0.7),-1.8em -1.8em 0 0em #fff}}#PPMiniWin .mask{display:block}.paypal-config{width:600px;margin:5em auto}.paypal-config fieldset{padding-left:10px;border-left:1px dotted #eee}.paypal-config .helpbox{margin-top:10px;background-color:khaki;color:gray;padding:5px 10px}.paypal-config .form-group textarea{height:150px;width:100%}.paypal-config .bottom-space{margin:1.5rem 0}.paypal-config .card-header{cursor:pointer}.paypal-config .paypal-button-PPLtBlue{padding-top:12px;border-radius:5px;border:1px solid #9DA3A6;vertical-align:middle;padding-right:16px;display:table-cell;text-decoration:none;background-color:#1B9DDb;color:#fff;font-size:15px;font-family:HelveticaNeueMedium,"Helvetica Neue Medium",Helvetica,Arial,sans-serif}.paypal-config .paypal-button-PPLtBlue:before{content:"";background:url(https://www.paypalobjects.com/images/shared/monogram@2x.png) 12px no-repeat #fff;background-size:18.34px;display:table-cell;width:40px;height:42px;float:left;margin-right:16px;border-bottom-left-radius:5px;border-top-left-radius:5px;margin-top:-12px} diff --git a/assets/css/paypal.css b/assets/css/paypal.css index e189f3f75..b9e5a778c 100644 --- a/assets/css/paypal.css +++ b/assets/css/paypal.css @@ -1 +1 @@ -.google-pay-loading-container{float:right;margin-right:calc(50%)}#oscpaypal_googlepay{float:right} +.paypal-button-or{padding:10px}.paypal-button-wrapper{width:100%}.paypal-button-wrapper.large{max-width:250px}.paypal-button-wrapper.small{max-width:200px}.paypal-button-right{margin-left:auto;text-align:right}#paypal-installment-banner-container{margin-bottom:1rem}.google-pay-loading-container{float:right;margin-right:calc(50%)}#oscpaypal_googlepay{float:right} diff --git a/assets/js/paypal-frontend.min.js b/assets/js/paypal-frontend.min.js index bf33200a8..600017a30 100644 --- a/assets/js/paypal-frontend.min.js +++ b/assets/js/paypal-frontend.min.js @@ -1 +1 @@ -window.OxidPayPal={sdkLoaded:!1,onSDKLoaded:function(){this.sdkLoaded=!0},isSDKLoaded:function(){return this.sdkLoaded}},window.OxidPayPalGooglePay={baseRequest:{apiVersion:2,apiVersionMinor:0},paymentsClient:null,allowedPaymentMethods:null,merchantInfo:null,googlePayContainer:null,buttonId:null,token:null,selfLink:null,useGooglePayAddress:null,isSandbox:null,merchantName:null,totalPrice:null,currency:null,deliveryAddressMD5:null,language:null,loadingContainer:null,init:async function(){var e;this.googlePayContainer=document.getElementById("oscpaypal_googlepay"),this.googlePayContainer&&(this.buttonId=this.googlePayContainer.dataset.buttonId,this.token=this.googlePayContainer.dataset.token,this.selfLink=this.googlePayContainer.dataset.selfLink,this.useGooglePayAddress=!!Number(this.googlePayContainer.dataset.useGooglePayAddress),this.isSandbox=!!Number(this.googlePayContainer.dataset.isSandbox),this.merchantName=this.googlePayContainer.dataset.merchantName,this.totalPrice=this.googlePayContainer.dataset.totalPrice,this.currency=this.googlePayContainer.dataset.currency,this.deliveryAddressMD5=this.googlePayContainer.dataset.deliveryAddressMd5,this.language=this.googlePayContainer.dataset.language,e=document.getElementsByClassName(this.googlePayContainer.dataset.loadingContainerClassName),this.loadingContainer=e[0],await window.googlePayReady,this.onGooglePayLoaded())},getGoogleIsReadyToPayRequest:function(e){return Object.assign({},this.baseRequest,{allowedPaymentMethods:e})},getGooglePayConfig:async function(){var e;return null!=this.allowedPaymentMethods&&null!=this.merchantInfo||(e=await paypal.Googlepay().config(),this.allowedPaymentMethods=e.allowedPaymentMethods,this.merchantInfo=e.merchantInfo,this.merchantInfo.merchantName=this.merchantName),{allowedPaymentMethods:this.allowedPaymentMethods,merchantInfo:this.merchantInfo}},getGooglePaymentDataRequest:async function(){const e=Object.assign({},this.baseRequest);var{allowedPaymentMethods:t,merchantInfo:a}=await this.getGooglePayConfig();return e.transactionInfo=this.getGoogleTransactionInfo(),e.allowedPaymentMethods=t,e.merchantInfo=a,e.callbackIntents=["PAYMENT_AUTHORIZATION"],e.emailRequired=!0,e.shippingAddressRequired=this.useGooglePayAddress,e.shippingAddressParameters={phoneNumberRequired:!0},e},onPaymentAuthorized:function(a){return new Promise(function(t,e){this.processPayment(a).then(function(e){t({transactionState:"SUCCESS"})}).catch(function(e){t({transactionState:"ERROR"})})}.bind(this))},getGooglePaymentsClient:function(){return null===this.paymentsClient&&(this.paymentsClient=new google.payments.api.PaymentsClient({environment:this.isSandbox?"TEST":"PRODUCTION",paymentDataCallbacks:{onPaymentAuthorized:this.onPaymentAuthorized.bind(this)}})),this.paymentsClient},onGooglePayLoaded:async function(){if(window.OxidPayPal&&window.OxidPayPal.isSDKLoaded()){const t=this.getGooglePaymentsClient();var e=(await this.getGooglePayConfig())["allowedPaymentMethods"];t.isReadyToPay(this.getGoogleIsReadyToPayRequest(e)).then(function(e){e.result&&(this.loadingContainer.style.display="none",this.addGooglePayButton())}.bind(this)).catch(function(e){console.error(e)})}else window.setTimeout(this.onGooglePayLoaded.bind(this),500)},addGooglePayButton:function(){const e=this.getGooglePaymentsClient();var t=e.createButton({buttonType:"buy",buttonLocale:this.language,onClick:this.onGooglePaymentButtonClicked.bind(this)});document.getElementById("oscpaypal_googlepay").appendChild(t)},getGoogleTransactionInfo:function(){return{currencyCode:this.currency,totalPriceStatus:"FINAL",totalPrice:this.totalPrice,totalPriceLabel:"Total"}},onGooglePaymentButtonClicked:async function(){const e=await this.getGooglePaymentDataRequest(),t=(e.transactionInfo=this.getGoogleTransactionInfo(),this.getGooglePaymentsClient());t.loadPaymentData(e)},processPayment:async function(e){try{var t=this.selfLink+"&cl=oscpaypalproxy&fnc=createGooglepayOrder&paymentid=oscpaypal_googlepay&context=continue&stoken="+this.token,{id:a,status:n,links:o}=await fetch(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)}).then(e=>e.json());const s=new OxidPayPalHateoasLinks;var i=s.getApproveLink(o);if(i)window.location.href=i;else{if("APPROVED"===n)return this.captureOrder(a),{transactionState:"SUCCESS"};if("PAYER_ACTION_REQUIRED"!==n)return console.error("Payment was not approved"),{transactionState:"ERROR"};console.log("==== Confirm Payment Completed Payer Action Required ====="),this.googlePayUserActionRequired(a)}}catch(e){return{transactionState:"ERROR",error:{message:e.message}}}},googlePayUserActionRequired:function(e){paypal.Googlepay().initiatePayerAction({orderId:e}).then(async()=>{console.log("===== Payer Action Completed ====="),await this.createOxidOrder(e)})},createOxidOrder:async function(e){var t=this.selfLink+"&cl=order&fnc=createGooglePayOrder&context=continue&stoken="+this.token+"&sDeliveryAddressMD5="+this.deliveryAddressMD5;(createData=new FormData).append("orderID",e),fetch(t,{method:"POST",body:createData}).then(function(e){return e.json()}).then(function(e){"ERROR"===e.status&&location.reload()})},captureOrder:async function(e){(captureData=new FormData).append("orderID",e);await fetch(this.selfLink+"&cl=order&fnc=captureGooglePayOrder&context=continue&stoken="+this.token+"&sDeliveryAddressMD5="+this.deliveryAddressMD5,{method:"post",body:captureData}).then(function(e){return e.json()}).then(function(e){console.log("==== Capture Order Completed ====");var t=Array.isArray(e.location)&&e.location[0];window.location.href=this.selfLink+t,"ERROR"===e.status&&location.reload()}.bind(this)).catch(e=>{console.error(e)})}},OxidPayPalGooglePay.init(),window.OxidPayPalGooglePay3DS={handle:async e=>{var t={...await window.OxidPayPalGooglePay.getGooglePaymentDataRequest(),paymentData:{tokenizationData:{type:"PAYMENT_GATEWAY",token:e.id},threeDSData:{authenticationParameters:{threeDSRequestData:{threeDSServerTransID:generateTransactionId(),challengeWindowSize:"03",messageCategory:"PAYMENT_AUTHENTICATION"}}}}};try{await paymentClient.loadPaymentData(t);if((await fetch("/v2/checkout/orders/"+e.id,{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify([{op:"replace",path:"/payment_source/google_pay/card/authentication_result",value:{liability_shift:"POSSIBLE",three_d_secure:{authentication_status:"Y",enrollment_status:"Y"}}}])})).ok)return await fetch(`/v2/checkout/orders/${e.id}/capture`,{method:"POST"})}catch(e){throw console.error("3DS Authentication failed:",e),e}}},function(){"use strict";function e(){}e.prototype.getApproveLink=function(e){e=e.find(e=>"approve"===e.rel);return e?e.href:null},window.OxidPayPalHateoasLinks=e}(); \ No newline at end of file +function registerClickListenerForSavedVaultRadioButtons(){const e=document.querySelectorAll(".vaulting_paymentsource");e&&0e.json());return"CREATED"===a?(this.confirmOrder(n,e),{transactionState:"SUCCESS"}):"APPROVED"===a?(this.captureOrder(n),{transactionState:"SUCCESS"}):(console.error("Payment was not approved"),{transactionState:"ERROR"})}catch(e){return{transactionState:"ERROR",error:{message:e.message}}}},confirmOrder:async function(e,t){"PAYER_ACTION_REQUIRED"===(await paypal.Googlepay().confirmOrder({orderId:e,paymentMethodData:t.paymentMethodData})).status?(console.log("==== Confirm Payment Completed Payer Action Required ====="),this.googlePayUserActionRequired(e)):this.isSandbox&&console.log("==== confirmOrder: Not Approved =====")},googlePayUserActionRequired:function(e){paypal.Googlepay().initiatePayerAction({orderId:e}).then(async()=>{console.log("===== Payer Action Completed ====="),await this.executeOxidOrder(e),await this.captureOrder(e)})},executeOxidOrder:async function(e){var t=this.selfLink+"&cl=order&fnc=executeGooglePayOrder&context=continue&stoken="+this.token+"&sDeliveryAddressMD5="+this.deliveryAddressMD5;(createData=new FormData).append("orderID",e),fetch(t,{method:"POST",body:createData}).then(function(e){return e.json()}).then(function(e){console.log("==== Create OXID Order Completed ===="),"ERROR"===e.status&&location.reload()})},captureOrder:async function(e){(captureData=new FormData).append("orderID",e),await fetch(this.selfLink+"&cl=order&fnc=captureGooglePayOrder&context=continue&stoken="+this.token+"&sDeliveryAddressMD5="+this.deliveryAddressMD5,{method:"post",body:captureData}).then(function(e){return e.json()}).then(function(e){console.log("==== Capture Order Completed ====");var t=Array.isArray(e.location)&&e.location[0];window.location.href=this.selfLink+t+"&stoken="+this.token,"ERROR"===e.status&&location.reload()}.bind(this)).catch(e=>{console.error(e)})}},OxidPayPalGooglePay.init(),window.OxidPayPalGooglePay3DS={handle:async e=>{var t={...await window.OxidPayPalGooglePay.getGooglePaymentDataRequest(),paymentData:{tokenizationData:{type:"PAYMENT_GATEWAY",token:e.id},threeDSData:{authenticationParameters:{threeDSRequestData:{threeDSServerTransID:generateTransactionId(),challengeWindowSize:"03",messageCategory:"PAYMENT_AUTHENTICATION"}}}}};try{await paymentClient.loadPaymentData(t);if((await fetch("/v2/checkout/orders/"+e.id,{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify([{op:"replace",path:"/payment_source/google_pay/card/authentication_result",value:{liability_shift:"POSSIBLE",three_d_secure:{authentication_status:"Y",enrollment_status:"Y"}}}])})).ok)return await fetch(`/v2/checkout/orders/${e.id}/capture`,{method:"POST"})}catch(e){throw console.error("3DS Authentication failed:",e),e}}},function(){"use strict";function e(){}e.prototype.getApproveLink=function(e){return this.getLinkByKeyword(e,"approve")},e.prototype.getPayerActionLink=function(e){return this.getLinkByKeyword(e,"payer-action")},e.prototype.getLinkByKeyword=function(e,t){e=e.find(e=>e.rel===t);return e?e.href:null},window.OxidPayPalHateoasLinks=e}(),document.addEventListener("DOMContentLoaded",function(){registerClickListenerForSavedVaultRadioButtons(),registerClickListenerForTheVaultCheckoutButton()}); \ No newline at end of file diff --git a/resources/build/js/paypal-frontend-googlepay.js b/resources/build/js/paypal-frontend-googlepay.js index 71c73e278..028c28464 100644 --- a/resources/build/js/paypal-frontend-googlepay.js +++ b/resources/build/js/paypal-frontend-googlepay.js @@ -7,7 +7,6 @@ window.OxidPayPalGooglePay = { paymentsClient: null, allowedPaymentMethods: null, merchantInfo: null, - googlePayContainer: null, buttonId: null, token: null, selfLink: null, @@ -20,19 +19,18 @@ window.OxidPayPalGooglePay = { language: null, loadingContainer: null, init: async function () { - this.googlePayContainer = document.getElementById('oscpaypal_googlepay'); - if (this.googlePayContainer) { - this.buttonId = this.googlePayContainer.dataset.buttonId; - this.token = this.googlePayContainer.dataset.token; - this.selfLink = this.googlePayContainer.dataset.selfLink; - this.useGooglePayAddress = !!Number(this.googlePayContainer.dataset.useGooglePayAddress); - this.isSandbox = !!Number(this.googlePayContainer.dataset.isSandbox); - this.merchantName = this.googlePayContainer.dataset.merchantName; - this.totalPrice = this.googlePayContainer.dataset.totalPrice; - this.currency = this.googlePayContainer.dataset.currency; - this.deliveryAddressMD5 = this.googlePayContainer.dataset.deliveryAddressMd5; - this.language = this.googlePayContainer.dataset.language; - let elements = document.getElementsByClassName(this.googlePayContainer.dataset.loadingContainerClassName); + const googlePayDataContainer = document.getElementById('google_pay_button_data_container'); + if (googlePayDataContainer) { + this.token = googlePayDataContainer.dataset.token; + this.selfLink = googlePayDataContainer.dataset.selfLink; + this.useGooglePayAddress = !!Number(googlePayDataContainer.dataset.useGooglePayAddress); + this.isSandbox = !!Number(googlePayDataContainer.dataset.isSandbox); + this.merchantName = googlePayDataContainer.dataset.merchantName; + this.totalPrice = googlePayDataContainer.dataset.totalPrice; + this.currency = googlePayDataContainer.dataset.currency; + this.deliveryAddressMD5 = googlePayDataContainer.dataset.deliveryAddressMd5; + this.language = googlePayDataContainer.dataset.language; + let elements = document.getElementsByClassName(googlePayDataContainer.dataset.loadingContainerClassName); this.loadingContainer = elements[0]; await window.googlePayReady; @@ -146,26 +144,22 @@ window.OxidPayPalGooglePay = { processPayment: async function (paymentData) { try { - const createOrderUrl = this.selfLink + '&cl=oscpaypalproxy&fnc=createGooglepayOrder&paymentid=oscpaypal_googlepay&context=continue&stoken=' + this.token; + const createOrderUrl = this.selfLink + '&cl=oscpaypalproxy&fnc=createGooglePayOrder&paymentid=oscpaypal_googlepay&context=continue&stoken=' + this.token; - const {id: orderId, status, links} = await fetch(createOrderUrl, { + const {id: orderId, status} = await fetch(createOrderUrl, { method: "POST", headers: {"Content-Type": "application/json"}, body: JSON.stringify(paymentData), }).then((res) => res.json()); - const hateoasLinks = new OxidPayPalHateoasLinks(); - const approveLink = hateoasLinks.getApproveLink(links); - - if (approveLink) { - window.location.href = approveLink; + if (status === "CREATED") { + /* Capture the Order */ + this.confirmOrder(orderId, paymentData); + return {transactionState: "SUCCESS"}; } else if (status === "APPROVED") { /* Capture the Order */ this.captureOrder(orderId); return {transactionState: "SUCCESS"}; - } else if (status === "PAYER_ACTION_REQUIRED") { - console.log("==== Confirm Payment Completed Payer Action Required ====="); - this.googlePayUserActionRequired(orderId); } else { console.error("Payment was not approved"); return {transactionState: "ERROR"}; @@ -179,17 +173,34 @@ window.OxidPayPalGooglePay = { }; } }, + confirmOrder: async function (orderId, paymentData) { + const confirmOrderResponse = await paypal.Googlepay().confirmOrder({ + orderId: orderId, + paymentMethodData: paymentData.paymentMethodData + }); + + if (confirmOrderResponse.status === "PAYER_ACTION_REQUIRED") { + console.log("==== Confirm Payment Completed Payer Action Required ====="); + this.googlePayUserActionRequired(orderId); + } else { + if (this.isSandbox) { + console.log("==== confirmOrder: Not Approved ====="); + } + } + }, + googlePayUserActionRequired: function (orderId) { paypal .Googlepay() .initiatePayerAction({ orderId: orderId }) .then(async () => { console.log("===== Payer Action Completed ====="); - await this.createOxidOrder(orderId); + await this.executeOxidOrder(orderId); + await this.captureOrder(orderId); }); }, - createOxidOrder: async function (orderId) { - const url = this.selfLink + '&cl=order&fnc=createGooglePayOrder&context=continue&stoken=' + this.token + '&sDeliveryAddressMD5=' + this.deliveryAddressMD5; + executeOxidOrder: async function (orderId) { + const url = this.selfLink + '&cl=order&fnc=executeGooglePayOrder&context=continue&stoken=' + this.token + '&sDeliveryAddressMD5=' + this.deliveryAddressMD5; createData = new FormData(); createData.append('orderID', orderId); fetch(url, { @@ -198,6 +209,8 @@ window.OxidPayPalGooglePay = { }).then(function (res) { return res.json(); }).then(function (data) { + console.log("==== Create OXID Order Completed ===="); + if (data.status === "ERROR") { location.reload(); } @@ -214,8 +227,8 @@ window.OxidPayPalGooglePay = { }).then(function (data) { console.log("==== Capture Order Completed ===="); var goNext = Array.isArray(data.location) && data.location[0]; + window.location.href = this.selfLink + goNext + '&stoken=' + this.token; - window.location.href = this.selfLink + goNext; if (data.status === "ERROR") { location.reload(); } diff --git a/resources/build/js/paypal-frontend-hateoaslinks.js b/resources/build/js/paypal-frontend-hateoaslinks.js index 745361eed..a6ed81449 100644 --- a/resources/build/js/paypal-frontend-hateoaslinks.js +++ b/resources/build/js/paypal-frontend-hateoaslinks.js @@ -10,16 +10,36 @@ */ /** - * Process an array of links. + * Process an array of links and return the aprove-link * @param {Link[]} links - An array of link objects. * * @returns {string|null} */ OxidPayPalHateoasLinks.prototype.getApproveLink = function (links) { - const approveHateoasLink = links.find(link => link.rel === 'approve'); + return this.getLinkByKeyword(links, 'approve'); + }; + + /** + * Process an array of links and return the payer-action-link + * @param {Link[]} links - An array of link objects. + * + * @returns {string|null} + */ + OxidPayPalHateoasLinks.prototype.getPayerActionLink = function (links) { + return this.getLinkByKeyword(links, 'payer-action'); + }; + + /** + * Process an array of links. + * @param {Link[]} links - An array of link objects. + * + * @returns {string|null} + */ + OxidPayPalHateoasLinks.prototype.getLinkByKeyword = function (links, keyword) { + const hateoasLink = links.find(link => link.rel === keyword); - if (approveHateoasLink) { - return approveHateoasLink.href; + if (hateoasLink) { + return hateoasLink.href; } return null; diff --git a/resources/build/js/paypal-frontend-paypal-vault-checkout.js b/resources/build/js/paypal-frontend-paypal-vault-checkout.js new file mode 100644 index 000000000..5d02822f5 --- /dev/null +++ b/resources/build/js/paypal-frontend-paypal-vault-checkout.js @@ -0,0 +1,42 @@ +function registerClickListenerForSavedVaultRadioButtons() { + const vaultingPaymentsourceRadioButtons = document.querySelectorAll(".vaulting_paymentsource"); + if (vaultingPaymentsourceRadioButtons && vaultingPaymentsourceRadioButtons.length > 0) { + vaultingPaymentsourceRadioButtons.forEach(function (paymentsource) { + paymentsource.onclick = function () { + if (paymentsource.checked) { + document.getElementById("paypalVaultCheckoutButton").disabled = false; + } + }; + }); + } +} + +// clicking the vault checkout button will submit the form for payment +function registerClickListenerForTheVaultCheckoutButton() { + const paypalVaultCheckoutButton = document.getElementById("paypalVaultCheckoutButton"); + if (paypalVaultCheckoutButton) { + paypalVaultCheckoutButton.onclick = function () { + const vaultingPaymentsourceRadioButtons = document.querySelectorAll(".vaulting_paymentsource"); + if (vaultingPaymentsourceRadioButtons && vaultingPaymentsourceRadioButtons.length > 0) { + vaultingPaymentsourceRadioButtons.forEach(function (paymentsource) { + if (paymentsource.checked) { + document.getElementById("payment_oscpaypal").click(); + + let input = document.createElement("input"); + input.type = "hidden"; + input.name = "vaultingpaymentsource"; + input.value = paymentsource.dataset.index; + document.getElementById("payment").appendChild(input); + + document.getElementById("paymentNextStepBottom").click(); + } + }); + } + }; + } +} + +document.addEventListener("DOMContentLoaded", function() { + registerClickListenerForSavedVaultRadioButtons(); + registerClickListenerForTheVaultCheckoutButton(); +}); diff --git a/resources/build/scss/paypal.scss b/resources/build/scss/paypal.scss index 5fcec2132..0b468be6f 100644 --- a/resources/build/scss/paypal.scss +++ b/resources/build/scss/paypal.scss @@ -1,3 +1,26 @@ +/* SMARTY STUFF */ +.paypal-button-or { + padding: 10px; +} +.paypal-button-wrapper { + width: 100%; + &.large { + max-width: 250px; + } + &.small { + max-width: 200px; + } +} +.paypal-button-right { + margin-left: auto; + text-align: right; +} + +#paypal-installment-banner-container { + margin-bottom: 1rem; +} + +/* TWIG STUFF */ .google-pay-loading-container { float: right; margin-right: calc(50%); diff --git a/resources/grunt/concat.js b/resources/grunt/concat.js index 424867295..ed9e2b9b1 100644 --- a/resources/grunt/concat.js +++ b/resources/grunt/concat.js @@ -1,6 +1,9 @@ module.exports = { moduleproduction: { + options: { + seperator: ";" + }, files: { "../assets/js/paypal-admin.min.js": [ "build/js/paypal-admin.js", @@ -13,6 +16,7 @@ module.exports = { "build/js/paypal-frontend-googlepay.js", "build/js/paypal-frontend-googlepay-3ds.js", "build/js/paypal-frontend-hateoaslinks.js", + "build/js/paypal-frontend-paypal-vault-checkout.js", ] } } diff --git a/resources/grunt/uglify.js b/resources/grunt/uglify.js index 4e193ac62..8a1b16c35 100644 --- a/resources/grunt/uglify.js +++ b/resources/grunt/uglify.js @@ -5,7 +5,7 @@ module.exports = { }, moduleproduction: { files: { - "../out/src/js/paypal-admin.min.js": [ + "../assets/js/paypal-admin.min.js": [ "build/js/paypal-admin.js", "node_modules/jquery/dist/jquery.js", "node_modules/popper.js/dist/umd/popper.js", @@ -16,6 +16,7 @@ module.exports = { "build/js/paypal-frontend-googlepay.js", "build/js/paypal-frontend-googlepay-3ds.js", "build/js/paypal-frontend-hateoaslinks.js", + "build/js/paypal-frontend-paypal-vault-checkout.js", ] } } From 05fe9cfa6e723be03f5da028c48e8b05b6f10ade Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Thu, 9 Jan 2025 15:37:24 +0100 Subject: [PATCH 04/30] take over changes #879 --- assets/img/loading.svg | 7 +++++++ .../checkout_order_btn_submit_bottom.tpl | 7 +------ .../flow/page/checkout/change_payment.tpl | 21 +------------------ views/smarty/frontend/shared/googlepay.tpl | 4 ++-- .../wave/page/checkout/change_payment.tpl | 21 +------------------ 5 files changed, 12 insertions(+), 48 deletions(-) create mode 100644 assets/img/loading.svg diff --git a/assets/img/loading.svg b/assets/img/loading.svg new file mode 100644 index 000000000..653252009 --- /dev/null +++ b/assets/img/loading.svg @@ -0,0 +1,7 @@ + + + + + + diff --git a/views/smarty/frontend/blocks/page/checkout/checkout_order_btn_submit_bottom.tpl b/views/smarty/frontend/blocks/page/checkout/checkout_order_btn_submit_bottom.tpl index f5f8ebe59..16da8cf41 100644 --- a/views/smarty/frontend/blocks/page/checkout/checkout_order_btn_submit_bottom.tpl +++ b/views/smarty/frontend/blocks/page/checkout/checkout_order_btn_submit_bottom.tpl @@ -21,12 +21,7 @@ [{/if}] [{/if}] [{if "oscpaypal_googlepay" == $payment->getId()}] - [{if $oViewConf->isFlowCompatibleTheme()}] - [{include file="@osc_paypal/frontend/shared/googlepay.tpl" buttonId=$payment->getId() buttonClass="paypal-button-wrapper large"}] - [{else}] - [{include file="@osc_paypal/frontend/shared/googlepay.tpl" buttonId=$payment->getId() buttonClass="paypal-button-wrapper large"}] - [{/if}] -
+ [{include file="@osc_paypal/frontend/shared/googlepay.tpl" buttonClass="paypal-button-wrapper large"}] [{elseif "oscpaypal_apple_pay" == $payment->getId()}] [{if $oViewConf->isFlowCompatibleTheme()}] diff --git a/views/smarty/frontend/flow/page/checkout/change_payment.tpl b/views/smarty/frontend/flow/page/checkout/change_payment.tpl index cdba60df4..251264f1e 100644 --- a/views/smarty/frontend/flow/page/checkout/change_payment.tpl +++ b/views/smarty/frontend/flow/page/checkout/change_payment.tpl @@ -23,32 +23,13 @@
- - [{/if}] [{if 'oscpaypal_express'|array_key_exists:$oView->getPaymentList() && $oViewConf->isPayPalExpressSessionActive()}] diff --git a/views/smarty/frontend/shared/googlepay.tpl b/views/smarty/frontend/shared/googlepay.tpl index d1cf9bd4f..59a67352e 100644 --- a/views/smarty/frontend/shared/googlepay.tpl +++ b/views/smarty/frontend/shared/googlepay.tpl @@ -8,9 +8,8 @@
loading animation
-
+
[{/oxhasrights}] [{/block}] diff --git a/views/smarty/frontend/wave/page/checkout/change_payment.tpl b/views/smarty/frontend/wave/page/checkout/change_payment.tpl index e21a38174..6ffe8c123 100644 --- a/views/smarty/frontend/wave/page/checkout/change_payment.tpl +++ b/views/smarty/frontend/wave/page/checkout/change_payment.tpl @@ -23,32 +23,13 @@
- - [{/if}] [{if 'oscpaypal_express'|array_key_exists:$oView->getPaymentList() && $oViewConf->isPayPalExpressSessionActive()}] [{assign var="config" value=$oViewConf->getPayPalCheckoutConfig()}] From a7db7faa890ee7cd1236b782e056b11896c8f913 Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Fri, 10 Jan 2025 09:10:00 +0100 Subject: [PATCH 05/30] take over changes from smarty --- views/twig/admin/oscpaypalconfig.html.twig | 155 ++++++++++++++++----- 1 file changed, 119 insertions(+), 36 deletions(-) diff --git a/views/twig/admin/oscpaypalconfig.html.twig b/views/twig/admin/oscpaypalconfig.html.twig index 0347d20d6..8eb2b7b76 100644 --- a/views/twig/admin/oscpaypalconfig.html.twig +++ b/views/twig/admin/oscpaypalconfig.html.twig @@ -1,4 +1,4 @@ -{% include "headitem.html.twig" with {title: "paypal"|translate, box: "boxpaypal"} %} +{% include "headitem.html.twig" with {title: "paypal", box: "boxpaypal"} %} {% set isSandBox = config.isSandbox() %} {% set sSelfLink = oViewConf.getSslSelfLink()|replace({"&": "&"}) %} @@ -13,9 +13,9 @@

{{ translate({ ident: "paypal" }) }} {{ translate({ ident: "OSC_PAYPAL_CONFIG" }) }}

@@ -50,19 +50,17 @@

{{ translate({ ident: "HELP_OSC_PAYPAL_CREDENTIALS_PART1" }) }}

- - {% if not config.getLiveClientId() and not config.getLiveClientSecret() and not config.getLiveWebhookId() %} -

{{ translate({ ident: "HELP_OSC_PAYPAL_CREDENTIALS_PART2" }) }}

-

- {{ translate({ ident: "OSC_PAYPAL_LIVE_BUTTON_CREDENTIALS" }) }} - -

- {% endif %} +

{{ translate({ ident: "HELP_OSC_PAYPAL_CREDENTIALS_PART2" }) }}

+ +

+ {{ translate({ ident: "OSC_PAYPAL_LIVE_BUTTON_CREDENTIALS" }) }} + +

{{ translate({ ident: "OSC_PAYPAL_LIVE_CREDENTIALS" }) }}

@@ -99,15 +97,20 @@
- +
- {{ translate({ ident: "OSC_PAYPAL_SPECIAL_PAYMENTS_PUI", suffix:"COLON" }) }} {% if config.isPuiEligibility() %}{{ translate({ ident: "GENERAL_YES" }) }}{% else %}{{ translate({ ident: "GENERAL_NO" }) }}{% endif %}
- {{ translate({ ident: "OSC_PAYPAL_SPECIAL_PAYMENTS_ACDC", suffix:"COLON" }) }} {% if config.isAcdcEligibility() %}{{ translate({ ident: "GENERAL_YES" }) }}{% else %}{{ translate({ ident: "GENERAL_NO" }) }} {{ translate({ ident: "OSC_PAYPAL_SPECIAL_PAYMENTS_ACDC_FALLBACK" }) }}{% endif %} + {{ translate({ ident: "OSC_PAYPAL_SPECIAL_PAYMENTS_PUI", suffix: "COLON" }) }} {% if config.isLivePuiEligibility() %}{{ translate({ ident: "GENERAL_YES" }) }}{% else %}{{ translate({ ident: "GENERAL_NO" }) }}{% endif %} +
+ {{ translate({ ident: "OSC_PAYPAL_SPECIAL_PAYMENTS_ACDC", suffix: "COLON" }) }} {% if config.isLiveAcdcEligibility() %}{{ translate({ ident: "GENERAL_YES" }) }}{% else %}{{ translate({ ident: "GENERAL_NO" }) }} {{ translate({ ident: "OSC_PAYPAL_SPECIAL_PAYMENTS_ACDC_FALLBACK" }) }}{% endif %} +
+ {{ translate({ ident: "OSC_PAYPAL_SPECIAL_PAYMENTS_VAULTING", suffix: "COLON" }) }} {% if config.isLiveVaultingEligibility() %}{{ translate({ ident: "GENERAL_YES" }) }}{% else %}{{ translate({ ident: "GENERAL_NO" }) }}{% endif %} +
+ {{ translate({ ident: "OSC_PAYPAL_SPECIAL_PAYMENTS_GOOGLEPAY", suffix: "COLON" }) }} {% if config.isLiveGooglePayEligibility() %}{{ translate({ ident: "GENERAL_YES" }) }}{% else %}{{ translate({ ident: "GENERAL_NO" }) }}{% endif %} +
+ {{ translate({ ident: "OSC_PAYPAL_SPECIAL_PAYMENTS_APPLEPAY", suffix: "COLON" }) }} {% if config.isLiveApplePayEligibility() %}{{ translate({ ident: "GENERAL_YES" }) }}{% else %}{{ translate({ ident: "GENERAL_NO" }) }}{% endif %}
- {% if not config.getSandboxClientId() and not config.getSandboxClientSecret() and not config.getSandboxWebhookId() %} -

{{ translate({ ident: "HELP_OSC_PAYPAL_CREDENTIALS_PART2" }) }}

- {% endif %}

{{ translate({ ident: "OSC_PAYPAL_SANDBOX_CREDENTIALS" }) }}

@@ -154,10 +156,19 @@
- +
- {{ translate({ ident: "OSC_PAYPAL_SPECIAL_PAYMENTS_PUI", suffix:"COLON" }) }} {% if config.isLivePuiEligibility() %}{{ translate({ ident: "GENERAL_YES" }) }}{% else %}{{ translate({ ident: "GENERAL_NO" }) }}{% endif %}
- {{ translate({ ident: "OSC_PAYPAL_SPECIAL_PAYMENTS_ACDC", suffix:"COLON" }) }} {% if config.isLiveAcdcEligibility() %}{{ translate({ ident: "GENERAL_YES" }) }}{% else %}{{ translate({ ident: "GENERAL_NO" }) }} {{ translate({ ident: "OSC_PAYPAL_SPECIAL_PAYMENTS_ACDC_FALLBACK" }) }}{% endif %} + {{ translate({ ident: "OSC_PAYPAL_SPECIAL_PAYMENTS_PUI", suffix: "COLON" }) }} {% if config.isSandboxPuiEligibility() %}{{ translate({ ident: "GENERAL_YES" }) }}{% else %}{{ translate({ ident: "GENERAL_NO" }) }}{% endif %} +
+ {{ translate({ ident: "OSC_PAYPAL_SPECIAL_PAYMENTS_ACDC", suffix: "COLON" }) }} {% if config.isSandboxAcdcEligibility() %}{{ translate({ ident: "GENERAL_YES" }) }}{% else %}{{ translate({ ident: "GENERAL_NO" }) }} {{ translate({ ident: "OSC_PAYPAL_SPECIAL_PAYMENTS_ACDC_FALLBACK" }) }}{% endif %} +
+ {{ translate({ ident: "OSC_PAYPAL_SPECIAL_PAYMENTS_VAULTING", suffix: "COLON" }) }} {% if config.isSandboxVaultingEligibility() %}{{ translate({ ident: "GENERAL_YES" }) }}{% else %}{{ translate({ ident: "GENERAL_NO" }) }}{% endif %} +
+ {{ translate({ ident: "OSC_PAYPAL_SPECIAL_PAYMENTS_GOOGLEPAY", suffix: "COLON" }) }} {% if config.isSandboxGooglePayEligibility() %}{{ translate({ ident: "GENERAL_YES" }) }}{% else %}{{ translate({ ident: "GENERAL_NO" }) }}{% endif %} + +
+ {{ translate({ ident: "OSC_PAYPAL_SPECIAL_PAYMENTS_APPLEPAY", suffix: "COLON" }) }} {% if config.isSandboxApplePayEligibility() %}{{ translate({ ident: "GENERAL_YES" }) }}{% else %}{{ translate({ ident: "GENERAL_NO" }) }}{% endif %} +
@@ -345,7 +356,7 @@
{% if oView.showTransferLegacySettingsButton() %} - {{ translate({ ident: "OSC_PAYPAL_BANNER_TRANSFERLEGACYSETTINGS" }) }} + {{ translate({ ident: 'OSC_PAYPAL_BANNER_TRANSFERLEGACYSETTINGS' }) }} {% endif %}

{{ translate({ ident: "OSC_PAYPAL_BANNER_INFOTEXT" }) }}

@@ -434,8 +445,6 @@
{{ translate({ ident: "HELP_OSC_PAYPAL_BANNER_CARTPAGESELECTOR" }) }} - -
@@ -455,13 +464,13 @@ - - - @@ -492,24 +501,98 @@
+
+
+
+
+ +
+ {{ translate({ ident: "HELP_OSC_PAYPAL_VAULTING_ACTIVATE_VAULTING" }) }} +
+
+
+
+
+ +
+
+ +
+
- -
- - {{ translate({ ident: "OSC_PAYPAL_EXPRESS_SHIPPING_DESC" }) }} +
+ +
+ + {{ translate({ ident: "OSC_PAYPAL_EXPRESS_SHIPPING_DESC" }) }} +
+
+
+
+
+
+
+ +
+
+ +
+
+
+
+
+
+
+ + {{ translate({ ident: "OSC_PAYPAL_CUSTOM_ID_CONTENTS_DESC" }) }} +
+ {# +
+
+ +
+
+
+
+
+
+
+
+ +
+ {{ translate({ ident: "HELP_OSC_OSC_PAYPAL_GOOGLEPAY_ADRESS_ACTIVATE" }) }} +
+
+
+
+
+
+
#}
From 39247b9edb3dd59de8d7763926d8c1980a1425e2 Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Fri, 10 Jan 2025 09:13:42 +0100 Subject: [PATCH 06/30] Update Client Version --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 899e91b85..0db42139d 100644 --- a/composer.json +++ b/composer.json @@ -25,7 +25,7 @@ "giggsey/libphonenumber-for-php": "^8.12", "viison/address-splitter": "^0.3.4", "webmozart/path-util": "^2.3.0", - "oxid-solution-catalysts/paypal-client": "v3.0.12" + "oxid-solution-catalysts/paypal-client": "v3.0.13" }, "require-dev": { "codeception/module-rest": "^3.3.0", From e9bb0af8c1f8209215c6ad2c3f48b2aa7f4186be Mon Sep 17 00:00:00 2001 From: Lars Stegelitz Date: Fri, 10 Jan 2025 13:25:25 +0100 Subject: [PATCH 07/30] fixed base twig template and ShopControl (renamed base method) --- src/Core/ShopControl.php | 6 +-- .../themes/default/layout/base.html.twig | 45 ++++++++----------- 2 files changed, 22 insertions(+), 29 deletions(-) diff --git a/src/Core/ShopControl.php b/src/Core/ShopControl.php index 56f6cf336..32855f9bf 100644 --- a/src/Core/ShopControl.php +++ b/src/Core/ShopControl.php @@ -22,12 +22,12 @@ class ShopControl extends ShopControl_parent /** * @param StandardException $exception */ - protected function _handleBaseException($exception) // phpcs:ignore PSR2.Methods.MethodDeclaration.Underscore + protected function handleBaseException($exception) // phpcs:ignore PSR2.Methods.MethodDeclaration.Underscore { if ($exception instanceof PayPalException) { $this->handleCustomPayPalException($exception); } else { - parent::_handleBaseException($exception); + parent::handleBaseException($exception); } } // @codeCoverageIgnore @@ -41,7 +41,7 @@ public function handleCustomPayPalException(PayPalException $exception): void } elseif ($exception instanceof Redirect) { $this->handlePayPalRedirectException($exception, false); } else { - parent::_handleBaseException($exception); + parent::handleBaseException($exception); } } // @codeCoverageIgnore diff --git a/views/twig/extensions/themes/default/layout/base.html.twig b/views/twig/extensions/themes/default/layout/base.html.twig index 8a21b3ff0..abf342741 100644 --- a/views/twig/extensions/themes/default/layout/base.html.twig +++ b/views/twig/extensions/themes/default/layout/base.html.twig @@ -4,31 +4,21 @@ {{ parent() }} {% if oViewConf.isPayPalCheckoutActive() %} {% set className = oViewConf.getTopActiveClassName() %} - {% if oViewConf.isPayPalExpressPaymentEnabled() and - ((className == 'order' and not oViewConf.isPayPalACDCSessionActive()) or (className != 'order' and className != 'payment')) and - ( - (oxcmp_basket.getProductsCount() and oViewConf.showPayPalMiniBasketButton()) or - (className == 'details' and oViewConf.showPayPalProductDetailsButton()) or - (className == 'basket' and oViewConf.showPayPalBasketButton()) - ) - %} - - - {% set sCountryRestriction = oViewConf.getCountryRestrictionForPayPalExpress() %} - {% if sCountryRestriction %} - - {% endif %} - {% elseif className == 'order' and oViewConf.isPayPalACDCSessionActive() %} - - {% elseif className == 'payment' %} - - {% elseif oViewConf.isPayPalBannerActive() and (className == 'start' or className == 'search' or className == 'details' or className == 'alist' or className == 'basket') %} - + {% set sFileMTime = oViewConf.getModulePath('osc_paypal', 'js/paypal-frontend.min.js') %} + + + {% set sCountryRestriction = oViewConf.getCountryRestrictionForPayPalExpress() %} + {% if sCountryRestriction %} + {% endif %} {% if submitCart %} [{/if}] -[{/capture}] -[{oxscript include="https://applepay.cdn-apple.com/jsapi/v1/apple-pay-sdk.js" }] -[{oxscript add=$smarty.capture.detailsApplePayScript}] -[{/oxhasrights}] -[{/block}] diff --git a/views/smarty/frontend/blocks/googlepay.tpl b/views/smarty/frontend/blocks/googlepay.tpl deleted file mode 100644 index d6283a60b..000000000 --- a/views/smarty/frontend/blocks/googlepay.tpl +++ /dev/null @@ -1,284 +0,0 @@ -[{block name="oscpaypal_googlepay"}] -[{oxhasrights ident="PAYWITHGOOGLEPAY"}] -[{assign var="sToken" value=$oViewConf->getSessionChallengeToken()}] -[{assign var="sSelfLink" value=$oViewConf->getSslSelfLink()|replace:"&":"&"}] -[{assign var="oPPconfig" value=$oViewConf->getPayPalCheckoutConfig()}] -[{assign var="oConfig" value=$oViewConf->getConfig()}] -[{assign var="bGooglePayDelivery" value=$oConfig->getConfigParam('oscPayPalUseGooglePayAddress')}] - -[{capture name="detailsGooglePayScript"}] - [{if false}] -
+
[{/oxhasrights}] [{/block}] From e61a3215bb7fca00e97b183dcfb878f3340a7126 Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Thu, 16 Jan 2025 15:14:25 +0100 Subject: [PATCH 23/30] Apple Pay eligibility variable fix in onboarding --- src/Core/Onboarding/Onboarding.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Core/Onboarding/Onboarding.php b/src/Core/Onboarding/Onboarding.php index b91d1ed7b..8784e2a58 100755 --- a/src/Core/Onboarding/Onboarding.php +++ b/src/Core/Onboarding/Onboarding.php @@ -226,7 +226,6 @@ public function saveEligibility(array $merchantInformations): array $isAcdcEligibility = false; $isVaultingEligibility = false; $isVaultingCapability = false; - $isGooglePayCapability = false; $isApplePayEligibility = false; $isGooglePayCapability = false; @@ -287,7 +286,7 @@ public function saveEligibility(array $merchantInformations): array 'pui' => $isPuiEligibility, 'vaulting' => $isVaultingEligibility, 'googlepay' => $isGooglePayCapability, - 'applepay' => $isVaultingEligibility, + 'applepay' => $isApplePayEligibility, ]; } } From f617e3d552b6c7ac36f0b55c03f044ce6a38dac6 Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Thu, 16 Jan 2025 15:22:15 +0100 Subject: [PATCH 24/30] WIP: TakeOver Vaulting --- metadata.php | 4 +- .../PayPalVaultingCardController.php | 2 +- src/Controller/PayPalVaultingController.php | 2 +- .../page/account/account_vaulting_card.tpl | 102 ----------------- .../page/account/account_vaulting_paypal.tpl | 67 ----------- .../page/account/account_vaulting_paypal.tpl | 54 ++++----- .../frontend/shared/page/checkout/acdc.tpl | 14 +-- .../default/page/account/dashboard.html.twig | 32 ++++++ .../page/account/inc/account_menu.html.twig | 13 +++ .../default/page/checkout/order.html.twig | 12 +- .../default/page/checkout/thankyou.html.twig | 19 ++++ .../frontend/account_vaulting_card.html.twig | 106 ++++++++++++++++++ .../account_vaulting_paypal.html.twig | 74 ++++++++++++ views/twig/frontend/acdc.html.twig | 19 ++-- views/twig/frontend/paypal.html.twig | 6 + .../{pui_flow.html.twig => pui.html.twig} | 0 .../frontend/vaultedpaymentsources.html.twig | 38 +++++++ 17 files changed, 343 insertions(+), 221 deletions(-) delete mode 100644 views/smarty/frontend/blocks/page/account/account_vaulting_card.tpl delete mode 100644 views/smarty/frontend/blocks/page/account/account_vaulting_paypal.tpl create mode 100644 views/twig/extensions/themes/default/page/account/dashboard.html.twig create mode 100644 views/twig/extensions/themes/default/page/account/inc/account_menu.html.twig create mode 100644 views/twig/extensions/themes/default/page/checkout/thankyou.html.twig create mode 100644 views/twig/frontend/account_vaulting_card.html.twig create mode 100644 views/twig/frontend/account_vaulting_paypal.html.twig create mode 100644 views/twig/frontend/paypal.html.twig rename views/twig/frontend/{pui_flow.html.twig => pui.html.twig} (100%) create mode 100644 views/twig/frontend/vaultedpaymentsources.html.twig diff --git a/metadata.php b/metadata.php index 9976a9d23..7320da3f2 100755 --- a/metadata.php +++ b/metadata.php @@ -138,8 +138,8 @@ '@osc_paypal/frontend/shared/applepay.tpl' => 'views/smarty/frontend/shared/applepay.tpl', //PSPAYPAL-680 Vaulting - '@osc_paypal/frontend/shared/account_vaulting_paypal.tpl' => 'views/smarty/frontend/shared/page/account/account_vaulting_paypal.tpl', - '@osc_paypal/frontend/shared/account_vaulting_card.tpl' => 'views/smarty/frontend/shared/page/account/account_vaulting_card.tpl', + '@osc_paypal/frontend/account_vaulting_paypal.tpl' => 'views/smarty/frontend/shared/page/account/account_vaulting_paypal.tpl', + '@osc_paypal/frontend/account_vaulting_card.tpl' => 'views/smarty/frontend/shared/page/account/account_vaulting_card.tpl', '@osc_paypal/frontend/shared/vaultedpaymentsources.tpl' => 'views/smarty/frontend/shared/vaultedpaymentsources.tpl', '@osc_paypal/frontend/flow/vaultedpaymentsources.tpl' => 'views/smarty/frontend/flow/vaulting/vaultedpaymentsources.tpl', '@osc_paypal/frontend/wave/vaultedpaymentsources.tpl' => 'views/smarty/frontend/wave/vaulting/vaultedpaymentsources.tpl', diff --git a/src/Controller/PayPalVaultingCardController.php b/src/Controller/PayPalVaultingCardController.php index 3b02826e6..613419075 100644 --- a/src/Controller/PayPalVaultingCardController.php +++ b/src/Controller/PayPalVaultingCardController.php @@ -21,7 +21,7 @@ public function render() $this->_aViewData['vaultingUserId'] = oxNew(Config::class)->getUserIdForVaulting(); $moduleSettings = $this->getServiceFromContainer(ModuleSettings::class); if ($moduleSettings->isVaultingAllowedForACDC()) { - $this->_sThisTemplate = '@osc_paypal/frontend/shared/account_vaulting_card'; + $this->_sThisTemplate = '@osc_paypal/frontend/account_vaulting_card'; } return parent::render(); diff --git a/src/Controller/PayPalVaultingController.php b/src/Controller/PayPalVaultingController.php index 7708e7679..dbb893496 100644 --- a/src/Controller/PayPalVaultingController.php +++ b/src/Controller/PayPalVaultingController.php @@ -21,7 +21,7 @@ public function render() $this->_aViewData['vaultingUserId'] = oxNew(Config::class)->getUserIdForVaulting(); $moduleSettings = $this->getServiceFromContainer(ModuleSettings::class); if ($moduleSettings->isVaultingAllowedForPayPal()) { - $this->_sThisTemplate = '@osc_paypal/frontend/shared/account_vaulting_paypal'; + $this->_sThisTemplate = '@osc_paypal/frontend/account_vaulting_paypal'; } return parent::render(); diff --git a/views/smarty/frontend/blocks/page/account/account_vaulting_card.tpl b/views/smarty/frontend/blocks/page/account/account_vaulting_card.tpl deleted file mode 100644 index ad44237b0..000000000 --- a/views/smarty/frontend/blocks/page/account/account_vaulting_card.tpl +++ /dev/null @@ -1,102 +0,0 @@ -[{capture append="oxidBlock_content"}] - [{assign var="template_title" value="OSC_PAYPAL_VAULTING_MENU_CARD"|oxmultilangassign}] - -

[{oxmultilang ident="OSC_PAYPAL_VAULTING_MENU_CARD"}]

- -
-
-

[{oxmultilang ident="OSC_PAYPAL_VAULTING_SAVE_INSTRUCTION_CARD"}]

-
-
- - -
-
-
-
-
- -
-
-
- - -
- - [{include file="@osc_paypal/frontend/shared/vaultedpaymentsources.tpl"}] - - [{insert name="oxid_tracker" title=$template_title}] -[{/capture}] - -[{capture append="oxidBlock_sidebar"}] - [{include file="page/account/inc/account_menu.tpl" active_link="oscPayPalVaultingCard"}] -[{/capture}] -[{include file="layout/page.tpl" sidebar="Left"}] \ No newline at end of file diff --git a/views/smarty/frontend/blocks/page/account/account_vaulting_paypal.tpl b/views/smarty/frontend/blocks/page/account/account_vaulting_paypal.tpl deleted file mode 100644 index 4eb45776b..000000000 --- a/views/smarty/frontend/blocks/page/account/account_vaulting_paypal.tpl +++ /dev/null @@ -1,67 +0,0 @@ -[{capture append="oxidBlock_content"}] - [{assign var="template_title" value="OSC_PAYPAL_VAULTING_MENU"|oxmultilangassign}] - -

[{oxmultilang ident="OSC_PAYPAL_VAULTING_MENU"}]

- -
-
-

[{oxmultilang ident="OSC_PAYPAL_VAULTING_SAVE_INSTRUCTION"}]

-
-
- - -
-
-
- - - [{include file="@osc_paypal/frontend/shared/vaultedpaymentsources.tpl"}] - - [{insert name="oxid_tracker" title=$template_title}] -[{/capture}] - -[{capture append="oxidBlock_sidebar"}] - [{include file="page/account/inc/account_menu.tpl" active_link="oscPayPalVaulting"}] -[{/capture}] -[{include file="layout/page.tpl" sidebar="Left"}] \ No newline at end of file diff --git a/views/smarty/frontend/shared/page/account/account_vaulting_paypal.tpl b/views/smarty/frontend/shared/page/account/account_vaulting_paypal.tpl index 4eb45776b..63583fe02 100644 --- a/views/smarty/frontend/shared/page/account/account_vaulting_paypal.tpl +++ b/views/smarty/frontend/shared/page/account/account_vaulting_paypal.tpl @@ -16,34 +16,34 @@ +
+
+ + {% include "@osc_paypal/frontend/vaultedpaymentsources.html.twig" %} + {% endblock %} +
+ {{ insert_tracker({title: template_title}) }} +{% endcapture %} + +{% include "layout/page.html.twig" %} \ No newline at end of file diff --git a/views/twig/frontend/account_vaulting_paypal.html.twig b/views/twig/frontend/account_vaulting_paypal.html.twig new file mode 100644 index 000000000..30aa19245 --- /dev/null +++ b/views/twig/frontend/account_vaulting_paypal.html.twig @@ -0,0 +1,74 @@ +{% capture append = "oxidBlock_content" %} + {% set template_title = "OSC_PAYPAL_VAULTING_MENU"|translate %} +
+
+ +
+ {% include "page/account/inc/account_menu.html.twig" with {active_link: "oscPayPalVaulting"} %} +
+
+ {% block account_vaulting_paypal %} +
+
+
+

{{ translate({ ident: "OSC_PAYPAL_VAULTING_SAVE_INSTRUCTION" }) }}

+
+
+ + +
+
+
+ + + {% include "@osc_paypal/frontend/vaultedpaymentsources.html.twig" %} +
+ {% endblock %} +
+ {{ insert_tracker({title: template_title}) }} +{% endcapture %} + +{% include "layout/page.html.twig" %} \ No newline at end of file diff --git a/views/twig/frontend/acdc.html.twig b/views/twig/frontend/acdc.html.twig index 0a78f84da..4f1432479 100644 --- a/views/twig/frontend/acdc.html.twig +++ b/views/twig/frontend/acdc.html.twig @@ -18,8 +18,8 @@
{% if oscpaypal_isVaultingPossible %} - - + + {% endif %}
-
    +
      {% for paymentToken in vaultedPaymentSources %} -
    • -
      +
    • + + {% capture name = "detailsApplePayScript" %} + {% if phpstorm %}{% endif %} + {% endcapture %} + {{ script({ include: "https://applepay.cdn-apple.com/jsapi/v1/apple-pay-sdk.js", dynamic: __oxid_include_dynamic }) }} + {{ script({ add: smarty.capture.detailsApplePayScript, dynamic: __oxid_include_dynamic }) }} + {% endhasrights %} +{% endblock %} From 3212be4e28fc7493f4b0824252745b46d10a701c Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Fri, 17 Jan 2025 14:36:26 +0100 Subject: [PATCH 30/30] cleanUp in Smarty --- .../shared/page/details/inc/details_productmain_tobasket.tpl | 1 - 1 file changed, 1 deletion(-) diff --git a/views/smarty/frontend/shared/page/details/inc/details_productmain_tobasket.tpl b/views/smarty/frontend/shared/page/details/inc/details_productmain_tobasket.tpl index 2cd896fda..097fbcc9f 100644 --- a/views/smarty/frontend/shared/page/details/inc/details_productmain_tobasket.tpl +++ b/views/smarty/frontend/shared/page/details/inc/details_productmain_tobasket.tpl @@ -1,5 +1,4 @@ [{assign var="config" value=$oViewConf->getPayPalCheckoutConfig()}] [{if $blCanBuy && !$oDetailsProduct->isNotBuyable() && $config->isActive() && !$oViewConf->isPayPalExpressSessionActive() && $config->showPayPalProductDetailsButton()}] [{include file="@osc_paypal/frontend/shared/paymentbuttons.tpl" buttonId="PayPalButtonProductMain" buttonClass="paypal-button-wrapper large" aid=$oDetailsProduct->oxarticles__oxid->value}] - [{*include file="@osc_paypal/frontend/shared/googlepay.tpl" buttonId="PayPalButtonProductMain" buttonClass="paypal-button-wrapper large" aid=$oDetailsProduct->oxarticles__oxid->value*}] [{/if}]