Plugin Directory

Changeset 3262577


Ignore:
Timestamp:
03/27/2025 07:46:57 AM (12 months ago)
Author:
danielhuesken
Message:

Update develop branch for release 8.0.0

Location:
mollie-payments-for-woocommerce/trunk
Files:
98 added
13 deleted
66 edited

Legend:

Unmodified
Added
Removed
  • mollie-payments-for-woocommerce/trunk/inc/utils.php

    r3191126 r3262577  
    166166function mollieWooCommerceIsMollieGateway($gateway)
    167167{
    168     if (strpos($gateway, 'mollie_wc_gateway_') !== false) {
     168    if (
     169        (is_string($gateway) && strpos($gateway, 'mollie_wc_gateway_') !== false)
     170        || (is_object($gateway) && strpos($gateway->id, 'mollie_wc_gateway_') !== false)
     171    ) {
    169172        return true;
    170173    }
  • mollie-payments-for-woocommerce/trunk/mollie-payments-for-woocommerce.php

    r3242448 r3262577  
    55 * Plugin URI: https://www.mollie.com
    66 * Description: Accept payments in WooCommerce with the official Mollie plugin
    7  * Version: 7.10.0
     7 * Version: 8.0.0
    88 * Author: Mollie
    99 * Author URI: https://www.mollie.com
     
    1414 * License: GPLv2 or later
    1515 * WC requires at least: 3.9
    16  * WC tested up to: 9.5
     16 * WC tested up to: 9.7
    1717 * Requires PHP: 7.4
    1818 * Requires Plugins: woocommerce
     
    9797function initialize()
    9898{
    99     try {
    100         require_once __DIR__ . '/inc/functions.php';
    101         if (!mollie_wc_plugin_autoload()) {
    102             return;
     99    static $package;
     100    if (!$package) {
     101        try {
     102            require_once __DIR__ . '/inc/functions.php';
     103            if (!mollie_wc_plugin_autoload()) {
     104                return;
     105            }
     106            $checker = new ConstraintsChecker();
     107            $meetRequirements = $checker->handleActivation();
     108            if (!$meetRequirements) {
     109                $nextScheduledTime = wp_next_scheduled('pending_payment_confirmation_check');
     110                if ($nextScheduledTime) {
     111                    wp_unschedule_event($nextScheduledTime, 'pending_payment_confirmation_check');
     112                }
     113                return;
     114            }
     115            // Initialize plugin.
     116            $properties = PluginProperties::new(__FILE__);
     117            $package = Package::new($properties);
     118            $modules = (require __DIR__ . '/inc/modules.php')();
     119            $modules = apply_filters('mollie_wc_plugin_modules', $modules);
     120            foreach ($modules as $module) {
     121                $package->addModule($module);
     122            }
     123            $package->boot();
     124        } catch (Throwable $throwable) {
     125            handleException($throwable);
    103126        }
    104         $checker = new ConstraintsChecker();
    105         $meetRequirements = $checker->handleActivation();
    106         if (!$meetRequirements) {
    107             $nextScheduledTime = wp_next_scheduled('pending_payment_confirmation_check');
    108             if ($nextScheduledTime) {
    109                 wp_unschedule_event($nextScheduledTime, 'pending_payment_confirmation_check');
    110             }
    111             return;
    112         }
    113         // Initialize plugin.
    114         $properties = PluginProperties::new(__FILE__);
    115         $bootstrap = Package::new($properties);
    116         $modules = [new ActivationModule(__FILE__, $properties->get('version')), new NoticeModule(), new SharedModule(), new SDKModule(), new SettingsModule(), new LogModule('mollie-payments-for-woocommerce-'), new AssetsModule(), new GatewayModule(), new VoucherModule(), new PaymentModule(), new MerchantCaptureModule(), new UninstallModule()];
    117         $modules = apply_filters('mollie_wc_plugin_modules', $modules);
    118         foreach ($modules as $module) {
    119             $bootstrap->addModule($module);
    120         }
    121         $bootstrap->boot();
    122     } catch (Throwable $throwable) {
    123         handleException($throwable);
    124127    }
     128    /** @var Package $package */
     129    return $package;
    125130}
    126 add_action('plugins_loaded', __NAMESPACE__ . '\initialize');
     131add_action(
     132    /**
     133     * @throws Throwable
     134     */
     135    'plugins_loaded',
     136    static function () {
     137        initialize();
     138    }
     139);
  • mollie-payments-for-woocommerce/trunk/public/js/mollieBlockIndex.min.js

    r3242448 r3262577  
    338338  return wcSettings.currency.priceFormat.replace('%1$s', wcSettings.currency.symbol).replace('%2$s', price.toFixed(wcSettings.currency.precision).replace('.', wcSettings.currency.decimalSeparator));
    339339}
    340 function loadCachedAvailableGateways() {
    341   var storedData = localStorage.getItem('cachedAvailableGateways');
    342   if (storedData) {
    343     try {
    344       cachedAvailableGateways = JSON.parse(storedData);
    345     } catch (e) {
    346       console.warn('Error parsing cachedAvailableGateways from localStorage:', e);
    347       cachedAvailableGateways = {};
    348     }
    349   }
    350 }
    351 function saveCachedAvailableGateways() {
    352   localStorage.setItem('cachedAvailableGateways', JSON.stringify(cachedAvailableGateways));
    353 }
    354 loadCachedAvailableGateways();
    355340function setAvailableGateways(country, currencyCode, data) {
    356341  cachedAvailableGateways = _objectSpread(_objectSpread({}, cachedAvailableGateways), data);
    357   saveCachedAvailableGateways();
    358342}
    359 function useMollieAvailableGateways(billing, currencyCode, cartTotal, filters, ajaxUrl, jQuery, item) {
     343function useMollieAvailableGateways(billing, currencyCode, cartTotal, filters, ajaxUrl) {
    360344  var country = billing.country;
    361345  var code = currencyCode;
     
    366350  }
    367351  wp.element.useEffect(function () {
    368     if (!country || !item) return;
     352    if (!country) return;
    369353    var currencyCode = code;
    370354    var cartTotal = value;
     
    373357      return;
    374358    }
    375     jQuery.ajax({
    376       url: ajaxUrl,
     359    fetch(ajaxUrl, {
    377360      method: 'POST',
    378       data: {
     361      headers: {
     362        "Content-Type": "application/x-www-form-urlencoded"
     363      },
     364      body: new URLSearchParams({
    379365        action: 'mollie_checkout_blocks_canmakepayment',
    380         currentGateway: item,
    381366        currency: currencyCode,
    382367        billingCountry: country,
    383368        cartTotal: cartTotal,
    384369        paymentLocale: filters.paymentLocale
    385       },
    386       success: function success(response) {
    387         setAvailableGateways(country, currencyCode, response.data);
    388         var cartTotals = wp.data.select('wc/store/cart').getCartTotals();
    389         // Dispatch them again to trigger a re-render:
    390         wp.data.dispatch('wc/store/cart').setCartData(_objectSpread({}, cartTotals));
    391       },
    392       error: function error(jqXHR, textStatus, errorThrown) {
    393         console.warn('Failed to fetch available gateways:', textStatus, errorThrown);
    394       }
     370      })
     371    }).then(function (response) {
     372      return response.json();
     373    }).then(function (data) {
     374      setAvailableGateways(country, currencyCode, data.data);
     375      var cartTotals = wp.data.select('wc/store/cart').getCartTotals();
     376      // Dispatch them again to trigger a re-render:
     377      wp.data.dispatch('wc/store/cart').setCartData(_objectSpread({}, cartTotals));
    395378    });
    396   }, [billing, currencyCode, filters.paymentLocale, ajaxUrl, jQuery, item]);
     379  }, [billing, currencyCode, filters.paymentLocale]);
    397380  return cachedAvailableGateways;
    398381}
     
    404387    cartTotal = _ref.cartTotal,
    405388    filters = _ref.filters,
    406     ajaxUrl = _ref.ajaxUrl,
    407     jQuery = _ref.jQuery,
    408     item = _ref.item;
    409   useMollieAvailableGateways(billing, currencyCode, cartTotal, filters, ajaxUrl, jQuery, item);
     389    ajaxUrl = _ref.ajaxUrl;
     390  useMollieAvailableGateways(billing, currencyCode, cartTotal, filters, ajaxUrl);
    410391  return null;
    411392}
     
    523504  useEffect(function () {
    524505    var onProcessingPayment = function onProcessingPayment() {
     506      var data = _defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty({
     507        payment_method: activePaymentMethod,
     508        payment_method_title: item.title
     509      }, issuerKey, selectedIssuer), "billing_phone", inputPhone), "billing_company_billie", inputCompany), "billing_birthdate", inputBirthdate), "cardToken", '');
    525510      var tokenVal = jQuery('.mollie-components > input').val();
     511      if (tokenVal) {
     512        data.cardToken = tokenVal;
     513      }
    526514      return {
    527515        type: responseTypes.SUCCESS,
    528516        meta: {
    529           paymentMethodData: _defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty({
    530             payment_method: activePaymentMethod,
    531             payment_method_title: item.title
    532           }, issuerKey, selectedIssuer), "billing_phone", inputPhone), "billing_company_billie", inputCompany), "billing_birthdate", inputBirthdate), "cardToken", tokenVal)
     517          paymentMethodData: data
    533518        }
    534519      };
     
    682667  var item = _ref2.item,
    683668    filters = _ref2.filters,
    684     ajaxUrl = _ref2.ajaxUrl,
    685     jQuery = _ref2.jQuery;
     669    ajaxUrl = _ref2.ajaxUrl;
    686670  var cartData = wp.data.useSelect(function (select) {
    687671    return select('wc/store/cart').getCartData();
     
    700684    filters: filters,
    701685    ajaxUrl: ajaxUrl,
    702     jQuery: jQuery,
    703     item: item,
    704686    cartTotal: cartTotal
    705687  }));
    706688};
    707689var molliePaymentMethod = function molliePaymentMethod(useEffect, ajaxUrl, filters, gatewayData, availableGateways, item, jQuery, requiredFields, isCompanyFieldVisible, isPhoneFieldVisible) {
    708   document.addEventListener('mollie_components_ready_to_submit', function () {
    709     onSubmitLocal();
    710   });
     690  if (item.name === "mollie_wc_gateway_creditcard") {
     691    document.addEventListener('mollie_components_ready_to_submit', function () {
     692      onSubmitLocal();
     693    });
     694  }
    711695  function creditcardSelectedEvent() {
    712696    if (item.name === "mollie_wc_gateway_creditcard") {
    713697      document.documentElement.dispatchEvent(creditCardSelected);
    714698    }
    715   }
    716 
    717   // On first load, if availableGateways is not empty, store it
    718   if (_.isEmpty(cachedAvailableGateways) && !_.isEmpty(availableGateways)) {
    719     cachedAvailableGateways = availableGateways;
    720     saveCachedAvailableGateways();
    721699  }
    722700  return {
     
    725703      item: item,
    726704      ajaxUrl: ajaxUrl,
    727       jQuery: jQuery,
    728705      filters: filters
    729706    }),
     
    747724        return true;
    748725      }
    749       loadCachedAvailableGateways();
    750726      var currencyCode = cartTotals === null || cartTotals === void 0 ? void 0 : cartTotals.currency_code;
    751727      var country = billingData === null || billingData === void 0 ? void 0 : billingData.country;
     
    757733      creditcardSelectedEvent();
    758734      if (!cachedAvailableGateways.hasOwnProperty(currentFilterKey)) {
    759         return false;
    760       }
    761       return cachedAvailableGateways[currentFilterKey].hasOwnProperty(item.name);
     735        cachedAvailableGateways = _objectSpread(_objectSpread({}, cachedAvailableGateways), availableGateways);
     736      }
     737      if (availableGateways.hasOwnProperty(currentFilterKey) && availableGateways[currentFilterKey].hasOwnProperty(item.name)) {
     738        return true;
     739      }
     740      if (cachedAvailableGateways.hasOwnProperty(currentFilterKey) && cachedAvailableGateways[currentFilterKey].hasOwnProperty(item.name)) {
     741        return true;
     742      }
     743      return false;
    762744    },
    763745    ariaLabel: item.ariaLabel,
     
    857839  var useEffect = wp.element.useEffect;
    858840  var isAppleSession = typeof window.ApplePaySession === "function";
    859   localStorage.removeItem('cachedAvailableGateways');
    860841  function getPhoneField() {
    861842    var phoneFieldDataset = document.querySelector('[data-show-phone-field]');
     
    911892/******/ })()
    912893;
    913 //# sourceMappingURL=data:application/json;charset=utf-8;base64,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dUIsTUFBQyxDQUFDO1VBQ25DZ1MsSUFBSSxlQUFFMUwsS0FBQSxDQUFBQyxhQUFBLENBQUNLLDZFQUE2QixNQUFDLENBQUM7VUFDdEM0TCxTQUFTLEVBQUUsV0FBVztVQUN0Qk4sY0FBYyxFQUFFLFNBQUFBLGVBQUE7WUFBQSxPQUFNLElBQUk7VUFBQTtVQUMxQkQsZUFBZSxFQUFFLDRCQUE0QjtVQUM3QzJCLFNBQVMsRUFBRSw0QkFBNEI7VUFDdkNuQixRQUFRLEVBQUU7WUFDTkMsUUFBUSxFQUFFLENBQUMsVUFBVSxDQUFDO1lBQ3RCclIsS0FBSyxFQUFFLENBQUMsUUFBUSxFQUFFLGNBQWM7VUFDcEM7UUFDSixDQUFDLENBQUM7TUFDTjtNQUNBO0lBQ0o7SUFDQWtTLFFBQVEsQ0FBQyxDQUFDO0VBQ2QsQ0FBQyxDQUFDO0FBQ04sQ0FBQyxFQUNIbFQsTUFBTSxFQUFFc1MsRUFBRSxDQUFDLEMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9tb2xsaWUtcGF5bWVudHMtZm9yLXdvb2NvbW1lcmNlLy4vcmVzb3VyY2VzL2pzL2FwcGxlUGF5RXJyb3IuanMiLCJ3ZWJwYWNrOi8vbW9sbGllLXBheW1lbnRzLWZvci13b29jb21tZXJjZS8uL3Jlc291cmNlcy9qcy9hcHBsZVBheVJlcXVlc3QuanMiLCJ3ZWJwYWNrOi8vbW9sbGllLXBheW1lbnRzLWZvci13b29jb21tZXJjZS8uL3Jlc291cmNlcy9qcy9ibG9ja3MvQXBwbGVQYXlCdXR0b25Db21wb25lbnQuanMiLCJ3ZWJwYWNrOi8vbW9sbGllLXBheW1lbnRzLWZvci13b29jb21tZXJjZS8uL3Jlc291cmNlcy9qcy9ibG9ja3MvQXBwbGVQYXlCdXR0b25FZGl0b3JDb21wb25lbnQuanMiLCJ3ZWJwYWNrOi8vbW9sbGllLXBheW1lbnRzLWZvci13b29jb21tZXJjZS8uL3Jlc291cmNlcy9qcy9ibG9ja3MvbW9sbGllUGF5bWVudE1ldGhvZC5qcyIsIndlYnBhY2s6Ly9tb2xsaWUtcGF5bWVudHMtZm9yLXdvb2NvbW1lcmNlL3dlYnBhY2svYm9vdHN0cmFwIiwid2VicGFjazovL21vbGxpZS1wYXltZW50cy1mb3Itd29vY29tbWVyY2Uvd2VicGFjay9ydW50aW1lL2RlZmluZSBwcm9wZXJ0eSBnZXR0ZXJzIiwid2VicGFjazovL21vbGxpZS1wYXltZW50cy1mb3Itd29vY29tbWVyY2Uvd2VicGFjay9ydW50aW1lL2hhc093blByb3BlcnR5IHNob3J0aGFuZCIsIndlYnBhY2s6Ly9tb2xsaWUtcGF5bWVudHMtZm9yLXdvb2NvbW1lcmNlL3dlYnBhY2svcnVudGltZS9tYWtlIG5hbWVzcGFjZSBvYmplY3QiLCJ3ZWJwYWNrOi8vbW9sbGllLXBheW1lbnRzLWZvci13b29jb21tZXJjZS8uL3Jlc291cmNlcy9qcy9tb2xsaWVCbG9ja0luZGV4LmpzIl0sInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBmdW5jdGlvbiBjcmVhdGVBcHBsZUVycm9ycyhlcnJvcnMpIHtcbiAgICBjb25zdCBlcnJvckxpc3QgPSBbXVxuICAgIGZvciAoY29uc3QgZXJyb3Igb2YgZXJyb3JzKSB7XG4gICAgICAgIGNvbnN0IHtjb250YWN0RmllbGQgPSBudWxsLCBjb2RlID0gbnVsbCwgbWVzc2FnZSA9IG51bGx9ID0gZXJyb3JcbiAgICAgICAgY29uc3QgYXBwbGVFcnJvciA9IGNvbnRhY3RGaWVsZCA/IG5ldyBBcHBsZVBheUVycm9yKGNvZGUsIGNvbnRhY3RGaWVsZCwgbWVzc2FnZSkgOiBuZXcgQXBwbGVQYXlFcnJvcihjb2RlKVxuICAgICAgICBlcnJvckxpc3QucHVzaChhcHBsZUVycm9yKVxuICAgIH1cblxuICAgIHJldHVybiBlcnJvckxpc3Rcbn1cbiIsImV4cG9ydCBjb25zdCByZXF1ZXN0ID0gKGNvdW50cnlDb2RlLCBjdXJyZW5jeUNvZGUsIHRvdGFsTGFiZWwsIHN1YnRvdGFsKSA9PiB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgY291bnRyeUNvZGU6IGNvdW50cnlDb2RlLFxuICAgICAgICBjdXJyZW5jeUNvZGU6IGN1cnJlbmN5Q29kZSxcbiAgICAgICAgc3VwcG9ydGVkTmV0d29ya3M6IFsnYW1leCcsICdtYWVzdHJvJywgJ21hc3RlckNhcmQnLCAndmlzYScsICd2UGF5J10sXG4gICAgICAgIG1lcmNoYW50Q2FwYWJpbGl0aWVzOiBbJ3N1cHBvcnRzM0RTJ10sXG4gICAgICAgIHNoaXBwaW5nVHlwZTogJ3NoaXBwaW5nJyxcbiAgICAgICAgcmVxdWlyZWRCaWxsaW5nQ29udGFjdEZpZWxkczogW1xuICAgICAgICAgICAgJ3Bvc3RhbEFkZHJlc3MnLFxuICAgICAgICAgICAgJ2VtYWlsJ1xuICAgICAgICBdLFxuICAgICAgICByZXF1aXJlZFNoaXBwaW5nQ29udGFjdEZpZWxkczogW1xuICAgICAgICAgICAgJ3Bvc3RhbEFkZHJlc3MnLFxuICAgICAgICAgICAgJ2VtYWlsJ1xuICAgICAgICBdLFxuICAgICAgICB0b3RhbDoge1xuICAgICAgICAgICAgbGFiZWw6IHRvdGFsTGFiZWwsXG4gICAgICAgICAgICBhbW91bnQ6IHN1YnRvdGFsLFxuICAgICAgICAgICAgdHlwZTogJ2ZpbmFsJ1xuICAgICAgICB9XG4gICAgfVxufVxuIiwiaW1wb3J0IHtyZXF1ZXN0fSBmcm9tIFwiLi4vYXBwbGVQYXlSZXF1ZXN0XCI7XG5pbXBvcnQge2NyZWF0ZUFwcGxlRXJyb3JzfSBmcm9tIFwiLi4vYXBwbGVQYXlFcnJvclwiO1xuXG5leHBvcnQgY29uc3QgQXBwbGVQYXlCdXR0b25Db21wb25lbnQgPSAoeyBidXR0b25BdHRyaWJ1dGVzID0ge30gfSkgPT4ge1xuICAgIGNvbnN0IG1vbGxpZUFwcGxlUGF5QmxvY2tEYXRhQ2FydCA9IHdpbmRvdy5tb2xsaWVBcHBsZVBheUJsb2NrRGF0YUNhcnQgfHwgd2luZG93Lm1vbGxpZUJsb2NrRGF0YS5tb2xsaWVBcHBsZVBheUJsb2NrRGF0YUNhcnRcbiAgICBjb25zdCBub25jZSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwid29vY29tbWVyY2UtcHJvY2Vzcy1jaGVja291dC1ub25jZVwiKS52YWx1ZVxuICAgIGxldCB1cGRhdGVkQ29udGFjdEluZm8gPSBbXVxuICAgIGxldCByZWRpcmVjdGlvblVybCA9ICcnXG4gICAgY29uc3Qge1xuICAgICAgICBwcm9kdWN0OiB7bmVlZFNoaXBwaW5nID0gdHJ1ZSwgc3VidG90YWx9LFxuICAgICAgICBzaG9wOiB7Y291bnRyeUNvZGUsIGN1cnJlbmN5Q29kZSA9ICdFVVInLCB0b3RhbExhYmVsID0gJyd9LFxuICAgICAgICBhamF4VXJsLFxuICAgIH0gPSBtb2xsaWVBcHBsZVBheUJsb2NrRGF0YUNhcnRcbiAgICBjb25zdCBzdHlsZSA9IHtcbiAgICAgICAgaGVpZ2h0OiBgJHtidXR0b25BdHRyaWJ1dGVzLmhlaWdodCB8fCA0OH1weGAsXG4gICAgICAgIGJvcmRlclJhZGl1czogYCR7YnV0dG9uQXR0cmlidXRlcy5ib3JkZXJSYWRpdXMgfHwgNH1weGBcbiAgICB9XG5cbiAgICBjb25zdCBmaW5kU2VsZWN0ZWRTaGlwcGluZ01ldGhvZCA9IChzaGlwcGluZ1JhdGVzKSA9PiB7XG4gICAgICAgIGxldCBzaGlwcGluZ1JhdGUgPSBzaGlwcGluZ1JhdGVzLmZpbmQoKHNoaXBwaW5nTWV0aG9kKSA9PiBzaGlwcGluZ01ldGhvZC5zZWxlY3RlZCA9PT0gdHJ1ZSlcbiAgICAgICAgY29uc3QgYXBwbGVGb3JtYXR0ZWRSYXRlID0ge1xuICAgICAgICAgICAgYW1vdW50OiAnJyxcbiAgICAgICAgICAgIGRldGFpbDogJycsXG4gICAgICAgICAgICBsYWJlbDogc2hpcHBpbmdSYXRlLm5hbWUsXG4gICAgICAgICAgICBpZGVudGlmaWVyOiBzaGlwcGluZ1JhdGUucmF0ZV9pZCxcbiAgICAgICAgICAgIHNlbGVjdGVkOiBzaGlwcGluZ1JhdGUuc2VsZWN0ZWQsXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHNoaXBwaW5nUmF0ZSA/IGFwcGxlRm9ybWF0dGVkUmF0ZSA6ICcnXG4gICAgfVxuXG4gICAgbGV0IGFwcGxlUGF5U2Vzc2lvbiA9ICgpID0+IHtcbiAgICAgICAgY29uc3Qgc2Vzc2lvbiA9IG5ldyBBcHBsZVBheVNlc3Npb24oMywgcmVxdWVzdChjb3VudHJ5Q29kZSwgY3VycmVuY3lDb2RlLCB0b3RhbExhYmVsLCBzdWJ0b3RhbCkpXG4gICAgICAgIGNvbnN0IHN0b3JlID0gd3AuZGF0YS5zZWxlY3QoJ3djL3N0b3JlL2NhcnQnKVxuICAgICAgICBjb25zdCBzaGlwcGluZ1JhdGVzID0gc3RvcmUuZ2V0U2hpcHBpbmdSYXRlcygpPy5bMF0/LnNoaXBwaW5nX3JhdGVzO1xuICAgICAgICBsZXQgc2VsZWN0ZWRTaGlwcGluZ01ldGhvZCA9ICcnO1xuICAgICAgICBpZiAoc2hpcHBpbmdSYXRlcyAmJiBzaGlwcGluZ1JhdGVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHNlbGVjdGVkU2hpcHBpbmdNZXRob2QgPSBmaW5kU2VsZWN0ZWRTaGlwcGluZ01ldGhvZChzaGlwcGluZ1JhdGVzLCBzZWxlY3RlZFNoaXBwaW5nTWV0aG9kKTtcbiAgICAgICAgfVxuICAgICAgICAgICAgc2Vzc2lvbi5vbnNoaXBwaW5nbWV0aG9kc2VsZWN0ZWQgPSBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAgICAgICAgIGpRdWVyeS5hamF4KHtcbiAgICAgICAgICAgICAgICB1cmw6IGFqYXhVcmwsXG4gICAgICAgICAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgICAgICAgICAgZGF0YToge1xuICAgICAgICAgICAgICAgICAgICBhY3Rpb246ICdtb2xsaWVfYXBwbGVfcGF5X3VwZGF0ZV9zaGlwcGluZ19tZXRob2QnLFxuICAgICAgICAgICAgICAgICAgICBzaGlwcGluZ01ldGhvZDogZXZlbnQuc2hpcHBpbmdNZXRob2QsXG4gICAgICAgICAgICAgICAgICAgIGNhbGxlclBhZ2U6ICdjYXJ0JyxcbiAgICAgICAgICAgICAgICAgICAgc2ltcGxpZmllZENvbnRhY3Q6IHVwZGF0ZWRDb250YWN0SW5mbyxcbiAgICAgICAgICAgICAgICAgICAgJ3dvb2NvbW1lcmNlLXByb2Nlc3MtY2hlY2tvdXQtbm9uY2UnOiBub25jZSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHN1Y2Nlc3M6IChhcHBsZVBheVNoaXBwaW5nTWV0aG9kVXBkYXRlLCB0ZXh0U3RhdHVzLCBqcVhIUikgPT4ge1xuICAgICAgICAgICAgICAgICAgICBsZXQgcmVzcG9uc2UgPSBhcHBsZVBheVNoaXBwaW5nTWV0aG9kVXBkYXRlLmRhdGFcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0ZWRTaGlwcGluZ01ldGhvZCA9IGV2ZW50LnNoaXBwaW5nTWV0aG9kXG4gICAgICAgICAgICAgICAgICAgIGlmIChhcHBsZVBheVNoaXBwaW5nTWV0aG9kVXBkYXRlLnN1Y2Nlc3MgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNwb25zZS5lcnJvcnMgPSBjcmVhdGVBcHBsZUVycm9ycyhyZXNwb25zZS5lcnJvcnMpXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb21wbGV0ZVNoaXBwaW5nTWV0aG9kU2VsZWN0aW9uKHJlc3BvbnNlKVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgZXJyb3I6IChqcVhIUiwgdGV4dFN0YXR1cywgZXJyb3JUaHJvd24pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKHRleHRTdGF0dXMsIGVycm9yVGhyb3duKVxuICAgICAgICAgICAgICAgICAgICBzZXNzaW9uLmFib3J0KClcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgICAgICBzZXNzaW9uLm9uc2hpcHBpbmdjb250YWN0c2VsZWN0ZWQgPSBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAgICAgICAgIGpRdWVyeS5hamF4KHtcbiAgICAgICAgICAgICAgICB1cmw6IGFqYXhVcmwsXG4gICAgICAgICAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgICAgICAgICAgZGF0YToge1xuICAgICAgICAgICAgICAgICAgICBhY3Rpb246ICdtb2xsaWVfYXBwbGVfcGF5X3VwZGF0ZV9zaGlwcGluZ19jb250YWN0JyxcbiAgICAgICAgICAgICAgICAgICAgc2ltcGxpZmllZENvbnRhY3Q6IGV2ZW50LnNoaXBwaW5nQ29udGFjdCxcbiAgICAgICAgICAgICAgICAgICAgY2FsbGVyUGFnZTogJ2NhcnQnLFxuICAgICAgICAgICAgICAgICAgICBuZWVkU2hpcHBpbmc6IG5lZWRTaGlwcGluZyxcbiAgICAgICAgICAgICAgICAgICAgJ3dvb2NvbW1lcmNlLXByb2Nlc3MtY2hlY2tvdXQtbm9uY2UnOiBub25jZSxcbiAgICAgICAgICAgICAgICAgICAgc2hpcHBpbmdNZXRob2Q6IHNlbGVjdGVkU2hpcHBpbmdNZXRob2QsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBzdWNjZXNzOiAoYXBwbGVQYXlTaGlwcGluZ0NvbnRhY3RVcGRhdGUsIHRleHRTdGF0dXMsIGpxWEhSKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGxldCByZXNwb25zZSA9IGFwcGxlUGF5U2hpcHBpbmdDb250YWN0VXBkYXRlLmRhdGFcbiAgICAgICAgICAgICAgICAgICAgdXBkYXRlZENvbnRhY3RJbmZvID0gZXZlbnQuc2hpcHBpbmdDb250YWN0XG4gICAgICAgICAgICAgICAgICAgIGlmIChhcHBsZVBheVNoaXBwaW5nQ29udGFjdFVwZGF0ZS5zdWNjZXNzID09PSBmYWxzZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2UuZXJyb3JzID0gY3JlYXRlQXBwbGVFcnJvcnMocmVzcG9uc2UuZXJyb3JzKVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChyZXNwb25zZS5uZXdTaGlwcGluZ01ldGhvZHMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdGVkU2hpcHBpbmdNZXRob2QgPSByZXNwb25zZS5uZXdTaGlwcGluZ01ldGhvZHNbMF1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbXBsZXRlU2hpcHBpbmdDb250YWN0U2VsZWN0aW9uKHJlc3BvbnNlKVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgZXJyb3I6IChqcVhIUiwgdGV4dFN0YXR1cywgZXJyb3JUaHJvd24pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKHRleHRTdGF0dXMsIGVycm9yVGhyb3duKVxuICAgICAgICAgICAgICAgICAgICBzZXNzaW9uLmFib3J0KClcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgICAgICBzZXNzaW9uLm9udmFsaWRhdGVtZXJjaGFudCA9IChhcHBsZVBheVZhbGlkYXRlTWVyY2hhbnRFdmVudCkgPT4ge1xuICAgICAgICAgICAgalF1ZXJ5LmFqYXgoe1xuICAgICAgICAgICAgICAgIHVybDogYWpheFVybCxcbiAgICAgICAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICAgICAgICBkYXRhOiB7XG4gICAgICAgICAgICAgICAgICAgIGFjdGlvbjogJ21vbGxpZV9hcHBsZV9wYXlfdmFsaWRhdGlvbicsXG4gICAgICAgICAgICAgICAgICAgIHZhbGlkYXRpb25Vcmw6IGFwcGxlUGF5VmFsaWRhdGVNZXJjaGFudEV2ZW50LnZhbGlkYXRpb25VUkwsXG4gICAgICAgICAgICAgICAgICAgICd3b29jb21tZXJjZS1wcm9jZXNzLWNoZWNrb3V0LW5vbmNlJzogbm9uY2UsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBzdWNjZXNzOiAobWVyY2hhbnRTZXNzaW9uLCB0ZXh0U3RhdHVzLCBqcVhIUikgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAobWVyY2hhbnRTZXNzaW9uLnN1Y2Nlc3MgPT09IHRydWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb24uY29tcGxldGVNZXJjaGFudFZhbGlkYXRpb24oSlNPTi5wYXJzZShtZXJjaGFudFNlc3Npb24uZGF0YSkpXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4obWVyY2hhbnRTZXNzaW9uLmRhdGEpXG4gICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uLmFib3J0KClcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgZXJyb3I6IChqcVhIUiwgdGV4dFN0YXR1cywgZXJyb3JUaHJvd24pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKHRleHRTdGF0dXMsIGVycm9yVGhyb3duKVxuICAgICAgICAgICAgICAgICAgICBzZXNzaW9uLmFib3J0KClcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgICAgICBzZXNzaW9uLm9ucGF5bWVudGF1dGhvcml6ZWQgPSAoQXBwbGVQYXlQYXltZW50KSA9PiB7XG4gICAgICAgICAgICBjb25zdCB7YmlsbGluZ0NvbnRhY3QsIHNoaXBwaW5nQ29udGFjdH0gPSBBcHBsZVBheVBheW1lbnQucGF5bWVudFxuXG4gICAgICAgICAgICBqUXVlcnkuYWpheCh7XG4gICAgICAgICAgICAgICAgdXJsOiBhamF4VXJsLFxuICAgICAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgICAgIGRhdGE6IHtcbiAgICAgICAgICAgICAgICAgICAgYWN0aW9uOiAnbW9sbGllX2FwcGxlX3BheV9jcmVhdGVfb3JkZXJfY2FydCcsXG4gICAgICAgICAgICAgICAgICAgIHNoaXBwaW5nQ29udGFjdDogQXBwbGVQYXlQYXltZW50LnBheW1lbnQuc2hpcHBpbmdDb250YWN0LFxuICAgICAgICAgICAgICAgICAgICBiaWxsaW5nQ29udGFjdDogQXBwbGVQYXlQYXltZW50LnBheW1lbnQuYmlsbGluZ0NvbnRhY3QsXG4gICAgICAgICAgICAgICAgICAgIHRva2VuOiBBcHBsZVBheVBheW1lbnQucGF5bWVudC50b2tlbixcbiAgICAgICAgICAgICAgICAgICAgc2hpcHBpbmdNZXRob2Q6IHNlbGVjdGVkU2hpcHBpbmdNZXRob2QsXG4gICAgICAgICAgICAgICAgICAgICdtb2xsaWUtcGF5bWVudHMtZm9yLXdvb2NvbW1lcmNlX2lzc3Vlcl9hcHBsZXBheSc6ICdhcHBsZXBheScsXG4gICAgICAgICAgICAgICAgICAgICd3b29jb21tZXJjZS1wcm9jZXNzLWNoZWNrb3V0LW5vbmNlJzogbm9uY2UsXG4gICAgICAgICAgICAgICAgICAgICdiaWxsaW5nX2ZpcnN0X25hbWUnOiBiaWxsaW5nQ29udGFjdC5naXZlbk5hbWUgfHwgJycsXG4gICAgICAgICAgICAgICAgICAgICdiaWxsaW5nX2xhc3RfbmFtZSc6IGJpbGxpbmdDb250YWN0LmZhbWlseU5hbWUgfHwgJycsXG4gICAgICAgICAgICAgICAgICAgICdiaWxsaW5nX2NvbXBhbnknOiAnJyxcbiAgICAgICAgICAgICAgICAgICAgJ2JpbGxpbmdfY291bnRyeSc6IGJpbGxpbmdDb250YWN0LmNvdW50cnlDb2RlIHx8ICcnLFxuICAgICAgICAgICAgICAgICAgICAnYmlsbGluZ19hZGRyZXNzXzEnOiBiaWxsaW5nQ29udGFjdC5hZGRyZXNzTGluZXNbMF0gfHwgJycsXG4gICAgICAgICAgICAgICAgICAgICdiaWxsaW5nX2FkZHJlc3NfMic6IGJpbGxpbmdDb250YWN0LmFkZHJlc3NMaW5lc1sxXSB8fCAnJyxcbiAgICAgICAgICAgICAgICAgICAgJ2JpbGxpbmdfcG9zdGNvZGUnOiBiaWxsaW5nQ29udGFjdC5wb3N0YWxDb2RlIHx8ICcnLFxuICAgICAgICAgICAgICAgICAgICAnYmlsbGluZ19jaXR5JzogYmlsbGluZ0NvbnRhY3QubG9jYWxpdHkgfHwgJycsXG4gICAgICAgICAgICAgICAgICAgICdiaWxsaW5nX3N0YXRlJzogYmlsbGluZ0NvbnRhY3QuYWRtaW5pc3RyYXRpdmVBcmVhIHx8ICcnLFxuICAgICAgICAgICAgICAgICAgICAnYmlsbGluZ19waG9uZSc6IGJpbGxpbmdDb250YWN0LnBob25lTnVtYmVyIHx8ICcwMDAwMDAwMDAwMDAnLFxuICAgICAgICAgICAgICAgICAgICAnYmlsbGluZ19lbWFpbCc6IHNoaXBwaW5nQ29udGFjdC5lbWFpbEFkZHJlc3MgfHwgJycsXG4gICAgICAgICAgICAgICAgICAgICdzaGlwcGluZ19maXJzdF9uYW1lJzogc2hpcHBpbmdDb250YWN0LmdpdmVuTmFtZSB8fCAnJyxcbiAgICAgICAgICAgICAgICAgICAgJ3NoaXBwaW5nX2xhc3RfbmFtZSc6IHNoaXBwaW5nQ29udGFjdC5mYW1pbHlOYW1lIHx8ICcnLFxuICAgICAgICAgICAgICAgICAgICAnc2hpcHBpbmdfY29tcGFueSc6ICcnLFxuICAgICAgICAgICAgICAgICAgICAnc2hpcHBpbmdfY291bnRyeSc6IHNoaXBwaW5nQ29udGFjdC5jb3VudHJ5Q29kZSB8fCAnJyxcbiAgICAgICAgICAgICAgICAgICAgJ3NoaXBwaW5nX2FkZHJlc3NfMSc6IHNoaXBwaW5nQ29udGFjdC5hZGRyZXNzTGluZXNbMF0gfHwgJycsXG4gICAgICAgICAgICAgICAgICAgICdzaGlwcGluZ19hZGRyZXNzXzInOiBzaGlwcGluZ0NvbnRhY3QuYWRkcmVzc0xpbmVzWzFdIHx8ICcnLFxuICAgICAgICAgICAgICAgICAgICAnc2hpcHBpbmdfcG9zdGNvZGUnOiBzaGlwcGluZ0NvbnRhY3QucG9zdGFsQ29kZSB8fCAnJyxcbiAgICAgICAgICAgICAgICAgICAgJ3NoaXBwaW5nX2NpdHknOiBzaGlwcGluZ0NvbnRhY3QubG9jYWxpdHkgfHwgJycsXG4gICAgICAgICAgICAgICAgICAgICdzaGlwcGluZ19zdGF0ZSc6IHNoaXBwaW5nQ29udGFjdC5hZG1pbmlzdHJhdGl2ZUFyZWEgfHwgJycsXG4gICAgICAgICAgICAgICAgICAgICdzaGlwcGluZ19waG9uZSc6IHNoaXBwaW5nQ29udGFjdC5waG9uZU51bWJlciB8fCAnMDAwMDAwMDAwMDAwJyxcbiAgICAgICAgICAgICAgICAgICAgJ3NoaXBwaW5nX2VtYWlsJzogc2hpcHBpbmdDb250YWN0LmVtYWlsQWRkcmVzcyB8fCAnJyxcbiAgICAgICAgICAgICAgICAgICAgJ29yZGVyX2NvbW1lbnRzJzogJycsXG4gICAgICAgICAgICAgICAgICAgICdwYXltZW50X21ldGhvZCc6ICdtb2xsaWVfd2NfZ2F0ZXdheV9hcHBsZXBheScsXG4gICAgICAgICAgICAgICAgICAgICdfd3BfaHR0cF9yZWZlcmVyJzogJy8/d2MtYWpheD11cGRhdGVfb3JkZXJfcmV2aWV3J1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgc3VjY2VzczogKGF1dGhvcml6YXRpb25SZXN1bHQsIHRleHRTdGF0dXMsIGpxWEhSKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGxldCByZXN1bHQgPSBhdXRob3JpemF0aW9uUmVzdWx0LmRhdGFcbiAgICAgICAgICAgICAgICAgICAgaWYgKGF1dGhvcml6YXRpb25SZXN1bHQuc3VjY2VzcyA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVkaXJlY3Rpb25VcmwgPSByZXN1bHRbJ3JldHVyblVybCddO1xuICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbi5jb21wbGV0ZVBheW1lbnQocmVzdWx0WydyZXNwb25zZVRvQXBwbGUnXSlcbiAgICAgICAgICAgICAgICAgICAgICAgIHdpbmRvdy5sb2NhdGlvbi5ocmVmID0gcmVkaXJlY3Rpb25VcmxcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5lcnJvcnMgPSBjcmVhdGVBcHBsZUVycm9ycyhyZXN1bHQuZXJyb3JzKVxuICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbi5jb21wbGV0ZVBheW1lbnQocmVzdWx0KVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBlcnJvcjogKGpxWEhSLCB0ZXh0U3RhdHVzLCBlcnJvclRocm93bikgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4odGV4dFN0YXR1cywgZXJyb3JUaHJvd24pXG4gICAgICAgICAgICAgICAgICAgIHNlc3Npb24uYWJvcnQoKVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9KVxuICAgICAgICB9XG4gICAgICAgIHNlc3Npb24uYmVnaW4oKVxuICAgIH1cblxuICAgIHJldHVybiAoXG4gICAgICAgIDxidXR0b25cbiAgICAgICAgICAgIGlkPVwibW9sbGllX2FwcGxlcGF5X2J1dHRvblwiXG4gICAgICAgICAgICBjbGFzc05hbWU9XCJhcHBsZS1wYXktYnV0dG9uIGFwcGxlLXBheS1idXR0b24tYmxhY2tcIlxuICAgICAgICAgICAgb25DbGljaz17KGV2ZW50KSA9PiB7XG4gICAgICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICBhcHBsZVBheVNlc3Npb24oKTtcbiAgICAgICAgICAgIH19XG4gICAgICAgICAgICBzdHlsZT17c3R5bGV9XG4gICAgICAgID5cbiAgICAgICAgPC9idXR0b24+XG4gICAgKTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgQXBwbGVQYXlCdXR0b25Db21wb25lbnQ7XG4iLCJleHBvcnQgY29uc3QgQXBwbGVQYXlCdXR0b25FZGl0b3JDb21wb25lbnQgPSAoeyBidXR0b25BdHRyaWJ1dGVzID0ge30gfSkgPT4ge1xuICAgIGNvbnN0IHN0eWxlID0ge1xuICAgICAgICBoZWlnaHQ6IGAke2J1dHRvbkF0dHJpYnV0ZXMuaGVpZ2h0IHx8IDQ4fXB4YCxcbiAgICAgICAgYm9yZGVyUmFkaXVzOiBgJHtidXR0b25BdHRyaWJ1dGVzLmJvcmRlclJhZGl1cyB8fCA0fXB4YFxuICAgIH1cblxuICAgIHJldHVybiAoXG4gICAgICAgIDxidXR0b25cbiAgICAgICAgICAgIGlkPVwibW9sbGllX2FwcGxlcGF5X2J1dHRvblwiXG4gICAgICAgICAgICBjbGFzc05hbWU9XCJhcHBsZS1wYXktYnV0dG9uIGFwcGxlLXBheS1idXR0b24tYmxhY2tcIlxuICAgICAgICAgICAgc3R5bGU9e3N0eWxlfVxuICAgICAgICA+XG4gICAgICAgIDwvYnV0dG9uPlxuICAgICk7XG59O1xuZXhwb3J0IGRlZmF1bHQgQXBwbGVQYXlCdXR0b25FZGl0b3JDb21wb25lbnQ7XG4iLCJsZXQgY2FjaGVkQXZhaWxhYmxlR2F0ZXdheXMgPSB7fTtcblxuZnVuY3Rpb24gZm9ybWF0UHJpY2VMaWtlV2MocHJpY2UpIHtcbiAgICAvLyB0b2RvIGFkZCB0aG91c2FuZFNlcGFyYXRvclxuICAgIHJldHVybiB3Y1NldHRpbmdzLmN1cnJlbmN5LnByaWNlRm9ybWF0LnJlcGxhY2UoJyUxJHMnLCB3Y1NldHRpbmdzLmN1cnJlbmN5LnN5bWJvbCkucmVwbGFjZSgnJTIkcycscHJpY2UudG9GaXhlZCh3Y1NldHRpbmdzLmN1cnJlbmN5LnByZWNpc2lvbikucmVwbGFjZSgnLicsIHdjU2V0dGluZ3MuY3VycmVuY3kuZGVjaW1hbFNlcGFyYXRvcikpO1xufVxuXG5mdW5jdGlvbiBsb2FkQ2FjaGVkQXZhaWxhYmxlR2F0ZXdheXMoKSB7XG4gICAgY29uc3Qgc3RvcmVkRGF0YSA9IGxvY2FsU3RvcmFnZS5nZXRJdGVtKCdjYWNoZWRBdmFpbGFibGVHYXRld2F5cycpO1xuICAgIGlmIChzdG9yZWREYXRhKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjYWNoZWRBdmFpbGFibGVHYXRld2F5cyA9IEpTT04ucGFyc2Uoc3RvcmVkRGF0YSk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIGNvbnNvbGUud2FybignRXJyb3IgcGFyc2luZyBjYWNoZWRBdmFpbGFibGVHYXRld2F5cyBmcm9tIGxvY2FsU3RvcmFnZTonLCBlKTtcbiAgICAgICAgICAgIGNhY2hlZEF2YWlsYWJsZUdhdGV3YXlzID0ge307XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmZ1bmN0aW9uIHNhdmVDYWNoZWRBdmFpbGFibGVHYXRld2F5cygpIHtcbiAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbSgnY2FjaGVkQXZhaWxhYmxlR2F0ZXdheXMnLCBKU09OLnN0cmluZ2lmeShjYWNoZWRBdmFpbGFibGVHYXRld2F5cykpO1xufVxuXG5sb2FkQ2FjaGVkQXZhaWxhYmxlR2F0ZXdheXMoKTtcbmZ1bmN0aW9uIHNldEF2YWlsYWJsZUdhdGV3YXlzKGNvdW50cnksIGN1cnJlbmN5Q29kZSwgZGF0YSkge1xuICAgIGNhY2hlZEF2YWlsYWJsZUdhdGV3YXlzID0ge1xuICAgICAgICAuLi5jYWNoZWRBdmFpbGFibGVHYXRld2F5cyxcbiAgICAgICAgLi4uZGF0YVxuICAgIH07XG4gICAgc2F2ZUNhY2hlZEF2YWlsYWJsZUdhdGV3YXlzKCk7XG59XG5mdW5jdGlvbiB1c2VNb2xsaWVBdmFpbGFibGVHYXRld2F5cyhiaWxsaW5nLCBjdXJyZW5jeUNvZGUsIGNhcnRUb3RhbCwgZmlsdGVycywgYWpheFVybCwgalF1ZXJ5LCBpdGVtKSB7XG4gICAgbGV0IGNvdW50cnkgPSBiaWxsaW5nLmNvdW50cnk7XG4gICAgY29uc3QgY29kZSA9IGN1cnJlbmN5Q29kZTtcbiAgICBjb25zdCB2YWx1ZSA9IGNhcnRUb3RhbDtcbiAgICBpZiAoIWNvdW50cnkpIHtcbiAgICAgICAgY291bnRyeSA9IHdjU2V0dGluZ3M/LmJhc2VMb2NhdGlvbi5jb3VudHJ5O1xuICAgIH1cblxuICAgIHdwLmVsZW1lbnQudXNlRWZmZWN0KCgpID0+IHtcbiAgICAgICAgaWYgKCFjb3VudHJ5IHx8ICFpdGVtKSByZXR1cm47XG4gICAgICAgIGNvbnN0IGN1cnJlbmN5Q29kZSA9IGNvZGU7XG4gICAgICAgIGNvbnN0IGNhcnRUb3RhbCA9IHZhbHVlO1xuICAgICAgICBjb25zdCBjdXJyZW50RmlsdGVyS2V5ID0gY3VycmVuY3lDb2RlICsgXCItXCIgKyBjb3VudHJ5O1xuICAgICAgICBpZiAoY2FjaGVkQXZhaWxhYmxlR2F0ZXdheXMuaGFzT3duUHJvcGVydHkoY3VycmVudEZpbHRlcktleSkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBqUXVlcnkuYWpheCh7XG4gICAgICAgICAgICB1cmw6IGFqYXhVcmwsXG4gICAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICAgIGRhdGE6IHtcbiAgICAgICAgICAgICAgICBhY3Rpb246ICdtb2xsaWVfY2hlY2tvdXRfYmxvY2tzX2Nhbm1ha2VwYXltZW50JyxcbiAgICAgICAgICAgICAgICBjdXJyZW50R2F0ZXdheTogaXRlbSxcbiAgICAgICAgICAgICAgICBjdXJyZW5jeTogY3VycmVuY3lDb2RlLFxuICAgICAgICAgICAgICAgIGJpbGxpbmdDb3VudHJ5OiBjb3VudHJ5LFxuICAgICAgICAgICAgICAgIGNhcnRUb3RhbCxcbiAgICAgICAgICAgICAgICBwYXltZW50TG9jYWxlOiBmaWx0ZXJzLnBheW1lbnRMb2NhbGVcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzdWNjZXNzOiAocmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICBzZXRBdmFpbGFibGVHYXRld2F5cyhjb3VudHJ5LCBjdXJyZW5jeUNvZGUsIHJlc3BvbnNlLmRhdGEpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGNhcnRUb3RhbHMgPSB3cC5kYXRhLnNlbGVjdCgnd2Mvc3RvcmUvY2FydCcpLmdldENhcnRUb3RhbHMoKTtcbiAgICAgICAgICAgICAgICAvLyBEaXNwYXRjaCB0aGVtIGFnYWluIHRvIHRyaWdnZXIgYSByZS1yZW5kZXI6XG4gICAgICAgICAgICAgICAgd3AuZGF0YS5kaXNwYXRjaCgnd2Mvc3RvcmUvY2FydCcpLnNldENhcnREYXRhKHsuLi5jYXJ0VG90YWxzfSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZXJyb3I6IChqcVhIUiwgdGV4dFN0YXR1cywgZXJyb3JUaHJvd24pID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oJ0ZhaWxlZCB0byBmZXRjaCBhdmFpbGFibGUgZ2F0ZXdheXM6JywgdGV4dFN0YXR1cywgZXJyb3JUaHJvd24pO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgfSwgW2JpbGxpbmcsIGN1cnJlbmN5Q29kZSwgZmlsdGVycy5wYXltZW50TG9jYWxlLCBhamF4VXJsLCBqUXVlcnksIGl0ZW1dKTtcblxuICAgIHJldHVybiBjYWNoZWRBdmFpbGFibGVHYXRld2F5cztcbn1cblxuLy8gQ29tcG9uZW50IHRoYXQgcnVucyB0aGUgaG9vayBidXQgZG9lcyBub3QgcmVuZGVyIGFueXRoaW5nLlxuZnVuY3Rpb24gTW9sbGllR2F0ZXdheVVwZGF0ZXIoeyBiaWxsaW5nLCBjdXJyZW5jeUNvZGUsIGNhcnRUb3RhbCwgZmlsdGVycywgYWpheFVybCwgalF1ZXJ5LCBpdGVtIH0pIHtcblxuICAgIHVzZU1vbGxpZUF2YWlsYWJsZUdhdGV3YXlzKGJpbGxpbmcsIGN1cnJlbmN5Q29kZSwgY2FydFRvdGFsLCBmaWx0ZXJzLCBhamF4VXJsLCBqUXVlcnksIGl0ZW0pO1xuICAgIHJldHVybiBudWxsO1xufVxuXG5sZXQgb25TdWJtaXRMb2NhbFxubGV0IGFjdGl2ZVBheW1lbnRNZXRob2RMb2NhbFxubGV0IGNyZWRpdENhcmRTZWxlY3RlZCA9IG5ldyBFdmVudChcIm1vbGxpZV9jcmVkaXRjYXJkX2NvbXBvbmVudF9zZWxlY3RlZFwiLCB7YnViYmxlczogdHJ1ZX0pO1xuY29uc3QgTW9sbGllQ29tcG9uZW50ID0gKHByb3BzKSA9PiB7XG4gICAgbGV0IHtvblN1Ym1pdCwgYWN0aXZlUGF5bWVudE1ldGhvZCwgYmlsbGluZywgaXRlbSwgdXNlRWZmZWN0LCBhamF4VXJsLCBqUXVlcnksIGVtaXRSZXNwb25zZSwgZXZlbnRSZWdpc3RyYXRpb24sIHJlcXVpcmVkRmllbGRzLCBzaGlwcGluZ0RhdGEsIGlzUGhvbmVGaWVsZFZpc2libGV9ID0gcHJvcHNcbiAgICBjb25zdCB7ICByZXNwb25zZVR5cGVzIH0gPSBlbWl0UmVzcG9uc2U7XG4gICAgY29uc3Qge29uUGF5bWVudFNldHVwLCBvbkNoZWNrb3V0VmFsaWRhdGlvbn0gPSBldmVudFJlZ2lzdHJhdGlvbjtcbiAgICBpZiAoIWl0ZW0gfHwgIWl0ZW0ubmFtZSkge1xuICAgICAgICByZXR1cm4gPGRpdj5Mb2FkaW5nIHBheW1lbnQgbWV0aG9kcy4uLjwvZGl2PjtcbiAgICB9XG4gICAgY29uc3QgWyBzZWxlY3RlZElzc3Vlciwgc2VsZWN0SXNzdWVyIF0gPSB3cC5lbGVtZW50LnVzZVN0YXRlKCcnKTtcbiAgICBjb25zdCBbIGlucHV0UGhvbmUsIHNlbGVjdFBob25lIF0gPSB3cC5lbGVtZW50LnVzZVN0YXRlKCcnKTtcbiAgICBjb25zdCBbIGlucHV0QmlydGhkYXRlLCBzZWxlY3RCaXJ0aGRhdGUgXSA9IHdwLmVsZW1lbnQudXNlU3RhdGUoJycpO1xuICAgIGNvbnN0IFsgaW5wdXRDb21wYW55LCBzZWxlY3RDb21wYW55IF0gPSB3cC5lbGVtZW50LnVzZVN0YXRlKCcnKTtcbiAgICBjb25zdCBpc3N1ZXJLZXkgPSAnbW9sbGllLXBheW1lbnRzLWZvci13b29jb21tZXJjZV9pc3N1ZXJfJyArIGFjdGl2ZVBheW1lbnRNZXRob2RcbiAgICBjb25zdCB7Y29tcGFueU5hbWVTdHJpbmcsIHBob25lU3RyaW5nfSA9IHJlcXVpcmVkRmllbGRzXG4gICAgZnVuY3Rpb24gZ2V0UGhvbmVGaWVsZCgpXG4gICAge1xuICAgICAgICBjb25zdCBzaGlwcGluZ1Bob25lID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NoaXBwaW5nLXBob25lJyk7XG4gICAgICAgIGNvbnN0IGJpbGxpbmdQaG9uZSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdiaWxsaW5nLXBob25lJyk7XG4gICAgICAgIHJldHVybiBiaWxsaW5nUGhvbmUgfHwgc2hpcHBpbmdQaG9uZTtcbiAgICB9XG4gICAgZnVuY3Rpb24gdXBkYXRlVG90YWxMYWJlbChuZXdUb3RhbCkge1xuICAgICAgICBsZXQgdG90YWxTcGFuID0gXCI8c3BhbiBjbGFzcz0nd2MtYmxvY2stZm9ybWF0dGVkLW1vbmV5LWFtb3VudCB3Yy1ibG9jay1jb21wb25lbnRzLWZvcm1hdHRlZC1tb25leS1hbW91bnQgd2MtYmxvY2stY29tcG9uZW50cy10b3RhbHMtaXRlbV9fdmFsdWUnPlwiICsgZm9ybWF0UHJpY2VMaWtlV2MobmV3VG90YWwpICsgXCI8L3NwYW4+XCJcbiAgICAgICAgbGV0IHRvdGFsID0galF1ZXJ5KCcud2MtYmxvY2stY29tcG9uZW50cy10b3RhbHMtZm9vdGVyLWl0ZW0gLndjLWJsb2NrLWZvcm1hdHRlZC1tb25leS1hbW91bnQ6Zmlyc3QnKVxuICAgICAgICB0b3RhbC5yZXBsYWNlV2l0aCh0b3RhbFNwYW4pXG4gICAgfVxuICAgIGZ1bmN0aW9uIHVwZGF0ZVRheGVzTGFiZWwobmV3VG90YWwpIHtcbiAgICAgICAgbGV0IHRvdGFsU3BhbiA9IFwiPHNwYW4gY2xhc3M9J3djLWJsb2NrLWZvcm1hdHRlZC1tb25leS1hbW91bnQgd2MtYmxvY2stY29tcG9uZW50cy1mb3JtYXR0ZWQtbW9uZXktYW1vdW50IHdjLWJsb2NrLWNvbXBvbmVudHMtdG90YWxzLWl0ZW1fX3ZhbHVlJz5cIiArIGZvcm1hdFByaWNlTGlrZVdjKG5ld1RvdGFsKSArIFwiPC9zcGFuPlwiXG4gICAgICAgIGxldCB0b3RhbCA9IGpRdWVyeSgnZGl2LndwLWJsb2NrLXdvb2NvbW1lcmNlLWNoZWNrb3V0LW9yZGVyLXN1bW1hcnktdGF4ZXMtYmxvY2sud2MtYmxvY2stY29tcG9uZW50cy10b3RhbHMtd3JhcHBlciA+IGRpdiA+IHNwYW4ud2MtYmxvY2stZm9ybWF0dGVkLW1vbmV5LWFtb3VudC53Yy1ibG9jay1jb21wb25lbnRzLWZvcm1hdHRlZC1tb25leS1hbW91bnQud2MtYmxvY2stY29tcG9uZW50cy10b3RhbHMtaXRlbV9fdmFsdWU6Zmlyc3QnKVxuICAgICAgICB0b3RhbC5yZXBsYWNlV2l0aCh0b3RhbFNwYW4pXG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaGlkZUZlZShmZWUsIHJlc3BvbnNlKSB7XG4gICAgICAgIGZlZT8uaGlkZSgpXG4gICAgICAgIHVwZGF0ZVRvdGFsTGFiZWwocmVzcG9uc2UuZGF0YS5uZXdUb3RhbCk7XG4gICAgICAgIHVwZGF0ZVRheGVzTGFiZWwocmVzcG9uc2UuZGF0YS50b3RhbFRheCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZmVlTWFya3VwKHJlc3BvbnNlKSB7XG4gICAgICAgIHJldHVybiBcIjxkaXYgY2xhc3M9J3djLWJsb2NrLWNvbXBvbmVudHMtdG90YWxzLWl0ZW0gd2MtYmxvY2stY29tcG9uZW50cy10b3RhbHMtZmVlcyc+XCIgK1xuICAgICAgICAgICAgXCI8c3BhbiBjbGFzcz0nd2MtYmxvY2stY29tcG9uZW50cy10b3RhbHMtaXRlbV9fbGFiZWwnPlwiXG4gICAgICAgICAgICArIHJlc3BvbnNlLmRhdGEubmFtZVxuICAgICAgICAgICAgKyBcIjwvc3Bhbj5cIiArXG4gICAgICAgICAgICBcIjxzcGFuIGNsYXNzPSd3Yy1ibG9jay1mb3JtYXR0ZWQtbW9uZXktYW1vdW50IHdjLWJsb2NrLWNvbXBvbmVudHMtZm9ybWF0dGVkLW1vbmV5LWFtb3VudCB3Yy1ibG9jay1jb21wb25lbnRzLXRvdGFscy1pdGVtX192YWx1ZSc+XCJcbiAgICAgICAgICAgICsgZm9ybWF0UHJpY2VMaWtlV2MocmVzcG9uc2UuZGF0YS5hbW91bnQpXG4gICAgICAgICAgICArIFwiPC9zcGFuPlwiICtcbiAgICAgICAgICAgIFwiPGRpdiBjbGFzcz0nd2MtYmxvY2stY29tcG9uZW50cy10b3RhbHMtaXRlbV9fZGVzY3JpcHRpb24nPlwiICtcbiAgICAgICAgICAgIFwiPC9kaXY+XCIgK1xuICAgICAgICAgICAgXCI8L2Rpdj5cIjtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiByZXBsYWNlRmVlKGZlZSwgbmV3RmVlLCByZXNwb25zZSkge1xuICAgICAgICBmZWUucmVwbGFjZVdpdGgobmV3RmVlKVxuICAgICAgICB1cGRhdGVUb3RhbExhYmVsKHJlc3BvbnNlLmRhdGEubmV3VG90YWwpO1xuICAgICAgICB1cGRhdGVUYXhlc0xhYmVsKHJlc3BvbnNlLmRhdGEudG90YWxUYXgpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGluc2VydE5ld0ZlZShuZXdGZWUsIHJlc3BvbnNlKSB7XG4gICAgICAgIGNvbnN0IHN1YnRvdGFsID0galF1ZXJ5KCcud2MtYmxvY2stY29tcG9uZW50cy10b3RhbHMtaXRlbTpmaXJzdCcpXG4gICAgICAgIHN1YnRvdGFsLmFmdGVyKG5ld0ZlZSlcbiAgICAgICAgdXBkYXRlVG90YWxMYWJlbChyZXNwb25zZS5kYXRhLm5ld1RvdGFsKTtcbiAgICAgICAgdXBkYXRlVGF4ZXNMYWJlbChyZXNwb25zZS5kYXRhLnRvdGFsVGF4KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBoYW5kbGVGZWVzKHJlc3BvbnNlKSB7XG4gICAgICAgIGNvbnN0IGZlZSA9IGpRdWVyeSgnLndjLWJsb2NrLWNvbXBvbmVudHMtdG90YWxzLWZlZXMnKVxuICAgICAgICBpZiAoIXJlc3BvbnNlLmRhdGEuYW1vdW50KSB7XG4gICAgICAgICAgICBoaWRlRmVlKGZlZSwgcmVzcG9uc2UpO1xuICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgIH1cblxuICAgICAgICBsZXQgbmV3RmVlID0gZmVlTWFya3VwKHJlc3BvbnNlKTtcbiAgICAgICAgaWYgKGZlZS5sZW5ndGgpIHtcbiAgICAgICAgICAgIHJlcGxhY2VGZWUoZmVlLCBuZXdGZWUsIHJlc3BvbnNlKTtcbiAgICAgICAgICAgIHJldHVyblxuICAgICAgICB9XG4gICAgICAgIGluc2VydE5ld0ZlZShuZXdGZWUsIHJlc3BvbnNlKTtcbiAgICB9XG5cbiAgICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgICAgICBpZihhY3RpdmVQYXltZW50TWV0aG9kTG9jYWwgIT09IGFjdGl2ZVBheW1lbnRNZXRob2QgJiYgYWN0aXZlUGF5bWVudE1ldGhvZCA9PT0gJ21vbGxpZV93Y19nYXRld2F5X2NyZWRpdGNhcmQnKXtcbiAgICAgICAgICAgIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5kaXNwYXRjaEV2ZW50KGNyZWRpdENhcmRTZWxlY3RlZCk7XG4gICAgICAgIH1cbiAgICAgICAgYWN0aXZlUGF5bWVudE1ldGhvZExvY2FsID0gYWN0aXZlUGF5bWVudE1ldGhvZFxuICAgICAgICBqUXVlcnkuYWpheCh7XG4gICAgICAgICAgICB1cmw6IGFqYXhVcmwsXG4gICAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICAgIGRhdGE6IHtcbiAgICAgICAgICAgICAgICBhY3Rpb246ICdtb2xsaWVfY2hlY2tvdXRfYmxvY2tzX3N1cmNoYWdlJyxcbiAgICAgICAgICAgICAgICBtZXRob2Q6IGFjdGl2ZVBheW1lbnRNZXRob2RcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBjb21wbGV0ZTogKGpxWEhSLCB0ZXh0U3RhdHVzKSA9PiB7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc3VjY2VzczogKHJlc3BvbnNlLCB0ZXh0U3RhdHVzLCBqcVhIUikgPT4ge1xuICAgICAgICAgICAgICAgIGhhbmRsZUZlZXMocmVzcG9uc2UpXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZXJyb3I6IChqcVhIUiwgdGV4dFN0YXR1cywgZXJyb3JUaHJvd24pID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4odGV4dFN0YXR1cywgZXJyb3JUaHJvd24pXG4gICAgICAgICAgICB9LFxuICAgICAgICB9KVxuICAgIH0sIFthY3RpdmVQYXltZW50TWV0aG9kLCBiaWxsaW5nLmNhcnRUb3RhbF0pXG5cbiAgICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgICAgICBjb25zdCBvblByb2Nlc3NpbmdQYXltZW50ID0gKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgdG9rZW5WYWwgPSBqUXVlcnkoJy5tb2xsaWUtY29tcG9uZW50cyA+IGlucHV0JykudmFsKClcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgdHlwZTogcmVzcG9uc2VUeXBlcy5TVUNDRVNTLFxuICAgICAgICAgICAgICAgIG1ldGE6IHtcbiAgICAgICAgICAgICAgICAgICAgcGF5bWVudE1ldGhvZERhdGE6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHBheW1lbnRfbWV0aG9kOiBhY3RpdmVQYXltZW50TWV0aG9kLFxuICAgICAgICAgICAgICAgICAgICAgICAgcGF5bWVudF9tZXRob2RfdGl0bGU6IGl0ZW0udGl0bGUsXG4gICAgICAgICAgICAgICAgICAgICAgICBbaXNzdWVyS2V5XTogc2VsZWN0ZWRJc3N1ZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICBiaWxsaW5nX3Bob25lOiBpbnB1dFBob25lLFxuICAgICAgICAgICAgICAgICAgICAgICAgYmlsbGluZ19jb21wYW55X2JpbGxpZTogaW5wdXRDb21wYW55LFxuICAgICAgICAgICAgICAgICAgICAgICAgYmlsbGluZ19iaXJ0aGRhdGU6IGlucHV0QmlydGhkYXRlLFxuICAgICAgICAgICAgICAgICAgICAgICAgY2FyZFRva2VuOiB0b2tlblZhbCxcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgdW5zdWJzY3JpYmVQYXltZW50UHJvY2Vzc2luZyA9IG9uUGF5bWVudFNldHVwKFxuICAgICAgICAgICAgb25Qcm9jZXNzaW5nUGF5bWVudFxuICAgICAgICApO1xuICAgICAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICAgICAgdW5zdWJzY3JpYmVQYXltZW50UHJvY2Vzc2luZygpXG4gICAgICAgIH07XG5cbiAgICB9LCBbc2VsZWN0ZWRJc3N1ZXIsIG9uUGF5bWVudFNldHVwLCBpbnB1dFBob25lLCBpbnB1dENvbXBhbnksIGlucHV0QmlydGhkYXRlXSlcblxuICAgIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgICAgIGxldCBjb21wYW55TGFiZWwgPSBqUXVlcnkoJ2Rpdi53Yy1ibG9jay1jb21wb25lbnRzLXRleHQtaW5wdXQud2MtYmxvY2stY29tcG9uZW50cy1hZGRyZXNzLWZvcm1fX2NvbXBhbnkgPiBsYWJlbCcpXG4gICAgICAgIGlmIChjb21wYW55TGFiZWwubGVuZ3RoID09PSAwIHx8IGl0ZW0uaGlkZUNvbXBhbnlGaWVsZCA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgIH1cblxuICAgICAgICBpZiAoYWN0aXZlUGF5bWVudE1ldGhvZCA9PT0gJ21vbGxpZV93Y19nYXRld2F5X2JpbGxpZScpIHtcbiAgICAgICAgICAgIGxldCBtZXNzYWdlID0gaXRlbS5jb21wYW55UGxhY2Vob2xkZXJcbiAgICAgICAgICAgIGNvbXBhbnlMYWJlbC5yZXBsYWNlV2l0aCgnPGxhYmVsIGh0bWxGb3I9XCJzaGlwcGluZy1jb21wYW55XCI+JyArIG1lc3NhZ2UgKyAnPC9sYWJlbD4nKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKGNvbXBhbnlOYW1lU3RyaW5nICE9PSBmYWxzZSkge1xuICAgICAgICAgICAgICAgIGNvbXBhbnlMYWJlbC5yZXBsYWNlV2l0aCgnPGxhYmVsIGh0bWxGb3I9XCJzaGlwcGluZy1jb21wYW55XCI+JyArIGNvbXBhbnlOYW1lU3RyaW5nICsgJzwvbGFiZWw+JylcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBsZXQgaXNDb21wYW55RW1wdHkgPSAoYmlsbGluZy5iaWxsaW5nRGF0YS5jb21wYW55ID09PSAnJyAmJiBzaGlwcGluZ0RhdGEuc2hpcHBpbmdBZGRyZXNzLmNvbXBhbnkgPT09ICcnKSAmJiBpbnB1dENvbXBhbnkgPT09ICcnO1xuICAgICAgICBjb25zdCB1bnN1YnNjcmliZVByb2Nlc3NpbmcgPSBvbkNoZWNrb3V0VmFsaWRhdGlvbihcbiAgICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoYWN0aXZlUGF5bWVudE1ldGhvZCA9PT0gJ21vbGxpZV93Y19nYXRld2F5X2JpbGxpZScgJiYgaXNDb21wYW55RW1wdHkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZTogaXRlbS5lcnJvck1lc3NhZ2UsXG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICApO1xuICAgICAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICAgICAgdW5zdWJzY3JpYmVQcm9jZXNzaW5nKClcbiAgICAgICAgfTtcblxuICAgIH0sIFthY3RpdmVQYXltZW50TWV0aG9kLCBvbkNoZWNrb3V0VmFsaWRhdGlvbiwgYmlsbGluZy5iaWxsaW5nRGF0YSwgaXRlbSwgY29tcGFueU5hbWVTdHJpbmcsIGlucHV0Q29tcGFueV0pO1xuXG4gICAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICAgICAgbGV0IHBob25lTGFiZWwgPSBnZXRQaG9uZUZpZWxkKCk/LmxhYmVscz8uWzBdID8/IG51bGw7XG4gICAgICAgIGlmICghcGhvbmVMYWJlbCB8fCBwaG9uZUxhYmVsLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgIH1cbiAgICAgICAgaWYgKGFjdGl2ZVBheW1lbnRNZXRob2QgPT09ICdtb2xsaWVfd2NfZ2F0ZXdheV9pbjMnKSB7XG4gICAgICAgICAgICBwaG9uZUxhYmVsLmlubmVyVGV4dCA9IGl0ZW0ucGhvbmVQbGFjZWhvbGRlclxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKHBob25lU3RyaW5nICE9PSBmYWxzZSkge1xuICAgICAgICAgICAgICAgIHBob25lTGFiZWwuaW5uZXJUZXh0ID0gcGhvbmVTdHJpbmdcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBsZXQgaXNQaG9uZUVtcHR5ID0gKGJpbGxpbmcuYmlsbGluZ0RhdGEucGhvbmUgPT09ICcnICYmIHNoaXBwaW5nRGF0YS5zaGlwcGluZ0FkZHJlc3MucGhvbmUgPT09ICcnKSAmJiBpbnB1dFBob25lID09PSAnJztcbiAgICAgICAgbGV0IGlzQmlydGhkYXRlVmFsaWQgPSBpbnB1dEJpcnRoZGF0ZSA9PT0gJydcbiAgICAgICAgbGV0IHRvZGF5ID0gbmV3IERhdGUoKTtcbiAgICAgICAgbGV0IGJpcnRoZGF0ZSA9IG5ldyBEYXRlKGlucHV0QmlydGhkYXRlKTtcbiAgICAgICAgaWYgKGJpcnRoZGF0ZSA+IHRvZGF5KSB7XG4gICAgICAgICAgICBpc0JpcnRoZGF0ZVZhbGlkID0gZmFsc2VcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB1bnN1YnNjcmliZVByb2Nlc3NpbmcgPSBvbkNoZWNrb3V0VmFsaWRhdGlvbihcblxuICAgICAgICAgICAgKCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChhY3RpdmVQYXltZW50TWV0aG9kID09PSAnbW9sbGllX3djX2dhdGV3YXlfaW4zJyAmJiAoaXNQaG9uZUVtcHR5IHx8IGlzQmlydGhkYXRlVmFsaWQpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2U6IGl0ZW0uZXJyb3JNZXNzYWdlLFxuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgICAgIHVuc3Vic2NyaWJlUHJvY2Vzc2luZygpXG4gICAgICAgIH07XG5cbiAgICB9LCBbYWN0aXZlUGF5bWVudE1ldGhvZCwgb25DaGVja291dFZhbGlkYXRpb24sIGJpbGxpbmcuYmlsbGluZ0RhdGEsIHNoaXBwaW5nRGF0YS5zaGlwcGluZ0FkZHJlc3MsIGl0ZW0sIHBob25lU3RyaW5nLCBpbnB1dEJpcnRoZGF0ZSwgaW5wdXRQaG9uZV0pO1xuXG4gICAgb25TdWJtaXRMb2NhbCA9IG9uU3VibWl0XG4gICAgY29uc3QgdXBkYXRlSXNzdWVyID0gKGUpID0+IHNlbGVjdElzc3VlcihlLnRhcmdldC52YWx1ZSk7XG4gICAgY29uc3QgdXBkYXRlQ29tcGFueSA9IChlKSA9PiBzZWxlY3RDb21wYW55KGUudGFyZ2V0LnZhbHVlKTtcbiAgICBjb25zdCB1cGRhdGVQaG9uZSA9IChlKSA9PiBzZWxlY3RQaG9uZShlLnRhcmdldC52YWx1ZSk7XG4gICAgY29uc3QgdXBkYXRlQmlydGhkYXRlID0gKGUpID0+IHNlbGVjdEJpcnRoZGF0ZSggZS50YXJnZXQudmFsdWUgKTtcblxuICAgIGZ1bmN0aW9uIGZpZWxkTWFya3VwKGlkLCBmaWVsZFR5cGUsIGxhYmVsLCBhY3Rpb24sIHZhbHVlLCBwbGFjZWhvbGRlciA9IG51bGwpIHtcbiAgICAgICAgY29uc3QgY2xhc3NOYW1lID0gXCJ3Yy1ibG9jay1jb21wb25lbnRzLXRleHQtaW5wdXQgd2MtYmxvY2stY29tcG9uZW50cy1hZGRyZXNzLWZvcm1fX1wiICsgaWQ7XG4gICAgICAgIHJldHVybiA8ZGl2IGNsYXNzPVwiY3VzdG9tLWlucHV0XCI+XG4gICAgICAgICAgICA8bGFiZWwgaHRtbEZvcj17aWR9IGRhbmdlcm91c2x5U2V0SW5uZXJIVE1MPXt7X19odG1sOiBsYWJlbH19PjwvbGFiZWw+XG4gICAgICAgICAgICA8aW5wdXQgdHlwZT17ZmllbGRUeXBlfSBuYW1lPXtpZH0gaWQ9e2lkfSB2YWx1ZT17dmFsdWV9IG9uQ2hhbmdlPXthY3Rpb259IHBsYWNlaG9sZGVyPXtwbGFjZWhvbGRlcn0+PC9pbnB1dD5cbiAgICAgICAgPC9kaXY+XG4gICAgfVxuXG4gICAgaWYgKGl0ZW0uaXNzdWVycyAmJiBpdGVtLm5hbWUgIT09IFwibW9sbGllX3djX2dhdGV3YXlfY3JlZGl0Y2FyZFwiKXtcbiAgICAgICAgcmV0dXJuIDxkaXY+PHA+e2l0ZW0uY29udGVudH08L3A+PHNlbGVjdCBuYW1lPXtpc3N1ZXJLZXl9IGRhbmdlcm91c2x5U2V0SW5uZXJIVE1MPXsge19faHRtbDogaXRlbS5pc3N1ZXJzfSB9IHZhbHVlPXtzZWxlY3RlZElzc3Vlcn0gb25DaGFuZ2U9e3VwZGF0ZUlzc3Vlcn0+PC9zZWxlY3Q+PC9kaXY+XG4gICAgfVxuXG4gICAgaWYoaXRlbS5uYW1lID09PSBcIm1vbGxpZV93Y19nYXRld2F5X2NyZWRpdGNhcmRcIil7XG4gICAgICAgIHJldHVybiA8ZGl2IGRhbmdlcm91c2x5U2V0SW5uZXJIVE1MPXsge19faHRtbDogaXRlbS5jb250ZW50fSB9PjwvZGl2PjtcbiAgICB9XG5cbiAgICBpZiAoaXRlbS5uYW1lID09PSBcIm1vbGxpZV93Y19nYXRld2F5X2JpbGxpZVwiKSB7XG4gICAgICAgIGNvbnN0IGJpbGxpbmdDb21wYW55RmllbGQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZy1jb21wYW55Jyk7XG4gICAgICAgIGNvbnN0IHNoaXBwaW5nQ29tcGFueUZpZWxkID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI3NoaXBwaW5nLWNvbXBhbnknKTtcbiAgICAgICAgY29uc3QgaXNCaWxsaW5nQ29tcGFueVJlcXVpcmVkID0gYmlsbGluZ0NvbXBhbnlGaWVsZD8uaGFzQXR0cmlidXRlKCdyZXF1aXJlZCcpO1xuICAgICAgICBjb25zdCBpc1NoaXBwaW5nQ29tcGFueVJlcXVpcmVkID0gc2hpcHBpbmdDb21wYW55RmllbGQ/Lmhhc0F0dHJpYnV0ZSgncmVxdWlyZWQnKTtcblxuICAgICAgICBpZiAoKGJpbGxpbmdDb21wYW55RmllbGQgJiYgaXNCaWxsaW5nQ29tcGFueVJlcXVpcmVkKSB8fCAoc2hpcHBpbmdDb21wYW55RmllbGQgJiYgaXNTaGlwcGluZ0NvbXBhbnlSZXF1aXJlZCkgfHwgaXRlbS5oaWRlQ29tcGFueUZpZWxkID09PSB0cnVlKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBjb21wYW55RmllbGQgPSBpdGVtLmNvbXBhbnlQbGFjZWhvbGRlciA/IGl0ZW0uY29tcGFueVBsYWNlaG9sZGVyIDogXCJDb21wYW55IG5hbWVcIjtcbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIDw+XG4gICAgICAgICAgICAgICAgPGRpdj48cD57aXRlbS5jb250ZW50fTwvcD48L2Rpdj5cbiAgICAgICAgICAgICAgICB7ZmllbGRNYXJrdXAoXCJiaWxsaW5nX2NvbXBhbnlfYmlsbGllXCIsXCJ0ZXh0XCIsIGNvbXBhbnlGaWVsZCwgdXBkYXRlQ29tcGFueSwgaW5wdXRDb21wYW55KX1cbiAgICAgICAgICAgIDwvPlxuICAgICAgICApO1xuICAgIH1cblxuICAgIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgICAgIGNvbnN0IGNvdW50cnlDb2RlcyA9IHtcbiAgICAgICAgICAgIEJFOiAnKzMyeHh4eHh4eHh4JyxcbiAgICAgICAgICAgIE5MOiAnKzMxNnh4eHh4eHh4JyxcbiAgICAgICAgICAgIERFOiAnKzQ5eHh4eHh4eHh4JyxcbiAgICAgICAgICAgIEFUOiAnKzQzeHh4eHh4eHh4JyxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgY291bnRyeSA9IGJpbGxpbmcuYmlsbGluZ0RhdGEuY291bnRyeTtcbiAgICAgICAgaXRlbS5waG9uZVBsYWNlaG9sZGVyID0gY291bnRyeUNvZGVzW2NvdW50cnldIHx8IGNvdW50cnlDb2Rlc1snTkwnXTtcbiAgICB9LCBbYmlsbGluZy5iaWxsaW5nRGF0YS5jb3VudHJ5XSk7XG5cbiAgICBpZiAoaXRlbS5uYW1lID09PSBcIm1vbGxpZV93Y19nYXRld2F5X2luM1wiKSB7XG4gICAgICAgIGNvbnN0IGJpcnRoZGF0ZUZpZWxkID0gaXRlbS5iaXJ0aGRhdGVQbGFjZWhvbGRlciB8fCBcIkJpcnRoZGF0ZVwiO1xuICAgICAgICBjb25zdCBwaG9uZUZpZWxkID0gaXRlbS5waG9uZVBsYWNlaG9sZGVyIHx8IFwiKzMxNnh4eHh4eHh4XCI7XG4gICAgICAgIGNvbnN0IHBob25lTGFiZWwgPSBpdGVtLnBob25lTGFiZWwgfHwgXCJQaG9uZVwiO1xuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgPD5cbiAgICAgICAgICAgICAgICA8ZGl2PjxwPntpdGVtLmNvbnRlbnR9PC9wPjwvZGl2PlxuICAgICAgICAgICAgICAgIHtmaWVsZE1hcmt1cChcImJpbGxpbmctYmlydGhkYXRlXCIsIFwiZGF0ZVwiLCBiaXJ0aGRhdGVGaWVsZCwgdXBkYXRlQmlydGhkYXRlLCBpbnB1dEJpcnRoZGF0ZSl9XG4gICAgICAgICAgICAgICAgeyFpc1Bob25lRmllbGRWaXNpYmxlICYmIGZpZWxkTWFya3VwKFwiYmlsbGluZy1waG9uZS1pbjNcIiwgXCJ0ZWxcIiwgcGhvbmVMYWJlbCwgdXBkYXRlUGhvbmUsIGlucHV0UGhvbmUsIHBob25lRmllbGQpfVxuICAgICAgICAgICAgPC8+XG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgaWYgKGl0ZW0ubmFtZSA9PT0gXCJtb2xsaWVfd2NfZ2F0ZXdheV9yaXZlcnR5XCIpIHtcbiAgICAgICAgY29uc3QgYmlydGhkYXRlRmllbGQgPSBpdGVtLmJpcnRoZGF0ZVBsYWNlaG9sZGVyIHx8IFwiQmlydGhkYXRlXCI7XG4gICAgICAgIGNvbnN0IHBob25lRmllbGQgPSBpdGVtLnBob25lUGxhY2Vob2xkZXIgfHwgXCIrMzE2eHh4eHh4eHhcIjtcbiAgICAgICAgY29uc3QgcGhvbmVMYWJlbCA9IGl0ZW0ucGhvbmVMYWJlbCB8fCBcIlBob25lXCI7XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICA8PlxuICAgICAgICAgICAgICAgIDxkaXY+PHA+e2l0ZW0uY29udGVudH08L3A+PC9kaXY+XG4gICAgICAgICAgICAgICAge2ZpZWxkTWFya3VwKFwiYmlsbGluZy1iaXJ0aGRhdGVcIiwgXCJkYXRlXCIsIGJpcnRoZGF0ZUZpZWxkLCB1cGRhdGVCaXJ0aGRhdGUsIGlucHV0QmlydGhkYXRlKX1cbiAgICAgICAgICAgICAgICB7IWlzUGhvbmVGaWVsZFZpc2libGUgJiYgZmllbGRNYXJrdXAoXCJiaWxsaW5nLXBob25lLXJpdmVydHlcIiwgXCJ0ZWxcIiwgcGhvbmVMYWJlbCwgdXBkYXRlUGhvbmUsIGlucHV0UGhvbmUsIHBob25lRmllbGQpfVxuICAgICAgICAgICAgPC8+XG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIDxkaXY+PHA+e2l0ZW0uY29udGVudH08L3A+PC9kaXY+XG59XG5cbmNvbnN0IExhYmVsID0gKHsgaXRlbSwgZmlsdGVycywgYWpheFVybCwgalF1ZXJ5IH0pID0+IHtcbiAgICBjb25zdCBjYXJ0RGF0YSA9IHdwLmRhdGEudXNlU2VsZWN0KChzZWxlY3QpID0+XG4gICAgICAgICAgICBzZWxlY3QoJ3djL3N0b3JlL2NhcnQnKS5nZXRDYXJ0RGF0YSgpLFxuICAgICAgICBbXVxuICAgICk7XG4gICAgY29uc3QgY2FydFRvdGFscyA9IHdwLmRhdGEudXNlU2VsZWN0KCAoc2VsZWN0KSA9PiBzZWxlY3QoJ3djL3N0b3JlL2NhcnQnKS5nZXRDYXJ0VG90YWxzKCksIFsgXSApO1xuICAgIGNvbnN0IGNhcnRUb3RhbCA9IGNhcnRUb3RhbHM/LnRvdGFsX3ByaWNlIHx8IDA7XG4gICAgcmV0dXJuIChcbiAgICAgICAgPD5cbiAgICAgICAgICAgIDxkaXYgZGFuZ2Vyb3VzbHlTZXRJbm5lckhUTUw9e3sgX19odG1sOiBpdGVtLmxhYmVsIH19Lz5cbiAgICAgICAgICAgIDxNb2xsaWVHYXRld2F5VXBkYXRlclxuICAgICAgICAgICAgICAgIGJpbGxpbmc9e2NhcnREYXRhLmJpbGxpbmdBZGRyZXNzfVxuICAgICAgICAgICAgICAgIGN1cnJlbmN5Q29kZT17d2NTZXR0aW5ncy5jdXJyZW5jeS5jb2RlfVxuICAgICAgICAgICAgICAgIGZpbHRlcnM9e2ZpbHRlcnN9XG4gICAgICAgICAgICAgICAgYWpheFVybD17YWpheFVybH1cbiAgICAgICAgICAgICAgICBqUXVlcnk9e2pRdWVyeX1cbiAgICAgICAgICAgICAgICBpdGVtPXtpdGVtfVxuICAgICAgICAgICAgICAgIGNhcnRUb3RhbD17Y2FydFRvdGFsfVxuICAgICAgICAgICAgLz5cbiAgICAgICAgPC8+XG4gICAgKTtcbn07XG5cbmNvbnN0IG1vbGxpZVBheW1lbnRNZXRob2QgPSAodXNlRWZmZWN0LCBhamF4VXJsLCBmaWx0ZXJzLCBnYXRld2F5RGF0YSwgYXZhaWxhYmxlR2F0ZXdheXMsIGl0ZW0sIGpRdWVyeSwgcmVxdWlyZWRGaWVsZHMsIGlzQ29tcGFueUZpZWxkVmlzaWJsZSwgaXNQaG9uZUZpZWxkVmlzaWJsZSkgPT57XG5cbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdtb2xsaWVfY29tcG9uZW50c19yZWFkeV90b19zdWJtaXQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIG9uU3VibWl0TG9jYWwoKVxuICAgIH0pXG4gICAgZnVuY3Rpb24gY3JlZGl0Y2FyZFNlbGVjdGVkRXZlbnQoKSB7XG4gICAgICAgIGlmIChpdGVtLm5hbWUgPT09IFwibW9sbGllX3djX2dhdGV3YXlfY3JlZGl0Y2FyZFwiKSB7XG4gICAgICAgICAgICBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuZGlzcGF0Y2hFdmVudChjcmVkaXRDYXJkU2VsZWN0ZWQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gT24gZmlyc3QgbG9hZCwgaWYgYXZhaWxhYmxlR2F0ZXdheXMgaXMgbm90IGVtcHR5LCBzdG9yZSBpdFxuICAgIGlmIChfLmlzRW1wdHkoY2FjaGVkQXZhaWxhYmxlR2F0ZXdheXMpICYmICFfLmlzRW1wdHkoYXZhaWxhYmxlR2F0ZXdheXMpKSB7XG4gICAgICAgIGNhY2hlZEF2YWlsYWJsZUdhdGV3YXlzID0gYXZhaWxhYmxlR2F0ZXdheXM7XG4gICAgICAgIHNhdmVDYWNoZWRBdmFpbGFibGVHYXRld2F5cygpO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgICBuYW1lOiBpdGVtLm5hbWUsXG4gICAgICAgIGxhYmVsOjxMYWJlbFxuICAgICAgICAgICAgaXRlbT17aXRlbX1cbiAgICAgICAgICAgIGFqYXhVcmw9e2FqYXhVcmx9XG4gICAgICAgICAgICBqUXVlcnk9e2pRdWVyeX1cbiAgICAgICAgICAgIGZpbHRlcnM9e2ZpbHRlcnN9XG4gICAgICAgIC8+LFxuICAgICAgICBjb250ZW50OiA8TW9sbGllQ29tcG9uZW50XG4gICAgICAgICAgICBpdGVtPXtpdGVtfVxuICAgICAgICAgICAgdXNlRWZmZWN0PXt1c2VFZmZlY3R9XG4gICAgICAgICAgICBhamF4VXJsPXthamF4VXJsfVxuICAgICAgICAgICAgalF1ZXJ5PXtqUXVlcnl9XG4gICAgICAgICAgICByZXF1aXJlZEZpZWxkcz17cmVxdWlyZWRGaWVsZHN9XG4gICAgICAgICAgICBpc1Bob25lRmllbGRWaXNpYmxlPXtpc1Bob25lRmllbGRWaXNpYmxlfS8+LFxuICAgICAgICBlZGl0OiA8ZGl2PntpdGVtLmVkaXR9PC9kaXY+LFxuICAgICAgICBwYXltZW50TWV0aG9kSWQ6IGl0ZW0ucGF5bWVudE1ldGhvZElkLFxuICAgICAgICBjYW5NYWtlUGF5bWVudDogKHtjYXJ0VG90YWxzLCBiaWxsaW5nRGF0YX0pID0+IHtcbiAgICAgICAgICAgIGlmICghXy5pc0VtcHR5KGl0ZW0uYWxsb3dlZENvdW50cmllcykgJiYgIShpdGVtLmFsbG93ZWRDb3VudHJpZXMuaW5jbHVkZXMoYmlsbGluZ0RhdGEuY291bnRyeSkpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoY2FydFRvdGFscyA8PSAwKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWVcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxvYWRDYWNoZWRBdmFpbGFibGVHYXRld2F5cygpO1xuICAgICAgICAgICAgY29uc3QgY3VycmVuY3lDb2RlID0gY2FydFRvdGFscz8uY3VycmVuY3lfY29kZTtcbiAgICAgICAgICAgIGxldCBjb3VudHJ5ID0gYmlsbGluZ0RhdGE/LmNvdW50cnk7XG4gICAgICAgICAgICBpZiAoIWNvdW50cnkpIHtcbiAgICAgICAgICAgICAgICBjb3VudHJ5ID0gd2NTZXR0aW5ncz8uYmFzZUxvY2F0aW9uLmNvdW50cnk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBjdXJyZW50RmlsdGVyS2V5ID0gY3VycmVuY3lDb2RlICsgXCItXCIgKyBjb3VudHJ5O1xuXG4gICAgICAgICAgICBjcmVkaXRjYXJkU2VsZWN0ZWRFdmVudCgpO1xuICAgICAgICAgICAgaWYgKCFjYWNoZWRBdmFpbGFibGVHYXRld2F5cy5oYXNPd25Qcm9wZXJ0eShjdXJyZW50RmlsdGVyS2V5KSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIGNhY2hlZEF2YWlsYWJsZUdhdGV3YXlzW2N1cnJlbnRGaWx0ZXJLZXldLmhhc093blByb3BlcnR5KGl0ZW0ubmFtZSk7XG4gICAgICAgIH0sXG4gICAgICAgIGFyaWFMYWJlbDogaXRlbS5hcmlhTGFiZWwsXG4gICAgICAgIHN1cHBvcnRzOiB7XG4gICAgICAgICAgICBmZWF0dXJlczogaXRlbS5zdXBwb3J0cyxcbiAgICAgICAgfSxcbiAgICB9O1xufVxuXG5leHBvcnQgZGVmYXVsdCBtb2xsaWVQYXltZW50TWV0aG9kXG5cbiIsIi8vIFRoZSBtb2R1bGUgY2FjaGVcbnZhciBfX3dlYnBhY2tfbW9kdWxlX2NhY2hlX18gPSB7fTtcblxuLy8gVGhlIHJlcXVpcmUgZnVuY3Rpb25cbmZ1bmN0aW9uIF9fd2VicGFja19yZXF1aXJlX18obW9kdWxlSWQpIHtcblx0Ly8gQ2hlY2sgaWYgbW9kdWxlIGlzIGluIGNhY2hlXG5cdHZhciBjYWNoZWRNb2R1bGUgPSBfX3dlYnBhY2tfbW9kdWxlX2NhY2hlX19bbW9kdWxlSWRdO1xuXHRpZiAoY2FjaGVkTW9kdWxlICE9PSB1bmRlZmluZWQpIHtcblx0XHRyZXR1cm4gY2FjaGVkTW9kdWxlLmV4cG9ydHM7XG5cdH1cblx0Ly8gQ3JlYXRlIGEgbmV3IG1vZHVsZSAoYW5kIHB1dCBpdCBpbnRvIHRoZSBjYWNoZSlcblx0dmFyIG1vZHVsZSA9IF9fd2VicGFja19tb2R1bGVfY2FjaGVfX1ttb2R1bGVJZF0gPSB7XG5cdFx0Ly8gbm8gbW9kdWxlLmlkIG5lZWRlZFxuXHRcdC8vIG5vIG1vZHVsZS5sb2FkZWQgbmVlZGVkXG5cdFx0ZXhwb3J0czoge31cblx0fTtcblxuXHQvLyBFeGVjdXRlIHRoZSBtb2R1bGUgZnVuY3Rpb25cblx0X193ZWJwYWNrX21vZHVsZXNfX1ttb2R1bGVJZF0obW9kdWxlLCBtb2R1bGUuZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXyk7XG5cblx0Ly8gUmV0dXJuIHRoZSBleHBvcnRzIG9mIHRoZSBtb2R1bGVcblx0cmV0dXJuIG1vZHVsZS5leHBvcnRzO1xufVxuXG4iLCIvLyBkZWZpbmUgZ2V0dGVyIGZ1bmN0aW9ucyBmb3IgaGFybW9ueSBleHBvcnRzXG5fX3dlYnBhY2tfcmVxdWlyZV9fLmQgPSAoZXhwb3J0cywgZGVmaW5pdGlvbikgPT4ge1xuXHRmb3IodmFyIGtleSBpbiBkZWZpbml0aW9uKSB7XG5cdFx0aWYoX193ZWJwYWNrX3JlcXVpcmVfXy5vKGRlZmluaXRpb24sIGtleSkgJiYgIV9fd2VicGFja19yZXF1aXJlX18ubyhleHBvcnRzLCBrZXkpKSB7XG5cdFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywga2V5LCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZGVmaW5pdGlvbltrZXldIH0pO1xuXHRcdH1cblx0fVxufTsiLCJfX3dlYnBhY2tfcmVxdWlyZV9fLm8gPSAob2JqLCBwcm9wKSA9PiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwgcHJvcCkpIiwiLy8gZGVmaW5lIF9fZXNNb2R1bGUgb24gZXhwb3J0c1xuX193ZWJwYWNrX3JlcXVpcmVfXy5yID0gKGV4cG9ydHMpID0+IHtcblx0aWYodHlwZW9mIFN5bWJvbCAhPT0gJ3VuZGVmaW5lZCcgJiYgU3ltYm9sLnRvU3RyaW5nVGFnKSB7XG5cdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFN5bWJvbC50b1N0cmluZ1RhZywgeyB2YWx1ZTogJ01vZHVsZScgfSk7XG5cdH1cblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdfX2VzTW9kdWxlJywgeyB2YWx1ZTogdHJ1ZSB9KTtcbn07IiwiaW1wb3J0IG1vbGxpZVBheW1lbnRNZXRob2QgZnJvbSAnLi9ibG9ja3MvbW9sbGllUGF5bWVudE1ldGhvZCdcbmltcG9ydCBBcHBsZVBheUJ1dHRvbkNvbXBvbmVudCBmcm9tICcuL2Jsb2Nrcy9BcHBsZVBheUJ1dHRvbkNvbXBvbmVudCdcbmltcG9ydCBBcHBsZVBheUJ1dHRvbkVkaXRvckNvbXBvbmVudCBmcm9tICcuL2Jsb2Nrcy9BcHBsZVBheUJ1dHRvbkVkaXRvckNvbXBvbmVudCdcblxuKFxuICAgIGZ1bmN0aW9uICh7bW9sbGllQmxvY2tEYXRhLCB3YywgXywgalF1ZXJ5fSkge1xuICAgICAgICBpZiAoXy5pc0VtcHR5KG1vbGxpZUJsb2NrRGF0YSkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHtyZWdpc3RlclBheW1lbnRNZXRob2R9ID0gd2Mud2NCbG9ja3NSZWdpc3RyeTtcbiAgICAgICAgY29uc3Qge2RlZmF1bHRGaWVsZHN9ID0gd2Mud2NTZXR0aW5ncy5hbGxTZXR0aW5ncztcbiAgICAgICAgY29uc3Qge2FqYXhVcmwsIGZpbHRlcnMsIGdhdGV3YXlEYXRhLCBhdmFpbGFibGVHYXRld2F5c30gPSBtb2xsaWVCbG9ja0RhdGEuZ2F0ZXdheURhdGE7XG4gICAgICAgIGNvbnN0IHt1c2VFZmZlY3R9ID0gd3AuZWxlbWVudDtcbiAgICAgICAgY29uc3QgaXNBcHBsZVNlc3Npb24gPSB0eXBlb2Ygd2luZG93LkFwcGxlUGF5U2Vzc2lvbiA9PT0gXCJmdW5jdGlvblwiXG4gICAgICAgIGxvY2FsU3RvcmFnZS5yZW1vdmVJdGVtKCdjYWNoZWRBdmFpbGFibGVHYXRld2F5cycpO1xuXG4gICAgICAgIGZ1bmN0aW9uIGdldFBob25lRmllbGQoKSB7XG4gICAgICAgICAgICBjb25zdCBwaG9uZUZpZWxkRGF0YXNldCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ1tkYXRhLXNob3ctcGhvbmUtZmllbGRdJyk7XG4gICAgICAgICAgICBpZiAoIXBob25lRmllbGREYXRhc2V0KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcGhvbmVGaWVsZERhdGFzZXQuZGF0YXNldC5zaG93UGhvbmVGaWVsZCAhPT0gXCJmYWxzZVwiXG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBjb21wYW55TmFtZVN0cmluZyA9IGRlZmF1bHRGaWVsZHMuY29tcGFueS5sYWJlbFxuICAgICAgICBjb25zdCBpc1Bob25lRmllbGRWaXNpYmxlID0gZ2V0UGhvbmVGaWVsZCgpO1xuICAgICAgICBjb25zdCBwaG9uZVN0cmluZyA9IGRlZmF1bHRGaWVsZHMucGhvbmUubGFiZWxcbiAgICAgICAgbGV0IHJlcXVpcmVkRmllbGRzID0ge1xuICAgICAgICAgICAgJ2NvbXBhbnlOYW1lU3RyaW5nJzogY29tcGFueU5hbWVTdHJpbmcsXG4gICAgICAgICAgICAncGhvbmVTdHJpbmcnOiBwaG9uZVN0cmluZyxcbiAgICAgICAgfVxuICAgICAgICBnYXRld2F5RGF0YS5mb3JFYWNoKGl0ZW0gPT4ge1xuICAgICAgICAgICAgbGV0IHJlZ2lzdGVyID0gKCkgPT4gcmVnaXN0ZXJQYXltZW50TWV0aG9kKG1vbGxpZVBheW1lbnRNZXRob2QodXNlRWZmZWN0LCBhamF4VXJsLCBmaWx0ZXJzLCBnYXRld2F5RGF0YSwgYXZhaWxhYmxlR2F0ZXdheXMsIGl0ZW0sIGpRdWVyeSwgcmVxdWlyZWRGaWVsZHMsIGlzUGhvbmVGaWVsZFZpc2libGUpKTtcbiAgICAgICAgICAgIGlmIChpdGVtLm5hbWUgPT09ICdtb2xsaWVfd2NfZ2F0ZXdheV9hcHBsZXBheScpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB7aXNFeHByZXNzRW5hYmxlZH0gPSBpdGVtO1xuICAgICAgICAgICAgICAgIGlmICgoaXNBcHBsZVNlc3Npb24gJiYgd2luZG93LkFwcGxlUGF5U2Vzc2lvbi5jYW5NYWtlUGF5bWVudHMoKSkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVnaXN0ZXIoKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzRXhwcmVzc0VuYWJsZWQgIT09IHRydWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjb25zdCB7cmVnaXN0ZXJFeHByZXNzUGF5bWVudE1ldGhvZH0gPSB3Yy53Y0Jsb2Nrc1JlZ2lzdHJ5O1xuICAgICAgICAgICAgICAgICAgICByZWdpc3RlckV4cHJlc3NQYXltZW50TWV0aG9kKHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6ICdtb2xsaWVfd2NfZ2F0ZXdheV9hcHBsZXBheV9leHByZXNzJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlOiAnQXBwbGUgUGF5IEV4cHJlc3MgYnV0dG9uJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOiAnQXBwbGUgUGF5IEV4cHJlc3MgYnV0dG9uJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQ6IDxBcHBsZVBheUJ1dHRvbkNvbXBvbmVudC8+LFxuICAgICAgICAgICAgICAgICAgICAgICAgZWRpdDogPEFwcGxlUGF5QnV0dG9uRWRpdG9yQ29tcG9uZW50Lz4sXG4gICAgICAgICAgICAgICAgICAgICAgICBhcmlhTGFiZWw6ICdBcHBsZSBQYXknLFxuICAgICAgICAgICAgICAgICAgICAgICAgY2FuTWFrZVBheW1lbnQ6ICgpID0+IHRydWUsXG4gICAgICAgICAgICAgICAgICAgICAgICBwYXltZW50TWV0aG9kSWQ6ICdtb2xsaWVfd2NfZ2F0ZXdheV9hcHBsZXBheScsXG4gICAgICAgICAgICAgICAgICAgICAgICBnYXRld2F5SWQ6ICdtb2xsaWVfd2NfZ2F0ZXdheV9hcHBsZXBheScsXG4gICAgICAgICAgICAgICAgICAgICAgICBzdXBwb3J0czoge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZlYXR1cmVzOiBbJ3Byb2R1Y3RzJ10sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IFsnaGVpZ2h0JywgJ2JvcmRlclJhZGl1cyddXG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZWdpc3RlcigpO1xuICAgICAgICB9KTtcbiAgICB9XG4pKHdpbmRvdywgd2MpXG4iXSwibmFtZXMiOlsiY3JlYXRlQXBwbGVFcnJvcnMiLCJlcnJvcnMiLCJlcnJvckxpc3QiLCJfaXRlcmF0b3IiLCJfY3JlYXRlRm9yT2ZJdGVyYXRvckhlbHBlciIsIl9zdGVwIiwicyIsIm4iLCJkb25lIiwiZXJyb3IiLCJ2YWx1ZSIsIl9lcnJvciRjb250YWN0RmllbGQiLCJjb250YWN0RmllbGQiLCJfZXJyb3IkY29kZSIsImNvZGUiLCJfZXJyb3IkbWVzc2FnZSIsIm1lc3NhZ2UiLCJhcHBsZUVycm9yIiwiQXBwbGVQYXlFcnJvciIsInB1c2giLCJlcnIiLCJlIiwiZiIsInJlcXVlc3QiLCJjb3VudHJ5Q29kZSIsImN1cnJlbmN5Q29kZSIsInRvdGFsTGFiZWwiLCJzdWJ0b3RhbCIsInN1cHBvcnRlZE5ldHdvcmtzIiwibWVyY2hhbnRDYXBhYmlsaXRpZXMiLCJzaGlwcGluZ1R5cGUiLCJyZXF1aXJlZEJpbGxpbmdDb250YWN0RmllbGRzIiwicmVxdWlyZWRTaGlwcGluZ0NvbnRhY3RGaWVsZHMiLCJ0b3RhbCIsImxhYmVsIiwiYW1vdW50IiwidHlwZSIsIkFwcGxlUGF5QnV0dG9uQ29tcG9uZW50IiwiX3JlZiIsIl9yZWYkYnV0dG9uQXR0cmlidXRlcyIsImJ1dHRvbkF0dHJpYnV0ZXMiLCJtb2xsaWVBcHBsZVBheUJsb2NrRGF0YUNhcnQiLCJ3aW5kb3ciLCJtb2xsaWVCbG9ja0RhdGEiLCJub25jZSIsImRvY3VtZW50IiwiZ2V0RWxlbWVudEJ5SWQiLCJ1cGRhdGVkQ29udGFjdEluZm8iLCJyZWRpcmVjdGlvblVybCIsIl9tb2xsaWVBcHBsZVBheUJsb2NrRCIsInByb2R1Y3QiLCJfbW9sbGllQXBwbGVQYXlCbG9ja0QyIiwibmVlZFNoaXBwaW5nIiwiX21vbGxpZUFwcGxlUGF5QmxvY2tEMyIsInNob3AiLCJfbW9sbGllQXBwbGVQYXlCbG9ja0Q0IiwiX21vbGxpZUFwcGxlUGF5QmxvY2tENSIsImFqYXhVcmwiLCJzdHlsZSIsImhlaWdodCIsImNvbmNhdCIsImJvcmRlclJhZGl1cyIsImZpbmRTZWxlY3RlZFNoaXBwaW5nTWV0aG9kIiwic2hpcHBpbmdSYXRlcyIsInNoaXBwaW5nUmF0ZSIsImZpbmQiLCJzaGlwcGluZ01ldGhvZCIsInNlbGVjdGVkIiwiYXBwbGVGb3JtYXR0ZWRSYXRlIiwiZGV0YWlsIiwibmFtZSIsImlkZW50aWZpZXIiLCJyYXRlX2lkIiwiYXBwbGVQYXlTZXNzaW9uIiwiX3N0b3JlJGdldFNoaXBwaW5nUmF0Iiwic2Vzc2lvbiIsIkFwcGxlUGF5U2Vzc2lvbiIsInN0b3JlIiwid3AiLCJkYXRhIiwic2VsZWN0IiwiZ2V0U2hpcHBpbmdSYXRlcyIsInNoaXBwaW5nX3JhdGVzIiwic2VsZWN0ZWRTaGlwcGluZ01ldGhvZCIsImxlbmd0aCIsIm9uc2hpcHBpbmdtZXRob2RzZWxlY3RlZCIsImV2ZW50IiwiX3RoaXMiLCJqUXVlcnkiLCJhamF4IiwidXJsIiwibWV0aG9kIiwiYWN0aW9uIiwiY2FsbGVyUGFnZSIsInNpbXBsaWZpZWRDb250YWN0Iiwic3VjY2VzcyIsImFwcGxlUGF5U2hpcHBpbmdNZXRob2RVcGRhdGUiLCJ0ZXh0U3RhdHVzIiwianFYSFIiLCJyZXNwb25zZSIsImNvbXBsZXRlU2hpcHBpbmdNZXRob2RTZWxlY3Rpb24iLCJlcnJvclRocm93biIsImNvbnNvbGUiLCJ3YXJuIiwiYWJvcnQiLCJvbnNoaXBwaW5nY29udGFjdHNlbGVjdGVkIiwiX3RoaXMyIiwic2hpcHBpbmdDb250YWN0IiwiYXBwbGVQYXlTaGlwcGluZ0NvbnRhY3RVcGRhdGUiLCJuZXdTaGlwcGluZ01ldGhvZHMiLCJjb21wbGV0ZVNoaXBwaW5nQ29udGFjdFNlbGVjdGlvbiIsIm9udmFsaWRhdGVtZXJjaGFudCIsImFwcGxlUGF5VmFsaWRhdGVNZXJjaGFudEV2ZW50IiwidmFsaWRhdGlvblVybCIsInZhbGlkYXRpb25VUkwiLCJtZXJjaGFudFNlc3Npb24iLCJjb21wbGV0ZU1lcmNoYW50VmFsaWRhdGlvbiIsIkpTT04iLCJwYXJzZSIsIm9ucGF5bWVudGF1dGhvcml6ZWQiLCJBcHBsZVBheVBheW1lbnQiLCJfQXBwbGVQYXlQYXltZW50JHBheW0iLCJwYXltZW50IiwiYmlsbGluZ0NvbnRhY3QiLCJ0b2tlbiIsImdpdmVuTmFtZSIsImZhbWlseU5hbWUiLCJhZGRyZXNzTGluZXMiLCJwb3N0YWxDb2RlIiwibG9jYWxpdHkiLCJhZG1pbmlzdHJhdGl2ZUFyZWEiLCJwaG9uZU51bWJlciIsImVtYWlsQWRkcmVzcyIsImF1dGhvcml6YXRpb25SZXN1bHQiLCJyZXN1bHQiLCJjb21wbGV0ZVBheW1lbnQiLCJsb2NhdGlvbiIsImhyZWYiLCJiZWdpbiIsIlJlYWN0IiwiY3JlYXRlRWxlbWVudCIsImlkIiwiY2xhc3NOYW1lIiwib25DbGljayIsInByZXZlbnREZWZhdWx0IiwiQXBwbGVQYXlCdXR0b25FZGl0b3JDb21wb25lbnQiLCJjYWNoZWRBdmFpbGFibGVHYXRld2F5cyIsImZvcm1hdFByaWNlTGlrZVdjIiwicHJpY2UiLCJ3Y1NldHRpbmdzIiwiY3VycmVuY3kiLCJwcmljZUZvcm1hdCIsInJlcGxhY2UiLCJzeW1ib2wiLCJ0b0ZpeGVkIiwicHJlY2lzaW9uIiwiZGVjaW1hbFNlcGFyYXRvciIsImxvYWRDYWNoZWRBdmFpbGFibGVHYXRld2F5cyIsInN0b3JlZERhdGEiLCJsb2NhbFN0b3JhZ2UiLCJnZXRJdGVtIiwic2F2ZUNhY2hlZEF2YWlsYWJsZUdhdGV3YXlzIiwic2V0SXRlbSIsInN0cmluZ2lmeSIsInNldEF2YWlsYWJsZUdhdGV3YXlzIiwiY291bnRyeSIsIl9vYmplY3RTcHJlYWQiLCJ1c2VNb2xsaWVBdmFpbGFibGVHYXRld2F5cyIsImJpbGxpbmciLCJjYXJ0VG90YWwiLCJmaWx0ZXJzIiwiaXRlbSIsIl93Y1NldHRpbmdzIiwiYmFzZUxvY2F0aW9uIiwiZWxlbWVudCIsInVzZUVmZmVjdCIsImN1cnJlbnRGaWx0ZXJLZXkiLCJoYXNPd25Qcm9wZXJ0eSIsImN1cnJlbnRHYXRld2F5IiwiYmlsbGluZ0NvdW50cnkiLCJwYXltZW50TG9jYWxlIiwiY2FydFRvdGFscyIsImdldENhcnRUb3RhbHMiLCJkaXNwYXRjaCIsInNldENhcnREYXRhIiwiTW9sbGllR2F0ZXdheVVwZGF0ZXIiLCJvblN1Ym1pdExvY2FsIiwiYWN0aXZlUGF5bWVudE1ldGhvZExvY2FsIiwiY3JlZGl0Q2FyZFNlbGVjdGVkIiwiRXZlbnQiLCJidWJibGVzIiwiTW9sbGllQ29tcG9uZW50IiwicHJvcHMiLCJvblN1Ym1pdCIsImFjdGl2ZVBheW1lbnRNZXRob2QiLCJlbWl0UmVzcG9uc2UiLCJldmVudFJlZ2lzdHJhdGlvbiIsInJlcXVpcmVkRmllbGRzIiwic2hpcHBpbmdEYXRhIiwiaXNQaG9uZUZpZWxkVmlzaWJsZSIsInJlc3BvbnNlVHlwZXMiLCJvblBheW1lbnRTZXR1cCIsIm9uQ2hlY2tvdXRWYWxpZGF0aW9uIiwiX3dwJGVsZW1lbnQkdXNlU3RhdGUiLCJ1c2VTdGF0ZSIsIl93cCRlbGVtZW50JHVzZVN0YXRlMiIsIl9zbGljZWRUb0FycmF5Iiwic2VsZWN0ZWRJc3N1ZXIiLCJzZWxlY3RJc3N1ZXIiLCJfd3AkZWxlbWVudCR1c2VTdGF0ZTMiLCJfd3AkZWxlbWVudCR1c2VTdGF0ZTQiLCJpbnB1dFBob25lIiwic2VsZWN0UGhvbmUiLCJfd3AkZWxlbWVudCR1c2VTdGF0ZTUiLCJfd3AkZWxlbWVudCR1c2VTdGF0ZTYiLCJpbnB1dEJpcnRoZGF0ZSIsInNlbGVjdEJpcnRoZGF0ZSIsIl93cCRlbGVtZW50JHVzZVN0YXRlNyIsIl93cCRlbGVtZW50JHVzZVN0YXRlOCIsImlucHV0Q29tcGFueSIsInNlbGVjdENvbXBhbnkiLCJpc3N1ZXJLZXkiLCJjb21wYW55TmFtZVN0cmluZyIsInBob25lU3RyaW5nIiwiZ2V0UGhvbmVGaWVsZCIsInNoaXBwaW5nUGhvbmUiLCJiaWxsaW5nUGhvbmUiLCJ1cGRhdGVUb3RhbExhYmVsIiwibmV3VG90YWwiLCJ0b3RhbFNwYW4iLCJyZXBsYWNlV2l0aCIsInVwZGF0ZVRheGVzTGFiZWwiLCJoaWRlRmVlIiwiZmVlIiwiaGlkZSIsInRvdGFsVGF4IiwiZmVlTWFya3VwIiwicmVwbGFjZUZlZSIsIm5ld0ZlZSIsImluc2VydE5ld0ZlZSIsImFmdGVyIiwiaGFuZGxlRmVlcyIsImRvY3VtZW50RWxlbWVudCIsImRpc3BhdGNoRXZlbnQiLCJjb21wbGV0ZSIsIm9uUHJvY2Vzc2luZ1BheW1lbnQiLCJ0b2tlblZhbCIsInZhbCIsIlNVQ0NFU1MiLCJtZXRhIiwicGF5bWVudE1ldGhvZERhdGEiLCJfZGVmaW5lUHJvcGVydHkiLCJwYXltZW50X21ldGhvZCIsInBheW1lbnRfbWV0aG9kX3RpdGxlIiwidGl0bGUiLCJ1bnN1YnNjcmliZVBheW1lbnRQcm9jZXNzaW5nIiwiY29tcGFueUxhYmVsIiwiaGlkZUNvbXBhbnlGaWVsZCIsImNvbXBhbnlQbGFjZWhvbGRlciIsImlzQ29tcGFueUVtcHR5IiwiYmlsbGluZ0RhdGEiLCJjb21wYW55Iiwic2hpcHBpbmdBZGRyZXNzIiwidW5zdWJzY3JpYmVQcm9jZXNzaW5nIiwiZXJyb3JNZXNzYWdlIiwiX2dldFBob25lRmllbGQkbGFiZWxzIiwiX2dldFBob25lRmllbGQiLCJwaG9uZUxhYmVsIiwibGFiZWxzIiwiaW5uZXJUZXh0IiwicGhvbmVQbGFjZWhvbGRlciIsImlzUGhvbmVFbXB0eSIsInBob25lIiwiaXNCaXJ0aGRhdGVWYWxpZCIsInRvZGF5IiwiRGF0ZSIsImJpcnRoZGF0ZSIsInVwZGF0ZUlzc3VlciIsInRhcmdldCIsInVwZGF0ZUNvbXBhbnkiLCJ1cGRhdGVQaG9uZSIsInVwZGF0ZUJpcnRoZGF0ZSIsImZpZWxkTWFya3VwIiwiZmllbGRUeXBlIiwicGxhY2Vob2xkZXIiLCJhcmd1bWVudHMiLCJ1bmRlZmluZWQiLCJjbGFzcyIsImh0bWxGb3IiLCJkYW5nZXJvdXNseVNldElubmVySFRNTCIsIl9faHRtbCIsIm9uQ2hhbmdlIiwiaXNzdWVycyIsImNvbnRlbnQiLCJiaWxsaW5nQ29tcGFueUZpZWxkIiwicXVlcnlTZWxlY3RvciIsInNoaXBwaW5nQ29tcGFueUZpZWxkIiwiaXNCaWxsaW5nQ29tcGFueVJlcXVpcmVkIiwiaGFzQXR0cmlidXRlIiwiaXNTaGlwcGluZ0NvbXBhbnlSZXF1aXJlZCIsImNvbXBhbnlGaWVsZCIsIkZyYWdtZW50IiwiY291bnRyeUNvZGVzIiwiQkUiLCJOTCIsIkRFIiwiQVQiLCJiaXJ0aGRhdGVGaWVsZCIsImJpcnRoZGF0ZVBsYWNlaG9sZGVyIiwicGhvbmVGaWVsZCIsIkxhYmVsIiwiX3JlZjIiLCJjYXJ0RGF0YSIsInVzZVNlbGVjdCIsImdldENhcnREYXRhIiwidG90YWxfcHJpY2UiLCJiaWxsaW5nQWRkcmVzcyIsIm1vbGxpZVBheW1lbnRNZXRob2QiLCJnYXRld2F5RGF0YSIsImF2YWlsYWJsZUdhdGV3YXlzIiwiaXNDb21wYW55RmllbGRWaXNpYmxlIiwiYWRkRXZlbnRMaXN0ZW5lciIsImNyZWRpdGNhcmRTZWxlY3RlZEV2ZW50IiwiXyIsImlzRW1wdHkiLCJlZGl0IiwicGF5bWVudE1ldGhvZElkIiwiY2FuTWFrZVBheW1lbnQiLCJfcmVmMyIsImFsbG93ZWRDb3VudHJpZXMiLCJpbmNsdWRlcyIsImN1cnJlbmN5X2NvZGUiLCJfd2NTZXR0aW5nczIiLCJhcmlhTGFiZWwiLCJzdXBwb3J0cyIsImZlYXR1cmVzIiwid2MiLCJyZWdpc3RlclBheW1lbnRNZXRob2QiLCJ3Y0Jsb2Nrc1JlZ2lzdHJ5IiwiZGVmYXVsdEZpZWxkcyIsImFsbFNldHRpbmdzIiwiX21vbGxpZUJsb2NrRGF0YSRnYXRlIiwiaXNBcHBsZVNlc3Npb24iLCJyZW1vdmVJdGVtIiwicGhvbmVGaWVsZERhdGFzZXQiLCJkYXRhc2V0Iiwic2hvd1Bob25lRmllbGQiLCJmb3JFYWNoIiwicmVnaXN0ZXIiLCJpc0V4cHJlc3NFbmFibGVkIiwiY2FuTWFrZVBheW1lbnRzIiwicmVnaXN0ZXJFeHByZXNzUGF5bWVudE1ldGhvZCIsImRlc2NyaXB0aW9uIiwiZ2F0ZXdheUlkIl0sInNvdXJjZVJvb3QiOiIifQ==
     894//# sourceMappingURL=data:application/json;charset=utf-8;base64,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Y0FBYyxJQUFJM1MsTUFBTSxDQUFDa0MsZUFBZSxDQUFDZ1IsZUFBZSxDQUFDLENBQUMsRUFBRztRQUM5REYsUUFBUSxDQUFDLENBQUM7UUFDVixJQUFJQyxnQkFBZ0IsS0FBSyxJQUFJLEVBQUU7VUFDM0I7UUFDSjtRQUNBLElBQU9FLDRCQUE0QixHQUFJZCxFQUFFLENBQUNFLGdCQUFnQixDQUFuRFksNEJBQTRCO1FBQ25DQSw0QkFBNEIsQ0FBQztVQUN6QnZSLElBQUksRUFBRSxvQ0FBb0M7VUFDMUNpTCxLQUFLLEVBQUUsMEJBQTBCO1VBQ2pDdUcsV0FBVyxFQUFFLDBCQUEwQjtVQUN2QzFELE9BQU8sZUFBRXpKLEtBQUEsQ0FBQUMsYUFBQSxDQUFDdkcsdUVBQXVCLE1BQUMsQ0FBQztVQUNuQzZSLElBQUksZUFBRXZMLEtBQUEsQ0FBQUMsYUFBQSxDQUFDSyw2RUFBNkIsTUFBQyxDQUFDO1VBQ3RDMkwsU0FBUyxFQUFFLFdBQVc7VUFDdEJSLGNBQWMsRUFBRSxTQUFBQSxlQUFBO1lBQUEsT0FBTSxJQUFJO1VBQUE7VUFDMUJELGVBQWUsRUFBRSw0QkFBNEI7VUFDN0M0QixTQUFTLEVBQUUsNEJBQTRCO1VBQ3ZDbEIsUUFBUSxFQUFFO1lBQ05DLFFBQVEsRUFBRSxDQUFDLFVBQVUsQ0FBQztZQUN0QnBSLEtBQUssRUFBRSxDQUFDLFFBQVEsRUFBRSxjQUFjO1VBQ3BDO1FBQ0osQ0FBQyxDQUFDO01BQ047TUFDQTtJQUNKO0lBQ0FnUyxRQUFRLENBQUMsQ0FBQztFQUNkLENBQUMsQ0FBQztBQUNOLENBQUMsRUFDSGhULE1BQU0sRUFBRXFTLEVBQUUsQ0FBQyxDIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vbW9sbGllLXBheW1lbnRzLWZvci13b29jb21tZXJjZS8uL3Jlc291cmNlcy9qcy9hcHBsZVBheUVycm9yLmpzIiwid2VicGFjazovL21vbGxpZS1wYXltZW50cy1mb3Itd29vY29tbWVyY2UvLi9yZXNvdXJjZXMvanMvYXBwbGVQYXlSZXF1ZXN0LmpzIiwid2VicGFjazovL21vbGxpZS1wYXltZW50cy1mb3Itd29vY29tbWVyY2UvLi9yZXNvdXJjZXMvanMvYmxvY2tzL0FwcGxlUGF5QnV0dG9uQ29tcG9uZW50LmpzIiwid2VicGFjazovL21vbGxpZS1wYXltZW50cy1mb3Itd29vY29tbWVyY2UvLi9yZXNvdXJjZXMvanMvYmxvY2tzL0FwcGxlUGF5QnV0dG9uRWRpdG9yQ29tcG9uZW50LmpzIiwid2VicGFjazovL21vbGxpZS1wYXltZW50cy1mb3Itd29vY29tbWVyY2UvLi9yZXNvdXJjZXMvanMvYmxvY2tzL21vbGxpZVBheW1lbnRNZXRob2QuanMiLCJ3ZWJwYWNrOi8vbW9sbGllLXBheW1lbnRzLWZvci13b29jb21tZXJjZS93ZWJwYWNrL2Jvb3RzdHJhcCIsIndlYnBhY2s6Ly9tb2xsaWUtcGF5bWVudHMtZm9yLXdvb2NvbW1lcmNlL3dlYnBhY2svcnVudGltZS9kZWZpbmUgcHJvcGVydHkgZ2V0dGVycyIsIndlYnBhY2s6Ly9tb2xsaWUtcGF5bWVudHMtZm9yLXdvb2NvbW1lcmNlL3dlYnBhY2svcnVudGltZS9oYXNPd25Qcm9wZXJ0eSBzaG9ydGhhbmQiLCJ3ZWJwYWNrOi8vbW9sbGllLXBheW1lbnRzLWZvci13b29jb21tZXJjZS93ZWJwYWNrL3J1bnRpbWUvbWFrZSBuYW1lc3BhY2Ugb2JqZWN0Iiwid2VicGFjazovL21vbGxpZS1wYXltZW50cy1mb3Itd29vY29tbWVyY2UvLi9yZXNvdXJjZXMvanMvbW9sbGllQmxvY2tJbmRleC5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgZnVuY3Rpb24gY3JlYXRlQXBwbGVFcnJvcnMoZXJyb3JzKSB7XG4gICAgY29uc3QgZXJyb3JMaXN0ID0gW11cbiAgICBmb3IgKGNvbnN0IGVycm9yIG9mIGVycm9ycykge1xuICAgICAgICBjb25zdCB7Y29udGFjdEZpZWxkID0gbnVsbCwgY29kZSA9IG51bGwsIG1lc3NhZ2UgPSBudWxsfSA9IGVycm9yXG4gICAgICAgIGNvbnN0IGFwcGxlRXJyb3IgPSBjb250YWN0RmllbGQgPyBuZXcgQXBwbGVQYXlFcnJvcihjb2RlLCBjb250YWN0RmllbGQsIG1lc3NhZ2UpIDogbmV3IEFwcGxlUGF5RXJyb3IoY29kZSlcbiAgICAgICAgZXJyb3JMaXN0LnB1c2goYXBwbGVFcnJvcilcbiAgICB9XG5cbiAgICByZXR1cm4gZXJyb3JMaXN0XG59XG4iLCJleHBvcnQgY29uc3QgcmVxdWVzdCA9IChjb3VudHJ5Q29kZSwgY3VycmVuY3lDb2RlLCB0b3RhbExhYmVsLCBzdWJ0b3RhbCkgPT4ge1xuICAgIHJldHVybiB7XG4gICAgICAgIGNvdW50cnlDb2RlOiBjb3VudHJ5Q29kZSxcbiAgICAgICAgY3VycmVuY3lDb2RlOiBjdXJyZW5jeUNvZGUsXG4gICAgICAgIHN1cHBvcnRlZE5ldHdvcmtzOiBbJ2FtZXgnLCAnbWFlc3RybycsICdtYXN0ZXJDYXJkJywgJ3Zpc2EnLCAndlBheSddLFxuICAgICAgICBtZXJjaGFudENhcGFiaWxpdGllczogWydzdXBwb3J0czNEUyddLFxuICAgICAgICBzaGlwcGluZ1R5cGU6ICdzaGlwcGluZycsXG4gICAgICAgIHJlcXVpcmVkQmlsbGluZ0NvbnRhY3RGaWVsZHM6IFtcbiAgICAgICAgICAgICdwb3N0YWxBZGRyZXNzJyxcbiAgICAgICAgICAgICdlbWFpbCdcbiAgICAgICAgXSxcbiAgICAgICAgcmVxdWlyZWRTaGlwcGluZ0NvbnRhY3RGaWVsZHM6IFtcbiAgICAgICAgICAgICdwb3N0YWxBZGRyZXNzJyxcbiAgICAgICAgICAgICdlbWFpbCdcbiAgICAgICAgXSxcbiAgICAgICAgdG90YWw6IHtcbiAgICAgICAgICAgIGxhYmVsOiB0b3RhbExhYmVsLFxuICAgICAgICAgICAgYW1vdW50OiBzdWJ0b3RhbCxcbiAgICAgICAgICAgIHR5cGU6ICdmaW5hbCdcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsImltcG9ydCB7cmVxdWVzdH0gZnJvbSBcIi4uL2FwcGxlUGF5UmVxdWVzdFwiO1xuaW1wb3J0IHtjcmVhdGVBcHBsZUVycm9yc30gZnJvbSBcIi4uL2FwcGxlUGF5RXJyb3JcIjtcblxuZXhwb3J0IGNvbnN0IEFwcGxlUGF5QnV0dG9uQ29tcG9uZW50ID0gKHsgYnV0dG9uQXR0cmlidXRlcyA9IHt9IH0pID0+IHtcbiAgICBjb25zdCBtb2xsaWVBcHBsZVBheUJsb2NrRGF0YUNhcnQgPSB3aW5kb3cubW9sbGllQXBwbGVQYXlCbG9ja0RhdGFDYXJ0IHx8IHdpbmRvdy5tb2xsaWVCbG9ja0RhdGEubW9sbGllQXBwbGVQYXlCbG9ja0RhdGFDYXJ0XG4gICAgY29uc3Qgbm9uY2UgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcIndvb2NvbW1lcmNlLXByb2Nlc3MtY2hlY2tvdXQtbm9uY2VcIikudmFsdWVcbiAgICBsZXQgdXBkYXRlZENvbnRhY3RJbmZvID0gW11cbiAgICBsZXQgcmVkaXJlY3Rpb25VcmwgPSAnJ1xuICAgIGNvbnN0IHtcbiAgICAgICAgcHJvZHVjdDoge25lZWRTaGlwcGluZyA9IHRydWUsIHN1YnRvdGFsfSxcbiAgICAgICAgc2hvcDoge2NvdW50cnlDb2RlLCBjdXJyZW5jeUNvZGUgPSAnRVVSJywgdG90YWxMYWJlbCA9ICcnfSxcbiAgICAgICAgYWpheFVybCxcbiAgICB9ID0gbW9sbGllQXBwbGVQYXlCbG9ja0RhdGFDYXJ0XG4gICAgY29uc3Qgc3R5bGUgPSB7XG4gICAgICAgIGhlaWdodDogYCR7YnV0dG9uQXR0cmlidXRlcy5oZWlnaHQgfHwgNDh9cHhgLFxuICAgICAgICBib3JkZXJSYWRpdXM6IGAke2J1dHRvbkF0dHJpYnV0ZXMuYm9yZGVyUmFkaXVzIHx8IDR9cHhgXG4gICAgfVxuXG4gICAgY29uc3QgZmluZFNlbGVjdGVkU2hpcHBpbmdNZXRob2QgPSAoc2hpcHBpbmdSYXRlcykgPT4ge1xuICAgICAgICBsZXQgc2hpcHBpbmdSYXRlID0gc2hpcHBpbmdSYXRlcy5maW5kKChzaGlwcGluZ01ldGhvZCkgPT4gc2hpcHBpbmdNZXRob2Quc2VsZWN0ZWQgPT09IHRydWUpXG4gICAgICAgIGNvbnN0IGFwcGxlRm9ybWF0dGVkUmF0ZSA9IHtcbiAgICAgICAgICAgIGFtb3VudDogJycsXG4gICAgICAgICAgICBkZXRhaWw6ICcnLFxuICAgICAgICAgICAgbGFiZWw6IHNoaXBwaW5nUmF0ZS5uYW1lLFxuICAgICAgICAgICAgaWRlbnRpZmllcjogc2hpcHBpbmdSYXRlLnJhdGVfaWQsXG4gICAgICAgICAgICBzZWxlY3RlZDogc2hpcHBpbmdSYXRlLnNlbGVjdGVkLFxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzaGlwcGluZ1JhdGUgPyBhcHBsZUZvcm1hdHRlZFJhdGUgOiAnJ1xuICAgIH1cblxuICAgIGxldCBhcHBsZVBheVNlc3Npb24gPSAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHNlc3Npb24gPSBuZXcgQXBwbGVQYXlTZXNzaW9uKDMsIHJlcXVlc3QoY291bnRyeUNvZGUsIGN1cnJlbmN5Q29kZSwgdG90YWxMYWJlbCwgc3VidG90YWwpKVxuICAgICAgICBjb25zdCBzdG9yZSA9IHdwLmRhdGEuc2VsZWN0KCd3Yy9zdG9yZS9jYXJ0JylcbiAgICAgICAgY29uc3Qgc2hpcHBpbmdSYXRlcyA9IHN0b3JlLmdldFNoaXBwaW5nUmF0ZXMoKT8uWzBdPy5zaGlwcGluZ19yYXRlcztcbiAgICAgICAgbGV0IHNlbGVjdGVkU2hpcHBpbmdNZXRob2QgPSAnJztcbiAgICAgICAgaWYgKHNoaXBwaW5nUmF0ZXMgJiYgc2hpcHBpbmdSYXRlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBzZWxlY3RlZFNoaXBwaW5nTWV0aG9kID0gZmluZFNlbGVjdGVkU2hpcHBpbmdNZXRob2Qoc2hpcHBpbmdSYXRlcywgc2VsZWN0ZWRTaGlwcGluZ01ldGhvZCk7XG4gICAgICAgIH1cbiAgICAgICAgICAgIHNlc3Npb24ub25zaGlwcGluZ21ldGhvZHNlbGVjdGVkID0gZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICAgICAgICBqUXVlcnkuYWpheCh7XG4gICAgICAgICAgICAgICAgdXJsOiBhamF4VXJsLFxuICAgICAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgICAgIGRhdGE6IHtcbiAgICAgICAgICAgICAgICAgICAgYWN0aW9uOiAnbW9sbGllX2FwcGxlX3BheV91cGRhdGVfc2hpcHBpbmdfbWV0aG9kJyxcbiAgICAgICAgICAgICAgICAgICAgc2hpcHBpbmdNZXRob2Q6IGV2ZW50LnNoaXBwaW5nTWV0aG9kLFxuICAgICAgICAgICAgICAgICAgICBjYWxsZXJQYWdlOiAnY2FydCcsXG4gICAgICAgICAgICAgICAgICAgIHNpbXBsaWZpZWRDb250YWN0OiB1cGRhdGVkQ29udGFjdEluZm8sXG4gICAgICAgICAgICAgICAgICAgICd3b29jb21tZXJjZS1wcm9jZXNzLWNoZWNrb3V0LW5vbmNlJzogbm9uY2UsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBzdWNjZXNzOiAoYXBwbGVQYXlTaGlwcGluZ01ldGhvZFVwZGF0ZSwgdGV4dFN0YXR1cywganFYSFIpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IHJlc3BvbnNlID0gYXBwbGVQYXlTaGlwcGluZ01ldGhvZFVwZGF0ZS5kYXRhXG4gICAgICAgICAgICAgICAgICAgIHNlbGVjdGVkU2hpcHBpbmdNZXRob2QgPSBldmVudC5zaGlwcGluZ01ldGhvZFxuICAgICAgICAgICAgICAgICAgICBpZiAoYXBwbGVQYXlTaGlwcGluZ01ldGhvZFVwZGF0ZS5zdWNjZXNzID09PSBmYWxzZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2UuZXJyb3JzID0gY3JlYXRlQXBwbGVFcnJvcnMocmVzcG9uc2UuZXJyb3JzKVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29tcGxldGVTaGlwcGluZ01ldGhvZFNlbGVjdGlvbihyZXNwb25zZSlcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGVycm9yOiAoanFYSFIsIHRleHRTdGF0dXMsIGVycm9yVGhyb3duKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2Fybih0ZXh0U3RhdHVzLCBlcnJvclRocm93bilcbiAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbi5hYm9ydCgpXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICAgICAgc2Vzc2lvbi5vbnNoaXBwaW5nY29udGFjdHNlbGVjdGVkID0gZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICAgICAgICBqUXVlcnkuYWpheCh7XG4gICAgICAgICAgICAgICAgdXJsOiBhamF4VXJsLFxuICAgICAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgICAgIGRhdGE6IHtcbiAgICAgICAgICAgICAgICAgICAgYWN0aW9uOiAnbW9sbGllX2FwcGxlX3BheV91cGRhdGVfc2hpcHBpbmdfY29udGFjdCcsXG4gICAgICAgICAgICAgICAgICAgIHNpbXBsaWZpZWRDb250YWN0OiBldmVudC5zaGlwcGluZ0NvbnRhY3QsXG4gICAgICAgICAgICAgICAgICAgIGNhbGxlclBhZ2U6ICdjYXJ0JyxcbiAgICAgICAgICAgICAgICAgICAgbmVlZFNoaXBwaW5nOiBuZWVkU2hpcHBpbmcsXG4gICAgICAgICAgICAgICAgICAgICd3b29jb21tZXJjZS1wcm9jZXNzLWNoZWNrb3V0LW5vbmNlJzogbm9uY2UsXG4gICAgICAgICAgICAgICAgICAgIHNoaXBwaW5nTWV0aG9kOiBzZWxlY3RlZFNoaXBwaW5nTWV0aG9kLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgc3VjY2VzczogKGFwcGxlUGF5U2hpcHBpbmdDb250YWN0VXBkYXRlLCB0ZXh0U3RhdHVzLCBqcVhIUikgPT4ge1xuICAgICAgICAgICAgICAgICAgICBsZXQgcmVzcG9uc2UgPSBhcHBsZVBheVNoaXBwaW5nQ29udGFjdFVwZGF0ZS5kYXRhXG4gICAgICAgICAgICAgICAgICAgIHVwZGF0ZWRDb250YWN0SW5mbyA9IGV2ZW50LnNoaXBwaW5nQ29udGFjdFxuICAgICAgICAgICAgICAgICAgICBpZiAoYXBwbGVQYXlTaGlwcGluZ0NvbnRhY3RVcGRhdGUuc3VjY2VzcyA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlLmVycm9ycyA9IGNyZWF0ZUFwcGxlRXJyb3JzKHJlc3BvbnNlLmVycm9ycylcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAocmVzcG9uc2UubmV3U2hpcHBpbmdNZXRob2RzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZFNoaXBwaW5nTWV0aG9kID0gcmVzcG9uc2UubmV3U2hpcHBpbmdNZXRob2RzWzBdXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb21wbGV0ZVNoaXBwaW5nQ29udGFjdFNlbGVjdGlvbihyZXNwb25zZSlcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGVycm9yOiAoanFYSFIsIHRleHRTdGF0dXMsIGVycm9yVGhyb3duKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2Fybih0ZXh0U3RhdHVzLCBlcnJvclRocm93bilcbiAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbi5hYm9ydCgpXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICAgICAgc2Vzc2lvbi5vbnZhbGlkYXRlbWVyY2hhbnQgPSAoYXBwbGVQYXlWYWxpZGF0ZU1lcmNoYW50RXZlbnQpID0+IHtcbiAgICAgICAgICAgIGpRdWVyeS5hamF4KHtcbiAgICAgICAgICAgICAgICB1cmw6IGFqYXhVcmwsXG4gICAgICAgICAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgICAgICAgICAgZGF0YToge1xuICAgICAgICAgICAgICAgICAgICBhY3Rpb246ICdtb2xsaWVfYXBwbGVfcGF5X3ZhbGlkYXRpb24nLFxuICAgICAgICAgICAgICAgICAgICB2YWxpZGF0aW9uVXJsOiBhcHBsZVBheVZhbGlkYXRlTWVyY2hhbnRFdmVudC52YWxpZGF0aW9uVVJMLFxuICAgICAgICAgICAgICAgICAgICAnd29vY29tbWVyY2UtcHJvY2Vzcy1jaGVja291dC1ub25jZSc6IG5vbmNlLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgc3VjY2VzczogKG1lcmNoYW50U2Vzc2lvbiwgdGV4dFN0YXR1cywganFYSFIpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG1lcmNoYW50U2Vzc2lvbi5zdWNjZXNzID09PSB0cnVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uLmNvbXBsZXRlTWVyY2hhbnRWYWxpZGF0aW9uKEpTT04ucGFyc2UobWVyY2hhbnRTZXNzaW9uLmRhdGEpKVxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKG1lcmNoYW50U2Vzc2lvbi5kYXRhKVxuICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbi5hYm9ydCgpXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGVycm9yOiAoanFYSFIsIHRleHRTdGF0dXMsIGVycm9yVGhyb3duKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2Fybih0ZXh0U3RhdHVzLCBlcnJvclRocm93bilcbiAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbi5hYm9ydCgpXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICAgICAgc2Vzc2lvbi5vbnBheW1lbnRhdXRob3JpemVkID0gKEFwcGxlUGF5UGF5bWVudCkgPT4ge1xuICAgICAgICAgICAgY29uc3Qge2JpbGxpbmdDb250YWN0LCBzaGlwcGluZ0NvbnRhY3R9ID0gQXBwbGVQYXlQYXltZW50LnBheW1lbnRcblxuICAgICAgICAgICAgalF1ZXJ5LmFqYXgoe1xuICAgICAgICAgICAgICAgIHVybDogYWpheFVybCxcbiAgICAgICAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICAgICAgICBkYXRhOiB7XG4gICAgICAgICAgICAgICAgICAgIGFjdGlvbjogJ21vbGxpZV9hcHBsZV9wYXlfY3JlYXRlX29yZGVyX2NhcnQnLFxuICAgICAgICAgICAgICAgICAgICBzaGlwcGluZ0NvbnRhY3Q6IEFwcGxlUGF5UGF5bWVudC5wYXltZW50LnNoaXBwaW5nQ29udGFjdCxcbiAgICAgICAgICAgICAgICAgICAgYmlsbGluZ0NvbnRhY3Q6IEFwcGxlUGF5UGF5bWVudC5wYXltZW50LmJpbGxpbmdDb250YWN0LFxuICAgICAgICAgICAgICAgICAgICB0b2tlbjogQXBwbGVQYXlQYXltZW50LnBheW1lbnQudG9rZW4sXG4gICAgICAgICAgICAgICAgICAgIHNoaXBwaW5nTWV0aG9kOiBzZWxlY3RlZFNoaXBwaW5nTWV0aG9kLFxuICAgICAgICAgICAgICAgICAgICAnbW9sbGllLXBheW1lbnRzLWZvci13b29jb21tZXJjZV9pc3N1ZXJfYXBwbGVwYXknOiAnYXBwbGVwYXknLFxuICAgICAgICAgICAgICAgICAgICAnd29vY29tbWVyY2UtcHJvY2Vzcy1jaGVja291dC1ub25jZSc6IG5vbmNlLFxuICAgICAgICAgICAgICAgICAgICAnYmlsbGluZ19maXJzdF9uYW1lJzogYmlsbGluZ0NvbnRhY3QuZ2l2ZW5OYW1lIHx8ICcnLFxuICAgICAgICAgICAgICAgICAgICAnYmlsbGluZ19sYXN0X25hbWUnOiBiaWxsaW5nQ29udGFjdC5mYW1pbHlOYW1lIHx8ICcnLFxuICAgICAgICAgICAgICAgICAgICAnYmlsbGluZ19jb21wYW55JzogJycsXG4gICAgICAgICAgICAgICAgICAgICdiaWxsaW5nX2NvdW50cnknOiBiaWxsaW5nQ29udGFjdC5jb3VudHJ5Q29kZSB8fCAnJyxcbiAgICAgICAgICAgICAgICAgICAgJ2JpbGxpbmdfYWRkcmVzc18xJzogYmlsbGluZ0NvbnRhY3QuYWRkcmVzc0xpbmVzWzBdIHx8ICcnLFxuICAgICAgICAgICAgICAgICAgICAnYmlsbGluZ19hZGRyZXNzXzInOiBiaWxsaW5nQ29udGFjdC5hZGRyZXNzTGluZXNbMV0gfHwgJycsXG4gICAgICAgICAgICAgICAgICAgICdiaWxsaW5nX3Bvc3Rjb2RlJzogYmlsbGluZ0NvbnRhY3QucG9zdGFsQ29kZSB8fCAnJyxcbiAgICAgICAgICAgICAgICAgICAgJ2JpbGxpbmdfY2l0eSc6IGJpbGxpbmdDb250YWN0LmxvY2FsaXR5IHx8ICcnLFxuICAgICAgICAgICAgICAgICAgICAnYmlsbGluZ19zdGF0ZSc6IGJpbGxpbmdDb250YWN0LmFkbWluaXN0cmF0aXZlQXJlYSB8fCAnJyxcbiAgICAgICAgICAgICAgICAgICAgJ2JpbGxpbmdfcGhvbmUnOiBiaWxsaW5nQ29udGFjdC5waG9uZU51bWJlciB8fCAnMDAwMDAwMDAwMDAwJyxcbiAgICAgICAgICAgICAgICAgICAgJ2JpbGxpbmdfZW1haWwnOiBzaGlwcGluZ0NvbnRhY3QuZW1haWxBZGRyZXNzIHx8ICcnLFxuICAgICAgICAgICAgICAgICAgICAnc2hpcHBpbmdfZmlyc3RfbmFtZSc6IHNoaXBwaW5nQ29udGFjdC5naXZlbk5hbWUgfHwgJycsXG4gICAgICAgICAgICAgICAgICAgICdzaGlwcGluZ19sYXN0X25hbWUnOiBzaGlwcGluZ0NvbnRhY3QuZmFtaWx5TmFtZSB8fCAnJyxcbiAgICAgICAgICAgICAgICAgICAgJ3NoaXBwaW5nX2NvbXBhbnknOiAnJyxcbiAgICAgICAgICAgICAgICAgICAgJ3NoaXBwaW5nX2NvdW50cnknOiBzaGlwcGluZ0NvbnRhY3QuY291bnRyeUNvZGUgfHwgJycsXG4gICAgICAgICAgICAgICAgICAgICdzaGlwcGluZ19hZGRyZXNzXzEnOiBzaGlwcGluZ0NvbnRhY3QuYWRkcmVzc0xpbmVzWzBdIHx8ICcnLFxuICAgICAgICAgICAgICAgICAgICAnc2hpcHBpbmdfYWRkcmVzc18yJzogc2hpcHBpbmdDb250YWN0LmFkZHJlc3NMaW5lc1sxXSB8fCAnJyxcbiAgICAgICAgICAgICAgICAgICAgJ3NoaXBwaW5nX3Bvc3Rjb2RlJzogc2hpcHBpbmdDb250YWN0LnBvc3RhbENvZGUgfHwgJycsXG4gICAgICAgICAgICAgICAgICAgICdzaGlwcGluZ19jaXR5Jzogc2hpcHBpbmdDb250YWN0LmxvY2FsaXR5IHx8ICcnLFxuICAgICAgICAgICAgICAgICAgICAnc2hpcHBpbmdfc3RhdGUnOiBzaGlwcGluZ0NvbnRhY3QuYWRtaW5pc3RyYXRpdmVBcmVhIHx8ICcnLFxuICAgICAgICAgICAgICAgICAgICAnc2hpcHBpbmdfcGhvbmUnOiBzaGlwcGluZ0NvbnRhY3QucGhvbmVOdW1iZXIgfHwgJzAwMDAwMDAwMDAwMCcsXG4gICAgICAgICAgICAgICAgICAgICdzaGlwcGluZ19lbWFpbCc6IHNoaXBwaW5nQ29udGFjdC5lbWFpbEFkZHJlc3MgfHwgJycsXG4gICAgICAgICAgICAgICAgICAgICdvcmRlcl9jb21tZW50cyc6ICcnLFxuICAgICAgICAgICAgICAgICAgICAncGF5bWVudF9tZXRob2QnOiAnbW9sbGllX3djX2dhdGV3YXlfYXBwbGVwYXknLFxuICAgICAgICAgICAgICAgICAgICAnX3dwX2h0dHBfcmVmZXJlcic6ICcvP3djLWFqYXg9dXBkYXRlX29yZGVyX3JldmlldydcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHN1Y2Nlc3M6IChhdXRob3JpemF0aW9uUmVzdWx0LCB0ZXh0U3RhdHVzLCBqcVhIUikgPT4ge1xuICAgICAgICAgICAgICAgICAgICBsZXQgcmVzdWx0ID0gYXV0aG9yaXphdGlvblJlc3VsdC5kYXRhXG4gICAgICAgICAgICAgICAgICAgIGlmIChhdXRob3JpemF0aW9uUmVzdWx0LnN1Y2Nlc3MgPT09IHRydWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlZGlyZWN0aW9uVXJsID0gcmVzdWx0WydyZXR1cm5VcmwnXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb24uY29tcGxldGVQYXltZW50KHJlc3VsdFsncmVzcG9uc2VUb0FwcGxlJ10pXG4gICAgICAgICAgICAgICAgICAgICAgICB3aW5kb3cubG9jYXRpb24uaHJlZiA9IHJlZGlyZWN0aW9uVXJsXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQuZXJyb3JzID0gY3JlYXRlQXBwbGVFcnJvcnMocmVzdWx0LmVycm9ycylcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb24uY29tcGxldGVQYXltZW50KHJlc3VsdClcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgZXJyb3I6IChqcVhIUiwgdGV4dFN0YXR1cywgZXJyb3JUaHJvd24pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKHRleHRTdGF0dXMsIGVycm9yVGhyb3duKVxuICAgICAgICAgICAgICAgICAgICBzZXNzaW9uLmFib3J0KClcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgICAgICBzZXNzaW9uLmJlZ2luKClcbiAgICB9XG5cbiAgICByZXR1cm4gKFxuICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICBpZD1cIm1vbGxpZV9hcHBsZXBheV9idXR0b25cIlxuICAgICAgICAgICAgY2xhc3NOYW1lPVwiYXBwbGUtcGF5LWJ1dHRvbiBhcHBsZS1wYXktYnV0dG9uLWJsYWNrXCJcbiAgICAgICAgICAgIG9uQ2xpY2s9eyhldmVudCkgPT4ge1xuICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgYXBwbGVQYXlTZXNzaW9uKCk7XG4gICAgICAgICAgICB9fVxuICAgICAgICAgICAgc3R5bGU9e3N0eWxlfVxuICAgICAgICA+XG4gICAgICAgIDwvYnV0dG9uPlxuICAgICk7XG59XG5cbmV4cG9ydCBkZWZhdWx0IEFwcGxlUGF5QnV0dG9uQ29tcG9uZW50O1xuIiwiZXhwb3J0IGNvbnN0IEFwcGxlUGF5QnV0dG9uRWRpdG9yQ29tcG9uZW50ID0gKHsgYnV0dG9uQXR0cmlidXRlcyA9IHt9IH0pID0+IHtcbiAgICBjb25zdCBzdHlsZSA9IHtcbiAgICAgICAgaGVpZ2h0OiBgJHtidXR0b25BdHRyaWJ1dGVzLmhlaWdodCB8fCA0OH1weGAsXG4gICAgICAgIGJvcmRlclJhZGl1czogYCR7YnV0dG9uQXR0cmlidXRlcy5ib3JkZXJSYWRpdXMgfHwgNH1weGBcbiAgICB9XG5cbiAgICByZXR1cm4gKFxuICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICBpZD1cIm1vbGxpZV9hcHBsZXBheV9idXR0b25cIlxuICAgICAgICAgICAgY2xhc3NOYW1lPVwiYXBwbGUtcGF5LWJ1dHRvbiBhcHBsZS1wYXktYnV0dG9uLWJsYWNrXCJcbiAgICAgICAgICAgIHN0eWxlPXtzdHlsZX1cbiAgICAgICAgPlxuICAgICAgICA8L2J1dHRvbj5cbiAgICApO1xufTtcbmV4cG9ydCBkZWZhdWx0IEFwcGxlUGF5QnV0dG9uRWRpdG9yQ29tcG9uZW50O1xuIiwibGV0IGNhY2hlZEF2YWlsYWJsZUdhdGV3YXlzID0ge307XG5cbmZ1bmN0aW9uIGZvcm1hdFByaWNlTGlrZVdjKHByaWNlKSB7XG4gICAgLy8gdG9kbyBhZGQgdGhvdXNhbmRTZXBhcmF0b3JcbiAgICByZXR1cm4gd2NTZXR0aW5ncy5jdXJyZW5jeS5wcmljZUZvcm1hdC5yZXBsYWNlKCclMSRzJywgd2NTZXR0aW5ncy5jdXJyZW5jeS5zeW1ib2wpLnJlcGxhY2UoJyUyJHMnLHByaWNlLnRvRml4ZWQod2NTZXR0aW5ncy5jdXJyZW5jeS5wcmVjaXNpb24pLnJlcGxhY2UoJy4nLCB3Y1NldHRpbmdzLmN1cnJlbmN5LmRlY2ltYWxTZXBhcmF0b3IpKTtcbn1cblxuZnVuY3Rpb24gc2V0QXZhaWxhYmxlR2F0ZXdheXMoY291bnRyeSwgY3VycmVuY3lDb2RlLCBkYXRhKSB7XG4gICAgY2FjaGVkQXZhaWxhYmxlR2F0ZXdheXMgPSB7XG4gICAgICAgIC4uLmNhY2hlZEF2YWlsYWJsZUdhdGV3YXlzLFxuICAgICAgICAuLi5kYXRhXG4gICAgfTtcbn1cbmZ1bmN0aW9uIHVzZU1vbGxpZUF2YWlsYWJsZUdhdGV3YXlzKGJpbGxpbmcsIGN1cnJlbmN5Q29kZSwgY2FydFRvdGFsLCBmaWx0ZXJzLCBhamF4VXJsKSB7XG4gICAgbGV0IGNvdW50cnkgPSBiaWxsaW5nLmNvdW50cnk7XG4gICAgY29uc3QgY29kZSA9IGN1cnJlbmN5Q29kZTtcbiAgICBjb25zdCB2YWx1ZSA9IGNhcnRUb3RhbDtcbiAgICBpZiAoIWNvdW50cnkpIHtcbiAgICAgICAgY291bnRyeSA9IHdjU2V0dGluZ3M/LmJhc2VMb2NhdGlvbi5jb3VudHJ5O1xuICAgIH1cblxuICAgIHdwLmVsZW1lbnQudXNlRWZmZWN0KCgpID0+IHtcbiAgICAgICAgaWYgKCFjb3VudHJ5KSByZXR1cm47XG4gICAgICAgIGNvbnN0IGN1cnJlbmN5Q29kZSA9IGNvZGU7XG4gICAgICAgIGNvbnN0IGNhcnRUb3RhbCA9IHZhbHVlO1xuICAgICAgICBjb25zdCBjdXJyZW50RmlsdGVyS2V5ID0gY3VycmVuY3lDb2RlICsgXCItXCIgKyBjb3VudHJ5O1xuICAgICAgICBpZiAoY2FjaGVkQXZhaWxhYmxlR2F0ZXdheXMuaGFzT3duUHJvcGVydHkoY3VycmVudEZpbHRlcktleSkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBmZXRjaChcbiAgICAgICAgICAgIGFqYXhVcmwsXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgICAgICAgICAgaGVhZGVyczoge1xuICAgICAgICAgICAgICAgICAgICBcIkNvbnRlbnQtVHlwZVwiOiBcImFwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZFwiLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgYm9keTogbmV3IFVSTFNlYXJjaFBhcmFtcyh7XG4gICAgICAgICAgICAgICAgICAgIGFjdGlvbjogJ21vbGxpZV9jaGVja291dF9ibG9ja3NfY2FubWFrZXBheW1lbnQnLFxuICAgICAgICAgICAgICAgICAgICBjdXJyZW5jeTogY3VycmVuY3lDb2RlLFxuICAgICAgICAgICAgICAgICAgICBiaWxsaW5nQ291bnRyeTogY291bnRyeSxcbiAgICAgICAgICAgICAgICAgICAgY2FydFRvdGFsLFxuICAgICAgICAgICAgICAgICAgICBwYXltZW50TG9jYWxlOiBmaWx0ZXJzLnBheW1lbnRMb2NhbGVcbiAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIH1cbiAgICAgICAgKS50aGVuKHJlc3BvbnNlID0+IHJlc3BvbnNlLmpzb24oKSkudGhlbihkYXRhID0+IHtcbiAgICAgICAgICAgIHNldEF2YWlsYWJsZUdhdGV3YXlzKGNvdW50cnksIGN1cnJlbmN5Q29kZSwgZGF0YS5kYXRhKTtcbiAgICAgICAgICAgIGNvbnN0IGNhcnRUb3RhbHMgPSB3cC5kYXRhLnNlbGVjdCgnd2Mvc3RvcmUvY2FydCcpLmdldENhcnRUb3RhbHMoKTtcbiAgICAgICAgICAgIC8vIERpc3BhdGNoIHRoZW0gYWdhaW4gdG8gdHJpZ2dlciBhIHJlLXJlbmRlcjpcbiAgICAgICAgICAgIHdwLmRhdGEuZGlzcGF0Y2goJ3djL3N0b3JlL2NhcnQnKS5zZXRDYXJ0RGF0YSh7Li4uY2FydFRvdGFsc30pO1xuICAgICAgICB9KTtcbiAgICB9LCBbYmlsbGluZywgY3VycmVuY3lDb2RlLCBmaWx0ZXJzLnBheW1lbnRMb2NhbGVdKTtcblxuICAgIHJldHVybiBjYWNoZWRBdmFpbGFibGVHYXRld2F5cztcbn1cblxuLy8gQ29tcG9uZW50IHRoYXQgcnVucyB0aGUgaG9vayBidXQgZG9lcyBub3QgcmVuZGVyIGFueXRoaW5nLlxuZnVuY3Rpb24gTW9sbGllR2F0ZXdheVVwZGF0ZXIoeyBiaWxsaW5nLCBjdXJyZW5jeUNvZGUsIGNhcnRUb3RhbCwgZmlsdGVycywgYWpheFVybH0pIHtcblxuICAgIHVzZU1vbGxpZUF2YWlsYWJsZUdhdGV3YXlzKGJpbGxpbmcsIGN1cnJlbmN5Q29kZSwgY2FydFRvdGFsLCBmaWx0ZXJzLCBhamF4VXJsKTtcbiAgICByZXR1cm4gbnVsbDtcbn1cblxubGV0IG9uU3VibWl0TG9jYWxcbmxldCBhY3RpdmVQYXltZW50TWV0aG9kTG9jYWxcbmxldCBjcmVkaXRDYXJkU2VsZWN0ZWQgPSBuZXcgRXZlbnQoXCJtb2xsaWVfY3JlZGl0Y2FyZF9jb21wb25lbnRfc2VsZWN0ZWRcIiwge2J1YmJsZXM6IHRydWV9KTtcbmNvbnN0IE1vbGxpZUNvbXBvbmVudCA9IChwcm9wcykgPT4ge1xuICAgIGxldCB7b25TdWJtaXQsIGFjdGl2ZVBheW1lbnRNZXRob2QsIGJpbGxpbmcsIGl0ZW0sIHVzZUVmZmVjdCwgYWpheFVybCwgalF1ZXJ5LCBlbWl0UmVzcG9uc2UsIGV2ZW50UmVnaXN0cmF0aW9uLCByZXF1aXJlZEZpZWxkcywgc2hpcHBpbmdEYXRhLCBpc1Bob25lRmllbGRWaXNpYmxlfSA9IHByb3BzXG4gICAgY29uc3QgeyAgcmVzcG9uc2VUeXBlcyB9ID0gZW1pdFJlc3BvbnNlO1xuICAgIGNvbnN0IHtvblBheW1lbnRTZXR1cCwgb25DaGVja291dFZhbGlkYXRpb259ID0gZXZlbnRSZWdpc3RyYXRpb247XG4gICAgaWYgKCFpdGVtIHx8ICFpdGVtLm5hbWUpIHtcbiAgICAgICAgcmV0dXJuIDxkaXY+TG9hZGluZyBwYXltZW50IG1ldGhvZHMuLi48L2Rpdj47XG4gICAgfVxuICAgIGNvbnN0IFsgc2VsZWN0ZWRJc3N1ZXIsIHNlbGVjdElzc3VlciBdID0gd3AuZWxlbWVudC51c2VTdGF0ZSgnJyk7XG4gICAgY29uc3QgWyBpbnB1dFBob25lLCBzZWxlY3RQaG9uZSBdID0gd3AuZWxlbWVudC51c2VTdGF0ZSgnJyk7XG4gICAgY29uc3QgWyBpbnB1dEJpcnRoZGF0ZSwgc2VsZWN0QmlydGhkYXRlIF0gPSB3cC5lbGVtZW50LnVzZVN0YXRlKCcnKTtcbiAgICBjb25zdCBbIGlucHV0Q29tcGFueSwgc2VsZWN0Q29tcGFueSBdID0gd3AuZWxlbWVudC51c2VTdGF0ZSgnJyk7XG4gICAgY29uc3QgaXNzdWVyS2V5ID0gJ21vbGxpZS1wYXltZW50cy1mb3Itd29vY29tbWVyY2VfaXNzdWVyXycgKyBhY3RpdmVQYXltZW50TWV0aG9kXG4gICAgY29uc3Qge2NvbXBhbnlOYW1lU3RyaW5nLCBwaG9uZVN0cmluZ30gPSByZXF1aXJlZEZpZWxkc1xuICAgIGZ1bmN0aW9uIGdldFBob25lRmllbGQoKVxuICAgIHtcbiAgICAgICAgY29uc3Qgc2hpcHBpbmdQaG9uZSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzaGlwcGluZy1waG9uZScpO1xuICAgICAgICBjb25zdCBiaWxsaW5nUGhvbmUgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYmlsbGluZy1waG9uZScpO1xuICAgICAgICByZXR1cm4gYmlsbGluZ1Bob25lIHx8IHNoaXBwaW5nUGhvbmU7XG4gICAgfVxuICAgIGZ1bmN0aW9uIHVwZGF0ZVRvdGFsTGFiZWwobmV3VG90YWwpIHtcbiAgICAgICAgbGV0IHRvdGFsU3BhbiA9IFwiPHNwYW4gY2xhc3M9J3djLWJsb2NrLWZvcm1hdHRlZC1tb25leS1hbW91bnQgd2MtYmxvY2stY29tcG9uZW50cy1mb3JtYXR0ZWQtbW9uZXktYW1vdW50IHdjLWJsb2NrLWNvbXBvbmVudHMtdG90YWxzLWl0ZW1fX3ZhbHVlJz5cIiArIGZvcm1hdFByaWNlTGlrZVdjKG5ld1RvdGFsKSArIFwiPC9zcGFuPlwiXG4gICAgICAgIGxldCB0b3RhbCA9IGpRdWVyeSgnLndjLWJsb2NrLWNvbXBvbmVudHMtdG90YWxzLWZvb3Rlci1pdGVtIC53Yy1ibG9jay1mb3JtYXR0ZWQtbW9uZXktYW1vdW50OmZpcnN0JylcbiAgICAgICAgdG90YWwucmVwbGFjZVdpdGgodG90YWxTcGFuKVxuICAgIH1cbiAgICBmdW5jdGlvbiB1cGRhdGVUYXhlc0xhYmVsKG5ld1RvdGFsKSB7XG4gICAgICAgIGxldCB0b3RhbFNwYW4gPSBcIjxzcGFuIGNsYXNzPSd3Yy1ibG9jay1mb3JtYXR0ZWQtbW9uZXktYW1vdW50IHdjLWJsb2NrLWNvbXBvbmVudHMtZm9ybWF0dGVkLW1vbmV5LWFtb3VudCB3Yy1ibG9jay1jb21wb25lbnRzLXRvdGFscy1pdGVtX192YWx1ZSc+XCIgKyBmb3JtYXRQcmljZUxpa2VXYyhuZXdUb3RhbCkgKyBcIjwvc3Bhbj5cIlxuICAgICAgICBsZXQgdG90YWwgPSBqUXVlcnkoJ2Rpdi53cC1ibG9jay13b29jb21tZXJjZS1jaGVja291dC1vcmRlci1zdW1tYXJ5LXRheGVzLWJsb2NrLndjLWJsb2NrLWNvbXBvbmVudHMtdG90YWxzLXdyYXBwZXIgPiBkaXYgPiBzcGFuLndjLWJsb2NrLWZvcm1hdHRlZC1tb25leS1hbW91bnQud2MtYmxvY2stY29tcG9uZW50cy1mb3JtYXR0ZWQtbW9uZXktYW1vdW50LndjLWJsb2NrLWNvbXBvbmVudHMtdG90YWxzLWl0ZW1fX3ZhbHVlOmZpcnN0JylcbiAgICAgICAgdG90YWwucmVwbGFjZVdpdGgodG90YWxTcGFuKVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGhpZGVGZWUoZmVlLCByZXNwb25zZSkge1xuICAgICAgICBmZWU/LmhpZGUoKVxuICAgICAgICB1cGRhdGVUb3RhbExhYmVsKHJlc3BvbnNlLmRhdGEubmV3VG90YWwpO1xuICAgICAgICB1cGRhdGVUYXhlc0xhYmVsKHJlc3BvbnNlLmRhdGEudG90YWxUYXgpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGZlZU1hcmt1cChyZXNwb25zZSkge1xuICAgICAgICByZXR1cm4gXCI8ZGl2IGNsYXNzPSd3Yy1ibG9jay1jb21wb25lbnRzLXRvdGFscy1pdGVtIHdjLWJsb2NrLWNvbXBvbmVudHMtdG90YWxzLWZlZXMnPlwiICtcbiAgICAgICAgICAgIFwiPHNwYW4gY2xhc3M9J3djLWJsb2NrLWNvbXBvbmVudHMtdG90YWxzLWl0ZW1fX2xhYmVsJz5cIlxuICAgICAgICAgICAgKyByZXNwb25zZS5kYXRhLm5hbWVcbiAgICAgICAgICAgICsgXCI8L3NwYW4+XCIgK1xuICAgICAgICAgICAgXCI8c3BhbiBjbGFzcz0nd2MtYmxvY2stZm9ybWF0dGVkLW1vbmV5LWFtb3VudCB3Yy1ibG9jay1jb21wb25lbnRzLWZvcm1hdHRlZC1tb25leS1hbW91bnQgd2MtYmxvY2stY29tcG9uZW50cy10b3RhbHMtaXRlbV9fdmFsdWUnPlwiXG4gICAgICAgICAgICArIGZvcm1hdFByaWNlTGlrZVdjKHJlc3BvbnNlLmRhdGEuYW1vdW50KVxuICAgICAgICAgICAgKyBcIjwvc3Bhbj5cIiArXG4gICAgICAgICAgICBcIjxkaXYgY2xhc3M9J3djLWJsb2NrLWNvbXBvbmVudHMtdG90YWxzLWl0ZW1fX2Rlc2NyaXB0aW9uJz5cIiArXG4gICAgICAgICAgICBcIjwvZGl2PlwiICtcbiAgICAgICAgICAgIFwiPC9kaXY+XCI7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcmVwbGFjZUZlZShmZWUsIG5ld0ZlZSwgcmVzcG9uc2UpIHtcbiAgICAgICAgZmVlLnJlcGxhY2VXaXRoKG5ld0ZlZSlcbiAgICAgICAgdXBkYXRlVG90YWxMYWJlbChyZXNwb25zZS5kYXRhLm5ld1RvdGFsKTtcbiAgICAgICAgdXBkYXRlVGF4ZXNMYWJlbChyZXNwb25zZS5kYXRhLnRvdGFsVGF4KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpbnNlcnROZXdGZWUobmV3RmVlLCByZXNwb25zZSkge1xuICAgICAgICBjb25zdCBzdWJ0b3RhbCA9IGpRdWVyeSgnLndjLWJsb2NrLWNvbXBvbmVudHMtdG90YWxzLWl0ZW06Zmlyc3QnKVxuICAgICAgICBzdWJ0b3RhbC5hZnRlcihuZXdGZWUpXG4gICAgICAgIHVwZGF0ZVRvdGFsTGFiZWwocmVzcG9uc2UuZGF0YS5uZXdUb3RhbCk7XG4gICAgICAgIHVwZGF0ZVRheGVzTGFiZWwocmVzcG9uc2UuZGF0YS50b3RhbFRheCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaGFuZGxlRmVlcyhyZXNwb25zZSkge1xuICAgICAgICBjb25zdCBmZWUgPSBqUXVlcnkoJy53Yy1ibG9jay1jb21wb25lbnRzLXRvdGFscy1mZWVzJylcbiAgICAgICAgaWYgKCFyZXNwb25zZS5kYXRhLmFtb3VudCkge1xuICAgICAgICAgICAgaGlkZUZlZShmZWUsIHJlc3BvbnNlKTtcbiAgICAgICAgICAgIHJldHVyblxuICAgICAgICB9XG5cbiAgICAgICAgbGV0IG5ld0ZlZSA9IGZlZU1hcmt1cChyZXNwb25zZSk7XG4gICAgICAgIGlmIChmZWUubGVuZ3RoKSB7XG4gICAgICAgICAgICByZXBsYWNlRmVlKGZlZSwgbmV3RmVlLCByZXNwb25zZSk7XG4gICAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuICAgICAgICBpbnNlcnROZXdGZWUobmV3RmVlLCByZXNwb25zZSk7XG4gICAgfVxuXG4gICAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICAgICAgaWYoYWN0aXZlUGF5bWVudE1ldGhvZExvY2FsICE9PSBhY3RpdmVQYXltZW50TWV0aG9kICYmIGFjdGl2ZVBheW1lbnRNZXRob2QgPT09ICdtb2xsaWVfd2NfZ2F0ZXdheV9jcmVkaXRjYXJkJyl7XG4gICAgICAgICAgICBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuZGlzcGF0Y2hFdmVudChjcmVkaXRDYXJkU2VsZWN0ZWQpO1xuICAgICAgICB9XG4gICAgICAgIGFjdGl2ZVBheW1lbnRNZXRob2RMb2NhbCA9IGFjdGl2ZVBheW1lbnRNZXRob2RcbiAgICAgICAgalF1ZXJ5LmFqYXgoe1xuICAgICAgICAgICAgdXJsOiBhamF4VXJsLFxuICAgICAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgICAgICBkYXRhOiB7XG4gICAgICAgICAgICAgICAgYWN0aW9uOiAnbW9sbGllX2NoZWNrb3V0X2Jsb2Nrc19zdXJjaGFnZScsXG4gICAgICAgICAgICAgICAgbWV0aG9kOiBhY3RpdmVQYXltZW50TWV0aG9kXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgY29tcGxldGU6IChqcVhIUiwgdGV4dFN0YXR1cykgPT4ge1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHN1Y2Nlc3M6IChyZXNwb25zZSwgdGV4dFN0YXR1cywganFYSFIpID0+IHtcbiAgICAgICAgICAgICAgICBoYW5kbGVGZWVzKHJlc3BvbnNlKVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGVycm9yOiAoanFYSFIsIHRleHRTdGF0dXMsIGVycm9yVGhyb3duKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS53YXJuKHRleHRTdGF0dXMsIGVycm9yVGhyb3duKVxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSlcbiAgICB9LCBbYWN0aXZlUGF5bWVudE1ldGhvZCwgYmlsbGluZy5jYXJ0VG90YWxdKVxuXG4gICAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICAgICAgY29uc3Qgb25Qcm9jZXNzaW5nUGF5bWVudCA9ICgpID0+IHtcbiAgICAgICAgICAgIGxldCBkYXRhID0ge1xuICAgICAgICAgICAgICAgIHBheW1lbnRfbWV0aG9kOiBhY3RpdmVQYXltZW50TWV0aG9kLFxuICAgICAgICAgICAgICAgIHBheW1lbnRfbWV0aG9kX3RpdGxlOiBpdGVtLnRpdGxlLFxuICAgICAgICAgICAgICAgIFtpc3N1ZXJLZXldOiBzZWxlY3RlZElzc3VlcixcbiAgICAgICAgICAgICAgICBiaWxsaW5nX3Bob25lOiBpbnB1dFBob25lLFxuICAgICAgICAgICAgICAgIGJpbGxpbmdfY29tcGFueV9iaWxsaWU6IGlucHV0Q29tcGFueSxcbiAgICAgICAgICAgICAgICBiaWxsaW5nX2JpcnRoZGF0ZTogaW5wdXRCaXJ0aGRhdGUsXG4gICAgICAgICAgICAgICAgY2FyZFRva2VuOiAnJyxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zdCB0b2tlblZhbCA9IGpRdWVyeSgnLm1vbGxpZS1jb21wb25lbnRzID4gaW5wdXQnKS52YWwoKVxuICAgICAgICAgICAgaWYgKHRva2VuVmFsKSB7XG4gICAgICAgICAgICAgICAgZGF0YS5jYXJkVG9rZW4gPSB0b2tlblZhbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgdHlwZTogcmVzcG9uc2VUeXBlcy5TVUNDRVNTLFxuICAgICAgICAgICAgICAgIG1ldGE6IHtcbiAgICAgICAgICAgICAgICAgICAgcGF5bWVudE1ldGhvZERhdGE6IGRhdGFcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHVuc3Vic2NyaWJlUGF5bWVudFByb2Nlc3NpbmcgPSBvblBheW1lbnRTZXR1cChcbiAgICAgICAgICAgIG9uUHJvY2Vzc2luZ1BheW1lbnRcbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgICAgIHVuc3Vic2NyaWJlUGF5bWVudFByb2Nlc3NpbmcoKVxuICAgICAgICB9O1xuXG4gICAgfSwgW3NlbGVjdGVkSXNzdWVyLCBvblBheW1lbnRTZXR1cCwgaW5wdXRQaG9uZSwgaW5wdXRDb21wYW55LCBpbnB1dEJpcnRoZGF0ZV0pXG5cbiAgICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgICAgICBsZXQgY29tcGFueUxhYmVsID0galF1ZXJ5KCdkaXYud2MtYmxvY2stY29tcG9uZW50cy10ZXh0LWlucHV0LndjLWJsb2NrLWNvbXBvbmVudHMtYWRkcmVzcy1mb3JtX19jb21wYW55ID4gbGFiZWwnKVxuICAgICAgICBpZiAoY29tcGFueUxhYmVsLmxlbmd0aCA9PT0gMCB8fCBpdGVtLmhpZGVDb21wYW55RmllbGQgPT09IHRydWUpIHtcbiAgICAgICAgICAgIHJldHVyblxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGFjdGl2ZVBheW1lbnRNZXRob2QgPT09ICdtb2xsaWVfd2NfZ2F0ZXdheV9iaWxsaWUnKSB7XG4gICAgICAgICAgICBsZXQgbWVzc2FnZSA9IGl0ZW0uY29tcGFueVBsYWNlaG9sZGVyXG4gICAgICAgICAgICBjb21wYW55TGFiZWwucmVwbGFjZVdpdGgoJzxsYWJlbCBodG1sRm9yPVwic2hpcHBpbmctY29tcGFueVwiPicgKyBtZXNzYWdlICsgJzwvbGFiZWw+JylcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmIChjb21wYW55TmFtZVN0cmluZyAhPT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgICBjb21wYW55TGFiZWwucmVwbGFjZVdpdGgoJzxsYWJlbCBodG1sRm9yPVwic2hpcHBpbmctY29tcGFueVwiPicgKyBjb21wYW55TmFtZVN0cmluZyArICc8L2xhYmVsPicpXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGlzQ29tcGFueUVtcHR5ID0gKGJpbGxpbmcuYmlsbGluZ0RhdGEuY29tcGFueSA9PT0gJycgJiYgc2hpcHBpbmdEYXRhLnNoaXBwaW5nQWRkcmVzcy5jb21wYW55ID09PSAnJykgJiYgaW5wdXRDb21wYW55ID09PSAnJztcbiAgICAgICAgY29uc3QgdW5zdWJzY3JpYmVQcm9jZXNzaW5nID0gb25DaGVja291dFZhbGlkYXRpb24oXG4gICAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGFjdGl2ZVBheW1lbnRNZXRob2QgPT09ICdtb2xsaWVfd2NfZ2F0ZXdheV9iaWxsaWUnICYmIGlzQ29tcGFueUVtcHR5KSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2U6IGl0ZW0uZXJyb3JNZXNzYWdlLFxuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgICAgIHVuc3Vic2NyaWJlUHJvY2Vzc2luZygpXG4gICAgICAgIH07XG5cbiAgICB9LCBbYWN0aXZlUGF5bWVudE1ldGhvZCwgb25DaGVja291dFZhbGlkYXRpb24sIGJpbGxpbmcuYmlsbGluZ0RhdGEsIGl0ZW0sIGNvbXBhbnlOYW1lU3RyaW5nLCBpbnB1dENvbXBhbnldKTtcblxuICAgIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgICAgIGxldCBwaG9uZUxhYmVsID0gZ2V0UGhvbmVGaWVsZCgpPy5sYWJlbHM/LlswXSA/PyBudWxsO1xuICAgICAgICBpZiAoIXBob25lTGFiZWwgfHwgcGhvbmVMYWJlbC5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHJldHVyblxuICAgICAgICB9XG4gICAgICAgIGlmIChhY3RpdmVQYXltZW50TWV0aG9kID09PSAnbW9sbGllX3djX2dhdGV3YXlfaW4zJykge1xuICAgICAgICAgICAgcGhvbmVMYWJlbC5pbm5lclRleHQgPSBpdGVtLnBob25lUGxhY2Vob2xkZXJcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmIChwaG9uZVN0cmluZyAhPT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgICBwaG9uZUxhYmVsLmlubmVyVGV4dCA9IHBob25lU3RyaW5nXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGlzUGhvbmVFbXB0eSA9IChiaWxsaW5nLmJpbGxpbmdEYXRhLnBob25lID09PSAnJyAmJiBzaGlwcGluZ0RhdGEuc2hpcHBpbmdBZGRyZXNzLnBob25lID09PSAnJykgJiYgaW5wdXRQaG9uZSA9PT0gJyc7XG4gICAgICAgIGxldCBpc0JpcnRoZGF0ZVZhbGlkID0gaW5wdXRCaXJ0aGRhdGUgPT09ICcnXG4gICAgICAgIGxldCB0b2RheSA9IG5ldyBEYXRlKCk7XG4gICAgICAgIGxldCBiaXJ0aGRhdGUgPSBuZXcgRGF0ZShpbnB1dEJpcnRoZGF0ZSk7XG4gICAgICAgIGlmIChiaXJ0aGRhdGUgPiB0b2RheSkge1xuICAgICAgICAgICAgaXNCaXJ0aGRhdGVWYWxpZCA9IGZhbHNlXG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdW5zdWJzY3JpYmVQcm9jZXNzaW5nID0gb25DaGVja291dFZhbGlkYXRpb24oXG5cbiAgICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoYWN0aXZlUGF5bWVudE1ldGhvZCA9PT0gJ21vbGxpZV93Y19nYXRld2F5X2luMycgJiYgKGlzUGhvbmVFbXB0eSB8fCBpc0JpcnRoZGF0ZVZhbGlkKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlOiBpdGVtLmVycm9yTWVzc2FnZSxcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgICAgICB1bnN1YnNjcmliZVByb2Nlc3NpbmcoKVxuICAgICAgICB9O1xuXG4gICAgfSwgW2FjdGl2ZVBheW1lbnRNZXRob2QsIG9uQ2hlY2tvdXRWYWxpZGF0aW9uLCBiaWxsaW5nLmJpbGxpbmdEYXRhLCBzaGlwcGluZ0RhdGEuc2hpcHBpbmdBZGRyZXNzLCBpdGVtLCBwaG9uZVN0cmluZywgaW5wdXRCaXJ0aGRhdGUsIGlucHV0UGhvbmVdKTtcblxuICAgIG9uU3VibWl0TG9jYWwgPSBvblN1Ym1pdFxuICAgIGNvbnN0IHVwZGF0ZUlzc3VlciA9IChlKSA9PiBzZWxlY3RJc3N1ZXIoZS50YXJnZXQudmFsdWUpO1xuICAgIGNvbnN0IHVwZGF0ZUNvbXBhbnkgPSAoZSkgPT4gc2VsZWN0Q29tcGFueShlLnRhcmdldC52YWx1ZSk7XG4gICAgY29uc3QgdXBkYXRlUGhvbmUgPSAoZSkgPT4gc2VsZWN0UGhvbmUoZS50YXJnZXQudmFsdWUpO1xuICAgIGNvbnN0IHVwZGF0ZUJpcnRoZGF0ZSA9IChlKSA9PiBzZWxlY3RCaXJ0aGRhdGUoIGUudGFyZ2V0LnZhbHVlICk7XG5cbiAgICBmdW5jdGlvbiBmaWVsZE1hcmt1cChpZCwgZmllbGRUeXBlLCBsYWJlbCwgYWN0aW9uLCB2YWx1ZSwgcGxhY2Vob2xkZXIgPSBudWxsKSB7XG4gICAgICAgIGNvbnN0IGNsYXNzTmFtZSA9IFwid2MtYmxvY2stY29tcG9uZW50cy10ZXh0LWlucHV0IHdjLWJsb2NrLWNvbXBvbmVudHMtYWRkcmVzcy1mb3JtX19cIiArIGlkO1xuICAgICAgICByZXR1cm4gPGRpdiBjbGFzcz1cImN1c3RvbS1pbnB1dFwiPlxuICAgICAgICAgICAgPGxhYmVsIGh0bWxGb3I9e2lkfSBkYW5nZXJvdXNseVNldElubmVySFRNTD17e19faHRtbDogbGFiZWx9fT48L2xhYmVsPlxuICAgICAgICAgICAgPGlucHV0IHR5cGU9e2ZpZWxkVHlwZX0gbmFtZT17aWR9IGlkPXtpZH0gdmFsdWU9e3ZhbHVlfSBvbkNoYW5nZT17YWN0aW9ufSBwbGFjZWhvbGRlcj17cGxhY2Vob2xkZXJ9PjwvaW5wdXQ+XG4gICAgICAgIDwvZGl2PlxuICAgIH1cblxuICAgIGlmIChpdGVtLmlzc3VlcnMgJiYgaXRlbS5uYW1lICE9PSBcIm1vbGxpZV93Y19nYXRld2F5X2NyZWRpdGNhcmRcIil7XG4gICAgICAgIHJldHVybiA8ZGl2PjxwPntpdGVtLmNvbnRlbnR9PC9wPjxzZWxlY3QgbmFtZT17aXNzdWVyS2V5fSBkYW5nZXJvdXNseVNldElubmVySFRNTD17IHtfX2h0bWw6IGl0ZW0uaXNzdWVyc30gfSB2YWx1ZT17c2VsZWN0ZWRJc3N1ZXJ9IG9uQ2hhbmdlPXt1cGRhdGVJc3N1ZXJ9Pjwvc2VsZWN0PjwvZGl2PlxuICAgIH1cblxuICAgIGlmKGl0ZW0ubmFtZSA9PT0gXCJtb2xsaWVfd2NfZ2F0ZXdheV9jcmVkaXRjYXJkXCIpe1xuICAgICAgICByZXR1cm4gPGRpdiBkYW5nZXJvdXNseVNldElubmVySFRNTD17IHtfX2h0bWw6IGl0ZW0uY29udGVudH0gfT48L2Rpdj47XG4gICAgfVxuXG4gICAgaWYgKGl0ZW0ubmFtZSA9PT0gXCJtb2xsaWVfd2NfZ2F0ZXdheV9iaWxsaWVcIikge1xuICAgICAgICBjb25zdCBiaWxsaW5nQ29tcGFueUZpZWxkID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmctY29tcGFueScpO1xuICAgICAgICBjb25zdCBzaGlwcGluZ0NvbXBhbnlGaWVsZCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNzaGlwcGluZy1jb21wYW55Jyk7XG4gICAgICAgIGNvbnN0IGlzQmlsbGluZ0NvbXBhbnlSZXF1aXJlZCA9IGJpbGxpbmdDb21wYW55RmllbGQ/Lmhhc0F0dHJpYnV0ZSgncmVxdWlyZWQnKTtcbiAgICAgICAgY29uc3QgaXNTaGlwcGluZ0NvbXBhbnlSZXF1aXJlZCA9IHNoaXBwaW5nQ29tcGFueUZpZWxkPy5oYXNBdHRyaWJ1dGUoJ3JlcXVpcmVkJyk7XG5cbiAgICAgICAgaWYgKChiaWxsaW5nQ29tcGFueUZpZWxkICYmIGlzQmlsbGluZ0NvbXBhbnlSZXF1aXJlZCkgfHwgKHNoaXBwaW5nQ29tcGFueUZpZWxkICYmIGlzU2hpcHBpbmdDb21wYW55UmVxdWlyZWQpIHx8IGl0ZW0uaGlkZUNvbXBhbnlGaWVsZCA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgY29tcGFueUZpZWxkID0gaXRlbS5jb21wYW55UGxhY2Vob2xkZXIgPyBpdGVtLmNvbXBhbnlQbGFjZWhvbGRlciA6IFwiQ29tcGFueSBuYW1lXCI7XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICA8PlxuICAgICAgICAgICAgICAgIDxkaXY+PHA+e2l0ZW0uY29udGVudH08L3A+PC9kaXY+XG4gICAgICAgICAgICAgICAge2ZpZWxkTWFya3VwKFwiYmlsbGluZ19jb21wYW55X2JpbGxpZVwiLFwidGV4dFwiLCBjb21wYW55RmllbGQsIHVwZGF0ZUNvbXBhbnksIGlucHV0Q29tcGFueSl9XG4gICAgICAgICAgICA8Lz5cbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgICAgICBjb25zdCBjb3VudHJ5Q29kZXMgPSB7XG4gICAgICAgICAgICBCRTogJyszMnh4eHh4eHh4eCcsXG4gICAgICAgICAgICBOTDogJyszMTZ4eHh4eHh4eCcsXG4gICAgICAgICAgICBERTogJys0OXh4eHh4eHh4eCcsXG4gICAgICAgICAgICBBVDogJys0M3h4eHh4eHh4eCcsXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IGNvdW50cnkgPSBiaWxsaW5nLmJpbGxpbmdEYXRhLmNvdW50cnk7XG4gICAgICAgIGl0ZW0ucGhvbmVQbGFjZWhvbGRlciA9IGNvdW50cnlDb2Rlc1tjb3VudHJ5XSB8fCBjb3VudHJ5Q29kZXNbJ05MJ107XG4gICAgfSwgW2JpbGxpbmcuYmlsbGluZ0RhdGEuY291bnRyeV0pO1xuXG4gICAgaWYgKGl0ZW0ubmFtZSA9PT0gXCJtb2xsaWVfd2NfZ2F0ZXdheV9pbjNcIikge1xuICAgICAgICBjb25zdCBiaXJ0aGRhdGVGaWVsZCA9IGl0ZW0uYmlydGhkYXRlUGxhY2Vob2xkZXIgfHwgXCJCaXJ0aGRhdGVcIjtcbiAgICAgICAgY29uc3QgcGhvbmVGaWVsZCA9IGl0ZW0ucGhvbmVQbGFjZWhvbGRlciB8fCBcIiszMTZ4eHh4eHh4eFwiO1xuICAgICAgICBjb25zdCBwaG9uZUxhYmVsID0gaXRlbS5waG9uZUxhYmVsIHx8IFwiUGhvbmVcIjtcbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIDw+XG4gICAgICAgICAgICAgICAgPGRpdj48cD57aXRlbS5jb250ZW50fTwvcD48L2Rpdj5cbiAgICAgICAgICAgICAgICB7ZmllbGRNYXJrdXAoXCJiaWxsaW5nLWJpcnRoZGF0ZVwiLCBcImRhdGVcIiwgYmlydGhkYXRlRmllbGQsIHVwZGF0ZUJpcnRoZGF0ZSwgaW5wdXRCaXJ0aGRhdGUpfVxuICAgICAgICAgICAgICAgIHshaXNQaG9uZUZpZWxkVmlzaWJsZSAmJiBmaWVsZE1hcmt1cChcImJpbGxpbmctcGhvbmUtaW4zXCIsIFwidGVsXCIsIHBob25lTGFiZWwsIHVwZGF0ZVBob25lLCBpbnB1dFBob25lLCBwaG9uZUZpZWxkKX1cbiAgICAgICAgICAgIDwvPlxuICAgICAgICApO1xuICAgIH1cblxuICAgIGlmIChpdGVtLm5hbWUgPT09IFwibW9sbGllX3djX2dhdGV3YXlfcml2ZXJ0eVwiKSB7XG4gICAgICAgIGNvbnN0IGJpcnRoZGF0ZUZpZWxkID0gaXRlbS5iaXJ0aGRhdGVQbGFjZWhvbGRlciB8fCBcIkJpcnRoZGF0ZVwiO1xuICAgICAgICBjb25zdCBwaG9uZUZpZWxkID0gaXRlbS5waG9uZVBsYWNlaG9sZGVyIHx8IFwiKzMxNnh4eHh4eHh4XCI7XG4gICAgICAgIGNvbnN0IHBob25lTGFiZWwgPSBpdGVtLnBob25lTGFiZWwgfHwgXCJQaG9uZVwiO1xuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgPD5cbiAgICAgICAgICAgICAgICA8ZGl2PjxwPntpdGVtLmNvbnRlbnR9PC9wPjwvZGl2PlxuICAgICAgICAgICAgICAgIHtmaWVsZE1hcmt1cChcImJpbGxpbmctYmlydGhkYXRlXCIsIFwiZGF0ZVwiLCBiaXJ0aGRhdGVGaWVsZCwgdXBkYXRlQmlydGhkYXRlLCBpbnB1dEJpcnRoZGF0ZSl9XG4gICAgICAgICAgICAgICAgeyFpc1Bob25lRmllbGRWaXNpYmxlICYmIGZpZWxkTWFya3VwKFwiYmlsbGluZy1waG9uZS1yaXZlcnR5XCIsIFwidGVsXCIsIHBob25lTGFiZWwsIHVwZGF0ZVBob25lLCBpbnB1dFBob25lLCBwaG9uZUZpZWxkKX1cbiAgICAgICAgICAgIDwvPlxuICAgICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiA8ZGl2PjxwPntpdGVtLmNvbnRlbnR9PC9wPjwvZGl2PlxufVxuXG5jb25zdCBMYWJlbCA9ICh7IGl0ZW0sIGZpbHRlcnMsIGFqYXhVcmwgfSkgPT4ge1xuICAgIGNvbnN0IGNhcnREYXRhID0gd3AuZGF0YS51c2VTZWxlY3QoKHNlbGVjdCkgPT5cbiAgICAgICAgICAgIHNlbGVjdCgnd2Mvc3RvcmUvY2FydCcpLmdldENhcnREYXRhKCksXG4gICAgICAgIFtdXG4gICAgKTtcbiAgICBjb25zdCBjYXJ0VG90YWxzID0gd3AuZGF0YS51c2VTZWxlY3QoIChzZWxlY3QpID0+IHNlbGVjdCgnd2Mvc3RvcmUvY2FydCcpLmdldENhcnRUb3RhbHMoKSwgWyBdICk7XG4gICAgY29uc3QgY2FydFRvdGFsID0gY2FydFRvdGFscz8udG90YWxfcHJpY2UgfHwgMDtcbiAgICByZXR1cm4gKFxuICAgICAgICA8PlxuICAgICAgICAgICAgPGRpdiBkYW5nZXJvdXNseVNldElubmVySFRNTD17eyBfX2h0bWw6IGl0ZW0ubGFiZWwgfX0vPlxuICAgICAgICAgICAgPE1vbGxpZUdhdGV3YXlVcGRhdGVyXG4gICAgICAgICAgICAgICAgYmlsbGluZz17Y2FydERhdGEuYmlsbGluZ0FkZHJlc3N9XG4gICAgICAgICAgICAgICAgY3VycmVuY3lDb2RlPXt3Y1NldHRpbmdzLmN1cnJlbmN5LmNvZGV9XG4gICAgICAgICAgICAgICAgZmlsdGVycz17ZmlsdGVyc31cbiAgICAgICAgICAgICAgICBhamF4VXJsPXthamF4VXJsfVxuICAgICAgICAgICAgICAgIGNhcnRUb3RhbD17Y2FydFRvdGFsfVxuICAgICAgICAgICAgLz5cbiAgICAgICAgPC8+XG4gICAgKTtcbn07XG5cbmNvbnN0IG1vbGxpZVBheW1lbnRNZXRob2QgPSAodXNlRWZmZWN0LCBhamF4VXJsLCBmaWx0ZXJzLCBnYXRld2F5RGF0YSwgYXZhaWxhYmxlR2F0ZXdheXMsIGl0ZW0sIGpRdWVyeSwgcmVxdWlyZWRGaWVsZHMsIGlzQ29tcGFueUZpZWxkVmlzaWJsZSwgaXNQaG9uZUZpZWxkVmlzaWJsZSkgPT57XG5cbiAgICBpZiAoaXRlbS5uYW1lID09PSBcIm1vbGxpZV93Y19nYXRld2F5X2NyZWRpdGNhcmRcIikge1xuICAgICAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdtb2xsaWVfY29tcG9uZW50c19yZWFkeV90b19zdWJtaXQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBvblN1Ym1pdExvY2FsKClcbiAgICAgICAgfSlcbiAgICB9XG4gICAgZnVuY3Rpb24gY3JlZGl0Y2FyZFNlbGVjdGVkRXZlbnQoKSB7XG4gICAgICAgIGlmIChpdGVtLm5hbWUgPT09IFwibW9sbGllX3djX2dhdGV3YXlfY3JlZGl0Y2FyZFwiKSB7XG4gICAgICAgICAgICBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuZGlzcGF0Y2hFdmVudChjcmVkaXRDYXJkU2VsZWN0ZWQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgICAgbmFtZTogaXRlbS5uYW1lLFxuICAgICAgICBsYWJlbDo8TGFiZWxcbiAgICAgICAgICAgIGl0ZW09e2l0ZW19XG4gICAgICAgICAgICBhamF4VXJsPXthamF4VXJsfVxuICAgICAgICAgICAgZmlsdGVycz17ZmlsdGVyc31cbiAgICAgICAgLz4sXG4gICAgICAgIGNvbnRlbnQ6IDxNb2xsaWVDb21wb25lbnRcbiAgICAgICAgICAgIGl0ZW09e2l0ZW19XG4gICAgICAgICAgICB1c2VFZmZlY3Q9e3VzZUVmZmVjdH1cbiAgICAgICAgICAgIGFqYXhVcmw9e2FqYXhVcmx9XG4gICAgICAgICAgICBqUXVlcnk9e2pRdWVyeX1cbiAgICAgICAgICAgIHJlcXVpcmVkRmllbGRzPXtyZXF1aXJlZEZpZWxkc31cbiAgICAgICAgICAgIGlzUGhvbmVGaWVsZFZpc2libGU9e2lzUGhvbmVGaWVsZFZpc2libGV9Lz4sXG4gICAgICAgIGVkaXQ6IDxkaXY+e2l0ZW0uZWRpdH08L2Rpdj4sXG4gICAgICAgIHBheW1lbnRNZXRob2RJZDogaXRlbS5wYXltZW50TWV0aG9kSWQsXG4gICAgICAgIGNhbk1ha2VQYXltZW50OiAoe2NhcnRUb3RhbHMsIGJpbGxpbmdEYXRhfSkgPT4ge1xuICAgICAgICAgICAgaWYgKCFfLmlzRW1wdHkoaXRlbS5hbGxvd2VkQ291bnRyaWVzKSAmJiAhKGl0ZW0uYWxsb3dlZENvdW50cmllcy5pbmNsdWRlcyhiaWxsaW5nRGF0YS5jb3VudHJ5KSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChjYXJ0VG90YWxzIDw9IDApIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgY3VycmVuY3lDb2RlID0gY2FydFRvdGFscz8uY3VycmVuY3lfY29kZTtcbiAgICAgICAgICAgIGxldCBjb3VudHJ5ID0gYmlsbGluZ0RhdGE/LmNvdW50cnk7XG4gICAgICAgICAgICBpZiAoIWNvdW50cnkpIHtcbiAgICAgICAgICAgICAgICBjb3VudHJ5ID0gd2NTZXR0aW5ncz8uYmFzZUxvY2F0aW9uLmNvdW50cnk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBjdXJyZW50RmlsdGVyS2V5ID0gY3VycmVuY3lDb2RlICsgXCItXCIgKyBjb3VudHJ5O1xuXG4gICAgICAgICAgICBjcmVkaXRjYXJkU2VsZWN0ZWRFdmVudCgpO1xuXG4gICAgICAgICAgICBpZiAoIWNhY2hlZEF2YWlsYWJsZUdhdGV3YXlzLmhhc093blByb3BlcnR5KGN1cnJlbnRGaWx0ZXJLZXkpKSB7XG4gICAgICAgICAgICAgICAgY2FjaGVkQXZhaWxhYmxlR2F0ZXdheXMgPSB7XG4gICAgICAgICAgICAgICAgICAgIC4uLmNhY2hlZEF2YWlsYWJsZUdhdGV3YXlzLFxuICAgICAgICAgICAgICAgICAgICAuLi5hdmFpbGFibGVHYXRld2F5c1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChhdmFpbGFibGVHYXRld2F5cy5oYXNPd25Qcm9wZXJ0eShjdXJyZW50RmlsdGVyS2V5KSAmJiBhdmFpbGFibGVHYXRld2F5c1tjdXJyZW50RmlsdGVyS2V5XS5oYXNPd25Qcm9wZXJ0eShpdGVtLm5hbWUpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChjYWNoZWRBdmFpbGFibGVHYXRld2F5cy5oYXNPd25Qcm9wZXJ0eShjdXJyZW50RmlsdGVyS2V5KSAmJiBjYWNoZWRBdmFpbGFibGVHYXRld2F5c1tjdXJyZW50RmlsdGVyS2V5XS5oYXNPd25Qcm9wZXJ0eShpdGVtLm5hbWUpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfSxcbiAgICAgICAgYXJpYUxhYmVsOiBpdGVtLmFyaWFMYWJlbCxcbiAgICAgICAgc3VwcG9ydHM6IHtcbiAgICAgICAgICAgIGZlYXR1cmVzOiBpdGVtLnN1cHBvcnRzLFxuICAgICAgICB9LFxuICAgIH07XG59XG5leHBvcnQgZGVmYXVsdCBtb2xsaWVQYXltZW50TWV0aG9kXG5cbiIsIi8vIFRoZSBtb2R1bGUgY2FjaGVcbnZhciBfX3dlYnBhY2tfbW9kdWxlX2NhY2hlX18gPSB7fTtcblxuLy8gVGhlIHJlcXVpcmUgZnVuY3Rpb25cbmZ1bmN0aW9uIF9fd2VicGFja19yZXF1aXJlX18obW9kdWxlSWQpIHtcblx0Ly8gQ2hlY2sgaWYgbW9kdWxlIGlzIGluIGNhY2hlXG5cdHZhciBjYWNoZWRNb2R1bGUgPSBfX3dlYnBhY2tfbW9kdWxlX2NhY2hlX19bbW9kdWxlSWRdO1xuXHRpZiAoY2FjaGVkTW9kdWxlICE9PSB1bmRlZmluZWQpIHtcblx0XHRyZXR1cm4gY2FjaGVkTW9kdWxlLmV4cG9ydHM7XG5cdH1cblx0Ly8gQ3JlYXRlIGEgbmV3IG1vZHVsZSAoYW5kIHB1dCBpdCBpbnRvIHRoZSBjYWNoZSlcblx0dmFyIG1vZHVsZSA9IF9fd2VicGFja19tb2R1bGVfY2FjaGVfX1ttb2R1bGVJZF0gPSB7XG5cdFx0Ly8gbm8gbW9kdWxlLmlkIG5lZWRlZFxuXHRcdC8vIG5vIG1vZHVsZS5sb2FkZWQgbmVlZGVkXG5cdFx0ZXhwb3J0czoge31cblx0fTtcblxuXHQvLyBFeGVjdXRlIHRoZSBtb2R1bGUgZnVuY3Rpb25cblx0X193ZWJwYWNrX21vZHVsZXNfX1ttb2R1bGVJZF0obW9kdWxlLCBtb2R1bGUuZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXyk7XG5cblx0Ly8gUmV0dXJuIHRoZSBleHBvcnRzIG9mIHRoZSBtb2R1bGVcblx0cmV0dXJuIG1vZHVsZS5leHBvcnRzO1xufVxuXG4iLCIvLyBkZWZpbmUgZ2V0dGVyIGZ1bmN0aW9ucyBmb3IgaGFybW9ueSBleHBvcnRzXG5fX3dlYnBhY2tfcmVxdWlyZV9fLmQgPSAoZXhwb3J0cywgZGVmaW5pdGlvbikgPT4ge1xuXHRmb3IodmFyIGtleSBpbiBkZWZpbml0aW9uKSB7XG5cdFx0aWYoX193ZWJwYWNrX3JlcXVpcmVfXy5vKGRlZmluaXRpb24sIGtleSkgJiYgIV9fd2VicGFja19yZXF1aXJlX18ubyhleHBvcnRzLCBrZXkpKSB7XG5cdFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywga2V5LCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZGVmaW5pdGlvbltrZXldIH0pO1xuXHRcdH1cblx0fVxufTsiLCJfX3dlYnBhY2tfcmVxdWlyZV9fLm8gPSAob2JqLCBwcm9wKSA9PiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwgcHJvcCkpIiwiLy8gZGVmaW5lIF9fZXNNb2R1bGUgb24gZXhwb3J0c1xuX193ZWJwYWNrX3JlcXVpcmVfXy5yID0gKGV4cG9ydHMpID0+IHtcblx0aWYodHlwZW9mIFN5bWJvbCAhPT0gJ3VuZGVmaW5lZCcgJiYgU3ltYm9sLnRvU3RyaW5nVGFnKSB7XG5cdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFN5bWJvbC50b1N0cmluZ1RhZywgeyB2YWx1ZTogJ01vZHVsZScgfSk7XG5cdH1cblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdfX2VzTW9kdWxlJywgeyB2YWx1ZTogdHJ1ZSB9KTtcbn07IiwiaW1wb3J0IG1vbGxpZVBheW1lbnRNZXRob2QgZnJvbSAnLi9ibG9ja3MvbW9sbGllUGF5bWVudE1ldGhvZCdcbmltcG9ydCBBcHBsZVBheUJ1dHRvbkNvbXBvbmVudCBmcm9tICcuL2Jsb2Nrcy9BcHBsZVBheUJ1dHRvbkNvbXBvbmVudCdcbmltcG9ydCBBcHBsZVBheUJ1dHRvbkVkaXRvckNvbXBvbmVudCBmcm9tICcuL2Jsb2Nrcy9BcHBsZVBheUJ1dHRvbkVkaXRvckNvbXBvbmVudCdcblxuKFxuICAgIGZ1bmN0aW9uICh7bW9sbGllQmxvY2tEYXRhLCB3YywgXywgalF1ZXJ5fSkge1xuICAgICAgICBpZiAoXy5pc0VtcHR5KG1vbGxpZUJsb2NrRGF0YSkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHtyZWdpc3RlclBheW1lbnRNZXRob2R9ID0gd2Mud2NCbG9ja3NSZWdpc3RyeTtcbiAgICAgICAgY29uc3Qge2RlZmF1bHRGaWVsZHN9ID0gd2Mud2NTZXR0aW5ncy5hbGxTZXR0aW5ncztcbiAgICAgICAgY29uc3Qge2FqYXhVcmwsIGZpbHRlcnMsIGdhdGV3YXlEYXRhLCBhdmFpbGFibGVHYXRld2F5c30gPSBtb2xsaWVCbG9ja0RhdGEuZ2F0ZXdheURhdGE7XG4gICAgICAgIGNvbnN0IHt1c2VFZmZlY3R9ID0gd3AuZWxlbWVudDtcbiAgICAgICAgY29uc3QgaXNBcHBsZVNlc3Npb24gPSB0eXBlb2Ygd2luZG93LkFwcGxlUGF5U2Vzc2lvbiA9PT0gXCJmdW5jdGlvblwiXG5cbiAgICAgICAgZnVuY3Rpb24gZ2V0UGhvbmVGaWVsZCgpIHtcbiAgICAgICAgICAgIGNvbnN0IHBob25lRmllbGREYXRhc2V0ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignW2RhdGEtc2hvdy1waG9uZS1maWVsZF0nKTtcbiAgICAgICAgICAgIGlmICghcGhvbmVGaWVsZERhdGFzZXQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBwaG9uZUZpZWxkRGF0YXNldC5kYXRhc2V0LnNob3dQaG9uZUZpZWxkICE9PSBcImZhbHNlXCJcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGNvbXBhbnlOYW1lU3RyaW5nID0gZGVmYXVsdEZpZWxkcy5jb21wYW55LmxhYmVsXG4gICAgICAgIGNvbnN0IGlzUGhvbmVGaWVsZFZpc2libGUgPSBnZXRQaG9uZUZpZWxkKCk7XG4gICAgICAgIGNvbnN0IHBob25lU3RyaW5nID0gZGVmYXVsdEZpZWxkcy5waG9uZS5sYWJlbFxuICAgICAgICBsZXQgcmVxdWlyZWRGaWVsZHMgPSB7XG4gICAgICAgICAgICAnY29tcGFueU5hbWVTdHJpbmcnOiBjb21wYW55TmFtZVN0cmluZyxcbiAgICAgICAgICAgICdwaG9uZVN0cmluZyc6IHBob25lU3RyaW5nLFxuICAgICAgICB9XG4gICAgICAgIGdhdGV3YXlEYXRhLmZvckVhY2goaXRlbSA9PiB7XG4gICAgICAgICAgICBsZXQgcmVnaXN0ZXIgPSAoKSA9PiByZWdpc3RlclBheW1lbnRNZXRob2QobW9sbGllUGF5bWVudE1ldGhvZCh1c2VFZmZlY3QsIGFqYXhVcmwsIGZpbHRlcnMsIGdhdGV3YXlEYXRhLCBhdmFpbGFibGVHYXRld2F5cywgaXRlbSwgalF1ZXJ5LCByZXF1aXJlZEZpZWxkcywgaXNQaG9uZUZpZWxkVmlzaWJsZSkpO1xuICAgICAgICAgICAgaWYgKGl0ZW0ubmFtZSA9PT0gJ21vbGxpZV93Y19nYXRld2F5X2FwcGxlcGF5Jykge1xuICAgICAgICAgICAgICAgIGNvbnN0IHtpc0V4cHJlc3NFbmFibGVkfSA9IGl0ZW07XG4gICAgICAgICAgICAgICAgaWYgKChpc0FwcGxlU2Vzc2lvbiAmJiB3aW5kb3cuQXBwbGVQYXlTZXNzaW9uLmNhbk1ha2VQYXltZW50cygpKSkge1xuICAgICAgICAgICAgICAgICAgICByZWdpc3RlcigpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNFeHByZXNzRW5hYmxlZCAhPT0gdHJ1ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHtyZWdpc3RlckV4cHJlc3NQYXltZW50TWV0aG9kfSA9IHdjLndjQmxvY2tzUmVnaXN0cnk7XG4gICAgICAgICAgICAgICAgICAgIHJlZ2lzdGVyRXhwcmVzc1BheW1lbnRNZXRob2Qoe1xuICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogJ21vbGxpZV93Y19nYXRld2F5X2FwcGxlcGF5X2V4cHJlc3MnLFxuICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGU6ICdBcHBsZSBQYXkgRXhwcmVzcyBidXR0b24nLFxuICAgICAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRpb246ICdBcHBsZSBQYXkgRXhwcmVzcyBidXR0b24nLFxuICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudDogPEFwcGxlUGF5QnV0dG9uQ29tcG9uZW50Lz4sXG4gICAgICAgICAgICAgICAgICAgICAgICBlZGl0OiA8QXBwbGVQYXlCdXR0b25FZGl0b3JDb21wb25lbnQvPixcbiAgICAgICAgICAgICAgICAgICAgICAgIGFyaWFMYWJlbDogJ0FwcGxlIFBheScsXG4gICAgICAgICAgICAgICAgICAgICAgICBjYW5NYWtlUGF5bWVudDogKCkgPT4gdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHBheW1lbnRNZXRob2RJZDogJ21vbGxpZV93Y19nYXRld2F5X2FwcGxlcGF5JyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGdhdGV3YXlJZDogJ21vbGxpZV93Y19nYXRld2F5X2FwcGxlcGF5JyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHN1cHBvcnRzOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmVhdHVyZXM6IFsncHJvZHVjdHMnXSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHlsZTogWydoZWlnaHQnLCAnYm9yZGVyUmFkaXVzJ11cbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlZ2lzdGVyKCk7XG4gICAgICAgIH0pO1xuICAgIH1cbikod2luZG93LCB3YylcbiJdLCJuYW1lcyI6WyJjcmVhdGVBcHBsZUVycm9ycyIsImVycm9ycyIsImVycm9yTGlzdCIsIl9pdGVyYXRvciIsIl9jcmVhdGVGb3JPZkl0ZXJhdG9ySGVscGVyIiwiX3N0ZXAiLCJzIiwibiIsImRvbmUiLCJlcnJvciIsInZhbHVlIiwiX2Vycm9yJGNvbnRhY3RGaWVsZCIsImNvbnRhY3RGaWVsZCIsIl9lcnJvciRjb2RlIiwiY29kZSIsIl9lcnJvciRtZXNzYWdlIiwibWVzc2FnZSIsImFwcGxlRXJyb3IiLCJBcHBsZVBheUVycm9yIiwicHVzaCIsImVyciIsImUiLCJmIiwicmVxdWVzdCIsImNvdW50cnlDb2RlIiwiY3VycmVuY3lDb2RlIiwidG90YWxMYWJlbCIsInN1YnRvdGFsIiwic3VwcG9ydGVkTmV0d29ya3MiLCJtZXJjaGFudENhcGFiaWxpdGllcyIsInNoaXBwaW5nVHlwZSIsInJlcXVpcmVkQmlsbGluZ0NvbnRhY3RGaWVsZHMiLCJyZXF1aXJlZFNoaXBwaW5nQ29udGFjdEZpZWxkcyIsInRvdGFsIiwibGFiZWwiLCJhbW91bnQiLCJ0eXBlIiwiQXBwbGVQYXlCdXR0b25Db21wb25lbnQiLCJfcmVmIiwiX3JlZiRidXR0b25BdHRyaWJ1dGVzIiwiYnV0dG9uQXR0cmlidXRlcyIsIm1vbGxpZUFwcGxlUGF5QmxvY2tEYXRhQ2FydCIsIndpbmRvdyIsIm1vbGxpZUJsb2NrRGF0YSIsIm5vbmNlIiwiZG9jdW1lbnQiLCJnZXRFbGVtZW50QnlJZCIsInVwZGF0ZWRDb250YWN0SW5mbyIsInJlZGlyZWN0aW9uVXJsIiwiX21vbGxpZUFwcGxlUGF5QmxvY2tEIiwicHJvZHVjdCIsIl9tb2xsaWVBcHBsZVBheUJsb2NrRDIiLCJuZWVkU2hpcHBpbmciLCJfbW9sbGllQXBwbGVQYXlCbG9ja0QzIiwic2hvcCIsIl9tb2xsaWVBcHBsZVBheUJsb2NrRDQiLCJfbW9sbGllQXBwbGVQYXlCbG9ja0Q1IiwiYWpheFVybCIsInN0eWxlIiwiaGVpZ2h0IiwiY29uY2F0IiwiYm9yZGVyUmFkaXVzIiwiZmluZFNlbGVjdGVkU2hpcHBpbmdNZXRob2QiLCJzaGlwcGluZ1JhdGVzIiwic2hpcHBpbmdSYXRlIiwiZmluZCIsInNoaXBwaW5nTWV0aG9kIiwic2VsZWN0ZWQiLCJhcHBsZUZvcm1hdHRlZFJhdGUiLCJkZXRhaWwiLCJuYW1lIiwiaWRlbnRpZmllciIsInJhdGVfaWQiLCJhcHBsZVBheVNlc3Npb24iLCJfc3RvcmUkZ2V0U2hpcHBpbmdSYXQiLCJzZXNzaW9uIiwiQXBwbGVQYXlTZXNzaW9uIiwic3RvcmUiLCJ3cCIsImRhdGEiLCJzZWxlY3QiLCJnZXRTaGlwcGluZ1JhdGVzIiwic2hpcHBpbmdfcmF0ZXMiLCJzZWxlY3RlZFNoaXBwaW5nTWV0aG9kIiwibGVuZ3RoIiwib25zaGlwcGluZ21ldGhvZHNlbGVjdGVkIiwiZXZlbnQiLCJfdGhpcyIsImpRdWVyeSIsImFqYXgiLCJ1cmwiLCJtZXRob2QiLCJhY3Rpb24iLCJjYWxsZXJQYWdlIiwic2ltcGxpZmllZENvbnRhY3QiLCJzdWNjZXNzIiwiYXBwbGVQYXlTaGlwcGluZ01ldGhvZFVwZGF0ZSIsInRleHRTdGF0dXMiLCJqcVhIUiIsInJlc3BvbnNlIiwiY29tcGxldGVTaGlwcGluZ01ldGhvZFNlbGVjdGlvbiIsImVycm9yVGhyb3duIiwiY29uc29sZSIsIndhcm4iLCJhYm9ydCIsIm9uc2hpcHBpbmdjb250YWN0c2VsZWN0ZWQiLCJfdGhpczIiLCJzaGlwcGluZ0NvbnRhY3QiLCJhcHBsZVBheVNoaXBwaW5nQ29udGFjdFVwZGF0ZSIsIm5ld1NoaXBwaW5nTWV0aG9kcyIsImNvbXBsZXRlU2hpcHBpbmdDb250YWN0U2VsZWN0aW9uIiwib252YWxpZGF0ZW1lcmNoYW50IiwiYXBwbGVQYXlWYWxpZGF0ZU1lcmNoYW50RXZlbnQiLCJ2YWxpZGF0aW9uVXJsIiwidmFsaWRhdGlvblVSTCIsIm1lcmNoYW50U2Vzc2lvbiIsImNvbXBsZXRlTWVyY2hhbnRWYWxpZGF0aW9uIiwiSlNPTiIsInBhcnNlIiwib25wYXltZW50YXV0aG9yaXplZCIsIkFwcGxlUGF5UGF5bWVudCIsIl9BcHBsZVBheVBheW1lbnQkcGF5bSIsInBheW1lbnQiLCJiaWxsaW5nQ29udGFjdCIsInRva2VuIiwiZ2l2ZW5OYW1lIiwiZmFtaWx5TmFtZSIsImFkZHJlc3NMaW5lcyIsInBvc3RhbENvZGUiLCJsb2NhbGl0eSIsImFkbWluaXN0cmF0aXZlQXJlYSIsInBob25lTnVtYmVyIiwiZW1haWxBZGRyZXNzIiwiYXV0aG9yaXphdGlvblJlc3VsdCIsInJlc3VsdCIsImNvbXBsZXRlUGF5bWVudCIsImxvY2F0aW9uIiwiaHJlZiIsImJlZ2luIiwiUmVhY3QiLCJjcmVhdGVFbGVtZW50IiwiaWQiLCJjbGFzc05hbWUiLCJvbkNsaWNrIiwicHJldmVudERlZmF1bHQiLCJBcHBsZVBheUJ1dHRvbkVkaXRvckNvbXBvbmVudCIsImNhY2hlZEF2YWlsYWJsZUdhdGV3YXlzIiwiZm9ybWF0UHJpY2VMaWtlV2MiLCJwcmljZSIsIndjU2V0dGluZ3MiLCJjdXJyZW5jeSIsInByaWNlRm9ybWF0IiwicmVwbGFjZSIsInN5bWJvbCIsInRvRml4ZWQiLCJwcmVjaXNpb24iLCJkZWNpbWFsU2VwYXJhdG9yIiwic2V0QXZhaWxhYmxlR2F0ZXdheXMiLCJjb3VudHJ5IiwiX29iamVjdFNwcmVhZCIsInVzZU1vbGxpZUF2YWlsYWJsZUdhdGV3YXlzIiwiYmlsbGluZyIsImNhcnRUb3RhbCIsImZpbHRlcnMiLCJfd2NTZXR0aW5ncyIsImJhc2VMb2NhdGlvbiIsImVsZW1lbnQiLCJ1c2VFZmZlY3QiLCJjdXJyZW50RmlsdGVyS2V5IiwiaGFzT3duUHJvcGVydHkiLCJmZXRjaCIsImhlYWRlcnMiLCJib2R5IiwiVVJMU2VhcmNoUGFyYW1zIiwiYmlsbGluZ0NvdW50cnkiLCJwYXltZW50TG9jYWxlIiwidGhlbiIsImpzb24iLCJjYXJ0VG90YWxzIiwiZ2V0Q2FydFRvdGFscyIsImRpc3BhdGNoIiwic2V0Q2FydERhdGEiLCJNb2xsaWVHYXRld2F5VXBkYXRlciIsIm9uU3VibWl0TG9jYWwiLCJhY3RpdmVQYXltZW50TWV0aG9kTG9jYWwiLCJjcmVkaXRDYXJkU2VsZWN0ZWQiLCJFdmVudCIsImJ1YmJsZXMiLCJNb2xsaWVDb21wb25lbnQiLCJwcm9wcyIsIm9uU3VibWl0IiwiYWN0aXZlUGF5bWVudE1ldGhvZCIsIml0ZW0iLCJlbWl0UmVzcG9uc2UiLCJldmVudFJlZ2lzdHJhdGlvbiIsInJlcXVpcmVkRmllbGRzIiwic2hpcHBpbmdEYXRhIiwiaXNQaG9uZUZpZWxkVmlzaWJsZSIsInJlc3BvbnNlVHlwZXMiLCJvblBheW1lbnRTZXR1cCIsIm9uQ2hlY2tvdXRWYWxpZGF0aW9uIiwiX3dwJGVsZW1lbnQkdXNlU3RhdGUiLCJ1c2VTdGF0ZSIsIl93cCRlbGVtZW50JHVzZVN0YXRlMiIsIl9zbGljZWRUb0FycmF5Iiwic2VsZWN0ZWRJc3N1ZXIiLCJzZWxlY3RJc3N1ZXIiLCJfd3AkZWxlbWVudCR1c2VTdGF0ZTMiLCJfd3AkZWxlbWVudCR1c2VTdGF0ZTQiLCJpbnB1dFBob25lIiwic2VsZWN0UGhvbmUiLCJfd3AkZWxlbWVudCR1c2VTdGF0ZTUiLCJfd3AkZWxlbWVudCR1c2VTdGF0ZTYiLCJpbnB1dEJpcnRoZGF0ZSIsInNlbGVjdEJpcnRoZGF0ZSIsIl93cCRlbGVtZW50JHVzZVN0YXRlNyIsIl93cCRlbGVtZW50JHVzZVN0YXRlOCIsImlucHV0Q29tcGFueSIsInNlbGVjdENvbXBhbnkiLCJpc3N1ZXJLZXkiLCJjb21wYW55TmFtZVN0cmluZyIsInBob25lU3RyaW5nIiwiZ2V0UGhvbmVGaWVsZCIsInNoaXBwaW5nUGhvbmUiLCJiaWxsaW5nUGhvbmUiLCJ1cGRhdGVUb3RhbExhYmVsIiwibmV3VG90YWwiLCJ0b3RhbFNwYW4iLCJyZXBsYWNlV2l0aCIsInVwZGF0ZVRheGVzTGFiZWwiLCJoaWRlRmVlIiwiZmVlIiwiaGlkZSIsInRvdGFsVGF4IiwiZmVlTWFya3VwIiwicmVwbGFjZUZlZSIsIm5ld0ZlZSIsImluc2VydE5ld0ZlZSIsImFmdGVyIiwiaGFuZGxlRmVlcyIsImRvY3VtZW50RWxlbWVudCIsImRpc3BhdGNoRXZlbnQiLCJjb21wbGV0ZSIsIm9uUHJvY2Vzc2luZ1BheW1lbnQiLCJfZGVmaW5lUHJvcGVydHkiLCJwYXltZW50X21ldGhvZCIsInBheW1lbnRfbWV0aG9kX3RpdGxlIiwidGl0bGUiLCJ0b2tlblZhbCIsInZhbCIsImNhcmRUb2tlbiIsIlNVQ0NFU1MiLCJtZXRhIiwicGF5bWVudE1ldGhvZERhdGEiLCJ1bnN1YnNjcmliZVBheW1lbnRQcm9jZXNzaW5nIiwiY29tcGFueUxhYmVsIiwiaGlkZUNvbXBhbnlGaWVsZCIsImNvbXBhbnlQbGFjZWhvbGRlciIsImlzQ29tcGFueUVtcHR5IiwiYmlsbGluZ0RhdGEiLCJjb21wYW55Iiwic2hpcHBpbmdBZGRyZXNzIiwidW5zdWJzY3JpYmVQcm9jZXNzaW5nIiwiZXJyb3JNZXNzYWdlIiwiX2dldFBob25lRmllbGQkbGFiZWxzIiwiX2dldFBob25lRmllbGQiLCJwaG9uZUxhYmVsIiwibGFiZWxzIiwiaW5uZXJUZXh0IiwicGhvbmVQbGFjZWhvbGRlciIsImlzUGhvbmVFbXB0eSIsInBob25lIiwiaXNCaXJ0aGRhdGVWYWxpZCIsInRvZGF5IiwiRGF0ZSIsImJpcnRoZGF0ZSIsInVwZGF0ZUlzc3VlciIsInRhcmdldCIsInVwZGF0ZUNvbXBhbnkiLCJ1cGRhdGVQaG9uZSIsInVwZGF0ZUJpcnRoZGF0ZSIsImZpZWxkTWFya3VwIiwiZmllbGRUeXBlIiwicGxhY2Vob2xkZXIiLCJhcmd1bWVudHMiLCJ1bmRlZmluZWQiLCJjbGFzcyIsImh0bWxGb3IiLCJkYW5nZXJvdXNseVNldElubmVySFRNTCIsIl9faHRtbCIsIm9uQ2hhbmdlIiwiaXNzdWVycyIsImNvbnRlbnQiLCJiaWxsaW5nQ29tcGFueUZpZWxkIiwicXVlcnlTZWxlY3RvciIsInNoaXBwaW5nQ29tcGFueUZpZWxkIiwiaXNCaWxsaW5nQ29tcGFueVJlcXVpcmVkIiwiaGFzQXR0cmlidXRlIiwiaXNTaGlwcGluZ0NvbXBhbnlSZXF1aXJlZCIsImNvbXBhbnlGaWVsZCIsIkZyYWdtZW50IiwiY291bnRyeUNvZGVzIiwiQkUiLCJOTCIsIkRFIiwiQVQiLCJiaXJ0aGRhdGVGaWVsZCIsImJpcnRoZGF0ZVBsYWNlaG9sZGVyIiwicGhvbmVGaWVsZCIsIkxhYmVsIiwiX3JlZjIiLCJjYXJ0RGF0YSIsInVzZVNlbGVjdCIsImdldENhcnREYXRhIiwidG90YWxfcHJpY2UiLCJiaWxsaW5nQWRkcmVzcyIsIm1vbGxpZVBheW1lbnRNZXRob2QiLCJnYXRld2F5RGF0YSIsImF2YWlsYWJsZUdhdGV3YXlzIiwiaXNDb21wYW55RmllbGRWaXNpYmxlIiwiYWRkRXZlbnRMaXN0ZW5lciIsImNyZWRpdGNhcmRTZWxlY3RlZEV2ZW50IiwiZWRpdCIsInBheW1lbnRNZXRob2RJZCIsImNhbk1ha2VQYXltZW50IiwiX3JlZjMiLCJfIiwiaXNFbXB0eSIsImFsbG93ZWRDb3VudHJpZXMiLCJpbmNsdWRlcyIsImN1cnJlbmN5X2NvZGUiLCJfd2NTZXR0aW5nczIiLCJhcmlhTGFiZWwiLCJzdXBwb3J0cyIsImZlYXR1cmVzIiwid2MiLCJyZWdpc3RlclBheW1lbnRNZXRob2QiLCJ3Y0Jsb2Nrc1JlZ2lzdHJ5IiwiZGVmYXVsdEZpZWxkcyIsImFsbFNldHRpbmdzIiwiX21vbGxpZUJsb2NrRGF0YSRnYXRlIiwiaXNBcHBsZVNlc3Npb24iLCJwaG9uZUZpZWxkRGF0YXNldCIsImRhdGFzZXQiLCJzaG93UGhvbmVGaWVsZCIsImZvckVhY2giLCJyZWdpc3RlciIsImlzRXhwcmVzc0VuYWJsZWQiLCJjYW5NYWtlUGF5bWVudHMiLCJyZWdpc3RlckV4cHJlc3NQYXltZW50TWV0aG9kIiwiZGVzY3JpcHRpb24iLCJnYXRld2F5SWQiXSwic291cmNlUm9vdCI6IiJ9
  • mollie-payments-for-woocommerce/trunk/readme.txt

    r3242454 r3262577  
    11=== Mollie Payments for WooCommerce ===
    22Contributors: daanvm, danielhuesken, davdebcom, dinamiko, syde, l.vangunst, ndijkstra, robin-mollie, wido, carmen222, inpsyde-maticluznar
    3 Tags: mollie, payments, payment gateway, woocommerce, credit card, apple pay, ideal, bancontact, klarna, sofort, woocommerce subscriptions
    4 Requires at least: 3.8
     3Tags: mollie, woocommerce, payments, ecommerce, credit card
     4Requires at least: 5.0
    55Tested up to: 6.7
    66Stable tag: 7.10.0
    7 Requires PHP: 7.2
     7Requires PHP: 7.4
    88License: GPLv2 or later
    99License URI: http://www.gnu.org/licenses/gpl-2.0.html
     
    197197= Minimum Requirements =
    198198
    199 * PHP version 7.2 or greater
     199* PHP version 7.4 or greater
    200200* PHP extensions enabled: cURL, JSON
    201 * WordPress 3.8 or greater
     201* WordPress 5.0 or greater
    202202* WooCommerce 3.9 or greater
    203203* Mollie account
     
    226226
    227227== Changelog ==
     228
     229= 8.0.0 - 27-03-2025 =
     230
     231* Feature Flag - Klarna, Riverty and Billie can be used with Payments API
     232* Feature - Added support for Mollie's new Payments API features
     233* Fixed - Notice for missing value of cardToken
     234* Fixed - ltrim error on Apple Pay notice with php 8.2 (author @kylwes)
     235* Fixed - Logged URL should be same as used in future logic (author @tombroucke)
    228236
    229237= 7.10.0 - 18-02-2025 =
     
    241249= 7.9.1 - 22-01-2025 =
    242250
    243 * Feature: Style Apple Pay express button via Checkout block
    244 * Fixed: Notice `_load_textdomain_just_in_time` due to early translation loading
    245 * Fixed: Company Name input field not saved in Order when Billie was enabled
    246 * Fixed: Mollie Payment methods may not load on Checkout block
    247 * Fixed: Mollie Payment methods may disappear from Checkout block when changing billing country
    248 * Fixed: Mollie Components are not enabled by default on new installations
     251* Feature - Style Apple Pay express button via Checkout block
     252* Fixed - Notice `_load_textdomain_just_in_time` due to early translation loading
     253* Fixed - Company Name input field not saved in Order when Billie was enabled
     254* Fixed - Mollie Payment methods may not load on Checkout block
     255* Fixed - Mollie Payment methods may disappear from Checkout block when changing billing country
     256* Fixed - Mollie Components are not enabled by default on new installations
    249257
    250258= 7.9.0 - 18-11-2024 =
     
    257265* Fixed - Bank Transfer payment details displayed in one line on order-received page
    258266
    259 
    260267= 7.8.2 - 08-09-2024 =
    261268
    262269* Fixed - Subscription renewal status on-hold instead of active
    263 
    264270
    265271= 7.8.1 - 07-09-2024 =
  • mollie-payments-for-woocommerce/trunk/src/Activation/ActivationModule.php

    r3226701 r3262577  
    1717    private $pluginVersion;
    1818    /**
    19      * ActivationModule constructor.
    20      */
    21     public function __construct($baseFile, $pluginVersion)
    22     {
    23         $this->baseFile = $baseFile;
    24         $this->pluginVersion = $pluginVersion;
    25     }
    26     /**
    2719     * @param ContainerInterface $container
    2820     *
     
    3123    public function run(ContainerInterface $container): bool
    3224    {
     25        $this->pluginVersion = $container->get('shared.plugin_version');
     26        $this->baseFile = \M4W_FILE;
    3327        add_action('init', [$this, 'pluginInit']);
    3428        add_action('admin_init', [$this, 'mollieWcNoticeApiKeyMissing']);
  • mollie-payments-for-woocommerce/trunk/src/Assets/AssetsModule.php

    r3226701 r3262577  
    2323        return \true;
    2424    }
    25     public function enqueueBlockCheckoutScripts(Data $dataService, array $gatewayInstances): void
     25    public function enqueueBlockCheckoutScripts(Data $dataService, array $gatewayInstances, ContainerInterface $container): void
    2626    {
    2727        if (!has_block('woocommerce/checkout')) {
     
    3131        wp_enqueue_style('mollie-gateway-icons');
    3232        wp_enqueue_style('mollie-block-custom-field');
    33         \Mollie\WooCommerce\Assets\MollieCheckoutBlocksSupport::localizeWCBlocksData($dataService, $gatewayInstances);
     33        \Mollie\WooCommerce\Assets\MollieCheckoutBlocksSupport::localizeWCBlocksData($dataService, $gatewayInstances, $container);
    3434    }
    3535    public function registerButtonsBlockScripts(string $pluginUrl, string $pluginPath): void
     
    145145     * Enqueue Frontend only scripts
    146146     *
    147      * @param $container Container
     147     * @param ContainerInterface $container
    148148     * @return void
    149149     */
     
    195195        $object_name = 'mollieComponentsSettings';
    196196        $data = ['merchantProfileId' => $merchantProfileId, 'options' => ['locale' => $locale, 'testmode' => $settingsHelper->isTestModeEnabled()], 'enabledGateways' => $gatewayNames, 'componentsSettings' => $mollieComponentsStylesGateways, 'componentsAttributes' => [['name' => 'cardHolder', 'label' => esc_html__('Name on card', 'mollie-payments-for-woocommerce')], ['name' => 'cardNumber', 'label' => esc_html__('Card number', 'mollie-payments-for-woocommerce')], ['name' => 'expiryDate', 'label' => esc_html__('Expiry date', 'mollie-payments-for-woocommerce')], ['name' => 'verificationCode', 'label' => esc_html__('CVC/CVV', 'mollie-payments-for-woocommerce')]], 'messages' => ['defaultErrorMessage' => esc_html__('An unknown error occurred, please check the card fields.', 'mollie-payments-for-woocommerce')], 'isCheckout' => is_checkout(), 'isCheckoutPayPage' => is_checkout_pay_page()];
    197         if (has_block("woocommerce/checkout")) {
     197        if (has_block("woocommerce/checkout") && !is_wc_endpoint_url('order-pay')) {
    198198            wp_enqueue_script('mollie-components-blocks');
    199199            wp_localize_script('mollie-components-blocks', $object_name, $data);
     
    288288        /** @var Settings */
    289289        $settingsHelper = $container->get('settings.settings_helper');
    290         $gatewayInstances = $container->get('gateway.instances');
    291         add_action('woocommerce_blocks_loaded', function () {
    292             woocommerce_store_api_register_update_callback(['namespace' => 'mollie-payments-for-woocommerce', 'callback' => function () {
     290        $gatewayInstances = $container->get('__deprecated.gateway_helpers');
     291        add_action('woocommerce_blocks_loaded', static function () {
     292            woocommerce_store_api_register_update_callback(['namespace' => 'mollie-payments-for-woocommerce', 'callback' => static function () {
    293293                // Do nothing
    294294            }]);
     
    296296        /** Add support to Mollie blocks for WooCommerce checkout blocks functionality */
    297297        //https://github.com/woocommerce/woocommerce-blocks/blob/trunk/docs/third-party-developers/extensibility/checkout-payment-methods/payment-method-integration.md#putting-it-all-together
    298         add_action('woocommerce_blocks_loaded', function () use ($dataService, $gatewayInstances, $pluginUrl, $pluginPath, $hasBlocksEnabled) {
     298        add_action('woocommerce_blocks_loaded', function () use ($dataService, $gatewayInstances, $pluginUrl, $pluginPath, $hasBlocksEnabled, $container) {
    299299            if ($hasBlocksEnabled && is_admin() && class_exists('Automattic\WooCommerce\Blocks\Payments\Integrations\AbstractPaymentMethodType')) {
    300                 add_action('woocommerce_blocks_payment_method_type_registration', function (PaymentMethodRegistry $paymentMethodRegistry) use ($dataService, $gatewayInstances, $pluginUrl, $pluginPath) {
    301                     $paymentMethodRegistry->register(new \Mollie\WooCommerce\Assets\MollieCheckoutBlocksSupport($dataService, $gatewayInstances, $this->getPluginUrl($pluginUrl, '/public/js/mollieBlockIndex.min.js'), (string) filemtime($this->getPluginPath($pluginPath, '/public/js/mollieBlockIndex.min.js'))));
     300                add_action('woocommerce_blocks_payment_method_type_registration', function (PaymentMethodRegistry $paymentMethodRegistry) use ($dataService, $gatewayInstances, $pluginUrl, $pluginPath, $container) {
     301                    $paymentMethodRegistry->register(new \Mollie\WooCommerce\Assets\MollieCheckoutBlocksSupport($dataService, $gatewayInstances, $this->getPluginUrl($pluginUrl, '/public/js/mollieBlockIndex.min.js'), (string) filemtime($this->getPluginPath($pluginPath, '/public/js/mollieBlockIndex.min.js')), $container));
    302302                });
    303303            }
     
    318318            if ($hasBlocksEnabled) {
    319319                /** @var array */
    320                 $gatewayInstances = $container->get('gateway.instances');
     320                $gatewayInstances = $container->get('__deprecated.gateway_helpers');
    321321                self::registerBlockScripts($pluginUrl, $pluginPath);
    322                 add_action('wp_enqueue_scripts', function () use ($dataService, $gatewayInstances) {
    323                     $this->enqueueBlockCheckoutScripts($dataService, $gatewayInstances);
     322                add_action('wp_enqueue_scripts', function () use ($dataService, $gatewayInstances, $container) {
     323                    $this->enqueueBlockCheckoutScripts($dataService, $gatewayInstances, $container);
    324324                });
    325325                $this->registerButtonsBlockScripts($pluginUrl, $pluginPath);
  • mollie-payments-for-woocommerce/trunk/src/Assets/MollieCheckoutBlocksSupport.php

    r3226701 r3262577  
    44
    55use Automattic\WooCommerce\Blocks\Payments\Integrations\AbstractPaymentMethodType;
    6 use Mollie\WooCommerce\Gateway\MolliePaymentGateway;
    7 use Mollie\WooCommerce\Gateway\MolliePaymentGatewayI;
     6use Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies\DefaultFieldsStrategy;
    87use Mollie\WooCommerce\PaymentMethods\PaymentMethodI;
    98use Mollie\WooCommerce\Shared\Data;
     9use Mollie\Psr\Container\ContainerInterface;
    1010final class MollieCheckoutBlocksSupport extends AbstractPaymentMethodType
    1111{
     
    2222    /** @var string $registerScriptVersion */
    2323    protected $registerScriptVersion;
    24     public function __construct(Data $dataService, array $gatewayInstances, string $registerScriptUrl, string $registerScriptVersion)
     24    private ContainerInterface $container;
     25    public function __construct(Data $dataService, array $gatewayInstances, string $registerScriptUrl, string $registerScriptVersion, ContainerInterface $container)
    2526    {
    2627        $this->dataService = $dataService;
     
    2829        $this->registerScriptUrl = $registerScriptUrl;
    2930        $this->registerScriptVersion = $registerScriptVersion;
     31        $this->container = $container;
    3032    }
    3133    public function initialize()
     
    4042    {
    4143        wp_register_script(self::$scriptHandle, $this->registerScriptUrl, ['wc-blocks-registry', 'underscore', 'jquery'], $this->registerScriptVersion, \true);
    42         self::localizeWCBlocksData($this->dataService, $this->gatewayInstances);
     44        self::localizeWCBlocksData($this->dataService, $this->gatewayInstances, $this->container);
    4345        return [self::$scriptHandle];
    4446    }
    45     public static function localizeWCBlocksData($dataService, $gatewayInstances)
     47    public static function localizeWCBlocksData($dataService, $gatewayInstances, $container)
    4648    {
    4749        wp_enqueue_style('mollie-applepaydirect');
    48         wp_localize_script(self::$scriptHandle, 'mollieBlockData', ['gatewayData' => self::gatewayDataForWCBlocks($dataService, $gatewayInstances), 'mollieApplePayBlockDataCart' => $dataService->mollieApplePayBlockDataCart()]);
     50        wp_localize_script(self::$scriptHandle, 'mollieBlockData', ['gatewayData' => self::gatewayDataForWCBlocks($dataService, $gatewayInstances, $container), 'mollieApplePayBlockDataCart' => $dataService->mollieApplePayBlockDataCart()]);
    4951    }
    50     public static function gatewayDataForWCBlocks(Data $dataService, array $gatewayInstances): array
     52    public static function gatewayDataForWCBlocks(Data $dataService, array $deprecatedGatewayHelpers, ContainerInterface $container): array
    5153    {
    5254        $filters = $dataService->wooCommerceFiltersForCheckout();
     
    5456        $availablePaymentMethods = [];
    5557        /**
    56          * @var MolliePaymentGatewayI $gateway
     58         * @var $gateway
    5759         * psalm-suppress  UnusedForeachValue
    5860         */
     
    6567            $filterKey = "{$filters['amount']['currency']}-{$filters['billingCountry']}";
    6668            foreach ($availableGateways as $key => $gateway) {
    67                 $availablePaymentMethods[$filterKey][$key] = $gateway->paymentMethod()->getProperty('id');
     69                $gatewayId = $gateway->id;
     70                $methodId = substr($gatewayId, strrpos($gatewayId, '_') + 1);
     71                $availablePaymentMethods[$filterKey][$key] = $methodId;
    6872            }
    6973        }
    7074        $dataToScript = ['ajaxUrl' => admin_url('admin-ajax.php'), 'filters' => ['currency' => isset($filters['amount']['currency']) ? $filters['amount']['currency'] : \false, 'cartTotal' => isset($filters['amount']['value']) ? $filters['amount']['value'] : \false, 'paymentLocale' => isset($filters['locale']) ? $filters['locale'] : \false, 'billingCountry' => isset($filters['billingCountry']) ? $filters['billingCountry'] : \false]];
     75        $paymentGateways = WC()->payment_gateways()->payment_gateways();
    7176        $gatewayData = [];
    72         $isSepaEnabled = isset($gatewayInstances['mollie_wc_gateway_directdebit']) && $gatewayInstances['mollie_wc_gateway_directdebit']->enabled === 'yes';
    73         /** @var MolliePaymentGateway $gateway */
    74         foreach ($gatewayInstances as $gatewayKey => $gateway) {
    75             $method = $gateway->paymentMethod();
     77        $isSepaEnabled = isset($deprecatedGatewayHelpers['mollie_wc_gateway_directdebit']) && $deprecatedGatewayHelpers['mollie_wc_gateway_directdebit']->enabled === 'yes';
     78        /** @var PaymentGateway $gateway */
     79        foreach ($paymentGateways as $gatewayKey => $gateway) {
     80            if (substr($gateway->id, 0, 18) !== 'mollie_wc_gateway_') {
     81                continue;
     82            }
     83            $deprecatedGateway = $deprecatedGatewayHelpers[$gatewayKey];
     84            $method = $deprecatedGateway->paymentMethod();
    7685            $gatewayId = is_string($method->getProperty('id')) ? $method->getProperty('id') : "";
    7786            if ($gateway->enabled !== 'yes' || $gatewayId === 'directdebit' && !is_admin()) {
     
    8190            $issuers = \false;
    8291            if ($method->getProperty('paymentFields') === \true) {
    83                 $paymentFieldsService = $method->paymentFieldsService();
    84                 $paymentFieldsService->setStrategy($method);
    85                 $issuers = $method->paymentFieldsService()->getStrategyMarkup($gateway);
     92                $className = 'Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies\\' . ucfirst($method->getProperty('id')) . 'FieldsStrategy';
     93                $paymentFieldsStrategy = class_exists($className) ? new $className($deprecatedGateway, $gateway->get_description(), $dataService) : new DefaultFieldsStrategy($deprecatedGateway, $gateway->get_description(), $dataService);
     94                $issuers = $paymentFieldsStrategy->getFieldMarkup($deprecatedGateway, $dataService);
    8695            }
    8796            if ($gatewayId === 'creditcard') {
     
    8998                $issuers = \false;
    9099            }
    91             $title = $method->title();
    92             $labelMarkup = "<span style='margin-right: 1em'>{$title}</span>{$gateway->icon}";
     100            $title = $method->title($container);
     101            $labelMarkup = "<span style='margin-right: 1em'>{$title}</span>{$gateway->get_icon()}";
    93102            $hasSurcharge = $method->hasSurcharge();
    94103            $countryCodes = ['BE' => '+32xxxxxxxxx', 'NL' => '+316xxxxxxxx', 'DE' => '+49xxxxxxxxx', 'AT' => '+43xxxxxxxxx'];
  • mollie-payments-for-woocommerce/trunk/src/BlockService/CheckoutBlockService.php

    r3226701 r3262577  
    6060            $filterKey = "{$filters['amount']['currency']}-{$filters['billingCountry']}";
    6161            foreach ($availableGateways as $key => $gateway) {
    62                 $availablePaymentMethods[$filterKey][$key] = $gateway->paymentMethod()->getProperty('id');
     62                $availablePaymentMethods[$filterKey][$key] = str_replace('mollie_wc_gateway_', '', $gateway->id);
    6363            }
    6464        }
  • mollie-payments-for-woocommerce/trunk/src/Buttons/ApplePayButton/ResponsesToApple.php

    r3191126 r3262577  
    1313    protected $logger;
    1414    /**
    15      * @var MolliePaymentGatewayI
     15     * @var
    1616     */
    17     protected $gateway;
     17    protected $deprecatedAppleHelper;
    1818    /**
    1919     * ResponsesToApple constructor.
    2020     */
    21     public function __construct(Logger $logger, MolliePaymentGatewayI $appleGateway)
     21    public function __construct(Logger $logger, $deprecatedAppleHelper)
    2222    {
    2323        $this->logger = $logger;
    24         $this->gateway = $appleGateway;
     24        $this->deprecatedAppleHelper = $deprecatedAppleHelper;
    2525    }
    2626    /**
     
    174174    {
    175175        $order = wc_get_order($orderId);
    176         $redirect_url = $this->gateway->getReturnRedirectUrlForOrder($order);
     176        $redirect_url = $this->deprecatedAppleHelper->getReturnRedirectUrlForOrder($order);
    177177        // Add utm_nooverride query string
    178178        $redirect_url = add_query_arg(['utm_nooverride' => 1], $redirect_url);
    179         $this->logger->debug(__METHOD__ . sprintf(': Redirect url on return order %s, order %s: %s', $this->gateway->paymentMethod()->getProperty('id'), $orderId, $redirect_url));
     179        $this->logger->debug(__METHOD__ . sprintf(': Redirect url on return order %s, order %s: %s', $this->deprecatedAppleHelper->paymentMethod()->getProperty('id'), $orderId, $redirect_url));
    180180        return $redirect_url;
    181181    }
  • mollie-payments-for-woocommerce/trunk/src/Buttons/PayPalButton/PayPalAjaxRequests.php

    r3164004 r3262577  
    44namespace Mollie\WooCommerce\Buttons\PayPalButton;
    55
     6use Mollie\Inpsyde\PaymentGateway\PaymentGateway;
    67use Mollie\WooCommerce\Gateway\Surcharge;
    78use Mollie\WooCommerce\Notice\NoticeInterface;
     
    2930     * @param  $gateway
    3031     */
    31     public function __construct($gateway, NoticeInterface $notice, Logger $logger)
     32    public function __construct(PaymentGateway $gateway, NoticeInterface $notice, Logger $logger)
    3233    {
    3334        $this->gateway = $gateway;
  • mollie-payments-for-woocommerce/trunk/src/Gateway/GatewayModule.php

    r3242448 r3262577  
    77use Automattic\WooCommerce\Internal\DataStores\Orders\CustomOrdersTableController;
    88use Automattic\WooCommerce\StoreApi\Exceptions\RouteException;
    9 use DateTime;
    109use Mollie\Inpsyde\Modularity\Module\ExecutableModule;
     10use Mollie\Inpsyde\Modularity\Module\ExtendingModule;
    1111use Mollie\Inpsyde\Modularity\Module\ModuleClassNameIdTrait;
    1212use Mollie\Inpsyde\Modularity\Module\ServiceModule;
     13use Mollie\Inpsyde\PaymentGateway\PaymentMethodServiceProviderTrait;
    1314use Mollie\WooCommerce\BlockService\CheckoutBlockService;
    14 use Mollie\WooCommerce\Buttons\ApplePayButton\AppleAjaxRequests;
    1515use Mollie\WooCommerce\Buttons\ApplePayButton\ApplePayDirectHandler;
    16 use Mollie\WooCommerce\Buttons\ApplePayButton\ResponsesToApple;
    17 use Mollie\WooCommerce\Buttons\PayPalButton\DataToPayPal;
    18 use Mollie\WooCommerce\Buttons\PayPalButton\PayPalAjaxRequests;
    1916use Mollie\WooCommerce\Buttons\PayPalButton\PayPalButtonHandler;
    2017use Mollie\WooCommerce\Gateway\Voucher\MaybeDisableGateway;
    21 use Mollie\WooCommerce\Notice\AdminNotice;
    22 use Mollie\WooCommerce\Notice\FrontendNotice;
    23 use Mollie\WooCommerce\Notice\NoticeInterface;
    24 use Mollie\WooCommerce\Payment\MollieObject;
    25 use Mollie\WooCommerce\Payment\MollieOrderService;
    26 use Mollie\WooCommerce\Payment\OrderInstructionsService;
    27 use Mollie\WooCommerce\Payment\PaymentCheckoutRedirectService;
    28 use Mollie\WooCommerce\Payment\PaymentFactory;
    29 use Mollie\WooCommerce\Payment\PaymentFieldsService;
    30 use Mollie\WooCommerce\Payment\PaymentService;
    3118use Mollie\WooCommerce\PaymentMethods\IconFactory;
    3219use Mollie\WooCommerce\PaymentMethods\PaymentMethodI;
    33 use Mollie\WooCommerce\SDK\Api;
    34 use Mollie\WooCommerce\SDK\HttpResponse;
    3520use Mollie\WooCommerce\Settings\Settings;
    3621use Mollie\WooCommerce\Shared\Data;
    3722use Mollie\WooCommerce\Shared\GatewaySurchargeHandler;
     23use Mollie\WooCommerce\PaymentMethods\Constants;
    3824use Mollie\WooCommerce\Shared\SharedDataDictionary;
    39 use Mollie\WooCommerce\Subscription\MollieSepaRecurringGateway;
    40 use Mollie\WooCommerce\Subscription\MollieSubscriptionGateway;
    41 use Mollie\WooCommerce\PaymentMethods\Constants;
    4225use Mollie\Psr\Container\ContainerInterface;
    43 use Mollie\Psr\Log\LoggerInterface as Logger;
    44 use WP_Post;
    45 class GatewayModule implements ServiceModule, ExecutableModule
     26class GatewayModule implements ServiceModule, ExecutableModule, ExtendingModule
    4627{
    4728    use ModuleClassNameIdTrait;
     29    use PaymentMethodServiceProviderTrait;
    4830    public const APPLE_PAY_METHOD_ALLOWED_KEY = 'mollie_apple_pay_method_allowed';
    4931    public const POST_DATA_KEY = 'post_data';
     
    5840    const FIELD_IN3_BIRTHDATE = 'billing_birthdate';
    5941    const GATEWAY_NAME_IN3 = "mollie_wc_gateway_in3";
    60     public function services(): array
    61     {
    62         return ['gateway.classnames' => static function (): array {
    63             return SharedDataDictionary::GATEWAY_CLASSNAMES;
    64         }, 'gateway.instances' => function (ContainerInterface $container): array {
    65             return $this->instantiatePaymentMethodGateways($container);
    66         }, 'gateway.paymentMethods' => static function (ContainerInterface $container): array {
    67             return (new self())->instantiatePaymentMethods($container);
    68         }, 'gateway.paymentMethodsEnabledAtMollie' => static function (ContainerInterface $container): array {
    69             $dataHelper = $container->get('settings.data_helper');
    70             assert($dataHelper instanceof Data);
    71             $settings = $container->get('settings.settings_helper');
    72             assert($settings instanceof Settings);
    73             $apiKey = $settings->getApiKey();
    74             $methods = $apiKey ? $dataHelper->getAllPaymentMethods($apiKey) : [];
    75             $enabledMethods = [];
    76             foreach ($methods as $method) {
    77                 $enabledMethods[] = $method['id'];
    78             }
    79             return $enabledMethods;
    80         }, 'gateway.listAllMethodsAvailable' => static function (ContainerInterface $container): array {
    81             $dataHelper = $container->get('settings.data_helper');
    82             assert($dataHelper instanceof Data);
    83             $settings = $container->get('settings.settings_helper');
    84             assert($settings instanceof Settings);
    85             $apiKey = $settings->getApiKey();
    86             $methods = $apiKey ? $dataHelper->getAllAvailablePaymentMethods() : [];
    87             $availableMethods = [];
    88             $implementedMethods = $container->get('gateway.classnames');
    89             foreach ($methods as $method) {
    90                 if (in_array('Mollie_WC_Gateway_' . ucfirst($method['id']), $implementedMethods, \true)) {
    91                     $availableMethods[] = $method;
    92                 }
    93             }
    94             return $availableMethods;
    95         }, 'gateway.getPaymentMethodsAfterFeatureFlag' => static function (ContainerInterface $container): array {
    96             $availablePaymentMethods = $container->get('gateway.listAllMethodsAvailable');
    97             $klarnaOneFlag = (bool) apply_filters('inpsyde.feature-flags.mollie-woocommerce.klarna_one_enabled', \true);
    98             if (!$klarnaOneFlag) {
    99                 $availablePaymentMethods = array_filter($availablePaymentMethods, static function ($method) {
    100                     return $method['id'] !== Constants::KLARNA;
    101                 });
    102             }
    103             $bancomatpayFlag = (bool) apply_filters('inpsyde.feature-flags.mollie-woocommerce.bancomatpay_enabled', \true);
    104             if (!$bancomatpayFlag) {
    105                 $availablePaymentMethods = array_filter($availablePaymentMethods, static function ($method) {
    106                     return $method['id'] !== Constants::BANCOMATPAY;
    107                 });
    108             }
    109             $almaFlag = (bool) apply_filters('inpsyde.feature-flags.mollie-woocommerce.alma_enabled', \true);
    110             if (!$almaFlag) {
    111                 $availablePaymentMethods = array_filter($availablePaymentMethods, static function ($method) {
    112                     return $method['id'] !== Constants::ALMA;
    113                 });
    114             }
    115             $swishFlag = (bool) apply_filters('inpsyde.feature-flags.mollie-woocommerce.swish_enabled', \true);
    116             if (!$swishFlag) {
    117                 $availablePaymentMethods = array_filter($availablePaymentMethods, static function ($method) {
    118                     return $method['id'] !== Constants::SWISH;
    119                 });
    120             }
    121             return $availablePaymentMethods;
    122         }, 'gateway.isSDDGatewayEnabled' => static function (ContainerInterface $container): bool {
    123             $enabledMethods = $container->get('gateway.paymentMethodsEnabledAtMollie');
    124             return in_array(Constants::DIRECTDEBIT, $enabledMethods, \true);
    125         }, IconFactory::class => static function (ContainerInterface $container): IconFactory {
    126             $pluginUrl = $container->get('shared.plugin_url');
    127             $pluginPath = $container->get('shared.plugin_path');
    128             return new IconFactory($pluginUrl, $pluginPath);
    129         }, PaymentService::class => static function (ContainerInterface $container): PaymentService {
    130             $logger = $container->get(Logger::class);
    131             assert($logger instanceof Logger);
    132             $notice = $container->get(AdminNotice::class);
    133             assert($notice instanceof AdminNotice);
    134             $paymentFactory = $container->get(PaymentFactory::class);
    135             assert($paymentFactory instanceof PaymentFactory);
    136             $data = $container->get('settings.data_helper');
    137             assert($data instanceof Data);
    138             $api = $container->get('SDK.api_helper');
    139             assert($api instanceof Api);
    140             $settings = $container->get('settings.settings_helper');
    141             assert($settings instanceof Settings);
    142             $pluginId = $container->get('shared.plugin_id');
    143             $paymentCheckoutRedirectService = $container->get(PaymentCheckoutRedirectService::class);
    144             assert($paymentCheckoutRedirectService instanceof PaymentCheckoutRedirectService);
    145             $voucherDefaultCategory = $container->get('voucher.defaultCategory');
    146             return new PaymentService($notice, $logger, $paymentFactory, $data, $api, $settings, $pluginId, $paymentCheckoutRedirectService, $voucherDefaultCategory);
    147         }, OrderInstructionsService::class => static function (): OrderInstructionsService {
    148             return new OrderInstructionsService();
    149         }, PaymentFieldsService::class => static function (ContainerInterface $container): PaymentFieldsService {
    150             $data = $container->get('settings.data_helper');
    151             assert($data instanceof Data);
    152             return new PaymentFieldsService($data);
    153         }, PaymentCheckoutRedirectService::class => static function (ContainerInterface $container): PaymentCheckoutRedirectService {
    154             $data = $container->get('settings.data_helper');
    155             assert($data instanceof Data);
    156             return new PaymentCheckoutRedirectService($data);
    157         }, \Mollie\WooCommerce\Gateway\Surcharge::class => static function (ContainerInterface $container): \Mollie\WooCommerce\Gateway\Surcharge {
    158             return new \Mollie\WooCommerce\Gateway\Surcharge();
    159         }, MollieOrderService::class => static function (ContainerInterface $container): MollieOrderService {
    160             $HttpResponseService = $container->get('SDK.HttpResponse');
    161             assert($HttpResponseService instanceof HttpResponse);
    162             $logger = $container->get(Logger::class);
    163             assert($logger instanceof Logger);
    164             $paymentFactory = $container->get(PaymentFactory::class);
    165             assert($paymentFactory instanceof PaymentFactory);
    166             $data = $container->get('settings.data_helper');
    167             assert($data instanceof Data);
    168             $pluginId = $container->get('shared.plugin_id');
    169             return new MollieOrderService($HttpResponseService, $logger, $paymentFactory, $data, $pluginId);
    170         }, \Mollie\WooCommerce\Gateway\OrderMandatoryGatewayDisabler::class => static function (ContainerInterface $container): \Mollie\WooCommerce\Gateway\OrderMandatoryGatewayDisabler {
    171             $settings = $container->get('settings.settings_helper');
    172             assert($settings instanceof Settings);
    173             $isSettingsOrderApi = $settings->isOrderApiSetting();
    174             return new \Mollie\WooCommerce\Gateway\OrderMandatoryGatewayDisabler($isSettingsOrderApi);
    175         }, 'gateway.isBillieEnabled' => static function (ContainerInterface $container): bool {
    176             $settings = $container->get('settings.settings_helper');
    177             assert($settings instanceof Settings);
    178             $isSettingsOrderApi = $settings->isOrderApiSetting();
    179             $billie = isset($container->get('gateway.paymentMethods')['billie']) ? $container->get('gateway.paymentMethods')['billie'] : null;
    180             $isBillieEnabled = \false;
    181             if ($billie instanceof PaymentMethodI) {
    182                 $isBillieEnabled = $billie->getProperty('enabled') === 'yes';
    183             }
    184             return $isSettingsOrderApi && $isBillieEnabled;
    185         }];
    186     }
    18742    public function run(ContainerInterface $container): bool
    18843    {
     
    19348        });
    19449        add_filter('woocommerce_payment_gateways', static function ($gateways) use ($container) {
    195             $mollieGateways = $container->get('gateway.instances');
    196             return array_merge($gateways, $mollieGateways);
    197         });
    198         add_filter('woocommerce_payment_gateways', static function ($gateways) use ($container) {
    19950            $orderMandatoryGatewayDisabler = $container->get(\Mollie\WooCommerce\Gateway\OrderMandatoryGatewayDisabler::class);
    20051            assert($orderMandatoryGatewayDisabler instanceof \Mollie\WooCommerce\Gateway\OrderMandatoryGatewayDisabler);
     
    20354        add_filter('woocommerce_payment_gateways', static function ($gateways) {
    20455            $maybeEnablegatewayHelper = new MaybeDisableGateway();
     56            $gateways = $maybeEnablegatewayHelper->maybeDisableBankTransferGateway($gateways);
    20557            return $maybeEnablegatewayHelper->maybeDisableMealVoucherGateway($gateways);
    20658        });
    207         add_filter('woocommerce_payment_gateways', [$this, 'maybeDisableBankTransferGateway'], 20);
     59        add_filter('woocommerce_payment_gateways', static function ($gateways) use ($container) {
     60            $deprecatedGatewayHelpers = $container->get('__deprecated.gateway_helpers');
     61            foreach ($gateways as $gateway) {
     62                $isMolliegateway = is_string($gateway) && strpos($gateway, 'mollie_wc_gateway_') !== \false || is_object($gateway) && strpos($gateway->id, 'mollie_wc_gateway_') !== \false;
     63                if (!$isMolliegateway) {
     64                    continue;
     65                }
     66                // Add subscription filters after payment gateways are loaded
     67                $isSubscriptiongateway = $gateway->supports('subscriptions');
     68                if ($isSubscriptiongateway) {
     69                    $deprecatedGatewayHelpers[$gateway->id]->addSubscriptionFilters($gateway);
     70                }
     71                // Add payment instructions
     72                $displayInstructionsService = $container->get('gateway.hooks.displayInstructions');
     73                $displayInstructionsService($gateway);
     74                // Add thankyou page actions for gateway
     75                $thankyouPageService = $container->get('gateway.hooks.thankyouPage');
     76                if (!has_action('woocommerce_thankyou_' . $gateway->id)) {
     77                    $thankyouPageService($gateway);
     78                }
     79                // Add subscription payment hooks
     80                $isSubscriptionPaymentService = $container->get('gateway.hooks.isSubscriptionPayment');
     81                $isSubscriptionPaymentService($gateway);
     82            }
     83            return $gateways;
     84        }, 30);
    20885        // Disable SEPA as payment option in WooCommerce checkout
    20986        add_filter('woocommerce_available_payment_gateways', [$this, 'disableSEPAInCheckout'], 11, 1);
     
    229106        assert($surchargeService instanceof \Mollie\WooCommerce\Gateway\Surcharge);
    230107        $this->gatewaySurchargeHandling($surchargeService);
    231         $notice = $container->get(AdminNotice::class);
    232         assert($notice instanceof AdminNotice);
    233         $logger = $container->get(Logger::class);
    234         assert($logger instanceof Logger);
    235         $pluginUrl = $container->get('shared.plugin_url');
    236         $apiHelper = $container->get('SDK.api_helper');
    237         assert($apiHelper instanceof Api);
    238         $settingsHelper = $container->get('settings.settings_helper');
    239         assert($settingsHelper instanceof Settings);
    240         $appleGateway = isset($container->get('gateway.instances')['mollie_wc_gateway_applepay']) ? $container->get('gateway.instances')['mollie_wc_gateway_applepay'] : \false;
    241         if ($appleGateway) {
    242             $this->mollieApplePayDirectHandling($notice, $logger, $apiHelper, $settingsHelper, $appleGateway);
    243         }
    244         $paypalGateway = isset($container->get('gateway.instances')['mollie_wc_gateway_paypal']) ? $container->get('gateway.instances')['mollie_wc_gateway_paypal'] : \false;
    245         if ($paypalGateway) {
    246             $this->molliePayPalButtonHandling($paypalGateway, $notice, $logger, $pluginUrl);
    247         }
     108        $this->paymentButtonsBootstrap($container);
    248109        $maybeDisableVoucher = new MaybeDisableGateway();
    249110        $dataService = $container->get('settings.data_helper');
     
    272133            return $fields;
    273134        }, 10, 3);
     135        add_action('init', static function () use ($container) {
     136            $paymentMethods = $container->get('gateway.paymentMethods');
     137            foreach ($paymentMethods as $paymentMethod) {
     138                assert($paymentMethod instanceof PaymentMethodI);
     139                $paymentMethod->initializeTranslations();
     140                $paymentMethod->updateSettingsWithDefaults($container);
     141            }
     142        });
     143        add_filter('woocommerce_get_transaction_url', static function ($return_url, $order, \WC_Payment_Gateway $wcGateway) {
     144            if ($return_url || strpos($wcGateway->id, 'mollie_wc_gateway_') === \false) {
     145                return $return_url;
     146            }
     147            $transactionId = $order->get_transaction_id();
     148            $isPaymentApi = substr($transactionId, 0, 3) === 'tr_';
     149            $resource = $transactionId && !$isPaymentApi ? 'orders' : 'payments';
     150            return 'https://my.mollie.com/dashboard/' . $resource . '/' . trim($transactionId) . '?utm_source=woocommerce&utm_medium=plugin&utm_campaign=partner';
     151        }, 10, 3);
    274152        return \true;
     153    }
     154    public function services(): array
     155    {
     156        static $services;
     157        if ($services === null) {
     158            $services = require_once __DIR__ . '/inc/services.php';
     159        }
     160        return $services();
     161    }
     162    /**
     163     * @inheritDoc
     164     */
     165    public function extensions(): array
     166    {
     167        static $extensions;
     168        if ($extensions === null) {
     169            $extensions = require_once __DIR__ . '/inc/extensions.php';
     170        }
     171        return $extensions();
    275172    }
    276173    /**
     
    292189            printf('<p style="border-bottom:solid 1px #eee;padding-bottom:13px;">%s</p>', wp_kses($meta, $allowedTags));
    293190        }, $screen, 'side', 'high');
    294     }
    295     /**
    296      * Disable Bank Transfer Gateway
    297      *
    298      * @param ?array $gateways
    299      * @return array
    300      */
    301     public function maybeDisableBankTransferGateway(?array $gateways): array
    302     {
    303         if (!is_array($gateways)) {
    304             return [];
    305         }
    306         $isWcApiRequest = (bool) filter_input(\INPUT_GET, 'wc-api', \FILTER_SANITIZE_SPECIAL_CHARS);
    307         $bankTransferSettings = get_option('mollie_wc_gateway_banktransfer_settings', \false);
    308         //If the setting is active is forced Payment API so we need to filter the gateway when order is in pay-page
    309         // as it might have been created with Orders API
    310         $isActiveExpiryDate = $bankTransferSettings && isset($bankTransferSettings['activate_expiry_days_setting']) && $bankTransferSettings['activate_expiry_days_setting'] === "yes" && isset($bankTransferSettings['order_dueDate']) && $bankTransferSettings['order_dueDate'] > 0;
    311         /*
    312          * There is only one case where we want to filter the gateway and it's when the
    313          * pay-page render the available payments methods AND the setting is enabled
    314          *
    315          * For any other case we want to be sure bank transfer gateway is included.
    316          */
    317         if ($isWcApiRequest || !$isActiveExpiryDate || is_checkout() && !is_wc_endpoint_url('order-pay') || !wp_doing_ajax() && !is_wc_endpoint_url('order-pay') || is_admin()) {
    318             return $gateways;
    319         }
    320         $bankTransferGatewayClassName = 'mollie_wc_gateway_banktransfer';
    321         unset($gateways[$bankTransferGatewayClassName]);
    322         return $gateways;
    323191    }
    324192    public function gatewaySurchargeHandling(\Mollie\WooCommerce\Gateway\Surcharge $surcharge)
     
    376244    }
    377245    /**
    378      * Bootstrap the ApplePay button logic if feature enabled
    379      */
    380     public function mollieApplePayDirectHandling(NoticeInterface $notice, Logger $logger, Api $apiHelper, Settings $settingsHelper, MollieSubscriptionGateway $appleGateway)
    381     {
    382         $buttonEnabledCart = mollieWooCommerceIsApplePayDirectEnabled('cart');
    383         $buttonEnabledProduct = mollieWooCommerceIsApplePayDirectEnabled('product');
    384         if ($buttonEnabledCart || $buttonEnabledProduct) {
    385             $notices = new AdminNotice();
    386             $responseTemplates = new ResponsesToApple($logger, $appleGateway);
    387             $ajaxRequests = new AppleAjaxRequests($responseTemplates, $notice, $logger, $apiHelper, $settingsHelper);
    388             $applePayHandler = new ApplePayDirectHandler($notices, $ajaxRequests);
    389             $applePayHandler->bootstrap($buttonEnabledProduct, $buttonEnabledCart);
    390         }
    391     }
    392     /**
    393      * Bootstrap the Mollie_WC_Gateway_PayPal button logic if feature enabled
    394      */
    395     public function molliePayPalButtonHandling($gateway, NoticeInterface $notice, Logger $logger, string $pluginUrl)
    396     {
    397         $enabledInProduct = mollieWooCommerceIsPayPalButtonEnabled('product');
    398         $enabledInCart = mollieWooCommerceIsPayPalButtonEnabled('cart');
    399         $shouldBuildIt = $enabledInProduct || $enabledInCart;
    400         if ($shouldBuildIt) {
    401             $ajaxRequests = new PayPalAjaxRequests($gateway, $notice, $logger);
    402             $data = new DataToPayPal($pluginUrl);
    403             $payPalHandler = new PayPalButtonHandler($ajaxRequests, $data);
    404             $payPalHandler->bootstrap($enabledInProduct, $enabledInCart);
    405         }
    406     }
    407     public function instantiatePaymentMethodGateways(ContainerInterface $container): array
    408     {
    409         $logger = $container->get(Logger::class);
    410         assert($logger instanceof Logger);
    411         $notice = $container->get(FrontendNotice::class);
    412         assert($notice instanceof FrontendNotice);
    413         $paymentService = $container->get(PaymentService::class);
    414         assert($paymentService instanceof PaymentService);
    415         $mollieOrderService = $container->get(MollieOrderService::class);
    416         assert($mollieOrderService instanceof MollieOrderService);
    417         $HttpResponseService = $container->get('SDK.HttpResponse');
    418         assert($HttpResponseService instanceof HttpResponse);
    419         $settingsHelper = $container->get('settings.settings_helper');
    420         assert($settingsHelper instanceof Settings);
    421         $apiHelper = $container->get('SDK.api_helper');
    422         assert($apiHelper instanceof Api);
    423         $paymentMethods = $container->get('gateway.paymentMethods');
    424         $data = $container->get('settings.data_helper');
    425         assert($data instanceof Data);
    426         $orderInstructionsService = new OrderInstructionsService();
    427         $mollieObject = $container->get(MollieObject::class);
    428         assert($mollieObject instanceof MollieObject);
    429         $paymentFactory = $container->get(PaymentFactory::class);
    430         assert($paymentFactory instanceof PaymentFactory);
    431         $pluginId = $container->get('shared.plugin_id');
    432         $gateways = [];
    433         if (empty($paymentMethods)) {
    434             return $gateways;
    435         }
    436         foreach ($paymentMethods as $paymentMethod) {
    437             $paymentMethodId = $paymentMethod->getIdFromConfig();
    438             if (!in_array($paymentMethodId, $container->get('gateway.paymentMethodsEnabledAtMollie'))) {
    439                 continue;
    440             }
    441             $isSepa = $paymentMethod->getProperty('SEPA');
    442             $key = 'mollie_wc_gateway_' . $paymentMethodId;
    443             if ($isSepa) {
    444                 $directDebit = $paymentMethods[Constants::DIRECTDEBIT];
    445                 $gateways[$key] = new MollieSepaRecurringGateway($directDebit, $paymentMethod, $paymentService, $orderInstructionsService, $mollieOrderService, $data, $logger, $notice, $HttpResponseService, $settingsHelper, $mollieObject, $paymentFactory, $pluginId, $apiHelper);
    446             } elseif ($paymentMethod->getProperty('Subscription')) {
    447                 $gateways[$key] = new MollieSubscriptionGateway($paymentMethod, $paymentService, $orderInstructionsService, $mollieOrderService, $data, $logger, $notice, $HttpResponseService, $settingsHelper, $mollieObject, $paymentFactory, $pluginId, $apiHelper);
    448             } else {
    449                 $gateways[$key] = new \Mollie\WooCommerce\Gateway\MolliePaymentGateway($paymentMethod, $paymentService, $orderInstructionsService, $mollieOrderService, $data, $logger, $notice, $HttpResponseService, $mollieObject, $paymentFactory, $pluginId);
    450             }
    451         }
    452         return $gateways;
    453     }
    454     /**
    455      * @param $container
     246     * @param ContainerInterface $container
     247     * @return void
     248     * @throws \Psr\Container\ContainerExceptionInterface
     249     * @throws \Psr\Container\NotFoundExceptionInterface
     250     */
     251    public function paymentButtonsBootstrap(ContainerInterface $container): void
     252    {
     253        $applePayDirectHandler = $container->get(ApplePayDirectHandler::class);
     254        if ($applePayDirectHandler instanceof ApplePayDirectHandler) {
     255            $buttonEnabledCart = mollieWooCommerceIsApplePayDirectEnabled('cart');
     256            $buttonEnabledProduct = mollieWooCommerceIsApplePayDirectEnabled('product');
     257            if ($buttonEnabledCart || $buttonEnabledProduct) {
     258                $applePayDirectHandler->bootstrap($buttonEnabledProduct, $buttonEnabledCart);
     259            }
     260        }
     261        $paypalButtonHandler = $container->get(PayPalButtonHandler::class);
     262        if ($paypalButtonHandler instanceof PayPalButtonHandler) {
     263            $enabledInProduct = mollieWooCommerceIsPayPalButtonEnabled('product');
     264            $enabledInCart = mollieWooCommerceIsPayPalButtonEnabled('cart');
     265            $shouldBuildIt = $enabledInProduct || $enabledInCart;
     266            if ($shouldBuildIt) {
     267                $paypalButtonHandler->bootstrap($enabledInProduct, $enabledInCart);
     268            }
     269        }
     270    }
     271    /**
     272     * This instantiates all payment methods that we have implemented
     273     * disregards if they are available at Mollie or not
     274     *
    456275     * @return array
    457276     */
    458     protected function instantiatePaymentMethods($container): array
     277    protected function instantiatePaymentMethods(): array
    459278    {
    460279        $paymentMethods = [];
    461         $listAllAvailablePaymentMethods = $container->get('gateway.getPaymentMethodsAfterFeatureFlag');
    462         $iconFactory = $container->get(IconFactory::class);
    463         assert($iconFactory instanceof IconFactory);
    464         $settingsHelper = $container->get('settings.settings_helper');
    465         assert($settingsHelper instanceof Settings);
    466         $surchargeService = $container->get(\Mollie\WooCommerce\Gateway\Surcharge::class);
    467         assert($surchargeService instanceof \Mollie\WooCommerce\Gateway\Surcharge);
    468         $paymentFieldsService = $container->get(PaymentFieldsService::class);
    469         assert($paymentFieldsService instanceof PaymentFieldsService);
    470         foreach ($listAllAvailablePaymentMethods as $paymentMethodAvailable) {
    471             $paymentMethodId = $paymentMethodAvailable['id'];
    472             $paymentMethods[$paymentMethodId] = $this->buildPaymentMethod($paymentMethodId, $iconFactory, $settingsHelper, $paymentFieldsService, $surchargeService, $paymentMethodAvailable);
     280        $allGatewayClassNames = SharedDataDictionary::GATEWAY_CLASSNAMES;
     281        foreach ($allGatewayClassNames as $gatewayClassName) {
     282            $parts = explode('_', $gatewayClassName);
     283            $methodId = strtolower(end($parts));
     284            $paymentMethods[$methodId] = $this->buildPaymentMethod($methodId);
    473285        }
    474286        //I need DirectDebit to create SEPA gateway
    475287        if (!in_array(Constants::DIRECTDEBIT, array_keys($paymentMethods), \true)) {
    476             $paymentMethodId = Constants::DIRECTDEBIT;
    477             $paymentMethods[$paymentMethodId] = $this->buildPaymentMethod($paymentMethodId, $iconFactory, $settingsHelper, $paymentFieldsService, $surchargeService, []);
     288            $methodId = Constants::DIRECTDEBIT;
     289            $paymentMethods[$methodId] = $this->buildPaymentMethod($methodId);
    478290        }
    479291        return $paymentMethods;
     292    }
     293    /**
     294     * @param string $id
     295     * @param IconFactory $iconFactory
     296     * @param Settings $settingsHelper
     297     * @param Surcharge $surchargeService
     298     * @param array $paymentMethods
     299     * @return PaymentMethodI | array
     300     */
     301    public function buildPaymentMethod(string $id)
     302    {
     303        $transformedId = ucfirst($id);
     304        $paymentMethodClassName = 'Mollie\WooCommerce\PaymentMethods\\' . $transformedId;
     305        return new $paymentMethodClassName();
    480306    }
    481307    public function in3FieldsMandatory($fields, $errors)
     
    503329    }
    504330    /**
    505      * @param string $id
    506      * @param IconFactory $iconFactory
    507      * @param Settings $settingsHelper
    508      * @param PaymentFieldsService $paymentFieldsService
    509      * @param Surcharge $surchargeService
    510      * @param array $paymentMethods
    511      * @return PaymentMethodI | array
    512      */
    513     public function buildPaymentMethod(string $id, IconFactory $iconFactory, Settings $settingsHelper, PaymentFieldsService $paymentFieldsService, \Mollie\WooCommerce\Gateway\Surcharge $surchargeService, array $apiMethod)
    514     {
    515         $transformedId = ucfirst($id);
    516         $paymentMethodClassName = 'Mollie\WooCommerce\PaymentMethods\\' . $transformedId;
    517         $paymentMethod = new $paymentMethodClassName($iconFactory, $settingsHelper, $paymentFieldsService, $surchargeService, $apiMethod);
    518         return $paymentMethod;
     331     * Some payment methods require mandatory fields, this function will add them to the checkout fields array
     332     * @param $fields
     333     * @param string $gatewayName
     334     * @param string $field
     335     * @param $errors
     336     * @return mixed
     337     */
     338    public function addPaymentMethodMandatoryFields($fields, string $gatewayName, string $field, string $fieldLabel, $errors)
     339    {
     340        if ($fields['payment_method'] !== $gatewayName) {
     341            return $fields;
     342        }
     343        if (!isset($fields[$field])) {
     344            $fieldPosted = filter_input(\INPUT_POST, $field, \FILTER_SANITIZE_SPECIAL_CHARS) ?? \false;
     345            if ($fieldPosted) {
     346                $fields[$field] = $fieldPosted;
     347            } else {
     348                $errors->add('validation', sprintf(
     349                    /* translators: Placeholder 1: field name. */
     350                    __('%s is a required field.', 'woocommerce'),
     351                    "<strong>{$fieldLabel}</strong>"
     352                ));
     353            }
     354        }
     355        return $fields;
    519356    }
    520357    public function addPaymentMethodMandatoryFieldsPhoneVerification($fields, string $gatewayName, string $field, string $fieldLabel, $errors)
  • mollie-payments-for-woocommerce/trunk/src/Gateway/OrderMandatoryGatewayDisabler.php

    r3164004 r3262577  
    44namespace Mollie\WooCommerce\Gateway;
    55
     6use Mollie\Inpsyde\PaymentGateway\PaymentGateway;
    67class OrderMandatoryGatewayDisabler
    78{
     
    1011     */
    1112    protected $isSettingsOrderApi;
     13    private array $paymentMethods;
    1214    /**
    1315     * OrderMandatoryGatewayDisabler constructor.
    1416     */
    15     public function __construct(bool $isSettingsOrderApi)
     17    public function __construct(bool $isSettingsOrderApi, array $paymentMethods)
    1618    {
    1719        $this->isSettingsOrderApi = $isSettingsOrderApi;
     20        $this->paymentMethods = $paymentMethods;
    1821    }
    1922    /**
     
    3639            return $gateways;
    3740        }
    38         return array_filter($gateways, static function ($gateway) {
    39             return !$gateway instanceof \Mollie\WooCommerce\Gateway\MolliePaymentGateway || !$gateway->paymentMethod()->getProperty('orderMandatory');
     41        $paymentMethods = $this->paymentMethods;
     42        return array_filter($gateways, static function ($gateway) use ($paymentMethods) {
     43            if (!mollieWooCommerceIsMollieGateway($gateway)) {
     44                return \true;
     45            }
     46            $gatewayId = $gateway->id;
     47            $methodId = substr($gatewayId, strrpos($gatewayId, '_') + 1);
     48            $method = $paymentMethods[$methodId] ?? null;
     49            return !$method->getProperty('orderMandatory');
    4050        });
    4151    }
  • mollie-payments-for-woocommerce/trunk/src/Gateway/Voucher/MaybeDisableGateway.php

    r3164004 r3262577  
    44namespace Mollie\WooCommerce\Gateway\Voucher;
    55
    6 use Mollie\WooCommerce\Gateway\MolliePaymentGateway;
    7 use Mollie\WooCommerce\Payment\PaymentService;
     6use Mollie\Inpsyde\PaymentGateway\PaymentGateway;
     7use Mollie\WooCommerce\Gateway\MolliePaymentGatewayHandler;
     8use Mollie\WooCommerce\Payment\PaymentProcessor;
    89use Mollie\WooCommerce\PaymentMethods\Voucher;
    910class MaybeDisableGateway
    1011{
     12    /**
     13     * Disable Bank Transfer Gateway
     14     *
     15     * @param ?array $gateways
     16     * @return array
     17     */
     18    public function maybeDisableBankTransferGateway(?array $gateways): array
     19    {
     20        if (!is_array($gateways)) {
     21            return [];
     22        }
     23        $isWcApiRequest = (bool) filter_input(\INPUT_GET, 'wc-api', \FILTER_SANITIZE_SPECIAL_CHARS);
     24        $bankTransferSettings = get_option('mollie_wc_gateway_banktransfer_settings', \false);
     25        //If the setting is active is forced Payment API so we need to filter the gateway when order is in pay-page
     26        // as it might have been created with Orders API
     27        $isActiveExpiryDate = $bankTransferSettings && isset($bankTransferSettings['activate_expiry_days_setting']) && $bankTransferSettings['activate_expiry_days_setting'] === "yes" && isset($bankTransferSettings['order_dueDate']) && $bankTransferSettings['order_dueDate'] > 0;
     28        /*
     29         * There is only one case where we want to filter the gateway and it's when the
     30         * pay-page render the available payments methods AND the setting is enabled
     31         *
     32         * For any other case we want to be sure bank transfer gateway is included.
     33         */
     34        if ($isWcApiRequest || !$isActiveExpiryDate || is_checkout() && !is_wc_endpoint_url('order-pay') || !wp_doing_ajax() && !is_wc_endpoint_url('order-pay') || is_admin()) {
     35            return $gateways;
     36        }
     37        $bankTransferGatewayClassName = 'mollie_wc_gateway_banktransfer';
     38        unset($gateways[$bankTransferGatewayClassName]);
     39        return $gateways;
     40    }
    1141    /**
    1242     * Disable Voucher Gateway if no categories associated with any product
     
    2454        }
    2555        $isWcApiRequest = (bool) filter_input(\INPUT_GET, 'wc-api', \FILTER_SANITIZE_SPECIAL_CHARS);
     56        $isCheckoutPage = is_checkout();
     57        $isOrderPayPage = is_wc_endpoint_url('order-pay');
    2658        // To exclude we are in Checkout or Order Pay page. These are the other options where gateways are required.
    27         $notInCheckoutOrPayPage = $isWcApiRequest || !doing_action('woocommerce_payment_gateways') || !wp_doing_ajax() && !is_wc_endpoint_url('order-pay');
     59        $notInCheckoutOrPayPage = $isWcApiRequest || !doing_action('woocommerce_payment_gateways') || !wp_doing_ajax() && !$isOrderPayPage && !$isCheckoutPage;
    2860        $notHasBlocks = !has_block('woocommerce/checkout');
    2961        /*
     
    3971        $mealVoucherGatewayIndex = \false;
    4072        foreach ($gateways as $key => $gateway) {
    41             if (!$gateway instanceof MolliePaymentGateway) {
     73            if (!mollieWooCommerceIsMollieGateway($gateway)) {
    4274                continue;
    4375            }
     
    4779        }
    4880        $productsWithCategory = $this->numberProductsWithCategory();
    49         $paymentAPISetting = get_option('mollie-payments-for-woocommerce_api_switch') === PaymentService::PAYMENT_METHOD_TYPE_PAYMENT;
     81        $paymentAPISetting = get_option('mollie-payments-for-woocommerce_api_switch') === PaymentProcessor::PAYMENT_METHOD_TYPE_PAYMENT;
    5082        if ($mealVoucherGatewayIndex !== \false && ($productsWithCategory === 0 || $paymentAPISetting)) {
    5183            unset($gateways[$mealVoucherGatewayIndex]);
  • mollie-payments-for-woocommerce/trunk/src/Gateway/Voucher/VoucherModule.php

    r3164004 r3262577  
    5050    public function run(ContainerInterface $container): bool
    5151    {
    52         $gatewayInstances = $container->get('gateway.instances');
     52        $gatewayInstances = $container->get('__deprecated.gateway_helpers');
    5353        $voucherGateway = $gatewayInstances['mollie_wc_gateway_voucher'] ?? \false;
    5454        $voucher = $voucherGateway && $voucherGateway->enabled === 'yes';
  • mollie-payments-for-woocommerce/trunk/src/Payment/MollieObject.php

    r3226701 r3262577  
    77use Mollie\Api\Resources\Order;
    88use Mollie\Api\Resources\Payment;
    9 use Mollie\WooCommerce\Gateway\MolliePaymentGateway;
     9use Mollie\WooCommerce\Payment\Request\RequestFactory;
    1010use Mollie\WooCommerce\PaymentMethods\Voucher;
    1111use Mollie\WooCommerce\SDK\Api;
    1212use Mollie\WooCommerce\Settings\Settings;
     13use Mollie\WooCommerce\Shared\SharedDataDictionary;
    1314use WC_Order;
    1415use WC_Payment_Gateway;
    1516use Mollie\Psr\Log\LoggerInterface as Logger;
    16 use stdClass;
    1717class MollieObject
    1818{
    19     public const MAXIMAL_LENGTH_ADDRESS = 100;
    20     public const MAXIMAL_LENGTH_POSTALCODE = 20;
    21     public const MAXIMAL_LENGTH_CITY = 200;
    22     public const MAXIMAL_LENGTH_REGION = 200;
    2319    protected $data;
    2420    /**
     
    3430     * @var Logger
    3531     */
    36     protected $logger;
     32    protected Logger $logger;
    3733    /**
    3834     * @var PaymentFactory
    3935     */
    40     protected $paymentFactory;
     36    protected \Mollie\WooCommerce\Payment\PaymentFactory $paymentFactory;
    4137    protected $dataService;
    4238    protected $apiHelper;
    43     protected $settingsHelper;
     39    protected Settings $settingsHelper;
    4440    protected $dataHelper;
    4541    /**
     
    4743     */
    4844    protected $pluginId;
    49     public function __construct($data, Logger $logger, \Mollie\WooCommerce\Payment\PaymentFactory $paymentFactory, Api $apiHelper, Settings $settingsHelper, string $pluginId)
     45    /**
     46     * @var null
     47     */
     48    private $paymentMethod;
     49    protected RequestFactory $requestFactory;
     50    public function __construct($data, Logger $logger, \Mollie\WooCommerce\Payment\PaymentFactory $paymentFactory, Api $apiHelper, Settings $settingsHelper, string $pluginId, RequestFactory $requestFactory)
    5051    {
    5152        $this->data = $data;
     
    5758        $base_location = wc_get_base_location();
    5859        static::$shop_country = $base_location['country'];
     60        $this->paymentMethod = null;
     61        $this->requestFactory = $requestFactory;
    5962    }
    6063    public function data()
     
    131134    protected function getPaymentRequestData($order, $customerId, $voucherDefaultCategory = Voucher::NO_CATEGORY)
    132135    {
     136    }
     137    /**
     138     * @param \WC_Order $order
     139     * @param string $new_status
     140     * @param string $note
     141     * @param bool $restore_stock
     142     */
     143    public function updateOrderStatus(\WC_Order $order, $new_status, $note = '', $restore_stock = \true)
     144    {
     145        $order->update_status($new_status, $note);
     146        switch ($new_status) {
     147            case SharedDataDictionary::STATUS_ON_HOLD:
     148                if ($restore_stock === \true) {
     149                    if (!$order->get_meta('_order_stock_reduced', \true)) {
     150                        // Reduce order stock
     151                        wc_reduce_stock_levels($order->get_id());
     152                        $this->logger->debug(__METHOD__ . ":  Stock for order {$order->get_id()} reduced.");
     153                    }
     154                }
     155                break;
     156            case SharedDataDictionary::STATUS_PENDING:
     157            case SharedDataDictionary::STATUS_FAILED:
     158            case SharedDataDictionary::STATUS_CANCELLED:
     159                if ($order->get_meta('_order_stock_reduced', \true)) {
     160                    // Restore order stock
     161                    $this->dataHelper->restoreOrderStock($order);
     162                    $this->logger->debug(__METHOD__ . " Stock for order {$order->get_id()} restored.");
     163                }
     164                break;
     165        }
    133166    }
    134167    /**
     
    497530        }
    498531    }
    499     protected function addSequenceTypeForSubscriptionsFirstPayments($orderId, $gateway, $paymentRequestData): array
    500     {
    501         if ($this->dataHelper->isSubscription($orderId) || $this->dataHelper->isWcSubscription($orderId)) {
    502             $disable_automatic_payments = apply_filters($this->pluginId . '_is_automatic_payment_disabled', \false);
    503             $supports_subscriptions = $gateway->supports('subscriptions');
    504             if ($supports_subscriptions == \true && $disable_automatic_payments == \false) {
    505                 $paymentRequestData = $this->addSequenceTypeFirst($paymentRequestData);
    506             }
    507         }
    508         return $paymentRequestData;
    509     }
    510     public function addSequenceTypeFirst($paymentRequestData)
    511     {
    512     }
    513532    /**
    514533     * @param $order
     
    540559    {
    541560        if (function_exists('wcs_order_contains_renewal') && wcs_order_contains_renewal($orderId)) {
    542             if ($gateway instanceof MolliePaymentGateway) {
    543                 $gateway->paymentService()->updateOrderStatus($order, $newOrderStatus, sprintf(
     561            if (mollieWooCommerceIsMollieGateway($gateway->id)) {
     562                $this->updateOrderStatus($order, $newOrderStatus, sprintf(
    544563                    /* translators: Placeholder 1: payment method title, placeholder 2: payment ID */
    545564                    __('%1$s renewal payment failed via Mollie (%2$s). You will need to manually review the payment and adjust product stocks if you use them.', 'mollie-payments-for-woocommerce'),
     
    554573                $emails['WC_Email_Failed_Order']->trigger($orderId);
    555574            }
    556         } elseif ($gateway instanceof MolliePaymentGateway) {
    557             $gateway->paymentService()->updateOrderStatus($order, $newOrderStatus, sprintf(
     575        } elseif (mollieWooCommerceIsMollieGateway($gateway->id)) {
     576            $this->updateOrderStatus($order, $newOrderStatus, sprintf(
    558577                /* translators: Placeholder 1: payment method title, placeholder 2: payment ID */
    559578                __('%1$s payment failed via Mollie (%2$s).', 'mollie-payments-for-woocommerce'),
     
    594613        }
    595614    }
    596     /**
    597      * Get the url to return to on Mollie return
    598      * saves the return redirect and failed redirect, so we save the page language in case there is one set
    599      * For example 'http://mollie-wc.docker.myhost/wc-api/mollie_return/?order_id=89&key=wc_order_eFZyH8jki6fge'
    600      *
    601      * @param WC_Order $order The order processed
    602      *
    603      * @return string The url with order id and key as params
    604      */
    605     public function getReturnUrl($order, $returnUrl)
    606     {
    607         $returnUrl = untrailingslashit($returnUrl);
    608         $returnUrl = $this->asciiDomainName($returnUrl);
    609         $orderId = $order->get_id();
    610         $orderKey = $order->get_order_key();
    611         $onMollieReturn = 'onMollieReturn';
    612         $returnUrl = $this->appendOrderArgumentsToUrl($orderId, $orderKey, $returnUrl, $onMollieReturn);
    613         $returnUrl = untrailingslashit($returnUrl);
    614         $this->logger->debug(" Order {$orderId} returnUrl: {$returnUrl}", [\true]);
    615         return apply_filters($this->pluginId . '_return_url', $returnUrl, $order);
    616     }
    617     /**
    618      * Get the webhook url
    619      * For example 'http://mollie-wc.docker.myhost/wc-api/mollie_return/mollie_wc_gateway_bancontact/?order_id=89&key=wc_order_eFZyH8jki6fge'
    620      *
    621      * @param WC_Order $order The order processed
    622      *
    623      * @return string The url with gateway and order id and key as params
    624      */
    625     public function getWebhookUrl($order, $gatewayId)
    626     {
    627         $webhookUrl = WC()->api_request_url($gatewayId);
    628         $webhookUrl = untrailingslashit($webhookUrl);
    629         $webhookUrl = $this->asciiDomainName($webhookUrl);
    630         $orderId = $order->get_id();
    631         $orderKey = $order->get_order_key();
    632         $webhookUrl = $this->appendOrderArgumentsToUrl($orderId, $orderKey, $webhookUrl);
    633         $webhookUrl = untrailingslashit($webhookUrl);
    634         $this->logger->debug(" Order {$orderId} webhookUrl: {$webhookUrl}", [\true]);
    635         return apply_filters($this->pluginId . '_webhook_url', $webhookUrl, $order);
    636     }
    637     /**
    638      * @param $url
    639      *
    640      * @return string
    641      */
    642     protected function asciiDomainName($url): string
    643     {
    644         $parsed = wp_parse_url($url);
    645         $scheme = isset($parsed['scheme']) ? $parsed['scheme'] : '';
    646         $domain = isset($parsed['host']) ? $parsed['host'] : \false;
    647         $query = isset($parsed['query']) ? $parsed['query'] : '';
    648         $path = isset($parsed['path']) ? $parsed['path'] : '';
    649         if (!$domain) {
    650             return $url;
    651         }
    652         if (function_exists('idn_to_ascii')) {
    653             $domain = $this->idnEncodeDomain($domain);
    654             $url = $scheme . "://" . $domain . $path . '?' . $query;
    655         }
    656         return $url;
    657     }
    658     /**
    659      * @param $order_id
    660      * @param $order_key
    661      * @param $webhook_url
    662      * @param string $filterFlag
    663      *
    664      * @return string
    665      */
    666     protected function appendOrderArgumentsToUrl($order_id, $order_key, $webhook_url, $filterFlag = '')
    667     {
    668         $webhook_url = add_query_arg(['order_id' => $order_id, 'key' => $order_key, 'filter_flag' => $filterFlag], $webhook_url);
    669         return $webhook_url;
    670     }
    671     /**
    672      * @param $domain
    673      * @return false|mixed|string
    674      */
    675     protected function idnEncodeDomain($domain)
    676     {
    677         if (defined('IDNA_NONTRANSITIONAL_TO_ASCII') && defined('INTL_IDNA_VARIANT_UTS46')) {
    678             $domain = idn_to_ascii($domain, \IDNA_NONTRANSITIONAL_TO_ASCII, \INTL_IDNA_VARIANT_UTS46) ? idn_to_ascii($domain, \IDNA_NONTRANSITIONAL_TO_ASCII, \INTL_IDNA_VARIANT_UTS46) : $domain;
    679         } else {
    680             $domain = idn_to_ascii($domain) ? idn_to_ascii($domain) : $domain;
    681         }
    682         return $domain;
    683     }
    684     protected function getPaymentDescription($order, $option)
    685     {
    686         $description = !$option ? '' : trim($option);
    687         $description = !$description ? '{orderNumber}' : $description;
    688         switch ($description) {
    689             // Support for old deprecated options.
    690             // TODO: remove when deprecated
    691             case '{orderNumber}':
    692                 $description = _x('Order {orderNumber}', 'Payment description for {orderNumber}', 'mollie-payments-for-woocommerce');
    693                 $description = $this->replaceTagsDescription($order, $description);
    694                 break;
    695             case '{storeName}':
    696                 $description = _x('StoreName {storeName}', 'Payment description for {storeName}', 'mollie-payments-for-woocommerce');
    697                 $description = $this->replaceTagsDescription($order, $description);
    698                 break;
    699             case '{customer.firstname}':
    700                 $description = _x('Customer Firstname {customer.firstname}', 'Payment description for {customer.firstname}', 'mollie-payments-for-woocommerce');
    701                 $description = $this->replaceTagsDescription($order, $description);
    702                 break;
    703             case '{customer.lastname}':
    704                 $description = _x('Customer Lastname {customer.lastname}', 'Payment description for {customer.lastname}', 'mollie-payments-for-woocommerce');
    705                 $description = $this->replaceTagsDescription($order, $description);
    706                 break;
    707             case '{customer.company}':
    708                 $description = _x('Customer Company {customer.company}', 'Payment description for {customer.company}', 'mollie-payments-for-woocommerce');
    709                 $description = $this->replaceTagsDescription($order, $description);
    710                 break;
    711             // Support for custom string with interpolation.
    712             default:
    713                 // Replace available description tags.
    714                 $description = $this->replaceTagsDescription($order, $description);
    715                 break;
    716         }
    717         // Fall back on default if description turns out empty.
    718         return !$description ? __('Order', 'woocommerce') . ' ' . $order->get_order_number() : $description;
    719     }
    720     /**
    721      * @param $order
    722      * @param $description
    723      * @return array|string|string[]
    724      */
    725     protected function replaceTagsDescription($order, $description)
    726     {
    727         $replacement_tags = ['{orderNumber}' => $order->get_order_number(), '{storeName}' => get_bloginfo('name'), '{customer.firstname}' => $order->get_billing_first_name(), '{customer.lastname}' => $order->get_billing_last_name(), '{customer.company}' => $order->get_billing_company()];
    728         foreach ($replacement_tags as $tag => $replacement) {
    729             $description = str_replace($tag, $replacement, $description);
    730         }
    731         return $description;
    732     }
    733     /**
    734      * @param $order
    735      * @return stdClass
    736      */
    737     protected function createBillingAddress($order)
    738     {
    739         // Setup billing and shipping objects
    740         $billingAddress = new stdClass();
    741         // Get user details
    742         $billingAddress->givenName = ctype_space($order->get_billing_first_name()) ? null : $order->get_billing_first_name();
    743         $billingAddress->familyName = ctype_space($order->get_billing_last_name()) ? null : $order->get_billing_last_name();
    744         $billingAddress->email = ctype_space($order->get_billing_email()) ? null : $order->get_billing_email();
    745         // Create billingAddress object
    746         $billingAddress->streetAndNumber = ctype_space($order->get_billing_address_1()) ? null : $this->maximalFieldLengths($order->get_billing_address_1(), self::MAXIMAL_LENGTH_ADDRESS);
    747         $billingAddress->streetAdditional = ctype_space($order->get_billing_address_2()) ? null : $this->maximalFieldLengths($order->get_billing_address_2(), self::MAXIMAL_LENGTH_ADDRESS);
    748         $billingAddress->postalCode = ctype_space($order->get_billing_postcode()) ? null : $this->maximalFieldLengths($order->get_billing_postcode(), self::MAXIMAL_LENGTH_POSTALCODE);
    749         $billingAddress->city = ctype_space($order->get_billing_city()) ? null : $this->maximalFieldLengths($order->get_billing_city(), self::MAXIMAL_LENGTH_CITY);
    750         $billingAddress->region = ctype_space($order->get_billing_state()) ? null : $this->maximalFieldLengths($order->get_billing_state(), self::MAXIMAL_LENGTH_REGION);
    751         $billingAddress->country = ctype_space($order->get_billing_country()) ? null : $this->maximalFieldLengths($order->get_billing_country(), self::MAXIMAL_LENGTH_REGION);
    752         $billingAddress->organizationName = $this->billingCompanyField($order);
    753         $phone = $this->getPhoneNumber($order);
    754         $billingAddress->phone = ctype_space($phone) ? null : $this->getFormattedPhoneNumber($phone);
    755         return $billingAddress;
    756     }
    757     protected function getPhoneNumber($order)
    758     {
    759         $phone = !empty($order->get_billing_phone()) ? $order->get_billing_phone() : $order->get_shipping_phone();
    760         if (empty($phone)) {
    761             //phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
    762             $phone = wc_clean(wp_unslash($_POST['billing_phone'] ?? ''));
    763         }
    764         return $phone;
    765     }
    766     protected function getFormattedPhoneNumber(string $phone)
    767     {
    768         //remove whitespaces and all non numerical characters except +
    769         $phone = preg_replace('/[^0-9+]+/', '', $phone);
    770         if (!is_string($phone)) {
    771             return null;
    772         }
    773         //check if phone starts with 06 and replace with +316
    774         $phone = transformPhoneToNLFormat($phone);
    775         //check that $phone is in E164 format or can be changed by api
    776         if (is_string($phone) && preg_match('/^\+[1-9]\d{10,13}$|^[1-9]\d{9,13}$/', $phone)) {
    777             return $phone;
    778         }
    779         return null;
    780     }
    781     /**
    782      * @param $order
    783      * @return string|null
    784      */
    785     public function billingCompanyField($order): ?string
    786     {
    787         if (!trim($order->get_billing_company())) {
    788             return $this->checkBillieCompanyField($order);
    789         }
    790         return $this->maximalFieldLengths($order->get_billing_company(), self::MAXIMAL_LENGTH_ADDRESS);
    791     }
    792     private function checkBillieCompanyField($order)
    793     {
    794         $gateway = wc_get_payment_gateway_by_order($order);
    795         if (!$gateway || !$gateway->id) {
    796             return null;
    797         }
    798         $isBillieMethodId = $gateway->id === 'mollie_wc_gateway_billie';
    799         if ($isBillieMethodId) {
    800             //phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
    801             $fieldPosted = wc_clean(wp_unslash($_POST["billing_company_billie"] ?? ''));
    802             $company = ($fieldPosted ?: $order->get_billing_company()) ?: $order->get_shipping_company();
    803             return $company ? $this->maximalFieldLengths($company, self::MAXIMAL_LENGTH_ADDRESS) : null;
    804         }
    805         return null;
    806     }
    807     /**
    808      * @param $order
    809      * @return stdClass
    810      */
    811     protected function createShippingAddress($order)
    812     {
    813         $shippingAddress = new stdClass();
    814         // Get user details
    815         $shippingAddress->givenName = ctype_space($order->get_shipping_first_name()) ? null : $order->get_shipping_first_name();
    816         $shippingAddress->familyName = ctype_space($order->get_shipping_last_name()) ? null : $order->get_shipping_last_name();
    817         $shippingAddress->email = ctype_space($order->get_billing_email()) ? null : $order->get_billing_email();
    818         // WooCommerce doesn't have a shipping email
    819         // Create shippingAddress object
    820         $shippingAddress->streetAndNumber = ctype_space($order->get_shipping_address_1()) ? null : $this->maximalFieldLengths($order->get_shipping_address_1(), self::MAXIMAL_LENGTH_ADDRESS);
    821         $shippingAddress->streetAdditional = ctype_space($order->get_shipping_address_2()) ? null : $this->maximalFieldLengths($order->get_shipping_address_2(), self::MAXIMAL_LENGTH_ADDRESS);
    822         $shippingAddress->postalCode = ctype_space($order->get_shipping_postcode()) ? null : $this->maximalFieldLengths($order->get_shipping_postcode(), self::MAXIMAL_LENGTH_POSTALCODE);
    823         $shippingAddress->city = ctype_space($order->get_shipping_city()) ? null : $this->maximalFieldLengths($order->get_shipping_city(), self::MAXIMAL_LENGTH_CITY);
    824         $shippingAddress->region = ctype_space($order->get_shipping_state()) ? null : $this->maximalFieldLengths($order->get_shipping_state(), self::MAXIMAL_LENGTH_REGION);
    825         $shippingAddress->country = ctype_space($order->get_shipping_country()) ? null : $this->maximalFieldLengths($order->get_shipping_country(), self::MAXIMAL_LENGTH_REGION);
    826         return $shippingAddress;
    827     }
    828     /**
    829      * Method that shortens the field to a certain length
    830      *
    831      * @param string $field
    832      * @param int    $maximalLength
    833      *
    834      * @return null|string
    835      */
    836     protected function maximalFieldLengths($field, $maximalLength)
    837     {
    838         if (!is_string($field)) {
    839             return null;
    840         }
    841         if (is_int($maximalLength) && strlen($field) > $maximalLength) {
    842             $field = substr($field, 0, $maximalLength);
    843             $field = !$field ? null : $field;
    844         }
    845         return $field;
    846     }
    847615}
  • mollie-payments-for-woocommerce/trunk/src/Payment/MollieOrder.php

    r3226701 r3262577  
    55
    66use Exception;
     7use Mollie\Inpsyde\PaymentGateway\PaymentGateway;
    78use Mollie\Api\Exceptions\ApiException;
    89use Mollie\Api\Resources\Payment;
    910use Mollie\Api\Resources\Order;
    1011use Mollie\Api\Resources\Refund;
    11 use Mollie\WooCommerce\Gateway\MolliePaymentGateway;
     12use Mollie\WooCommerce\Gateway\Refund\OrderItemsRefunder;
     13use Mollie\WooCommerce\Gateway\Refund\PartialRefundException;
     14use Mollie\WooCommerce\Payment\Request\RequestFactory;
    1215use Mollie\WooCommerce\PaymentMethods\Voucher;
    1316use Mollie\WooCommerce\SDK\Api;
     17use Mollie\WooCommerce\Settings\Settings;
     18use Mollie\WooCommerce\Shared\Data;
    1419use Mollie\WooCommerce\Shared\SharedDataDictionary;
     20use Mollie\Psr\Log\LoggerInterface as Logger;
    1521use Mollie\Psr\Log\LogLevel;
    1622use WC_Order;
     
    2632    protected static $shop_country;
    2733    /**
    28      * @var OrderLines
    29      */
    30     protected $orderLines;
    31     /**
    3234     * @var OrderItemsRefunder
    3335     */
     
    3941     * @param $data
    4042     */
    41     public function __construct(\Mollie\WooCommerce\Payment\OrderItemsRefunder $orderItemsRefunder, $data, $pluginId, Api $apiHelper, $settingsHelper, $dataHelper, $logger, \Mollie\WooCommerce\Payment\OrderLines $orderLines)
     43    public function __construct(OrderItemsRefunder $orderItemsRefunder, $data, string $pluginId, Api $apiHelper, Settings $settingsHelper, Data $dataHelper, Logger $logger, RequestFactory $requestFactory)
    4244    {
    4345        $this->data = $data;
     
    4648        $this->apiHelper = $apiHelper;
    4749        $this->settingsHelper = $settingsHelper;
     50        $this->logger = $logger;
     51        $this->requestFactory = $requestFactory;
    4852        $this->dataHelper = $dataHelper;
    49         $this->logger = $logger;
    50         $this->orderLines = $orderLines;
    5153    }
    5254    public function getPaymentObject($paymentId, $testMode = \false, $useCache = \true)
     
    7072    public function getPaymentRequestData($order, $customerId, $voucherDefaultCategory = Voucher::NO_CATEGORY)
    7173    {
    72         $settingsHelper = $this->settingsHelper;
    73         $paymentLocale = $settingsHelper->getPaymentLocale();
    74         $storeCustomer = $settingsHelper->shouldStoreCustomer();
    75         $gateway = wc_get_payment_gateway_by_order($order);
    76         if (!$gateway || !$gateway instanceof MolliePaymentGateway) {
    77             return ['result' => 'failure'];
    78         }
    79         $gatewayId = $gateway->id;
    80         $selectedIssuer = $gateway->getSelectedIssuer();
    81         $returnUrl = $gateway->get_return_url($order);
    82         $returnUrl = $this->getReturnUrl($order, $returnUrl);
    83         $webhookUrl = $this->getWebhookUrl($order, $gatewayId);
    84         $isPayPalExpressOrder = $order->get_meta('_mollie_payment_method_button') === 'PayPalButton';
    85         $billingAddress = null;
    86         if (!$isPayPalExpressOrder) {
    87             $billingAddress = $this->createBillingAddress($order);
    88             $shippingAddress = $this->createShippingAddress($order);
    89         }
    90         // Generate order lines for Mollie Orders
    91         $orderLinesHelper = $this->orderLines;
    92         $orderLines = $orderLinesHelper->order_lines($order, $voucherDefaultCategory);
    93         // Build the Mollie order data
    94         $paymentRequestData = ['amount' => ['currency' => $this->dataHelper->getOrderCurrency($order), 'value' => $this->dataHelper->formatCurrencyValue($order->get_total(), $this->dataHelper->getOrderCurrency($order))], 'redirectUrl' => $returnUrl, 'webhookUrl' => $webhookUrl, 'method' => $gateway->paymentMethod()->getProperty('id'), 'payment' => ['issuer' => $selectedIssuer], 'locale' => $paymentLocale, 'billingAddress' => $billingAddress, 'metadata' => apply_filters($this->pluginId . '_payment_object_metadata', ['order_id' => $order->get_id(), 'order_number' => $order->get_order_number()]), 'lines' => $orderLines['lines'], 'orderNumber' => $order->get_order_number()];
    95         $paymentRequestData = $this->addSequenceTypeForSubscriptionsFirstPayments($order->get_id(), $gateway, $paymentRequestData);
    96         // Only add shippingAddress if all required fields are set
    97         if (!empty($shippingAddress->streetAndNumber) && !empty($shippingAddress->postalCode) && !empty($shippingAddress->city) && !empty($shippingAddress->country)) {
    98             $paymentRequestData['shippingAddress'] = $shippingAddress;
    99         }
    100         // Only store customer at Mollie if setting is enabled
    101         if ($storeCustomer) {
    102             $paymentRequestData['payment']['customerId'] = $customerId;
    103         }
    104         $cardToken = mollieWooCommerceCardToken();
    105         if ($cardToken && isset($paymentRequestData['payment'])) {
    106             $paymentRequestData['payment']['cardToken'] = $cardToken;
    107         }
    108         //phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
    109         $applePayToken = wc_clean(wp_unslash($_POST["token"] ?? ''));
    110         if ($applePayToken && isset($paymentRequestData['payment'])) {
    111             $encodedApplePayToken = wp_json_encode($applePayToken);
    112             $paymentRequestData['payment']['applePayPaymentToken'] = $encodedApplePayToken;
    113         }
    114         $customerBirthdate = $this->getCustomerBirthdate($order);
    115         if ($customerBirthdate) {
    116             $paymentRequestData['consumerDateOfBirth'] = $customerBirthdate;
    117         }
    118         return $paymentRequestData;
     74        return $this->requestFactory->createRequest('order', $order, $customerId);
    11975    }
    12076    public function setActiveMolliePayment($orderId)
     
    162118        $ibanDetails = [];
    163119        if (isset($payment->_embedded->payments[0]->id)) {
    164             $actualPayment = new \Mollie\WooCommerce\Payment\MolliePayment($payment->_embedded->payments[0]->id, $this->pluginId, $this->apiHelper, $this->settingsHelper, $this->dataHelper, $this->logger);
     120            $actualPayment = new \Mollie\WooCommerce\Payment\MolliePayment($payment->_embedded->payments[0]->id, $this->pluginId, $this->apiHelper, $this->settingsHelper, $this->dataHelper, $this->logger, $this->requestFactory);
    165121            $actualPayment = $actualPayment->getPaymentObject($actualPayment->data);
    166122            /**
     
    171127        }
    172128        return $ibanDetails;
    173     }
    174     public function addSequenceTypeFirst($paymentRequestData)
    175     {
    176         $paymentRequestData['payment']['sequenceType'] = 'first';
    177         return $paymentRequestData;
    178129    }
    179130    /**
     
    462413            try {
    463414                return $this->orderItemsRefunder->refund($order, $items, $paymentObject, $reason);
    464             } catch (\Mollie\WooCommerce\Payment\PartialRefundException $exception) {
     415            } catch (PartialRefundException $exception) {
    465416                $this->logger->debug(__METHOD__ . ' - ' . $exception->getMessage());
    466417                return $this->refund_amount($order, $amount, $paymentObject, $reason);
     
    596547    {
    597548        $gateway = wc_get_payment_gateway_by_order($order);
    598         if (!$this->isOrderPaymentStartedByOtherGateway($order) && is_a($gateway, MolliePaymentGateway::class)) {
    599             $gateway->paymentService()->updateOrderStatus($order, $newOrderStatus);
     549        if (!$this->isOrderPaymentStartedByOtherGateway($order) && is_a($gateway, PaymentGateway::class)) {
     550            $this->updateOrderStatus($order, $newOrderStatus);
    600551        } else {
    601552            $this->informNotUpdatingStatus($gateway->id, $order);
     
    669620        unset($items[$item->get_id()]);
    670621    }
    671     protected function getCustomerBirthdate($order)
    672     {
    673         $gateway = wc_get_payment_gateway_by_order($order);
    674         if (!$gateway || !isset($gateway->id)) {
    675             return null;
    676         }
    677         if (strpos($gateway->id, 'mollie_wc_gateway_') === \false) {
    678             return null;
    679         }
    680         $additionalFields = $gateway->paymentMethod()->getProperty('additionalFields');
    681         $methodId = $additionalFields && in_array('birthdate', $additionalFields, \true);
    682         if ($methodId) {
    683             $optionName = 'billing_birthdate_' . $gateway->paymentMethod()->getProperty('id');
    684             //phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
    685             $fieldPosted = wc_clean(wp_unslash($_POST[$optionName] ?? ''));
    686             if ($fieldPosted === '' || !is_string($fieldPosted)) {
    687                 return null;
    688             }
    689             $order->update_meta_data($optionName, $fieldPosted);
    690             $order->save();
    691             $format = "Y-m-d";
    692             return gmdate($format, (int) strtotime($fieldPosted));
    693         }
    694         return null;
     622    public function setOrder($data)
     623    {
     624        $this->data = $data;
    695625    }
    696626}
  • mollie-payments-for-woocommerce/trunk/src/Payment/MollieOrderService.php

    r3242448 r3262577  
    44namespace Mollie\WooCommerce\Payment;
    55
     6use Mollie\Inpsyde\PaymentGateway\PaymentGateway;
    67use Mollie\Api\Exceptions\ApiException;
    78use Mollie\Api\Resources\Order;
    89use Mollie\Api\Resources\Payment;
    910use Mollie\WooCommerce\Gateway\AbstractGateway;
    10 use Mollie\WooCommerce\Gateway\MolliePaymentGateway;
     11use Mollie\WooCommerce\Gateway\MolliePaymentGatewayHandler;
    1112use Mollie\WooCommerce\SDK\HttpResponse;
    1213use Mollie\WooCommerce\Shared\Data;
    1314use Mollie\WooCommerce\Shared\SharedDataDictionary;
     15use Mollie\Psr\Container\ContainerInterface;
    1416use Mollie\Psr\Log\LoggerInterface as Logger;
    1517use Mollie\Psr\Log\LogLevel;
     
    3537    protected $data;
    3638    protected $pluginId;
    37     /**
    38      * PaymentService constructor.
    39      */
    40     public function __construct(HttpResponse $httpResponse, Logger $logger, \Mollie\WooCommerce\Payment\PaymentFactory $paymentFactory, Data $data, string $pluginId)
     39    private ContainerInterface $container;
     40    /**
     41     * MollieOrderService constructor.
     42     */
     43    public function __construct(HttpResponse $httpResponse, Logger $logger, \Mollie\WooCommerce\Payment\PaymentFactory $paymentFactory, Data $data, string $pluginId, ContainerInterface $container)
    4144    {
    4245        $this->httpResponse = $httpResponse;
     
    4548        $this->data = $data;
    4649        $this->pluginId = $pluginId;
     50        $this->container = $container;
    4751    }
    4852    public function setGateway($gateway)
     
    7781        }
    7882        $gateway = wc_get_payment_gateway_by_order($order);
    79         if (!$gateway instanceof MolliePaymentGateway) {
     83        if (!mollieWooCommerceIsMollieGateway($gateway->id)) {
    8084            return;
    8185        }
     
    98102            return;
    99103        }
    100         $payment = $payment_object->getPaymentObject($payment_object->data(), $test_mode, $use_cache = \false);
     104        $payment = $payment_object->getPaymentObject($payment_object->data(), $test_mode, \false);
    101105        // Payment not found
    102106        if (!$payment) {
    103107            $this->httpResponse->setHttpResponseCode(404);
    104108            $this->logger->debug(__METHOD__ . ": payment object {$payment_object_id} not found.", [\true]);
    105             return;
    106         }
    107         if (in_array($payment->method, ['klarna', 'klarnapaylater', 'klarnasliceit', 'klarnapaynow'], \true) && strpos($paymentId, 'tr_') === 0) {
    108             $this->httpResponse->setHttpResponseCode(200);
    109             $this->logger->debug($this->gateway->id . ": not respond on transaction webhooks for this payment method. Payment ID {$payment->id}, order ID {$order_id}");
    110109            return;
    111110        }
     
    125124            // TODO David: move to payment object?
    126125            // Add a debug message that order was already paid for
    127             $this->gateway->handlePaidOrderWebhook($order, $payment);
     126            $this->handlePaidOrderWebhook($order, $payment);
    128127            // Check and process a possible refund or chargeback
    129128            $this->processRefunds($order, $payment);
     
    155154    }
    156155    /**
     156     * @param \WC_Order $order
     157     * @param $payment
     158     */
     159    public function handlePaidOrderWebhook(\WC_Order $order, $payment)
     160    {
     161        // Duplicate webhook call
     162        $this->httpResponse->setHttpResponseCode(204);
     163        $order = wc_get_order($order);
     164        $order_id = $order->get_id();
     165        $this->logger->debug(__METHOD__ . ' - ' . $order_id . ": Order does not need a payment by Mollie (payment {$payment->id}).", [\true]);
     166    }
     167    /**
    157168     * @param WC_Order $order
    158169     *
     
    162173    {
    163174        $order_id = $order->get_id();
     175        $gateway = wc_get_payment_gateway_by_order($order);
     176        $paymentMethod = $this->container->get('payment_gateway.getPaymentMethod')($gateway->id);
    164177        // Check whether the order is processed and paid via another gateway
    165178        if ($this->isOrderPaidByOtherGateway($order)) {
    166             $this->logger->debug(__METHOD__ . ' ' . $this->gateway->id . ': Order ' . $order_id . ' orderNeedsPayment check: no, previously processed by other (non-Mollie) gateway.', [\true]);
     179            $this->logger->debug(__METHOD__ . ' ' . $gateway->id . ': Order ' . $order_id . ' orderNeedsPayment check: no, previously processed by other (non-Mollie) gateway.', [\true]);
    167180            return \false;
    168181        }
    169182        // Check whether the order is processed and paid via Mollie
    170183        if (!$this->isOrderPaidAndProcessed($order)) {
    171             $this->logger->debug(__METHOD__ . ' ' . $this->gateway->id . ': Order ' . $order_id . ' orderNeedsPayment check: yes, order not previously processed by Mollie gateway.', [\true]);
     184            $this->logger->debug(__METHOD__ . ' ' . $gateway->id . ': Order ' . $order_id . ' orderNeedsPayment check: yes, order not previously processed by Mollie gateway.', [\true]);
    172185            return \true;
    173186        }
     187        if ('1' === $order->get_meta('_mollie_authorized')) {
     188            $this->logger->debug(__METHOD__ . ' ' . $gateway->id . ': Order ' . $order_id . ' orderNeedsPayment check: yes, order is authorized.');
     189            return \true;
     190        }
    174191        if ($order->needs_payment()) {
    175             $this->logger->debug(__METHOD__ . ' ' . $this->gateway->id . ': Order ' . $order_id . ' orderNeedsPayment check: yes, WooCommerce thinks order needs payment.', [\true]);
     192            $this->logger->debug(__METHOD__ . ' ' . $gateway->id . ': Order ' . $order_id . ' orderNeedsPayment check: yes, WooCommerce thinks order needs payment.', [\true]);
    176193            return \true;
    177194        }
    178195        // Has initial order status 'on-hold'
    179         if ($this->gateway->paymentMethod()->getInitialOrderStatus() === SharedDataDictionary::STATUS_ON_HOLD && $order->has_status(SharedDataDictionary::STATUS_ON_HOLD)) {
    180             $this->logger->debug(__METHOD__ . ' ' . $this->gateway->id . ': Order ' . $order_id . ' orderNeedsPayment check: yes, has status On-Hold. ', [\true]);
     196        if ($paymentMethod->getInitialOrderStatus() === SharedDataDictionary::STATUS_ON_HOLD && $order->has_status(SharedDataDictionary::STATUS_ON_HOLD)) {
     197            $this->logger->debug(__METHOD__ . ' ' . $gateway->id . ': Order ' . $order_id . ' orderNeedsPayment check: yes, has status On-Hold. ', [\true]);
    181198            return \true;
    182199        }
     
    498515    {
    499516        $payment_method_title = '';
    500         if (!$this->gateway instanceof MolliePaymentGateway) {
    501             return $payment_method_title;
    502         }
    503         if ($payment->method === $this->gateway->paymentMethod()->getProperty('id')) {
     517        if ($payment->method === $this->gateway->id) {
    504518            $payment_method_title = $this->gateway->method_title;
    505519        }
  • mollie-payments-for-woocommerce/trunk/src/Payment/MolliePayment.php

    r3164004 r3262577  
    44namespace Mollie\WooCommerce\Payment;
    55
     6use Mollie\Inpsyde\PaymentGateway\PaymentGateway;
    67use Mollie\Api\Exceptions\ApiException;
    7 use Mollie\Api\Resources\Order;
    88use Mollie\Api\Resources\Payment;
    99use Mollie\Api\Resources\Refund;
    10 use Mollie\WooCommerce\Gateway\MolliePaymentGateway;
    11 use Mollie\WooCommerce\Gateway\MolliePaymentGatewayI;
     10use Mollie\WooCommerce\Payment\Request\RequestFactory;
    1211use Mollie\WooCommerce\PaymentMethods\Voucher;
    1312use Mollie\WooCommerce\SDK\Api;
     13use Mollie\WooCommerce\Settings\Settings;
     14use Mollie\WooCommerce\Shared\Data;
    1415use Mollie\WooCommerce\Shared\SharedDataDictionary;
     16use Mollie\Psr\Log\LoggerInterface as Logger;
    1517use Mollie\Psr\Log\LogLevel;
    1618use WC_Order;
    17 use WC_Payment_Gateway;
    1819use WC_Subscriptions_Manager;
    1920use WP_Error;
     
    2223    public const ACTION_AFTER_REFUND_PAYMENT_CREATED = 'mollie-payments-for-woocommerce' . '_refund_payment_created';
    2324    protected $pluginId;
    24     public function __construct($data, $pluginId, Api $apiHelper, $settingsHelper, $dataHelper, $logger)
     25    public function __construct($data, string $pluginId, Api $apiHelper, Settings $settingsHelper, Data $dataHelper, Logger $logger, RequestFactory $requestFactory)
    2526    {
    2627        $this->data = $data;
     
    2829        $this->apiHelper = $apiHelper;
    2930        $this->settingsHelper = $settingsHelper;
     31        $this->logger = $logger;
     32        $this->requestFactory = $requestFactory;
    3033        $this->dataHelper = $dataHelper;
    31         $this->logger = $logger;
    3234    }
    3335    public function getPaymentObject($paymentId, $testMode = \false, $useCache = \true)
     
    5355    public function getPaymentRequestData($order, $customerId, $voucherDefaultCategory = Voucher::NO_CATEGORY)
    5456    {
    55         $settingsHelper = $this->settingsHelper;
    56         $optionName = $this->pluginId . '_' . 'api_payment_description';
    57         $option = get_option($optionName);
    58         $paymentDescription = $this->getPaymentDescription($order, $option);
    59         $paymentLocale = $settingsHelper->getPaymentLocale();
    60         $storeCustomer = $settingsHelper->shouldStoreCustomer();
    61         $gateway = wc_get_payment_gateway_by_order($order);
    62         if (!$gateway || !$gateway instanceof MolliePaymentGateway) {
    63             return ['result' => 'failure'];
    64         }
    65         $gatewayId = $gateway->id;
    66         $selectedIssuer = $gateway->getSelectedIssuer();
    67         $returnUrl = $gateway->get_return_url($order);
    68         $returnUrl = $this->getReturnUrl($order, $returnUrl);
    69         $webhookUrl = $this->getWebhookUrl($order, $gatewayId);
    70         $orderId = $order->get_id();
    71         $paymentRequestData = ['amount' => ['currency' => $this->dataHelper->getOrderCurrency($order), 'value' => $this->dataHelper->formatCurrencyValue($order->get_total(), $this->dataHelper->getOrderCurrency($order))], 'description' => $paymentDescription, 'redirectUrl' => $returnUrl, 'webhookUrl' => $webhookUrl, 'method' => $gateway->paymentMethod()->getProperty('id'), 'issuer' => $selectedIssuer, 'locale' => $paymentLocale, 'metadata' => apply_filters($this->pluginId . '_payment_object_metadata', ['order_id' => $order->get_id()])];
    72         $paymentRequestData = $this->addSequenceTypeForSubscriptionsFirstPayments($order->get_id(), $gateway, $paymentRequestData);
    73         if ($storeCustomer) {
    74             $paymentRequestData['customerId'] = $customerId;
    75         }
    76         $cardToken = mollieWooCommerceCardToken();
    77         if ($cardToken) {
    78             $paymentRequestData['cardToken'] = $cardToken;
    79         }
    80         //phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
    81         $applePayToken = wc_clean(wp_unslash($_POST["token"] ?? ''));
    82         if ($applePayToken) {
    83             $encodedApplePayToken = wp_json_encode($applePayToken);
    84             $paymentRequestData['applePayPaymentToken'] = $encodedApplePayToken;
    85         }
    86         $paymentRequestData = $this->addCustomRequestFields($order, $paymentRequestData, $gateway);
    87         return $paymentRequestData;
    88     }
    89     public function addSequenceTypeFirst($paymentRequestData)
    90     {
    91         $paymentRequestData['sequenceType'] = 'first';
    92         return $paymentRequestData;
     57        return $this->requestFactory->createRequest('payment', $order, $customerId);
    9358    }
    9459    /**
     
    152117    /**
    153118     * @param \WC_Order                     $order
    154      * @param \Mollie\Api\Resources\Payment $payment
     119     * @param Payment $payment
    155120     * @param string                       $paymentMethodTitle
    156121     */
     
    190155            // Add messages to log
    191156            $this->logger->debug(__METHOD__ . ' payment at Mollie not paid, so no processing for order ' . $orderId);
     157        }
     158    }
     159    /**
     160     * @param \WC_Order                   $order
     161     * @param Payment $payment
     162     * @param string                     $paymentMethodTitle
     163     */
     164    public function onWebhookAuthorized(WC_Order $order, Payment $payment, $paymentMethodTitle)
     165    {
     166        // Get order ID in the correct way depending on WooCommerce version
     167        $orderId = $order->get_id();
     168        if ($payment->isAuthorized()) {
     169            // Add messages to log
     170            $this->logger->debug(__METHOD__ . ' called for order ' . $orderId);
     171            // WooCommerce 2.2.0 has the option to store the Payment transaction id.
     172            $order->payment_complete($payment->id);
     173            // Add messages to log
     174            $this->logger->debug(__METHOD__ . ' WooCommerce payment_complete() processed and returned to ' . __METHOD__ . ' for order ' . $orderId);
     175            $order->add_order_note(sprintf(
     176                /* translators: Placeholder 1: payment method title, placeholder 2: payment ID */
     177                __('Order authorized using %1$s payment (%2$s). Set order to completed in WooCommerce when you have shipped the products, to capture the payment. Do this within 28 days, or the order will expire. To handle individual order lines, process the order via the Mollie Dashboard.', 'mollie-payments-for-woocommerce'),
     178                $paymentMethodTitle,
     179                $payment->id . ($payment->mode === 'test' ? ' - ' . __('test mode', 'mollie-payments-for-woocommerce') : '')
     180            ));
     181            //check for webhook that order is Authorized on Paid webhook
     182            $order->update_meta_data('_mollie_authorized', '1');
     183            // Mark the order as processed and paid via Mollie
     184            $this->setOrderPaidAndProcessed($order);
     185            // Remove (old) cancelled payments from this order
     186            $this->unsetCancelledMolliePaymentId($orderId);
     187            // Add messages to log
     188            $this->logger->debug(__METHOD__ . ' processing order status update via Mollie plugin fully completed for order ' . $orderId);
     189            // Subscription processing
     190            $this->deleteSubscriptionFromPending($order);
     191        } else {
     192            // Add messages to log
     193            $this->logger->debug(__METHOD__ . ' order at Mollie not authorized, so no processing for order ' . $orderId);
    192194        }
    193195    }
     
    371373    /**
    372374     * @param WC_Order $order
    373      * @param MolliePaymentGatewayI $gateway
     375     * @param PaymentGateway $gateway
    374376     * @param                    $newOrderStatus
    375377     * @param                    $orderId
     
    377379    protected function maybeUpdateStatus(WC_Order $order, $gateway, $newOrderStatus)
    378380    {
    379         if ($this->isOrderPaymentStartedByOtherGateway($order) || !is_a($gateway, MolliePaymentGateway::class)) {
     381        if ($this->isOrderPaymentStartedByOtherGateway($order) || !is_a($gateway, PaymentGateway::class)) {
    380382            $this->informNotUpdatingStatus($gateway->id, $order);
    381383            return;
    382384        }
    383         $gateway->paymentService()->updateOrderStatus($order, $newOrderStatus);
    384     }
    385     protected function addCustomRequestFields($order, array $paymentRequestData, MolliePaymentGateway $gateway)
    386     {
    387         if ($gateway->paymentMethod()->hasProperty('paymentAPIfields')) {
    388             $paymentAPIfields = $gateway->paymentMethod()->getProperty('paymentAPIfields');
    389             foreach ($paymentAPIfields as $field) {
    390                 if (!method_exists($this, 'create' . ucfirst($field))) {
    391                     continue;
    392                 }
    393                 $value = $this->{'create' . ucfirst($field)}($order);
    394                 if ($value) {
    395                     $paymentRequestData[$field] = $value;
    396                 }
    397             }
    398         }
    399         return $paymentRequestData;
     385        $this->updateOrderStatus($order, $newOrderStatus);
     386    }
     387    public function setPayment($data)
     388    {
     389        $this->data = $data;
    400390    }
    401391}
  • mollie-payments-for-woocommerce/trunk/src/Payment/MollieSubscription.php

    r3164004 r3262577  
    44
    55use Mollie\Api\Types\SequenceType;
    6 use Mollie\WooCommerce\Gateway\MolliePaymentGateway;
     6use Mollie\WooCommerce\Payment\Request\Middleware\MiddlewareHandler;
     7use Mollie\WooCommerce\Payment\Request\Middleware\PaymentDescriptionMiddleware;
     8use Mollie\WooCommerce\PaymentMethods\AbstractPaymentMethod;
    79use Mollie\WooCommerce\SDK\Api;
    8 use Mollie\WooCommerce\Subscription\MollieSubscriptionGateway;
     10use Mollie\WooCommerce\Subscription\MollieSubscriptionGatewayHandler;
     11use Mollie\Psr\Log\LoggerInterface as Logger;
    912class MollieSubscription extends \Mollie\WooCommerce\Payment\MollieObject
    1013{
    1114    protected $pluginId;
    1215    /**
     16     * @var mixed
     17     */
     18    private AbstractPaymentMethod $paymentMethod;
     19    protected MiddlewareHandler $middleware;
     20    /**
    1321     * Molliesubscription constructor.
    1422     *
    1523     */
    16     public function __construct($pluginId, Api $apiHelper, $settingsHelper, $dataHelper, $logger)
     24    public function __construct($pluginId, Api $apiHelper, $settingsHelper, $dataHelper, Logger $logger, AbstractPaymentMethod $paymentMethod, $middlewareHandler)
    1725    {
    1826        $this->pluginId = $pluginId;
     
    2129        $this->dataHelper = $dataHelper;
    2230        $this->logger = $logger;
     31        $this->paymentMethod = $paymentMethod;
     32        $this->middleware = $middlewareHandler;
    2333    }
    2434    /**
     
    3141        $paymentLocale = $this->settingsHelper->getPaymentLocale();
    3242        $gateway = wc_get_payment_gateway_by_order($order);
    33         if (!$gateway || !$gateway instanceof MolliePaymentGateway) {
     43        if (!$gateway || !mollieWooCommerceIsMollieGateway($gateway->id)) {
    3444            return ['result' => 'failure'];
    3545        }
    3646        $gatewayId = $gateway->id;
     47        $methodId = substr($gatewayId, strrpos($gatewayId, '_') + 1);
    3748        $optionName = $this->pluginId . '_api_payment_description';
    3849        $option = get_option($optionName);
    3950        $paymentDescription = $this->getRecurringPaymentDescription($order, $option, $initialPaymentUsedOrderAPI);
    40         $selectedIssuer = $gateway->getSelectedIssuer();
    41         $returnUrl = $gateway->get_return_url($order);
    42         $returnUrl = $this->getReturnUrl($order, $returnUrl);
    43         $webhookUrl = $this->getWebhookUrl($order, $gatewayId);
    44         return array_filter(['amount' => ['currency' => $this->dataHelper->getOrderCurrency($order), 'value' => $this->dataHelper->formatCurrencyValue($order->get_total(), $this->dataHelper->getOrderCurrency($order))], 'description' => $paymentDescription, 'redirectUrl' => $returnUrl, 'webhookUrl' => $webhookUrl, 'method' => $gateway->paymentMethod()->getProperty('id'), 'issuer' => $selectedIssuer, 'locale' => $paymentLocale, 'metadata' => ['order_id' => $order->get_id()], 'sequenceType' => 'recurring', 'customerId' => $customerId]);
     51        $requestData = array_filter(['amount' => ['currency' => $this->dataHelper->getOrderCurrency($order), 'value' => $this->dataHelper->formatCurrencyValue($order->get_total(), $this->dataHelper->getOrderCurrency($order))], 'description' => $paymentDescription, 'method' => $methodId, 'locale' => $paymentLocale, 'metadata' => ['order_id' => $order->get_id()], 'sequenceType' => SequenceType::SEQUENCETYPE_RECURRING, 'customerId' => $customerId]);
     52        $context = 'payment';
     53        return $this->middleware->handle($requestData, $order, $context);
    4554    }
    4655    protected function getRecurringPaymentDescription($order, $option, $initialPaymentUsedOrderAPI)
     
    5665            return $description;
    5766        }
    58         return $this->getPaymentDescription($order, $option);
     67        $middleware = new PaymentDescriptionMiddleware($this->dataHelper);
     68        $requestData = [];
     69        $context = 'payment';
     70        $result = $middleware->__invoke($requestData, $order, $context, static function ($requestData) {
     71            return $requestData;
     72        });
     73        return $result['description'];
    5974    }
    6075    /**
     
    6277     *
    6378     * @param bool $status
    64      * @param MollieSubscriptionGateway $subscriptionGateway
     79     * @param MollieSubscriptionGatewayHandler $deprecatedSubscriptionHelper
    6580     * @return bool
    6681     */
    67     public function isAvailableForSubscriptions(bool $status, MollieSubscriptionGateway $subscriptionGateway, $orderTotal): bool
     82    public function isAvailableForSubscriptions(bool $status, MollieSubscriptionGatewayHandler $deprecatedSubscriptionHelper, $orderTotal, $gateway): bool
    6883    {
    6984        $subscriptionPluginActive = class_exists('WC_Subscriptions') && class_exists('WC_Subscriptions_Admin');
     
    7186            return $status;
    7287        }
    73         $currency = $subscriptionGateway->getCurrencyFromOrder();
    74         $billingCountry = $subscriptionGateway->getBillingCountry();
    75         $paymentLocale = $subscriptionGateway->dataService()->getPaymentLocale();
     88        $currency = $deprecatedSubscriptionHelper->getCurrencyFromOrder();
     89        $billingCountry = $deprecatedSubscriptionHelper->getBillingCountry();
     90        $paymentLocale = $deprecatedSubscriptionHelper->dataService()->getPaymentLocale();
    7691        // Check recurring totals against recurring payment methods for future renewal payments
    77         $recurringTotal = $subscriptionGateway->get_recurring_total();
     92        $recurringTotal = $deprecatedSubscriptionHelper->get_recurring_total();
    7893        // See get_available_payment_gateways() in woocommerce-subscriptions/includes/gateways/class-wc-subscriptions-payment-gateways.php
    7994        $acceptManualRenewals = 'yes' === get_option(\WC_Subscriptions_Admin::$option_prefix . '_accept_manual_renewals', 'no');
    80         $supportsSubscriptions = $subscriptionGateway->supports('subscriptions');
     95        $supportsSubscriptions = $gateway->supports('subscriptions');
    8196        if ($acceptManualRenewals === \true || !$supportsSubscriptions || empty($recurringTotal)) {
    8297            return $status;
     
    85100            // First check recurring payment methods CC and SDD
    86101            $filters = $this->buildFilters($currency, $recurring_total, $billingCountry, SequenceType::SEQUENCETYPE_RECURRING, $paymentLocale);
    87             $status = $subscriptionGateway->isAvailableMethodInCheckout($filters);
     102            $status = $deprecatedSubscriptionHelper->isAvailableMethodInCheckout($filters);
    88103        }
    89104        // Check available first payment methods with today's order total, but ignore SSD gateway (not shown in checkout)
    90         if ($subscriptionGateway->paymentMethod()->getProperty('id') === 'mollie_wc_gateway_directdebit') {
     105        if ($deprecatedSubscriptionHelper->paymentMethod()->getProperty('id') === 'mollie_wc_gateway_directdebit') {
    91106            return $status;
    92107        }
    93108        $filters = $this->buildFilters($currency, $orderTotal, $billingCountry, SequenceType::SEQUENCETYPE_FIRST, $paymentLocale);
    94         return $subscriptionGateway->isAvailableMethodInCheckout($filters);
     109        return $deprecatedSubscriptionHelper->isAvailableMethodInCheckout($filters);
    95110    }
    96111    /**
  • mollie-payments-for-woocommerce/trunk/src/Payment/OrderLines.php

    r3226701 r3262577  
    106106                }
    107107                $this->currency = $this->dataHelper->getOrderCurrency($this->order);
    108                 $mollie_order_item = ['sku' => $this->get_item_reference($product), 'name' => $this->get_item_name($cart_item), 'quantity' => $this->get_item_quantity($cart_item), 'vatRate' => round($this->get_item_vatRate($cart_item, $product), 2), 'unitPrice' => ['currency' => $this->currency, 'value' => $this->dataHelper->formatCurrencyValue($this->get_item_price($cart_item), $this->currency)], 'totalAmount' => ['currency' => $this->currency, 'value' => $this->dataHelper->formatCurrencyValue($this->get_item_total_amount($cart_item), $this->currency)], 'vatAmount' => ['currency' => $this->currency, 'value' => $this->dataHelper->formatCurrencyValue($this->get_item_tax_amount($cart_item), $this->currency)], 'discountAmount' => ['currency' => $this->currency, 'value' => $this->dataHelper->formatCurrencyValue($this->get_item_discount_amount($cart_item), $this->currency)], 'metadata' => ['order_item_id' => $cart_item->get_id()]];
     108                $mollie_order_item = ['sku' => $this->get_item_reference($product), 'type' => $product->is_virtual() ? 'digital' : 'physical', 'name' => $this->get_item_name($cart_item), 'quantity' => $this->get_item_quantity($cart_item), 'vatRate' => round($this->get_item_vatRate($cart_item, $product), 2), 'unitPrice' => ['currency' => $this->currency, 'value' => $this->dataHelper->formatCurrencyValue($this->get_item_price($cart_item), $this->currency)], 'totalAmount' => ['currency' => $this->currency, 'value' => $this->dataHelper->formatCurrencyValue($this->get_item_total_amount($cart_item), $this->currency)], 'vatAmount' => ['currency' => $this->currency, 'value' => $this->dataHelper->formatCurrencyValue($this->get_item_tax_amount($cart_item), $this->currency)], 'discountAmount' => ['currency' => $this->currency, 'value' => $this->dataHelper->formatCurrencyValue($this->get_item_discount_amount($cart_item), $this->currency)], 'metadata' => ['order_item_id' => $cart_item->get_id()], 'productUrl' => $product->get_permalink()];
     109                if ($product->get_image_id()) {
     110                    $productImage = wp_get_attachment_image_src($product->get_image_id(), 'full');
     111                    if (isset($productImage[0])) {
     112                        $mollie_order_item['imageUrl'] = $productImage[0];
     113                    }
     114                }
    109115                if ($isMealVoucherEnabled && $this->get_item_category($product, $voucherDefaultCategory) != "no_category") {
    110116                    $mollie_order_item['category'] = $this->get_item_category($product, $voucherDefaultCategory);
  • mollie-payments-for-woocommerce/trunk/src/Payment/PaymentCheckoutRedirectService.php

    r3164004 r3262577  
    1919    protected $dataHelper;
    2020    /**
    21      * PaymentService constructor.
     21     * PaymentCheckoutRedirectService constructor.
    2222     */
    2323    public function __construct($dataHelper)
  • mollie-payments-for-woocommerce/trunk/src/Payment/PaymentFactory.php

    r3164004 r3262577  
    1111class PaymentFactory
    1212{
    13     /**
    14      * @var Data
    15      */
    16     protected $dataHelper;
    17     /**
    18      * @var Api
    19      */
    20     protected $apiHelper;
    21     protected $settingsHelper;
    22     /**
    23      * @var string
    24      */
    25     protected $pluginId;
    26     protected $logger;
    27     /**
    28      * @var OrderLines
    29      */
    30     protected $orderLines;
     13    private $mollieOrderFactory;
     14    private $molliePaymentFactory;
    3115    /**
    3216     * PaymentFactory constructor.
    3317     */
    34     public function __construct(Data $dataHelper, Api $apiHelper, Settings $settingsHelper, string $pluginId, $logger, \Mollie\WooCommerce\Payment\OrderLines $orderLines)
     18    public function __construct(callable $mollieOrderFactory, callable $molliePaymentFactory)
    3519    {
    36         $this->dataHelper = $dataHelper;
    37         $this->apiHelper = $apiHelper;
    38         $this->settingsHelper = $settingsHelper;
    39         $this->pluginId = $pluginId;
    40         $this->logger = $logger;
    41         $this->orderLines = $orderLines;
     20        $this->mollieOrderFactory = $mollieOrderFactory;
     21        $this->molliePaymentFactory = $molliePaymentFactory;
    4222    }
    4323    /**
     
    4929    {
    5030        if (!is_object($data) && $data === 'order' || is_string($data) && strpos($data, 'ord_') !== \false || is_object($data) && $data->resource === 'order') {
    51             $refundLineItemsBuilder = new \Mollie\WooCommerce\Payment\RefundLineItemsBuilder($this->dataHelper);
    52             $apiKey = $this->settingsHelper->getApiKey();
    53             $orderItemsRefunded = new \Mollie\WooCommerce\Payment\OrderItemsRefunder($refundLineItemsBuilder, $this->dataHelper, $this->apiHelper->getApiClient($apiKey)->orders);
    54             return new \Mollie\WooCommerce\Payment\MollieOrder($orderItemsRefunded, $data, $this->pluginId, $this->apiHelper, $this->settingsHelper, $this->dataHelper, $this->logger, $this->orderLines);
     31            $mollieOrder = ($this->mollieOrderFactory)();
     32            $mollieOrder->setOrder($data);
     33            return $mollieOrder;
    5534        }
    5635        if (!is_object($data) && $data === 'payment' || !is_object($data) && strpos($data, 'tr_') !== \false || is_object($data) && $data->resource === 'payment') {
    57             return new \Mollie\WooCommerce\Payment\MolliePayment($data, $this->pluginId, $this->apiHelper, $this->settingsHelper, $this->dataHelper, $this->logger);
     36            $molliePayment = ($this->molliePaymentFactory)();
     37            $molliePayment->setPayment($data);
     38            return $molliePayment;
    5839        }
    5940        return \false;
  • mollie-payments-for-woocommerce/trunk/src/Payment/PaymentModule.php

    r3164004 r3262577  
    1010use Mollie\Api\Exceptions\ApiException;
    1111use Mollie\Api\Resources\Refund;
    12 use Mollie\WooCommerce\Gateway\MolliePaymentGateway;
    13 use Mollie\WooCommerce\Gateway\MolliePaymentGatewayI;
     12use Mollie\WooCommerce\Gateway\MolliePaymentGatewayHandler;
     13use Mollie\WooCommerce\Gateway\Refund\OrderItemsRefunder;
     14use Mollie\WooCommerce\MerchantCapture\Capture\Action\CapturePayment;
     15use Mollie\WooCommerce\PaymentMethods\InstructionStrategies\OrderInstructionsManager;
    1416use Mollie\WooCommerce\SDK\Api;
    1517use Mollie\WooCommerce\SDK\HttpResponse;
    1618use Mollie\WooCommerce\Settings\Settings;
    17 use Mollie\WooCommerce\Shared\Data;
    1819use Mollie\WooCommerce\Shared\SharedDataDictionary;
    1920use Mollie\Psr\Container\ContainerInterface;
    2021use Mollie\Psr\Log\LoggerInterface as Logger;
    21 use Mollie\Psr\Log\LogLevel;
    2222use RuntimeException;
    2323use WC_Order;
     
    4343     */
    4444    protected $gatewayClassnames;
     45    /**
     46     * @var ContainerInterface
     47     */
     48    protected $container;
    4549    public function services(): array
    4650    {
    47         return [\Mollie\WooCommerce\Payment\OrderLines::class => static function (ContainerInterface $container): \Mollie\WooCommerce\Payment\OrderLines {
    48             $data = $container->get('settings.data_helper');
    49             $pluginId = $container->get('shared.plugin_id');
    50             return new \Mollie\WooCommerce\Payment\OrderLines($data, $pluginId);
    51         }, \Mollie\WooCommerce\Payment\PaymentFactory::class => static function (ContainerInterface $container): \Mollie\WooCommerce\Payment\PaymentFactory {
    52             $settingsHelper = $container->get('settings.settings_helper');
    53             assert($settingsHelper instanceof Settings);
    54             $apiHelper = $container->get('SDK.api_helper');
    55             assert($apiHelper instanceof Api);
    56             $data = $container->get('settings.data_helper');
    57             assert($data instanceof Data);
    58             $pluginId = $container->get('shared.plugin_id');
    59             $logger = $container->get(Logger::class);
    60             assert($logger instanceof Logger);
    61             $orderLines = $container->get(\Mollie\WooCommerce\Payment\OrderLines::class);
    62             return new \Mollie\WooCommerce\Payment\PaymentFactory($data, $apiHelper, $settingsHelper, $pluginId, $logger, $orderLines);
    63         }, \Mollie\WooCommerce\Payment\MollieObject::class => static function (ContainerInterface $container): \Mollie\WooCommerce\Payment\MollieObject {
    64             $logger = $container->get(Logger::class);
    65             assert($logger instanceof Logger);
    66             $data = $container->get('settings.data_helper');
    67             assert($data instanceof Data);
    68             $apiHelper = $container->get('SDK.api_helper');
    69             assert($apiHelper instanceof Api);
    70             $pluginId = $container->get('shared.plugin_id');
    71             $paymentFactory = $container->get(\Mollie\WooCommerce\Payment\PaymentFactory::class);
    72             assert($paymentFactory instanceof \Mollie\WooCommerce\Payment\PaymentFactory);
    73             $settingsHelper = $container->get('settings.settings_helper');
    74             assert($settingsHelper instanceof Settings);
    75             return new \Mollie\WooCommerce\Payment\MollieObject($data, $logger, $paymentFactory, $apiHelper, $settingsHelper, $pluginId);
    76         }];
     51        static $services;
     52        if ($services === null) {
     53            $services = require_once __DIR__ . '/inc/services.php';
     54        }
     55        return $services();
    7756    }
    7857    public function run(ContainerInterface $container): bool
     
    8867        $this->pluginId = $container->get('shared.plugin_id');
    8968        $this->gatewayClassnames = $container->get('gateway.classnames');
     69        $this->container = $container;
    9070        // Listen to return URL call
    91         add_action('woocommerce_api_mollie_return', [$this, 'onMollieReturn']);
    92         add_action('template_redirect', [$this, 'mollieReturnRedirect']);
     71        add_action('woocommerce_api_mollie_return', function () use ($container) {
     72            $this->onMollieReturn($container);
     73        }, 10, 1);
     74        add_action('template_redirect', function () use ($container) {
     75            $this->mollieReturnRedirect($container);
     76        });
    9377        // Show Mollie instructions on order details page
    94         add_action('woocommerce_order_details_after_order_table', [$this, 'onOrderDetails'], 10, 1);
     78        add_action('woocommerce_order_details_after_order_table', function (WC_Order $order) use ($container) {
     79            $this->onOrderDetails($order, $container);
     80        }, 10, 1);
    9581        // Cancel order at Mollie (for Orders API/Klarna)
    9682        add_action('woocommerce_order_status_cancelled', [$this, 'cancelOrderAtMollie']);
     
    10288            $this->handleExpiryDateCancelation($paymentMethods);
    10389        }, 10, 2);
    104         add_action(\Mollie\WooCommerce\Payment\OrderItemsRefunder::ACTION_AFTER_REFUND_ORDER_ITEMS, [$this, 'addOrderNoteForRefundCreated'], 10, 3);
    105         add_action(\Mollie\WooCommerce\Payment\OrderItemsRefunder::ACTION_AFTER_CANCELED_ORDER_ITEMS, [$this, 'addOrderNoteForCancelledLineItems'], 10, 2);
     90        add_action(OrderItemsRefunder::ACTION_AFTER_REFUND_ORDER_ITEMS, [$this, 'addOrderNoteForRefundCreated'], 10, 3);
     91        add_action(OrderItemsRefunder::ACTION_AFTER_CANCELED_ORDER_ITEMS, [$this, 'addOrderNoteForCancelledLineItems'], 10, 2);
    10692        return \true;
    10793    }
     
    184170     *
    185171     */
    186     public function onMollieReturn()
     172    public function onMollieReturn($container)
    187173    {
    188174        try {
     
    195181        $gateway = wc_get_payment_gateway_by_order($order);
    196182        $orderId = $order->get_id();
     183        $oldGatewayInstances = $container->get('__deprecated.gateway_helpers');
     184        $mollieGatewayHelper = $oldGatewayInstances[$gateway->id];
    197185        if (!$gateway) {
    198186            $gatewayName = $order->get_payment_method();
     
    201189            return;
    202190        }
    203         if (!$gateway instanceof MolliePaymentGateway) {
     191        if (!mollieWooCommerceIsMollieGateway($gateway->id)) {
    204192            $this->httpResponse->setHttpResponseCode(400);
    205             $this->logger->debug(__METHOD__ . ": Invalid gateway {get_class({$gateway})} for this plugin. Order {$orderId}.");
    206             return;
    207         }
    208         $redirect_url = $gateway->getReturnRedirectUrlForOrder($order);
     193            $gatewayClass = get_class($gateway);
     194            $this->logger->debug(__METHOD__ . ": Invalid gateway {$gatewayClass} for this plugin. Order {$orderId}.");
     195            return;
     196        }
     197        $redirect_url = $mollieGatewayHelper->getReturnRedirectUrlForOrder($order);
    209198        // Add utm_nooverride query string
    210199        $redirect_url = add_query_arg(['utm_nooverride' => 1], $redirect_url);
     
    217206     *
    218207     */
    219     public function mollieReturnRedirect()
     208    public function mollieReturnRedirect($container)
    220209    {
    221210        if (isset($_GET['filter_flag'])) {
    222211            $filterFlag = sanitize_text_field(wp_unslash($_GET['filter_flag']));
    223212            if ($filterFlag === 'onMollieReturn') {
    224                 self::onMollieReturn();
     213                self::onMollieReturn($container);
    225214            }
    226215        }
     
    229218     * @param WC_Order $order
    230219     */
    231     public function onOrderDetails(WC_Order $order)
     220    public function onOrderDetails(WC_Order $order, ContainerInterface $container)
    232221    {
    233222        if (is_order_received_page()) {
     
    236225             * Instructions already displayed on top of order received page by $gateway->thankyou_page()
    237226             *
    238              * @see MolliePaymentGateway::thankyou_page
     227             * @see MolliePaymentGatewayHandler::thankyou_page
    239228             */
    240229            return;
    241230        }
    242231        $gateway = wc_get_payment_gateway_by_order($order);
    243         if (!$gateway || !$gateway instanceof MolliePaymentGateway) {
    244             return;
    245         }
    246         /** @var MolliePaymentGatewayI $gateway */
    247         $gateway->displayInstructions($order);
     232        if (!$gateway || !mollieWooCommerceIsMollieGateway($gateway->id)) {
     233            return;
     234        }
     235        assert($gateway instanceof \WC_Payment_Gateway);
     236        $instructionsManager = $container->get(OrderInstructionsManager::class);
     237        $oldGatewayInstances = $container->get('__deprecated.gateway_helpers');
     238        $mollieGatewayHelper = $oldGatewayInstances[$gateway->id];
     239        $instructionsManager->displayInstructions($gateway, $mollieGatewayHelper, $order);
    248240    }
    249241    /**
     
    264256        }
    265257        $this->logger->debug(__METHOD__ . ' - ' . $order_id . ' - Try to process completed order for a potential capture at Mollie.');
    266         // Does WooCommerce order contain a Mollie Order?
    267         $mollie_order_id = ($mollie_order_id = $order->get_meta('_mollie_order_id', \true)) ? $mollie_order_id : \false;
    268         // Is it a payment? you cannot ship a payment
    269         if ($mollie_order_id === \false || substr($mollie_order_id, 0, 3) === 'tr_') {
    270             $message = _x('Processing a payment, no capture needed', 'Order note info', 'mollie-payments-for-woocommerce');
     258        $mollie_transaction_id = ($mollie_transaction_id = $order->get_meta('_mollie_order_id', \true)) ? $mollie_transaction_id : \false;
     259        if (!$mollie_transaction_id) {
     260            $mollie_transaction_id = ($mollie_transaction_id = $order->get_meta('_mollie_payment_id', \true)) ? $mollie_transaction_id : \false;
     261        }
     262        if (empty($mollie_transaction_id)) {
     263            $message = _x('Order contains Mollie payment method, but not a valid Mollie Transaction ID. Processing shipment & capture failed.', 'Order note info', 'mollie-payments-for-woocommerce');
    271264            $order->add_order_note($message);
    272             $this->logger->debug(__METHOD__ . ' - ' . $order_id . ' - Processing a payment, no capture needed.');
    273             return;
     265            $this->logger->debug(__METHOD__ . ' - ' . $order_id . ' Order contains Mollie payment method, but not a valid Mollie Transaction ID. Processing shipment & capture failed.');
    274266        }
    275267        $apiKey = $this->settingsHelper->getApiKey();
    276268        try {
    277             // Get the order from the Mollie API
    278             $mollie_order = $this->apiHelper->getApiClient($apiKey)->orders->get($mollie_order_id);
     269            // Get the order or payment from the Mollie API
     270            if (substr($mollie_transaction_id, 0, 3) === 'tr_') {
     271                $mollie_transaction = $this->apiHelper->getApiClient($apiKey)->payments->get($mollie_transaction_id);
     272                $mollie_transaction_type = 'Payment';
     273            } else {
     274                $mollie_transaction = $this->apiHelper->getApiClient($apiKey)->orders->get($mollie_transaction_id);
     275                $mollie_transaction_type = 'Order';
     276            }
    279277            // Check that order is Paid or Authorized and can be captured
    280             if ($mollie_order->isCanceled()) {
    281                 $message = _x('Order already canceled at Mollie, can not be shipped/captured.', 'Order note info', 'mollie-payments-for-woocommerce');
     278            if ($mollie_transaction->isCanceled()) {
     279                $message = _x('Transaction already canceled at Mollie, can not be shipped/captured.', 'Order note info', 'mollie-payments-for-woocommerce');
    282280                $order->add_order_note($message);
    283                 $this->logger->debug(__METHOD__ . ' - ' . $order_id . ' - Order already canceled at Mollie, can not be shipped/captured.');
     281                $this->logger->debug(__METHOD__ . ' - ' . $order_id . ' - ' . $mollie_transaction_type . ' already canceled at Mollie, can not be shipped/captured.');
    284282                return;
    285283            }
    286             if ($mollie_order->isCompleted()) {
    287                 $message = _x('Order already completed at Mollie, can not be shipped/captured.', 'Order note info', 'mollie-payments-for-woocommerce');
     284            if (method_exists($mollie_transaction, 'isCompleted') && $mollie_transaction->isCompleted()) {
     285                $message = _x('Transaction already completed at Mollie, can not be shipped/captured.', 'Order note info', 'mollie-payments-for-woocommerce');
    288286                $order->add_order_note($message);
    289                 $this->logger->debug(__METHOD__ . ' - ' . $order_id . ' - Order already completed at Mollie, can not be shipped/captured.');
     287                $this->logger->debug(__METHOD__ . ' - ' . $order_id . ' - ' . $mollie_transaction_type . ' already completed at Mollie, can not be shipped/captured.');
    290288                return;
    291289            }
    292             if ($mollie_order->isPaid() || $mollie_order->isAuthorized()) {
    293                 $this->apiHelper->getApiClient($apiKey)->orders->get($mollie_order_id)->shipAll();
     290            if ($mollie_transaction->isPaid() || $mollie_transaction->isAuthorized()) {
     291                if (substr($mollie_transaction_id, 0, 3) === 'tr_') {
     292                    if ($mollie_transaction->isAuthorized()) {
     293                        $this->container->get(CapturePayment::class)($order_id);
     294                    } else {
     295                        $message = _x('Payment status is already paid at Mollie, can not be captured.', 'Order note info', 'mollie-payments-for-woocommerce');
     296                        $order->add_order_note($message);
     297                        $this->logger->debug(__METHOD__ . ' - ' . $order_id . ' - Payment already completed at Mollie, can not be captured.');
     298                    }
     299                    return;
     300                }
     301                $this->apiHelper->getApiClient($apiKey)->orders->get($mollie_transaction_id)->shipAll();
    294302                $message = _x('Order successfully updated to shipped at Mollie, capture of funds underway.', 'Order note info', 'mollie-payments-for-woocommerce');
    295303                $order->add_order_note($message);
     
    297305                return;
    298306            }
    299             $message = _x('Order not paid or authorized at Mollie yet, can not be shipped.', 'Order note info', 'mollie-payments-for-woocommerce');
     307            $message = _x('Transaction not paid or authorized at Mollie yet, can not be shipped.', 'Order note info', 'mollie-payments-for-woocommerce');
    300308            $order->add_order_note($message);
    301             $this->logger->debug(__METHOD__ . ' - ' . $order_id . ' - Order not paid or authorized at Mollie yet, can not be shipped.');
     309            $this->logger->debug(__METHOD__ . ' - ' . $order_id . ' - ' . $mollie_transaction_type . ' not paid or authorized at Mollie yet, can not be shipped.');
    302310        } catch (ApiException $e) {
    303311            $this->logger->debug(__METHOD__ . ' - ' . $order_id . ' - Processing shipment & capture failed, error: ' . $e->getMessage());
  • mollie-payments-for-woocommerce/trunk/src/PaymentMethods/AbstractPaymentMethod.php

    r3226701 r3262577  
    44namespace Mollie\WooCommerce\PaymentMethods;
    55
    6 use Mollie\WooCommerce\Gateway\MolliePaymentGateway;
     6use Mollie\Inpsyde\PaymentGateway\Icon;
     7use Mollie\Inpsyde\PaymentGateway\IconProviderInterface;
     8use Mollie\Inpsyde\PaymentGateway\Method\CustomSettingsFields;
     9use Mollie\Inpsyde\PaymentGateway\Method\CustomSettingsFieldsDefinition;
     10use Mollie\Inpsyde\PaymentGateway\Method\DefaultPaymentMethodDefinitionTrait;
     11use Mollie\Inpsyde\PaymentGateway\Method\PaymentMethodDefinition;
     12use Mollie\Inpsyde\PaymentGateway\PaymentFieldsRendererInterface;
     13use Mollie\Inpsyde\PaymentGateway\PaymentProcessorInterface;
     14use Mollie\Inpsyde\PaymentGateway\PaymentRequestValidatorInterface;
     15use Mollie\Inpsyde\PaymentGateway\RefundProcessorInterface;
     16use Mollie\Inpsyde\PaymentGateway\StaticIconProvider;
    717use Mollie\WooCommerce\Gateway\Surcharge;
    8 use Mollie\WooCommerce\Payment\PaymentFieldsService;
    9 use Mollie\WooCommerce\Settings\Settings;
     18use Mollie\WooCommerce\Payment\PaymentProcessor;
     19use Mollie\WooCommerce\Settings\General\MultiCountrySettingsField;
    1020use Mollie\WooCommerce\Shared\SharedDataDictionary;
    11 abstract class AbstractPaymentMethod implements \Mollie\WooCommerce\PaymentMethods\PaymentMethodI
     21use Mollie\Psr\Container\ContainerInterface;
     22use Mollie\WooCommerce\PaymentMethods\Icon\GatewayIconsRenderer;
     23use Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies\NoopPaymentFieldsRenderer;
     24use Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies\DefaultFieldsStrategy;
     25abstract class AbstractPaymentMethod implements \Mollie\WooCommerce\PaymentMethods\PaymentMethodI, PaymentMethodDefinition
    1226{
    13     /**
    14      * @var string
    15      */
    16     protected $id;
     27    use DefaultPaymentMethodDefinitionTrait;
    1728    /**
    1829     * @var string[]
     
    2334     */
    2435    protected $settings = [];
    25     /**
    26      * @var IconFactory
    27      */
    28     protected $iconFactory;
    29     /**
    30      * @var Settings
    31      */
    32     protected $settingsHelper;
    33     /**
    34      * @var PaymentFieldsService
    35      */
    36     protected $paymentFieldsService;
    37     /**
    38      * @var Surcharge
    39      */
    4036    protected $surcharge;
    4137    /**
    42      * @var array
    43      */
    44     private $apiPaymentMethod;
    45     /**
    4638     * @var bool
    4739     */
    4840    protected bool $translationsInitialized = \false;
    49     public function __construct(\Mollie\WooCommerce\PaymentMethods\IconFactory $iconFactory, Settings $settingsHelper, PaymentFieldsService $paymentFieldsService, Surcharge $surcharge, array $apiPaymentMethod)
    50     {
    51         $this->id = $this->getIdFromConfig();
    52         $this->iconFactory = $iconFactory;
    53         $this->settingsHelper = $settingsHelper;
    54         $this->paymentFieldsService = $paymentFieldsService;
    55         $this->surcharge = $surcharge;
     41    public function __construct()
     42    {
    5643        $this->config = $this->getConfig();
    5744        $this->settings = $this->getSettings();
    58         $this->apiPaymentMethod = $apiPaymentMethod;
    59         add_action('init', [$this, 'initializeTranslations']);
    60         add_action('init', [$this, 'updateSettingsWithDefaults']);
    61     }
    62     public function title(): string
    63     {
    64         $useApiTitle = apply_filters('mollie_wc_gateway_use_api_title', $this->isUseApiTitleChecked(), $this->id);
     45        $this->surcharge = new Surcharge();
     46    }
     47    public function title(ContainerInterface $container): string
     48    {
     49        $useApiTitle = apply_filters('mollie_wc_gateway_use_api_title', $this->isUseApiTitleChecked(), $this->getIdFromConfig());
    6550        $title = $this->getProperty('title');
    6651        //new installations should use the api title
    6752        if ($useApiTitle || $title === \false) {
    68             return $this->getApiTitle();
     53            return $this->getApiTitle($container);
    6954        }
    7055        return $title;
     
    7661    public function getIdFromConfig(): string
    7762    {
    78         return $this->getConfig()['id'];
     63        $config = $this->getConfig();
     64        return $config['id'];
    7965    }
    8066    public function getUploadedImage()
     
    11399    }
    114100    /**
    115      * Payment method custom icon url
    116      * @return string
    117      */
    118     public function getIconUrl(): string
    119     {
    120         if ($uploadedImageUrl = $this->getUploadedImage()) {
    121             return $this->iconFactory->getExternalIconHtml($uploadedImageUrl);
    122         }
    123         $useAPIImage = apply_filters('mollie_wc_gateway_use_api_icon', $this->isUseApiTitleChecked(), $this->id);
    124         if (isset($this->apiPaymentMethod["image"]) && property_exists($this->apiPaymentMethod["image"], "svg") && !$this->isCreditCardSelectorEnabled() && $useAPIImage) {
    125             return $this->iconFactory->getExternalIconHtml($this->apiPaymentMethod["image"]->svg);
    126         }
    127         return $this->iconFactory->getIconUrl($this->getIdFromConfig());
    128     }
    129     /**
    130101     * Check if payment method should show any icon
    131102     * @return bool
     
    135106        $defaultIconSetting = \true;
    136107        return $this->hasProperty('display_logo') ? $this->getProperty('display_logo') === 'yes' : $defaultIconSetting;
    137     }
    138     /**
    139      * Settings that apply to all payment methods
    140      * @return array
    141      */
    142     public function getSharedFormFields()
    143     {
    144         $defaultTitle = $this->getApiTitle();
    145         return $this->settingsHelper->generalFormFields($defaultTitle, $this->config['defaultDescription'], $this->config['confirmationDelayed']);
    146     }
    147     /**
    148      * Settings specific to every payment method
    149      * @return mixed
    150      */
    151     public function getAllFormFields()
    152     {
    153         return $this->getFormFields($this->getSharedFormFields());
    154     }
    155     /**
    156      * Sets the gateway's payment fields strategy based on payment method
    157      * @param $gateway
    158      * @return void
    159      */
    160     public function paymentFieldsStrategy($gateway)
    161     {
    162         $this->paymentFieldsService->setStrategy($this);
    163         $this->paymentFieldsService->executeStrategy($gateway);
    164     }
    165     /**
    166      * @return PaymentFieldsService
    167      */
    168     public function paymentFieldsService(): PaymentFieldsService
    169     {
    170         return $this->paymentFieldsService;
    171108    }
    172109    /**
     
    194131    public function getSettings(): array
    195132    {
    196         $optionName = 'mollie_wc_gateway_' . $this->id . '_settings';
     133        $optionName = 'mollie_wc_gateway_' . $this->getIdFromConfig() . '_settings';
    197134        $settings = get_option($optionName, \false);
    198135        if (!$settings) {
     
    205142     * @return array
    206143     */
    207     public function updateSettingsWithDefaults(): array
    208     {
    209         $optionName = 'mollie_wc_gateway_' . $this->id . '_settings';
     144    public function updateSettingsWithDefaults(ContainerInterface $container): array
     145    {
     146        $optionName = 'mollie_wc_gateway_' . $this->getIdFromConfig() . '_settings';
    210147        $settings = get_option($optionName, \false);
    211148        if (!$settings) {
    212             $settings = $this->defaultSettings();
     149            $settings = $this->defaultSettings($container);
    213150            update_option($optionName, $settings, \true);
    214151        }
    215152        return $settings;
    216     }
    217     /**
    218      * Order status for cancelled payments setting
    219      *
    220      * @return string|null
    221      */
    222     public function getOrderStatusCancelledPayments()
    223     {
    224         return $this->settingsHelper->getOrderStatusCancelledPayments();
    225153    }
    226154    /**
     
    268196     * @return array
    269197     */
    270     public function defaultSettings(): array
    271     {
    272         $fields = $this->getAllFormFields();
     198    public function defaultSettings(ContainerInterface $container): array
     199    {
     200        $defaultTitle = $this->getApiTitle($container);
     201        $settingsHelper = $container->get('settings.settings_helper');
     202        $generalFormFields = $settingsHelper->generalFormFields($defaultTitle, $this->config['defaultDescription'], $this->config['confirmationDelayed']);
     203        $fields = $this->getFormFields($generalFormFields);
    273204        //remove setting title fields
    274205        $fields = array_filter($fields, static function ($field) {
     
    280211        return array_combine(array_keys($fields), array_column($fields, 'default')) ?: [];
    281212    }
    282     /**
    283      * Update the payment method's settings
    284      * @param string $optionName
    285      * @param string $newValue
    286      * @return void
    287      */
    288     public function updateMethodOption(string $optionName, string $newValue)
    289     {
    290         $settingName = 'mollie_wc_gateway_' . $this->id . '_settings';
    291         $settings = get_option($settingName, \false);
    292         $settings[$optionName] = $newValue;
    293         update_option($settingName, $settings, \true);
    294     }
    295     private function getApiTitle()
    296     {
    297         $apiTitle = $this->apiPaymentMethod['description'] ?? null;
     213    private function getApiTitle(ContainerInterface $container): string
     214    {
     215        $apiMethod = $container->get('gateway.getPaymentMethodsAfterFeatureFlag')[$this->getIdFromConfig()];
     216        $apiTitle = $apiMethod['description'] ?? null;
    298217        return $apiTitle ?: $this->config['defaultTitle'];
    299218    }
     
    310229        return $savedTitle === $this->config['defaultTitle'];
    311230    }
     231    public function id(): string
     232    {
     233        return 'mollie_wc_gateway_' . $this->getIdFromConfig();
     234    }
     235    public function paymentProcessor(ContainerInterface $container): PaymentProcessorInterface
     236    {
     237        return $container->get(PaymentProcessor::class);
     238    }
     239    public function paymentRequestValidator(ContainerInterface $container): PaymentRequestValidatorInterface
     240    {
     241        return $container->get('payment_gateways.noop_payment_request_validator');
     242    }
     243    public function methodTitle(ContainerInterface $container): string
     244    {
     245        return 'Mollie - ' . $this->title($container);
     246    }
     247    public function description(ContainerInterface $container): string
     248    {
     249        $description = $this->getProcessedDescription();
     250        return empty($description) ? '' : $description;
     251    }
     252    public function methodDescription(ContainerInterface $container): string
     253    {
     254        return $this->getProperty('settingsDescription');
     255    }
     256    /**
     257     * @inheritDoc
     258     */
     259    public function availabilityCallback(ContainerInterface $container): callable
     260    {
     261        $gatewayInstances = $container->get('__deprecated.gateway_helpers');
     262        $gatewayId = $this->id();
     263        return static function ($gateway) use ($gatewayInstances, $gatewayId) {
     264            return $gatewayInstances[$gatewayId]->is_available($gateway);
     265        };
     266    }
     267    public function supports(ContainerInterface $container): array
     268    {
     269        $supports = $this->getProperty('supports');
     270        $isSepa = $this->getProperty('SEPA') === \true;
     271        $isSubscription = $this->getProperty('Subscription') === \true;
     272        $subscriptionHooks = $container->get('gateway.subscriptionsSupports');
     273        if ($isSepa || $isSubscription) {
     274            $supports = array_merge($supports, $subscriptionHooks);
     275        }
     276        return $supports;
     277    }
     278    public function refundProcessor(ContainerInterface $container): RefundProcessorInterface
     279    {
     280        $supports = $this->getProperty('supports');
     281        $supportsRefunds = $supports && in_array('refunds', $supports, \true);
     282        if ($supportsRefunds) {
     283            return $container->get('payment_gateway.getRefundProcessor')($this->getIdFromConfig());
     284        }
     285        return $container->get('payment_gateways.noop_refund_processor');
     286    }
     287    public function paymentMethodIconProvider(ContainerInterface $container): IconProviderInterface
     288    {
     289        $iconFactory = $container->get(\Mollie\WooCommerce\PaymentMethods\IconFactory::class);
     290        $url = $iconFactory->getIconUrl($this->getIdFromConfig());
     291        if ($uploadedImageUrl = $this->getUploadedImage()) {
     292            $url = $iconFactory->getExternalIconHtml($uploadedImageUrl);
     293        }
     294        $useAPIImage = apply_filters('mollie_wc_gateway_use_api_icon', $this->isUseApiTitleChecked(), $this->getIdFromConfig());
     295        if (isset($this->apiPaymentMethod["image"]) && property_exists($this->apiPaymentMethod["image"], "svg") && !$this->isCreditCardSelectorEnabled() && $useAPIImage) {
     296            $url = $iconFactory->getExternalIconHtml($this->apiPaymentMethod["image"]->svg);
     297        }
     298        $alt = $this->getIdFromConfig() . ' icon';
     299        $icon = new Icon($this->getIdFromConfig(), $url, $alt);
     300        return new StaticIconProvider($icon);
     301    }
     302    public function gatewayIconsRenderer(ContainerInterface $container): \Mollie\Inpsyde\PaymentGateway\GatewayIconsRendererInterface
     303    {
     304        return new GatewayIconsRenderer($this, $this->paymentMethodIconProvider($container));
     305    }
     306    public function paymentFieldsRenderer(ContainerInterface $container): PaymentFieldsRendererInterface
     307    {
     308        $oldGatewayInstances = $container->get('__deprecated.gateway_helpers');
     309        //not all payment methods have a gateway
     310        if (!isset($oldGatewayInstances[$this->id()])) {
     311            return new NoopPaymentFieldsRenderer();
     312        }
     313        $gatewayDescription = $container->get('payment_gateway.' . $this->id() . '.description');
     314        $dataHelper = $container->get('settings.data_helper');
     315        $deprecatedGatewayHelper = $oldGatewayInstances[$this->id()];
     316        if (!$this->getProperty('paymentFields')) {
     317            return new DefaultFieldsStrategy($deprecatedGatewayHelper, $gatewayDescription, $dataHelper);
     318        } else {
     319            $className = 'Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies\\' . ucfirst($this->getIdFromConfig()) . 'FieldsStrategy';
     320            return class_exists($className) ? new $className($deprecatedGatewayHelper, $gatewayDescription, $dataHelper) : new DefaultFieldsStrategy($deprecatedGatewayHelper, $gatewayDescription, $dataHelper);
     321        }
     322    }
     323    public function hasFields(ContainerInterface $container): bool
     324    {
     325        $hasFields = $this->hasPaymentFields();
     326        if ($hasFields) {
     327            return \true;
     328        }
     329        /* Override show issuers dropdown? */
     330        $dropdownEnabled = $this->getProperty('issuers_dropdown_shown') === 'yes';
     331        if ($dropdownEnabled) {
     332            return \true;
     333        }
     334        return \false;
     335    }
     336    public function formFields(ContainerInterface $container): array
     337    {
     338        $defaultTitle = $this->getApiTitle($container);
     339        $settingsHelper = $container->get('settings.settings_helper');
     340        $generalFormFields = $settingsHelper->generalFormFields($defaultTitle, $this->config['defaultDescription'], $this->config['confirmationDelayed']);
     341        return $this->getFormFields($generalFormFields);
     342    }
     343    public function optionKey(ContainerInterface $container): string
     344    {
     345        return $this->id() . '_settings';
     346    }
     347    public function registerBlocks(ContainerInterface $container): bool
     348    {
     349        //we handle it outside for the moment
     350        return \false;
     351    }
     352    public function orderButtonText(ContainerInterface $container): string
     353    {
     354        return '';
     355    }
     356    public function customSettings(): CustomSettingsFieldsDefinition
     357    {
     358        return new CustomSettingsFields(['multi_select_countries' => function () {
     359            return new MultiCountrySettingsField($this);
     360        }], []);
     361    }
     362    public function icon(ContainerInterface $container): string
     363    {
     364        return '';
     365    }
    312366}
  • mollie-payments-for-woocommerce/trunk/src/PaymentMethods/Alma.php

    r3226701 r3262577  
    88    protected function getConfig(): array
    99    {
    10         return ['id' => 'alma', 'defaultTitle' => 'Alma', 'settingsDescription' => '', 'defaultDescription' => '', 'paymentFields' => \false, 'instructions' => \false, 'supports' => ['products', 'refunds'], 'filtersOnBuild' => \false, 'confirmationDelayed' => \false, 'SEPA' => \false, 'paymentAPIfields' => ['billingAddress', 'shippingAddress'], 'docs' => 'https://www.mollie.com/gb/payments/alma'];
     10        return ['id' => 'alma', 'defaultTitle' => 'Alma', 'settingsDescription' => '', 'defaultDescription' => '', 'paymentFields' => \false, 'instructions' => \false, 'supports' => ['products', 'refunds'], 'filtersOnBuild' => \false, 'confirmationDelayed' => \false, 'SEPA' => \false, 'paymentAPIfields' => ['AddressMiddleware'], 'docs' => 'https://www.mollie.com/gb/payments/alma'];
    1111    }
    1212    // Replace translatable strings after the 'after_setup_theme' hook
  • mollie-payments-for-woocommerce/trunk/src/PaymentMethods/Applepay.php

    r3226701 r3262577  
    2424        $checkout_page_id = wc_get_page_id('checkout');
    2525        $edit_checkout_page_link = get_edit_post_link($checkout_page_id);
    26         $notice = ['notice' => ['title' => sprintf(
    27             /* translators: Placeholder 1: link url */
    28             __('<p>The appearance of the Apple Pay button can be controlled in the <a href="%1$s">Checkout page editor</a>.</p>', 'mollie-payments-for-woocommerce'),
    29             esc_url($edit_checkout_page_link)
    30         ), 'type' => 'title', 'class' => 'notice notice-warning', 'css' => 'padding:20px;']];
     26        if ($edit_checkout_page_link) {
     27            $notice = ['notice' => ['title' => sprintf(
     28                /* translators: Placeholder 1: link url */
     29                __('<p>The appearance of the Apple Pay button can be controlled in the <a href="%1$s">Checkout page editor</a>.</p>', 'mollie-payments-for-woocommerce'),
     30                esc_url($edit_checkout_page_link)
     31            ), 'type' => 'title', 'class' => 'notice notice-warning', 'css' => 'padding:20px;']];
     32        } else {
     33            $notice = [];
     34        }
    3135        $paymentMethodFormFieds = ['mollie_apple_pay_button_enabled_cart' => ['title' => __('Enable Apple Pay Button on Cart page', 'mollie-payments-for-woocommerce'), 'desc' => __('Enable the Apple Pay direct buy button on the Cart page', 'mollie-payments-for-woocommerce'), 'type' => 'checkbox', 'default' => 'no'], 'mollie_apple_pay_button_enabled_product' => ['title' => __('Enable Apple Pay Button on Product page', 'mollie-payments-for-woocommerce'), 'desc' => __('Enable the Apple Pay direct buy button on the Product page', 'mollie-payments-for-woocommerce'), 'type' => 'checkbox', 'default' => 'no'], 'mollie_apple_pay_button_enabled_express_checkout' => ['title' => __('Enable Apple Pay Express Button on Checkout page', 'mollie-payments-for-woocommerce'), 'desc' => __('Enable the Apple Pay direct buy button on the Express Buttons section of the Checkout page', 'mollie-payments-for-woocommerce'), 'type' => 'checkbox', 'default' => 'no']];
    3236        return array_merge($notice, $generalFormFields, $paymentMethodFormFieds);
  • mollie-payments-for-woocommerce/trunk/src/PaymentMethods/Billie.php

    r3226701 r3262577  
    1818    protected function getConfig(): array
    1919    {
    20         return ['id' => 'billie', 'defaultTitle' => 'Billie', 'settingsDescription' => 'To accept payments via Billie, all default WooCommerce checkout fields should be enabled and required.', 'defaultDescription' => '', 'paymentFields' => \true, 'instructions' => \false, 'supports' => ['products', 'refunds'], 'filtersOnBuild' => \true, 'confirmationDelayed' => \false, 'SEPA' => \false, 'orderMandatory' => \true, 'errorMessage' => 'Company field is empty. The company field is required.', 'companyPlaceholder' => 'Please enter your company name here.', 'docs' => 'https://www.mollie.com/gb/payments/billie'];
     20        return ['id' => 'billie', 'defaultTitle' => 'Billie', 'settingsDescription' => 'To accept payments via Billie, all default WooCommerce checkout fields should be enabled and required.', 'defaultDescription' => '', 'paymentFields' => \true, 'instructions' => \false, 'supports' => ['products', 'refunds'], 'filtersOnBuild' => \true, 'confirmationDelayed' => \false, 'SEPA' => \false, 'orderMandatory' => !apply_filters('inpsyde.feature-flags.mollie-woocommerce.billie_payments_api', \true), 'paymentCaptureMode' => 'manual', 'errorMessage' => 'Company field is empty. The company field is required.', 'companyPlaceholder' => 'Please enter your company name here.', 'docs' => 'https://www.mollie.com/gb/payments/billie'];
    2121    }
    2222    // Replace translatable strings after the 'after_setup_theme' hook
  • mollie-payments-for-woocommerce/trunk/src/PaymentMethods/Klarna.php

    r3226701 r3262577  
    88    protected function getConfig(): array
    99    {
    10         return ['id' => 'klarna', 'defaultTitle' => 'Pay with Klarna', 'settingsDescription' => 'To accept payments via Klarna, all default WooCommerce checkout fields should be enabled and required.', 'defaultDescription' => '', 'paymentFields' => \false, 'instructions' => \false, 'supports' => ['products', 'refunds'], 'filtersOnBuild' => \false, 'confirmationDelayed' => \false, 'SEPA' => \false, 'orderMandatory' => \true, 'docs' => 'https://www.mollie.com/gb/payments/klarna'];
     10        return ['id' => 'klarna', 'defaultTitle' => 'Pay with Klarna', 'settingsDescription' => 'To accept payments via Klarna, all default WooCommerce checkout fields should be enabled and required.', 'defaultDescription' => '', 'paymentFields' => \false, 'instructions' => \false, 'supports' => ['products', 'refunds'], 'confirmationDelayed' => \false, 'SEPA' => \false, 'orderMandatory' => !apply_filters('inpsyde.feature-flags.mollie-woocommerce.klarna_payments_api', \true), 'paymentCaptureMode' => 'manual', 'docs' => 'https://www.mollie.com/gb/payments/klarna'];
    1111    }
    1212    public function initializeTranslations(): void
  • mollie-payments-for-woocommerce/trunk/src/PaymentMethods/PaymentFieldsStrategies/BancomatpayFieldsStrategy.php

    r3164004 r3262577  
    44namespace Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies;
    55
    6 class BancomatpayFieldsStrategy implements \Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies\PaymentFieldsStrategyI
     6use Mollie\Inpsyde\PaymentGateway\PaymentFieldsRendererInterface;
     7class BancomatpayFieldsStrategy extends \Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies\AbstractPaymentFieldsRenderer implements PaymentFieldsRendererInterface
    78{
    89    const FIELD_PHONE = "billing_phone_bancomatpay";
    9     public function execute($gateway, $dataHelper)
     10    public function renderFields(): string
    1011    {
    1112        $showPhoneField = \false;
     
    2122        }
    2223        if ($showPhoneField) {
    23             $this->phoneNumber($phoneValue);
     24            return $this->gatewayDescription . $this->phoneNumber($phoneValue);
    2425        }
     26        return $this->gatewayDescription;
    2527    }
    2628    protected function getOrderIdOnPayForOrderPage()
     
    3335    {
    3436        $phoneValue = $phoneValue ?: '';
    35         ?>
    36         <p class="form-row form-row-wide" id="billing_phone_field">
    37             <label for="<?php
    38         echo esc_attr(self::FIELD_PHONE);
    39         ?>" class=""><?php
    40         echo esc_html__('Phone', 'mollie-payments-for-woocommerce');
    41         ?>
    42                 <abbr class="required" title="required">*</abbr>
    43             </label>
    44             <span class="woocommerce-input-wrapper">
    45         <input type="tel" class="input-text " name="<?php
    46         echo esc_attr(self::FIELD_PHONE);
    47         ?>" id="<?php
    48         echo esc_attr(self::FIELD_PHONE);
    49         ?>"
    50                placeholder="+39xxxxxxxxx"
    51                value="<?php
    52         echo esc_attr($phoneValue);
    53         ?>" autocomplete="phone">
    54         </span>
    55         </p>
    56         <?php
     37        return '
     38            <p class="form-row form-row-wide" id="billing_phone_field">
     39                <label for="' . esc_attr(self::FIELD_PHONE) . '" class="">' . esc_html__('Phone', 'mollie-payments-for-woocommerce') . '
     40                    <abbr class="required" title="required">*</abbr>
     41                </label>
     42                <span class="woocommerce-input-wrapper">
     43                    <input type="tel" class="input-text" name="' . esc_attr(self::FIELD_PHONE) . '" id="' . esc_attr(self::FIELD_PHONE) . '"
     44                           placeholder="+39xxxxxxxxx"
     45                           value="' . esc_attr($phoneValue) . '" autocomplete="phone">
     46                </span>
     47            </p>';
    5748    }
    5849    public function getFieldMarkup($gateway, $dataHelper)
  • mollie-payments-for-woocommerce/trunk/src/PaymentMethods/PaymentFieldsStrategies/BillieFieldsStrategy.php

    r3226701 r3262577  
    44namespace Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies;
    55
    6 class BillieFieldsStrategy implements \Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies\PaymentFieldsStrategyI
     6use Mollie\Inpsyde\PaymentGateway\PaymentFieldsRendererInterface;
     7class BillieFieldsStrategy extends \Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies\AbstractPaymentFieldsRenderer implements PaymentFieldsRendererInterface
    78{
    89    public const FIELD_COMPANY = 'billing_company_billie';
    9     public function execute($gateway, $dataHelper)
     10    public function renderFields(): string
    1011    {
    1112        $showCompanyField = \false;
     
    2021        }
    2122        if ($showCompanyField) {
    22             $this->company();
     23            return $this->gatewayDescription . $this->company();
    2324        }
     25        return $this->gatewayDescription;
    2426    }
    2527    protected function getOrderIdOnPayForOrderPage()
     
    3133    protected function company()
    3234    {
    33         ?>
    34         <p class="form-row form-row-wide" id="billing_company_field">
    35             <label for="<?php
    36         echo esc_attr(self::FIELD_COMPANY);
    37         ?>" class=""><?php
    38         echo esc_html__('Company', 'mollie-payments-for-woocommerce');
    39         ?>
    40                 <abbr class="required" title="required">*</abbr>
    41             </label>
    42             <span class="woocommerce-input-wrapper">
    43         <input type="tel" class="input-text " name="<?php
    44         echo esc_attr(self::FIELD_COMPANY);
    45         ?>" id="<?php
    46         echo esc_attr(self::FIELD_COMPANY);
    47         ?>"
    48                placeholder="Company name"
    49                value="" autocomplete="organization">
     35        return '
     36    <p class="form-row form-row-wide" id="billing_company_field">
     37        <label for="' . esc_attr(self::FIELD_COMPANY) . '" class="">' . esc_html__('Company', 'mollie-payments-for-woocommerce') . '
     38            <abbr class="required" title="required">*</abbr>
     39        </label>
     40        <span class="woocommerce-input-wrapper">
     41            <input type="tel" class="input-text" name="' . esc_attr(self::FIELD_COMPANY) . '" id="' . esc_attr(self::FIELD_COMPANY) . '"
     42                   placeholder="Company name"
     43                   value="" autocomplete="organization">
    5044        </span>
    51         </p>
    52         <?php
     45    </p>';
    5346    }
    5447    public function getFieldMarkup($gateway, $dataHelper)
    5548    {
    56         return "";
     49        return '';
    5750    }
    5851    /**
  • mollie-payments-for-woocommerce/trunk/src/PaymentMethods/PaymentFieldsStrategies/CreditcardFieldsStrategy.php

    r3164004 r3262577  
    44namespace Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies;
    55
     6use Mollie\Inpsyde\PaymentGateway\PaymentFieldsRendererInterface;
    67use Mollie\WooCommerce\PaymentMethods\PaymentMethodI;
    7 class CreditcardFieldsStrategy implements \Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies\PaymentFieldsStrategyI
     8class CreditcardFieldsStrategy extends \Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies\AbstractPaymentFieldsRenderer implements PaymentFieldsRendererInterface
    89{
    9     public function execute($gateway, $dataHelper)
     10    public function renderFields(): string
    1011    {
    11         if (!$this->isMollieComponentsEnabled($gateway->paymentMethod())) {
    12             return;
     12        if (!$this->isMollieComponentsEnabled($this->deprecatedHelperGateway->paymentMethod())) {
     13            return $this->gatewayDescription;
    1314        }
    14         $gateway->has_fields = \true;
    1515        $allowedHtml = $this->svgAllowedHtml();
    16         ?>
    17         <div class="mollie-components"></div>
    18         <p class="mollie-components-description">
    19             <?php
    20         printf(
    21             /* translators: Placeholder 1: Lock icon. Placeholder 2: Mollie logo. */
    22             esc_html(__('%1$s Secure payments provided by %2$s', 'mollie-payments-for-woocommerce')),
    23             wp_kses($this->lockIcon($dataHelper), $allowedHtml),
    24             wp_kses($this->mollieLogo($dataHelper), $allowedHtml)
    25         );
    26         ?>
    27         </p>
    28         <?php
     16        $output = $this->gatewayDescription;
     17        $output .= '<div class="mollie-components"></div>';
     18        $output .= '<p class="mollie-components-description">';
     19        $output .= sprintf(esc_html__('%1$s Secure payments provided by %2$s', 'mollie-payments-for-woocommerce'), wp_kses($this->lockIcon($this->dataHelper), $allowedHtml), wp_kses($this->mollieLogo($this->dataHelper), $allowedHtml));
     20        $output .= '</p>';
     21        return $output;
    2922    }
    3023    public function getFieldMarkup($gateway, $dataHelper)
     
    4033    protected function isMollieComponentsEnabled(PaymentMethodI $paymentMethod): bool
    4134    {
    42         return $paymentMethod->hasPaymentFields();
     35        $hasComponentsEnabled = $paymentMethod->getProperty('mollie_components_enabled');
     36        return $hasComponentsEnabled === 'yes';
    4337    }
    4438    protected function lockIcon($dataHelper)
  • mollie-payments-for-woocommerce/trunk/src/PaymentMethods/PaymentFieldsStrategies/DefaultFieldsStrategy.php

    r3164004 r3262577  
    44namespace Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies;
    55
    6 class DefaultFieldsStrategy implements \Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies\PaymentFieldsStrategyI
     6use Mollie\Inpsyde\PaymentGateway\PaymentFieldsRendererInterface;
     7class DefaultFieldsStrategy extends \Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies\AbstractPaymentFieldsRenderer implements PaymentFieldsRendererInterface
    78{
    8     public function execute($gateway, $dataHelper)
     9    public function renderFields(): string
    910    {
     11        return $this->gatewayDescription;
    1012    }
    1113    public function getFieldMarkup($gateway, $dataHelper)
    1214    {
     15        return '';
    1316    }
    1417}
  • mollie-payments-for-woocommerce/trunk/src/PaymentMethods/PaymentFieldsStrategies/GiftcardFieldsStrategy.php

    r3164004 r3262577  
    44namespace Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies;
    55
    6 class GiftcardFieldsStrategy implements \Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies\PaymentFieldsStrategyI
     6use Mollie\Inpsyde\PaymentGateway\PaymentFieldsRendererInterface;
     7class GiftcardFieldsStrategy extends \Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies\AbstractPaymentFieldsRenderer implements PaymentFieldsRendererInterface
    78{
    89    use \Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies\IssuersDropdownBehavior;
    9     public function execute($gateway, $dataHelper)
     10    public function renderFields(): string
    1011    {
    11         if (!$this->dropDownEnabled($gateway)) {
    12             return;
     12        if (!$this->dropDownEnabled($this->deprecatedHelperGateway)) {
     13            return $this->gatewayDescription;
    1314        }
    14         $issuers = $this->getIssuers($gateway, $dataHelper);
     15        $issuers = $this->getIssuers($this->deprecatedHelperGateway, $this->dataHelper);
    1516        if (empty($issuers)) {
    16             return;
     17            return $this->gatewayDescription;
    1718        }
    18         $selectedIssuer = $gateway->getSelectedIssuer();
     19        $selectedIssuer = $this->getSelectedIssuer($this->deprecatedHelperGateway);
    1920        $html = '';
    2021        // If only one gift card issuers is available, show it without a dropdown
     
    2829            }
    2930            //phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
    30             echo wpautop(wptexturize($html));
    31             return;
     31            return $this->gatewayDescription . wpautop(wptexturize($html));
    3232        }
    33         $this->renderIssuers($gateway, $issuers, $selectedIssuer);
     33        return $this->gatewayDescription . $this->renderIssuers($this->deprecatedHelperGateway, $issuers, $selectedIssuer);
    3434    }
    3535    public function getFieldMarkup($gateway, $dataHelper)
     
    3939        }
    4040        $issuers = $this->getIssuers($gateway, $dataHelper);
    41         $selectedIssuer = $gateway->getSelectedIssuer();
     41        $selectedIssuer = $this->getSelectedIssuer($gateway);
    4242        $markup = $this->dropdownOptions($gateway, $issuers, $selectedIssuer);
    4343        return $markup;
  • mollie-payments-for-woocommerce/trunk/src/PaymentMethods/PaymentFieldsStrategies/In3FieldsStrategy.php

    r3164004 r3262577  
    44namespace Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies;
    55
    6 class In3FieldsStrategy implements \Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies\PaymentFieldsStrategyI
     6use Mollie\Inpsyde\PaymentGateway\PaymentFieldsRendererInterface;
     7class In3FieldsStrategy extends \Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies\AbstractPaymentFieldsRenderer implements PaymentFieldsRendererInterface
    78{
    89    use \Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies\PaymentFieldsStrategiesTrait;
    910    const FIELD_BIRTHDATE = "billing_birthdate_in3";
    1011    const FIELD_PHONE = "billing_phone_in3";
    11     public function execute($gateway, $dataHelper)
     12    public function renderFields(): string
    1213    {
    1314        $showBirthdateField = \false;
     
    1617        $phoneValue = \false;
    1718        $birthValue = \false;
     19        $html = $this->gatewayDescription;
    1820        if (is_checkout_pay_page()) {
    1921            $showBirthdateField = \true;
     
    3032        }
    3133        if ($showPhoneField) {
    32             $this->phoneNumber($phoneValue);
     34            $html .= $this->phoneNumber($phoneValue);
    3335        }
    3436        if ($showBirthdateField) {
    35             $this->dateOfBirth($birthValue);
     37            $html .= $this->dateOfBirth($birthValue);
    3638        }
     39        return $html;
    3740    }
    3841    protected function phoneNumber($phoneValue)
    3942    {
    4043        $phoneValue = $phoneValue ?: '';
    41         ?>
    42         <p class="form-row form-row-wide" id="billing_phone_field">
    43             <label for="<?php
    44         echo esc_attr(self::FIELD_PHONE);
    45         ?>" class=""><?php
    46         echo esc_html__('Phone', 'mollie-payments-for-woocommerce');
    47         ?>
    48             </label>
    49             <span class="woocommerce-input-wrapper">
    50         <input type="tel" class="input-text " name="<?php
    51         echo esc_attr(self::FIELD_PHONE);
    52         ?>" id="<?php
    53         echo esc_attr(self::FIELD_PHONE);
    54         ?>"
    55                placeholder="+316xxxxxxxx"
    56                value="<?php
    57         echo esc_attr($phoneValue);
    58         ?>" autocomplete="phone">
    59         </span>
    60         </p>
    61         <?php
     44        $html = '<p class="form-row form-row-wide" id="billing_phone_field">';
     45        $html .= '<label for="' . esc_attr(self::FIELD_PHONE) . '" class="">' . esc_html__('Phone', 'mollie-payments-for-woocommerce') . '</label>';
     46        $html .= '<span class="woocommerce-input-wrapper">';
     47        $html .= '<input type="tel" class="input-text " name="' . esc_attr(self::FIELD_PHONE) . '" id="' . esc_attr(self::FIELD_PHONE) . '" placeholder="+316xxxxxxxx" value="' . esc_attr($phoneValue) . '" autocomplete="phone">';
     48        $html .= '</span></p>';
     49        return $html;
    6250    }
    6351    public function getFieldMarkup($gateway, $dataHelper)
  • mollie-payments-for-woocommerce/trunk/src/PaymentMethods/PaymentFieldsStrategies/IssuersDropdownBehavior.php

    r3164004 r3262577  
    2121        return $dataHelper->getMethodIssuers($apiKey, $testMode, $gateway->paymentMethod()->getProperty('id'));
    2222    }
     23    /**
     24     * @return string|NULL
     25     */
     26    public function getSelectedIssuer($gateway): ?string
     27    {
     28        $issuer_id = 'mollie-payments-for-woocommerce' . '_issuer_' . $gateway->paymentMethod()->getIdFromConfig();
     29        //phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
     30        $postedIssuer = wc_clean(wp_unslash($_POST[$issuer_id] ?? ''));
     31        return !empty($postedIssuer) ? $postedIssuer : null;
     32    }
    2333    public function renderIssuers($gateway, $issuers, $selectedIssuer)
    2434    {
    2535        $html = $this->issuersDropdownMarkup($gateway, $issuers, $selectedIssuer);
    26         echo wp_kses($html, ['select' => ['name' => [], 'id' => [], 'class' => []], 'option' => ['value' => [], 'selected' => []]]);
     36        return wp_kses($html, ['select' => ['name' => [], 'id' => [], 'class' => []], 'option' => ['value' => [], 'selected' => []]]);
    2737    }
    2838    /**
  • mollie-payments-for-woocommerce/trunk/src/PaymentMethods/PaymentFieldsStrategies/KbcFieldsStrategy.php

    r3164004 r3262577  
    44namespace Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies;
    55
    6 class KbcFieldsStrategy implements \Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies\PaymentFieldsStrategyI
     6use Mollie\Inpsyde\PaymentGateway\PaymentFieldsRendererInterface;
     7class KbcFieldsStrategy extends \Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies\AbstractPaymentFieldsRenderer implements PaymentFieldsRendererInterface
    78{
    89    use \Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies\IssuersDropdownBehavior;
    9     public function execute($gateway, $dataHelper)
     10    public function renderFields(): string
    1011    {
    11         if (!$this->dropDownEnabled($gateway)) {
    12             return;
     12        if (!$this->dropDownEnabled($this->deprecatedHelperGateway)) {
     13            return $this->gatewayDescription;
    1314        }
    14         $issuers = $this->getIssuers($gateway, $dataHelper);
    15         $selectedIssuer = $gateway->getSelectedIssuer();
    16         $this->renderIssuers($gateway, $issuers, $selectedIssuer);
     15        $issuers = $this->getIssuers($this->deprecatedHelperGateway, $this->dataHelper);
     16        $selectedIssuer = $this->getSelectedIssuer($this->deprecatedHelperGateway);
     17        return $this->gatewayDescription . $this->renderIssuers($this->deprecatedHelperGateway, $issuers, $selectedIssuer);
    1718    }
    1819    public function getFieldMarkup($gateway, $dataHelper)
    1920    {
    2021        if (!$this->dropDownEnabled($gateway)) {
    21             return "";
     22            return '';
    2223        }
    2324        $issuers = $this->getIssuers($gateway, $dataHelper);
    24         $selectedIssuer = $gateway->getSelectedIssuer();
     25        $selectedIssuer = $this->getSelectedIssuer($gateway);
    2526        $markup = $this->dropdownOptions($gateway, $issuers, $selectedIssuer);
    2627        return $markup;
  • mollie-payments-for-woocommerce/trunk/src/PaymentMethods/PaymentFieldsStrategies/PaymentFieldsStrategiesTrait.php

    r3164004 r3262577  
    1414    {
    1515        $birthValue = $birthValue ?: '';
    16         ?>
    17         <p class="form-row form-row-wide" id="billing_birthdate_field">
    18             <label for="<?php
    19         echo esc_attr(self::FIELD_BIRTHDATE);
    20         ?>" class=""><?php
    21         echo esc_html__('Birthdate', 'mollie-payments-for-woocommerce');
    22         ?>
    23             </label>
    24             <span class="woocommerce-input-wrapper">
    25                 <input type="date" class="input-text " name="<?php
    26         echo esc_attr(self::FIELD_BIRTHDATE);
    27         ?>"
    28                        id="<?php
    29         echo esc_attr(self::FIELD_BIRTHDATE);
    30         ?>" value="<?php
    31         echo esc_attr($birthValue);
    32         ?>"
    33                        autocomplete="birthdate"></span>
    34         </p>
    35         <?php
     16        $html = '<p class="form-row form-row-wide" id="billing_birthdate_field">';
     17        $html .= '<label for="' . esc_attr(self::FIELD_BIRTHDATE) . '" class="">' . esc_html__('Birthdate', 'mollie-payments-for-woocommerce') . '</label>';
     18        $html .= '<span class="woocommerce-input-wrapper">';
     19        $html .= '<input type="date" class="input-text " name="' . esc_attr(self::FIELD_BIRTHDATE) . '" id="' . esc_attr(self::FIELD_BIRTHDATE) . '" value="' . esc_attr($birthValue) . '" autocomplete="birthdate">';
     20        $html .= '</span></p>';
     21        return $html;
    3622    }
    3723}
  • mollie-payments-for-woocommerce/trunk/src/PaymentMethods/PaymentFieldsStrategies/PaymentFieldsStrategyI.php

    r3164004 r3262577  
    66interface PaymentFieldsStrategyI
    77{
    8     public function execute($gateway, $dataHelper);
     8    public function execute($deprecatedHelperDeprecatedHelperGateway, $gatewayDescription, $dataHelper): string;
    99}
  • mollie-payments-for-woocommerce/trunk/src/PaymentMethods/PaymentFieldsStrategies/RivertyFieldsStrategy.php

    r3164004 r3262577  
    44namespace Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies;
    55
    6 class RivertyFieldsStrategy implements \Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies\PaymentFieldsStrategyI
     6use Mollie\Inpsyde\PaymentGateway\PaymentFieldsRendererInterface;
     7class RivertyFieldsStrategy extends \Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies\AbstractPaymentFieldsRenderer implements PaymentFieldsRendererInterface
    78{
    89    use \Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies\PaymentFieldsStrategiesTrait;
    910    const FIELD_BIRTHDATE = "billing_birthdate_riverty";
    1011    const FIELD_PHONE = "billing_phone_riverty";
    11     public function execute($gateway, $dataHelper)
     12    public function renderFields(): string
    1213    {
    1314        $showBirthdateField = \false;
     
    1617        $phoneValue = \false;
    1718        $birthValue = \false;
     19        $html = $this->gatewayDescription;
    1820        if (is_checkout_pay_page()) {
    1921            $showBirthdateField = \true;
     
    3032        }
    3133        if ($showPhoneField) {
    32             $this->phoneNumber($phoneValue);
     34            $html .= $this->phoneNumber($phoneValue);
    3335        }
    3436        if ($showBirthdateField) {
    35             $this->dateOfBirth($birthValue);
     37            $html .= $this->dateOfBirth($birthValue);
    3638        }
     39        return $html;
    3740    }
    3841    protected function phoneNumber($phoneValue)
     
    4245        $countryCodes = ['BE' => '+32xxxxxxxxx', 'NL' => '+316xxxxxxxx', 'DE' => '+49xxxxxxxxx', 'AT' => '+43xxxxxxxxx'];
    4346        $placeholder = in_array($country, array_keys($countryCodes)) ? $countryCodes[$country] : $countryCodes['NL'];
    44         ?>
    45         <p class="form-row form-row-wide" id="billing_phone_field">
    46             <label for="<?php
    47         echo esc_attr(self::FIELD_PHONE);
    48         ?>" class=""><?php
    49         echo esc_html__('Phone', 'mollie-payments-for-woocommerce');
    50         ?>
    51             </label>
    52             <span class="woocommerce-input-wrapper">
    53         <input type="tel" class="input-text " name="<?php
    54         echo esc_attr(self::FIELD_PHONE);
    55         ?>" id="<?php
    56         echo esc_attr(self::FIELD_PHONE);
    57         ?>"
    58                placeholder="<?php
    59         echo esc_attr($placeholder);
    60         ?>"
    61                value="<?php
    62         echo esc_attr($phoneValue);
    63         ?>" autocomplete="phone">
    64         </span>
    65         </p>
    66         <?php
     47        $html = '<p class="form-row form-row-wide" id="billing_phone_field">';
     48        $html .= '<label for="' . esc_attr(self::FIELD_PHONE) . '" class="">' . esc_html__('Phone', 'mollie-payments-for-woocommerce') . '</label>';
     49        $html .= '<span class="woocommerce-input-wrapper">';
     50        $html .= '<input type="tel" class="input-text " name="' . esc_attr(self::FIELD_PHONE) . '" id="' . esc_attr(self::FIELD_PHONE) . '" placeholder="' . esc_attr($placeholder) . '" value="' . esc_attr($phoneValue) . '" autocomplete="phone">';
     51        $html .= '</span></p>';
     52        return $html;
    6753    }
    6854    public function getFieldMarkup($gateway, $dataHelper)
  • mollie-payments-for-woocommerce/trunk/src/PaymentMethods/PaymentMethodI.php

    r3164004 r3262577  
    44namespace Mollie\WooCommerce\PaymentMethods;
    55
    6 use Mollie\WooCommerce\Payment\PaymentFieldsService;
     6use Mollie\Psr\Container\ContainerInterface;
    77interface PaymentMethodI
    88{
    99    public function getProperty(string $propertyName);
    1010    public function hasProperty(string $propertyName): bool;
    11     public function title(): string;
    12     public function hasPaymentFields(): bool;
    13     public function getProcessedDescriptionForBlock(): string;
    14     public function paymentFieldsService(): PaymentFieldsService;
    15     public function hasSurcharge(): bool;
    1611}
  • mollie-payments-for-woocommerce/trunk/src/PaymentMethods/PaymentMethodsIconUrl.php

    r3191126 r3262577  
    9696            return \false;
    9797        }
    98         if (!isset($gatewaySettings['iconFileUrl']) && !is_string($gatewaySettings['iconFileUrl'])) {
     98        if (!isset($gatewaySettings['iconFileUrl']) || !is_string($gatewaySettings['iconFileUrl'])) {
    9999            return \false;
    100100        }
  • mollie-payments-for-woocommerce/trunk/src/PaymentMethods/Riverty.php

    r3226701 r3262577  
    99    protected function getConfig(): array
    1010    {
    11         return ['id' => 'riverty', 'defaultTitle' => 'Riverty', 'settingsDescription' => 'To accept payments via Riverty, all default WooCommerce checkout fields should be enabled and required.', 'defaultDescription' => '', 'paymentFields' => \true, 'additionalFields' => ['birthdate', 'phone'], 'instructions' => \false, 'supports' => ['products', 'refunds'], 'filtersOnBuild' => \true, 'confirmationDelayed' => \false, 'SEPA' => \false, 'orderMandatory' => \true, 'phonePlaceholder' => 'Please enter your phone here. +316xxxxxxxx', 'mollie-payments-for-woocommerce', 'birthdatePlaceholder' => 'Please enter your birthdate here.', 'mollie-payments-for-woocommerce', 'docs' => 'https://www.mollie.com/gb/payments/riverty'];
     11        return ['id' => 'riverty', 'defaultTitle' => 'Riverty', 'settingsDescription' => 'To accept payments via Riverty, all default WooCommerce checkout fields should be enabled and required.', 'defaultDescription' => '', 'paymentFields' => \true, 'additionalFields' => ['birthdate', 'phone'], 'instructions' => \false, 'supports' => ['products', 'refunds'], 'filtersOnBuild' => \true, 'confirmationDelayed' => \false, 'SEPA' => \false, 'orderMandatory' => !apply_filters('inpsyde.feature-flags.mollie-woocommerce.riverty_payments_api', \true), 'paymentCaptureMode' => 'manual', 'phonePlaceholder' => 'Please enter your phone here. +316xxxxxxxx', 'mollie-payments-for-woocommerce', 'birthdatePlaceholder' => 'Please enter your birthdate here.', 'mollie-payments-for-woocommerce', 'docs' => 'https://www.mollie.com/gb/payments/riverty'];
    1212    }
    1313    // Replace translatable strings after the 'after_setup_theme' hook
  • mollie-payments-for-woocommerce/trunk/src/Settings/General/MollieGeneralSettings.php

    r3164004 r3262577  
    33namespace Mollie\WooCommerce\Settings\General;
    44
    5 use Mollie\WooCommerce\Gateway\MolliePaymentGateway;
     5use Mollie\WooCommerce\Gateway\MolliePaymentGatewayHandler;
    66use Mollie\WooCommerce\Gateway\Surcharge;
    77use Mollie\WooCommerce\Shared\SharedDataDictionary;
     
    2626            __('Payment method description that the customer will see on your checkout. Default <code>%s</code>', 'mollie-payments-for-woocommerce'),
    2727            $defaultDescription
    28         ), 'default' => $defaultDescription, 'desc_tip' => \true], 'sales' => ['id' => $defaultTitle . '_' . 'title', 'title' => __('Sales countries', 'mollie-payments-for-woocommerce'), 'type' => 'title'], 'allowed_countries' => ['title' => __('Sell to specific countries', 'mollie-payments-for-woocommerce'), 'desc' => '', 'css' => 'min-width: 350px;', 'default' => [], 'type' => 'multi_select_countries'], 'surcharge' => ['id' => $defaultTitle . '_' . 'surcharge', 'title' => sprintf(
     28        ), 'default' => $defaultDescription, 'desc_tip' => \true], 'sales' => ['id' => $defaultTitle . '_' . 'title', 'title' => __('Sales countries', 'mollie-payments-for-woocommerce'), 'type' => 'title'], 'allowed_countries' => ['title' => __('Sell to specific countries', 'mollie-payments-for-woocommerce'), 'desc' => '', 'css' => 'min-width: 350px;', 'default' => [], 'type' => 'multi_select_countries', 'sanitize_callback' => static function ($value) {
     29            return is_array($value) ? array_map('wc_clean', array_map('stripslashes', $value)) : '';
     30        }], 'surcharge' => ['id' => $defaultTitle . '_' . 'surcharge', 'title' => sprintf(
    2931            /* translators: Placeholder 1: Gateway title */
    3032            __('%s surcharge', 'mollie-payments-for-woocommerce'),
  • mollie-payments-for-woocommerce/trunk/src/Settings/MollieSettingsPage.php

    r3226701 r3262577  
    1010use Mollie\WooCommerce\Settings\Page\PagePaymentMethods;
    1111use Mollie\WooCommerce\Shared\Data;
     12use Mollie\Psr\Container\ContainerInterface;
    1213use WC_Admin_Settings;
    1314use WC_Settings_Page;
     
    2122    protected bool $isTestModeEnabled;
    2223    protected Data $dataHelper;
    23     public function __construct(\Mollie\WooCommerce\Settings\Settings $settings, string $pluginPath, string $pluginUrl, array $mollieGateways, array $paymentMethods, bool $isTestModeEnabled, Data $dataHelper)
     24    protected ContainerInterface $container;
     25    public function __construct(\Mollie\WooCommerce\Settings\Settings $settings, string $pluginPath, string $pluginUrl, array $mollieGateways, array $paymentMethods, bool $isTestModeEnabled, Data $dataHelper, ContainerInterface $container)
    2426    {
    2527        $this->id = 'mollie_settings';
     
    3234        $this->dataHelper = $dataHelper;
    3335        $this->paymentMethods = $paymentMethods;
     36        $this->container = $container;
    3437        $this->registerContentFieldType();
    3538        $this->outputSections();
     
    105108        foreach ($this->pages() as $pageClass) {
    106109            /** @var AbstractPage $page */
    107             $page = new $pageClass($this->settings, $this->pluginUrl, $this->pages(), $defaultSection, $connectionStatus, $this->isTestModeEnabled, $this->mollieGateways, $this->paymentMethods, $this->dataHelper);
     110            $page = new $pageClass($this->settings, $this->pluginUrl, $this->pages(), $defaultSection, $connectionStatus, $this->isTestModeEnabled, $this->mollieGateways, $this->paymentMethods, $this->dataHelper, $this->container);
    108111            if ($page::slug() === $defaultSection) {
    109112                $mollieSettings = $this->hideKeysIntoStars($page->settings());
  • mollie-payments-for-woocommerce/trunk/src/Settings/Page/AbstractPage.php

    r3191126 r3262577  
    77use Mollie\WooCommerce\Settings\Settings;
    88use Mollie\WooCommerce\Shared\Data;
     9use Mollie\Psr\Container\ContainerInterface;
    910abstract class AbstractPage
    1011{
     
    1819    protected array $paymentMethods;
    1920    protected Data $dataHelper;
    20     public function __construct(Settings $settings, string $pluginUrl, array $pages, string $currentSection, bool $connectionStatus, bool $testModeEnabled, array $mollieGateways, array $paymentMethods, Data $dataHelper)
     21    protected ContainerInterface $container;
     22    public function __construct(Settings $settings, string $pluginUrl, array $pages, string $currentSection, bool $connectionStatus, bool $testModeEnabled, array $mollieGateways, array $paymentMethods, Data $dataHelper, ContainerInterface $container)
    2123    {
    2224        $this->settings = $settings;
     
    2931        $this->paymentMethods = $paymentMethods;
    3032        $this->dataHelper = $dataHelper;
     33        $this->container = $container;
    3134    }
    3235    abstract public static function isTab(): bool;
     
    4649        foreach ($this->sections() as $sectionClass) {
    4750            /** @var AbstractSection $section */
    48             $section = new $sectionClass($this->settings, $this->pluginUrl, $this->pages, $this->currentSection, $this->connectionStatus, $this->testModeEnabled, $this->mollieGateways, $this->paymentMethods, $this->dataHelper);
     51            $section = new $sectionClass($this->settings, $this->pluginUrl, $this->pages, $this->currentSection, $this->connectionStatus, $this->testModeEnabled, $this->mollieGateways, $this->paymentMethods, $this->dataHelper, $this->container);
    4952            foreach ($section->config() as $field) {
    5053                $settings[] = $field;
  • mollie-payments-for-woocommerce/trunk/src/Settings/Page/Section/AbstractSection.php

    r3191126 r3262577  
    66use Mollie\WooCommerce\Settings\Settings;
    77use Mollie\WooCommerce\Shared\Data;
     8use Mollie\Psr\Container\ContainerInterface;
    89abstract class AbstractSection
    910{
     
    1718    protected array $paymentMethods;
    1819    protected Data $dataHelper;
    19     public function __construct(Settings $settings, string $pluginUrl, array $pages, string $currentSection, bool $connectionStatus, bool $testModeEnabled, array $mollieGateways, array $paymentMethods, Data $dataHelper)
     20    protected ContainerInterface $container;
     21    public function __construct(Settings $settings, string $pluginUrl, array $pages, string $currentSection, bool $connectionStatus, bool $testModeEnabled, array $mollieGateways, array $paymentMethods, Data $dataHelper, ContainerInterface $container)
    2022    {
    2123        $this->settings = $settings;
     
    2830        $this->paymentMethods = $paymentMethods;
    2931        $this->dataHelper = $dataHelper;
     32        $this->container = $container;
    3033    }
    3134    abstract public function config(): array;
  • mollie-payments-for-woocommerce/trunk/src/Settings/Page/Section/Advanced.php

    r3191126 r3262577  
    55
    66use Mollie\WooCommerce\Shared\SharedDataDictionary;
    7 use Mollie\WooCommerce\Payment\PaymentService;
     7use Mollie\WooCommerce\Payment\PaymentProcessor;
    88class Advanced extends \Mollie\WooCommerce\Settings\Page\Section\AbstractSection
    99{
     
    2121            strtolower(__('Enabled', 'mollie-payments-for-woocommerce')),
    2222            __('Single Click Payments', 'mollie-payments-for-woocommerce')
    23         ), 'type' => 'checkbox', 'default' => 'yes'], ['id' => $this->settings->getSettingId('api_switch'), 'title' => __('Select API Method', 'mollie-payments-for-woocommerce'), 'type' => 'select', 'options' => [PaymentService::PAYMENT_METHOD_TYPE_ORDER => ucfirst(PaymentService::PAYMENT_METHOD_TYPE_ORDER) . ' (' . __('default', 'mollie-payments-for-woocommerce') . ')', PaymentService::PAYMENT_METHOD_TYPE_PAYMENT => ucfirst(PaymentService::PAYMENT_METHOD_TYPE_PAYMENT)], 'default' => PaymentService::PAYMENT_METHOD_TYPE_ORDER, 'desc' => sprintf(
     23        ), 'type' => 'checkbox', 'default' => 'yes'], ['id' => $this->settings->getSettingId('api_switch'), 'title' => __('Select API Method', 'mollie-payments-for-woocommerce'), 'type' => 'select', 'options' => [PaymentProcessor::PAYMENT_METHOD_TYPE_ORDER => ucfirst(PaymentProcessor::PAYMENT_METHOD_TYPE_ORDER) . ' (' . __('default', 'mollie-payments-for-woocommerce') . ')', PaymentProcessor::PAYMENT_METHOD_TYPE_PAYMENT => ucfirst(PaymentProcessor::PAYMENT_METHOD_TYPE_PAYMENT)], 'default' => PaymentProcessor::PAYMENT_METHOD_TYPE_ORDER, 'desc' => sprintf(
    2424            /* translators: Placeholder 1: opening link tag, placeholder 2: closing link tag */
    2525            __('Click %1$shere%2$s to read more about the differences between the Payments and Orders API', 'mollie-payments-for-woocommerce'),
  • mollie-payments-for-woocommerce/trunk/src/Settings/Page/Section/Notices.php

    r3226701 r3262577  
    44namespace Mollie\WooCommerce\Settings\Page\Section;
    55
     6use Mollie\WooCommerce\PaymentMethods\AbstractPaymentMethod;
    67use Mollie\WooCommerce\PaymentMethods\Constants;
    78use WC_Gateway_BACS;
     
    3940    protected function warnDirectDebitStatus(): string
    4041    {
     42        if (!$this->paymentMethods["directdebit"] instanceof AbstractPaymentMethod) {
     43            return '';
     44        }
    4145        $hasCustomSepaSettings = $this->paymentMethods["directdebit"]->getProperty('enabled') !== \false;
    4246        $isSepaEnabled = !$hasCustomSepaSettings || $this->paymentMethods["directdebit"]->getProperty('enabled') === 'yes';
  • mollie-payments-for-woocommerce/trunk/src/Settings/Page/Section/PaymentMethods.php

    r3242448 r3262577  
    182182            $button = '<a class="button-secondary" href="https://my.mollie.com/dashboard/settings/profiles?utm_source=woocommerce&utm_medium=plugin&utm_campaign=partner" target="_blank">' . esc_html(__('Activate Payment Method', 'mollie-payments-for-woocommerce')) . '</a>';
    183183        }
     184        $iconProvider = $paymentMethod->paymentMethodIconProvider($this->container);
     185        $icon = $iconProvider->provideIcons()[0];
    184186        ob_start();
    185187        ?>
    186188        <div class="mollie-settings-pm__single">
    187189            <?php
    188         echo $paymentMethod->getIconUrl();
     190        echo $icon->src();
    189191        // phpcs:ignore XSS ok.
    190192        ?>
    191193            <?php
    192         echo esc_html($paymentMethod->title());
     194        echo esc_html($paymentMethod->title($this->container));
    193195        ?>
    194196            <?php
  • mollie-payments-for-woocommerce/trunk/src/Settings/Settings.php

    r3191126 r3262577  
    77use DateTime;
    88use Mollie\Api\Exceptions\ApiException;
     9use Mollie\WooCommerce\Gateway\MolliePaymentGatewayHandler;
    910use Mollie\WooCommerce\Gateway\Surcharge;
    1011use Mollie\WooCommerce\Notice\AdminNotice;
    11 use Mollie\WooCommerce\Payment\PaymentService;
     12use Mollie\WooCommerce\Payment\PaymentProcessor;
    1213use Mollie\WooCommerce\Settings\General\MollieGeneralSettings;
    1314use Mollie\WooCommerce\Shared\SharedDataDictionary;
     
    4849        return $generalSettings->gatewayFormFields($defaultTitle, $defaultDescription, $paymentConfirmation);
    4950    }
    50     public function processSettings(WC_Payment_Gateway $gateway)
     51    public function processSettings(string $gatewayId)
    5152    {
    5253        $nonce = filter_input(\INPUT_POST, '_wpnonce', \FILTER_SANITIZE_SPECIAL_CHARS);
     
    5657        }
    5758        if (isset($_POST['save'])) {
    58             $this->processAdminOptionCustomLogo($gateway);
    59             $this->processAdminOptionSurcharge($gateway);
     59            $this->processAdminOptionCustomLogo($gatewayId);
     60            $this->processAdminOptionSurcharge($gatewayId);
    6061            //only credit cards have a selector
    61             if ($gateway->id === 'mollie_wc_gateway_creditcard') {
     62            if ($gatewayId === 'mollie_wc_gateway_creditcard') {
    6263                $this->processAdminOptionCreditcardSelector();
    6364            }
    6465        }
    6566    }
    66     public function processAdminOptionCustomLogo(WC_Payment_Gateway $gateway)
     67    public function processAdminOptionCustomLogo(string $gatewayId)
    6768    {
    6869        $nonce = filter_input(\INPUT_POST, '_wpnonce', \FILTER_SANITIZE_SPECIAL_CHARS);
     
    7172            return;
    7273        }
    73         $enabledLogoOptionName = $gateway->id . '_enable_custom_logo';
    74         $gatewaySettings = get_option(sprintf('%s_settings', $gateway->id), []);
     74        $enabledLogoOptionName = 'woocommerce_' . $gatewayId . '_enable_custom_logo';
     75        $gatewaySettings = get_option(sprintf('%s_settings', $gatewayId), []);
    7576        if (!isset($_POST[$enabledLogoOptionName])) {
    7677            $gatewaySettings["iconFileUrl"] = null;
    7778            $gatewaySettings["iconFilePath"] = null;
    78             update_option(sprintf('%s_settings', $gateway->id), $gatewaySettings);
     79            update_option(sprintf('%s_settings', $gatewayId), $gatewaySettings);
    7980            return;
    8081        }
    81         $fileOptionName = $gateway->id . '_upload_logo';
     82        $fileOptionName = 'woocommerce_' . $gatewayId . '_upload_logo';
    8283        if (!empty($_FILES[$fileOptionName]['size']) && !empty($_FILES[$fileOptionName]['name']) && is_string($_FILES[$fileOptionName]['name']) && !empty($_FILES[$fileOptionName]['tmp_name']) && is_string($_FILES[$fileOptionName]['tmp_name'])) {
    8384            $name = filter_var(wp_unslash($_FILES[$fileOptionName]['name']), \FILTER_SANITIZE_FULL_SPECIAL_CHARS);
     
    8788                return;
    8889            }
    89             $this->processUploadedFile($name, $tempName, $gateway);
    90         }
    91     }
    92     public function processAdminOptionSurcharge(WC_Payment_Gateway $gateway)
     90            $this->processUploadedFile($name, $tempName, $gatewayId);
     91        }
     92    }
     93    public function processAdminOptionSurcharge(string $gatewayId)
    9394    {
    9495        $nonce = filter_input(\INPUT_POST, '_wpnonce', \FILTER_SANITIZE_SPECIAL_CHARS);
     
    9798            return;
    9899        }
    99         $paymentSurcharge = $gateway->id . '_payment_surcharge';
     100        $paymentSurcharge = $gatewayId . '_payment_surcharge';
    100101        if (isset($_POST[$paymentSurcharge]) && $_POST[$paymentSurcharge] !== Surcharge::NO_FEE) {
    101102            $surchargeFields = ['_fixed_fee', '_percentage', '_surcharge_limit'];
    102103            foreach ($surchargeFields as $field) {
    103                 $optionName = $gateway->id . $field;
     104                $optionName = $gatewayId . $field;
    104105                $validatedValue = isset($_POST[$optionName]) && $_POST[$optionName] > 0 && $_POST[$optionName] < 999;
    105106                if (!$validatedValue) {
     
    109110        }
    110111    }
    111     public function adminOptions(WC_Payment_Gateway $gateway)
    112     {
    113         if (!$gateway->enabled && count($gateway->errors)) {
    114             echo '<div class="inline error"><p><strong>' . esc_html(__('Gateway Disabled', 'mollie-payments-for-woocommerce')) . '</strong>: ' . wp_kses_post(implode('<br/>', $gateway->errors)) . '</p></div>';
    115             return;
    116         }
    117         $html = '';
    118         foreach ($gateway->get_form_fields() as $k => $v) {
    119             $type = $gateway->get_field_type($v);
    120             if ($type === 'multi_select_countries') {
    121                 $html .= $this->multiSelectCountry($gateway);
    122             } elseif (method_exists($gateway, 'generate_' . $type . '_html')) {
    123                 $html .= $gateway->{'generate_' . $type . '_html'}($k, $v);
    124             } else {
    125                 $html .= $gateway->generate_text_html($k, $v);
    126             }
    127         }
    128         echo '<h2>' . esc_html($gateway->get_method_title());
    129         wc_back_link(__('Return to payments', 'mollie-payments-for-woocommerce'), admin_url('admin.php?page=wc-settings&tab=checkout'));
    130         echo '</h2>';
    131         echo wp_kses_post(wpautop($gateway->get_method_description()));
    132         echo '<table class="form-table">' . $html . '</table>';
    133     }
    134     public function multiSelectCountry($gateway)
    135     {
    136         $selections = (array) $gateway->get_option('allowed_countries', []);
    137         $gatewayId = $gateway->paymentMethod()->getProperty('id');
    138         $id = 'mollie_wc_gateway_' . $gatewayId . '_allowed_countries';
    139         $title = __('Sell to specific countries', 'mollie-payments-for-woocommerce');
    140         $countries = WC()->countries->countries;
    141         asort($countries);
    142         ob_start();
    143         ?>
    144         <tr valign="top">
    145             <th scope="row" class="titledesc">
    146                 <label for="<?php
    147         echo esc_attr($id);
    148         ?>"><?php
    149         echo esc_html($title);
    150         ?> </label>
    151             </th>
    152             <td class="forminp">
    153                 <select multiple="multiple" name="<?php
    154         echo esc_attr($id);
    155         ?>[]" style="width:350px"
    156                         data-placeholder="<?php
    157         esc_attr_e('Choose countries&hellip;', 'mollie-payments-for-woocommerce');
    158         ?>"
    159                         aria-label="<?php
    160         esc_attr_e('Country', 'mollie-payments-for-woocommerce');
    161         ?>" class="wc-enhanced-select">
    162                     <?php
    163         if (!empty($countries)) {
    164             foreach ($countries as $key => $val) {
    165                 echo '<option value="' . esc_attr($key) . '"' . esc_attr(wc_selected($key, $selections)) . '>' . esc_html($val) . '</option>';
    166             }
    167         }
    168         ?>
    169                 </select><br/><a class="select_all button" href="#"><?php
    170         esc_html_e('Select all', 'mollie-payments-for-woocommerce');
    171         ?></a>
    172                 <a class="select_none button" href="#"><?php
    173         esc_html_e('Select none', 'mollie-payments-for-woocommerce');
    174         ?></a>
    175             </td>
    176         </tr>
    177         <?php
    178         return ob_get_clean();
    179     }
    180112    /**
    181113     * @return bool
     
    193125    {
    194126        $orderApiSetting = get_option($this->getSettingId('api_switch'));
    195         return !$orderApiSetting || is_string($orderApiSetting) && trim($orderApiSetting) === PaymentService::PAYMENT_METHOD_TYPE_ORDER;
     127        return !$orderApiSetting || is_string($orderApiSetting) && trim($orderApiSetting) === PaymentProcessor::PAYMENT_METHOD_TYPE_ORDER;
    196128    }
    197129    /**
     
    564496        return \true;
    565497    }
    566     protected function processUploadedFile(string $name, string $tempName, WC_Payment_Gateway $gateway)
     498    protected function processUploadedFile(string $name, string $tempName, string $gatewayId)
    567499    {
    568500        $fileName = preg_replace('#\s+#', '_', $name);
     
    572504        $upload_overrides = ['test_form' => \false];
    573505        // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
    574         $file = isset($_FILES[$gateway->id . '_upload_logo']) ? wp_unslash($_FILES[$gateway->id . '_upload_logo']) : [];
     506        $file = isset($_FILES['woocommerce_' . $gatewayId . '_upload_logo']) ? wp_unslash($_FILES['woocommerce_' . $gatewayId . '_upload_logo']) : [];
    575507        if (!empty($file)) {
    576508            $file = ['name' => $file['name'], 'type' => $file['type'], 'tmp_name' => $file['tmp_name'], 'error' => $file['error'], 'size' => $file['size']];
    577509            $movefile = wp_handle_upload($file, $upload_overrides);
    578510            if ($movefile) {
     511                $gatewaySettings = get_option(sprintf('%s_settings', $gatewayId), []);
    579512                $gatewaySettings["iconFileUrl"] = $movefile['url'];
    580513                $gatewaySettings["iconFilePath"] = $movefile['file'];
    581                 update_option(sprintf('%s_settings', $gateway->id), $gatewaySettings);
     514                update_option(sprintf('%s_settings', $gatewayId), $gatewaySettings);
    582515            }
    583516        }
  • mollie-payments-for-woocommerce/trunk/src/Settings/SettingsModule.php

    r3226701 r3262577  
    119119            $this->maybeTestModeNotice();
    120120        });
    121         $gateways = $container->get('gateway.instances');
     121        $gateways = $container->get('__deprecated.gateway_helpers');
    122122        $isSDDGatewayEnabled = $container->get('gateway.isSDDGatewayEnabled');
    123         $this->initMollieSettingsPage($isSDDGatewayEnabled, $gateways, $pluginPath, $pluginUrl, $paymentMethods);
     123        $this->initMollieSettingsPage($isSDDGatewayEnabled, $gateways, $pluginPath, $pluginUrl, $paymentMethods, $container);
    124124        add_action('woocommerce_admin_settings_sanitize_option', [$this->settingsHelper, 'updateMerchantIdOnApiKeyChanges'], 10, 2);
    125125        add_action('update_option_mollie-payments-for-woocommerce_live_api_key', [$this->settingsHelper, 'updateMerchantIdAfterApiKeyChanges'], 10, 3);
     
    189189     * @param $pluginUrl
    190190     * @param $paymentMethods
     191     * @param $container
    191192     * @return void
    192193     */
    193     protected function initMollieSettingsPage($isSDDGatewayEnabled, $gateways, $pluginPath, $pluginUrl, $paymentMethods): void
     194    protected function initMollieSettingsPage($isSDDGatewayEnabled, $gateways, $pluginPath, $pluginUrl, $paymentMethods, $container): void
    194195    {
    195196        if (!$isSDDGatewayEnabled) {
     
    197198            unset($gateways['mollie_wc_gateway_directdebit']);
    198199        }
    199         add_filter('woocommerce_get_settings_pages', function ($settings) use ($pluginPath, $pluginUrl, $gateways, $paymentMethods) {
    200             $settings[] = new \Mollie\WooCommerce\Settings\MollieSettingsPage($this->settingsHelper, $pluginPath, $pluginUrl, $gateways, $paymentMethods, $this->isTestModeEnabled, $this->dataHelper);
     200        add_filter('woocommerce_get_settings_pages', function ($settings) use ($pluginPath, $pluginUrl, $gateways, $paymentMethods, $container) {
     201            $settings[] = new \Mollie\WooCommerce\Settings\MollieSettingsPage($this->settingsHelper, $pluginPath, $pluginUrl, $gateways, $paymentMethods, $this->isTestModeEnabled, $this->dataHelper, $container);
    201202            return $settings;
    202203        });
  • mollie-payments-for-woocommerce/trunk/src/Shared/Data.php

    r3191126 r3262577  
    104104        $this->settingsHelper->processSettings($gateway);
    105105    }
    106     public function processAdminOptions($gateway)
    107     {
    108         $this->settingsHelper->adminOptions($gateway);
    109     }
    110106    public function getPaymentLocale()
    111107    {
  • mollie-payments-for-woocommerce/trunk/src/Subscription/SubscriptionModule.php

    r3164004 r3262577  
    88use Mollie\Inpsyde\Modularity\Module\ExecutableModule;
    99use Mollie\Inpsyde\Modularity\Module\ModuleClassNameIdTrait;
    10 use Mollie\WooCommerce\Gateway\MolliePaymentGateway;
     10use Mollie\WooCommerce\Gateway\MolliePaymentGatewayHandler;
    1111use Mollie\WooCommerce\Settings\Settings;
    1212use Mollie\WooCommerce\Shared\Data;
     
    3838        $this->settingsHelper = $container->get('settings.settings_helper');
    3939        assert($this->settingsHelper instanceof Settings);
    40         $this->maybeFixSubscriptions();
    4140        $this->schedulePendingPaymentOrdersExpirationCheck();
    4241        return \true;
    43     }
    44     /**
    45      * See MOL-322, MOL-405
    46      */
    47     public function maybeFixSubscriptions()
    48     {
    49         $fixer = new \Mollie\WooCommerce\Subscription\MaybeFixSubscription();
    50         $fixer->maybeFix();
    5142    }
    5243    /**
  • mollie-payments-for-woocommerce/trunk/vendor/autoload.php

    r3226701 r3262577  
    2323require_once __DIR__ . '/composer/autoload_real.php';
    2424
    25 return ComposerAutoloaderInitc0778a800f6c5eb39482522e8993a1d5::getLoader();
     25return ComposerAutoloaderInitb1e8936703aa6cff296fa891dd9ccf25::getLoader();
  • mollie-payments-for-woocommerce/trunk/vendor/composer/autoload_classmap.php

    r3242448 r3262577  
    154154    'Mollie\\Api\\Types\\SubscriptionStatus' => $vendorDir . '/mollie/mollie-api-php/src/Types/SubscriptionStatus.php',
    155155    'Mollie\\Api\\Types\\TerminalStatus' => $vendorDir . '/mollie/mollie-api-php/src/Types/TerminalStatus.php',
     156    'Mollie\\Dhii\\Services\\Extension' => $vendorDir . '/dhii/services/src/Extension.php',
     157    'Mollie\\Dhii\\Services\\Extensions\\ArrayExtension' => $vendorDir . '/dhii/services/src/Extensions/ArrayExtension.php',
     158    'Mollie\\Dhii\\Services\\Factories\\Alias' => $vendorDir . '/dhii/services/src/Factories/Alias.php',
     159    'Mollie\\Dhii\\Services\\Factories\\Constructor' => $vendorDir . '/dhii/services/src/Factories/Constructor.php',
     160    'Mollie\\Dhii\\Services\\Factories\\FuncService' => $vendorDir . '/dhii/services/src/Factories/FuncService.php',
     161    'Mollie\\Dhii\\Services\\Factories\\GlobalVar' => $vendorDir . '/dhii/services/src/Factories/GlobalVar.php',
     162    'Mollie\\Dhii\\Services\\Factories\\ServiceList' => $vendorDir . '/dhii/services/src/Factories/ServiceList.php',
     163    'Mollie\\Dhii\\Services\\Factories\\StringService' => $vendorDir . '/dhii/services/src/Factories/StringService.php',
     164    'Mollie\\Dhii\\Services\\Factories\\Value' => $vendorDir . '/dhii/services/src/Factories/Value.php',
     165    'Mollie\\Dhii\\Services\\Factory' => $vendorDir . '/dhii/services/src/Factory.php',
     166    'Mollie\\Dhii\\Services\\ResolveKeysCapableTrait' => $vendorDir . '/dhii/services/src/ResolveKeysCapableTrait.php',
     167    'Mollie\\Dhii\\Services\\Service' => $vendorDir . '/dhii/services/src/Service.php',
    156168    'Mollie\\Inpsyde\\EnvironmentChecker\\ConstraintsCollectionFactory' => $baseDir . '/pluginEnvironmentChecker/ConstraintsCollectionFactory.php',
    157169    'Mollie\\Inpsyde\\EnvironmentChecker\\ConstraintsCollectionFactoryInterface' => $baseDir . '/pluginEnvironmentChecker/ConstraintsCollectionFactoryInterface.php',
     
    182194    'Mollie\\Inpsyde\\Modularity\\Properties\\Properties' => $vendorDir . '/inpsyde/modularity/src/Properties/Properties.php',
    183195    'Mollie\\Inpsyde\\Modularity\\Properties\\ThemeProperties' => $vendorDir . '/inpsyde/modularity/src/Properties/ThemeProperties.php',
     196    'Mollie\\Inpsyde\\PaymentGateway\\DefaultIconsRenderer' => $baseDir . '/lib/payment-gateway/src/DefaultIconsRenderer.php',
     197    'Mollie\\Inpsyde\\PaymentGateway\\Fields\\ContentField' => $baseDir . '/lib/payment-gateway/src/Fields/ContentField.php',
     198    'Mollie\\Inpsyde\\PaymentGateway\\GatewayIconsRendererInterface' => $baseDir . '/lib/payment-gateway/src/GatewayIconsRendererInterface.php',
     199    'Mollie\\Inpsyde\\PaymentGateway\\I18n' => $baseDir . '/lib/payment-gateway/src/I18n.php',
     200    'Mollie\\Inpsyde\\PaymentGateway\\Icon' => $baseDir . '/lib/payment-gateway/src/Icon.php',
     201    'Mollie\\Inpsyde\\PaymentGateway\\IconProviderInterface' => $baseDir . '/lib/payment-gateway/src/IconProviderInterface.php',
     202    'Mollie\\Inpsyde\\PaymentGateway\\Method\\CustomSettingsFields' => $baseDir . '/lib/payment-gateway/src/Method/CustomSettingsFields.php',
     203    'Mollie\\Inpsyde\\PaymentGateway\\Method\\CustomSettingsFieldsDefinition' => $baseDir . '/lib/payment-gateway/src/Method/CustomSettingsFieldsDefinition.php',
     204    'Mollie\\Inpsyde\\PaymentGateway\\Method\\DefaultPaymentMethodDefinitionTrait' => $baseDir . '/lib/payment-gateway/src/Method/DefaultPaymentMethodDefinitionTrait.php',
     205    'Mollie\\Inpsyde\\PaymentGateway\\Method\\PaymentMethodDefinition' => $baseDir . '/lib/payment-gateway/src/Method/PaymentMethodDefinition.php',
     206    'Mollie\\Inpsyde\\PaymentGateway\\NoopPaymentProcessor' => $baseDir . '/lib/payment-gateway/src/NoopPaymentProcessor.php',
     207    'Mollie\\Inpsyde\\PaymentGateway\\NoopPaymentRequestValidator' => $baseDir . '/lib/payment-gateway/src/NoopPaymentRequestValidator.php',
     208    'Mollie\\Inpsyde\\PaymentGateway\\NoopRefundProcessor' => $baseDir . '/lib/payment-gateway/src/NoopRefundProcessor.php',
     209    'Mollie\\Inpsyde\\PaymentGateway\\PaymentFieldsRendererInterface' => $baseDir . '/lib/payment-gateway/src/PaymentFieldsRendererInterface.php',
     210    'Mollie\\Inpsyde\\PaymentGateway\\PaymentGateway' => $baseDir . '/lib/payment-gateway/src/PaymentGateway.php',
     211    'Mollie\\Inpsyde\\PaymentGateway\\PaymentGatewayBlocks' => $baseDir . '/lib/payment-gateway/src/PaymentGatewayBlocks.php',
     212    'Mollie\\Inpsyde\\PaymentGateway\\PaymentGatewayModule' => $baseDir . '/lib/payment-gateway/src/PaymentGatewayModule.php',
     213    'Mollie\\Inpsyde\\PaymentGateway\\PaymentGatewayValidator' => $baseDir . '/lib/payment-gateway/src/PaymentGatewayValidator.php',
     214    'Mollie\\Inpsyde\\PaymentGateway\\PaymentMethodServiceProviderTrait' => $baseDir . '/lib/payment-gateway/src/PaymentMethodServiceProviderTrait.php',
     215    'Mollie\\Inpsyde\\PaymentGateway\\PaymentProcessorInterface' => $baseDir . '/lib/payment-gateway/src/PaymentProcessorInterface.php',
     216    'Mollie\\Inpsyde\\PaymentGateway\\PaymentRequestValidatorInterface' => $baseDir . '/lib/payment-gateway/src/PaymentRequestValidatorInterface.php',
     217    'Mollie\\Inpsyde\\PaymentGateway\\RefundProcessorInterface' => $baseDir . '/lib/payment-gateway/src/RefundProcessorInterface.php',
     218    'Mollie\\Inpsyde\\PaymentGateway\\ServiceKeyGenerator' => $baseDir . '/lib/payment-gateway/src/ServiceKeyGenerator.php',
     219    'Mollie\\Inpsyde\\PaymentGateway\\SettingsFieldRendererInterface' => $baseDir . '/lib/payment-gateway/src/SettingsFieldRendererInterface.php',
     220    'Mollie\\Inpsyde\\PaymentGateway\\SettingsFieldSanitizerInterface' => $baseDir . '/lib/payment-gateway/src/SettingsFieldSanitizerInterface.php',
     221    'Mollie\\Inpsyde\\PaymentGateway\\StaticIconProvider' => $baseDir . '/lib/payment-gateway/src/StaticIconProvider.php',
    184222    'Mollie\\Psr\\Container\\ContainerExceptionInterface' => $vendorDir . '/psr/container/src/ContainerExceptionInterface.php',
    185223    'Mollie\\Psr\\Container\\ContainerInterface' => $vendorDir . '/psr/container/src/ContainerInterface.php',
     
    217255    'Mollie\\WooCommerce\\Components\\ComponentsStyles' => $baseDir . '/src/Components/ComponentsStyles.php',
    218256    'Mollie\\WooCommerce\\Components\\StylesPropertiesDictionary' => $baseDir . '/src/Components/StylesPropertiesDictionary.php',
     257    'Mollie\\WooCommerce\\Gateway\\DeprecatedGatewayBuilder' => $baseDir . '/src/Gateway/DeprecatedGatewayBuilder.php',
    219258    'Mollie\\WooCommerce\\Gateway\\GatewayModule' => $baseDir . '/src/Gateway/GatewayModule.php',
    220     'Mollie\\WooCommerce\\Gateway\\MolliePaymentGateway' => $baseDir . '/src/Gateway/MolliePaymentGateway.php',
    221     'Mollie\\WooCommerce\\Gateway\\MolliePaymentGatewayI' => $baseDir . '/src/Gateway/MolliePaymentGatewayI.php',
     259    'Mollie\\WooCommerce\\Gateway\\MolliePaymentGatewayHandler' => $baseDir . '/src/Gateway/MolliePaymentGatewayHandler.php',
    222260    'Mollie\\WooCommerce\\Gateway\\OrderMandatoryGatewayDisabler' => $baseDir . '/src/Gateway/OrderMandatoryGatewayDisabler.php',
     261    'Mollie\\WooCommerce\\Gateway\\Refund\\OrderItemsRefunder' => $baseDir . '/src/Gateway/Refund/OrderItemsRefunder.php',
     262    'Mollie\\WooCommerce\\Gateway\\Refund\\OrderLineStatus' => $baseDir . '/src/Gateway/Refund/OrderLineStatus.php',
     263    'Mollie\\WooCommerce\\Gateway\\Refund\\PartialRefundException' => $baseDir . '/src/Gateway/Refund/PartialRefundException.php',
     264    'Mollie\\WooCommerce\\Gateway\\Refund\\RefundLineItemsBuilder' => $baseDir . '/src/Gateway/Refund/RefundLineItemsBuilder.php',
     265    'Mollie\\WooCommerce\\Gateway\\Refund\\RefundProcessor' => $baseDir . '/src/Gateway/Refund/RefundProcessor.php',
    223266    'Mollie\\WooCommerce\\Gateway\\Surcharge' => $baseDir . '/src/Gateway/Surcharge.php',
    224267    'Mollie\\WooCommerce\\Gateway\\Voucher\\MaybeDisableGateway' => $baseDir . '/src/Gateway/Voucher/MaybeDisableGateway.php',
     
    258301    'Mollie\\WooCommerce\\PaymentMethods\\Giropay' => $baseDir . '/src/PaymentMethods/Giropay.php',
    259302    'Mollie\\WooCommerce\\PaymentMethods\\IconFactory' => $baseDir . '/src/PaymentMethods/IconFactory.php',
     303    'Mollie\\WooCommerce\\PaymentMethods\\Icon\\GatewayIconsRenderer' => $baseDir . '/src/PaymentMethods/Icon/GatewayIconsRenderer.php',
    260304    'Mollie\\WooCommerce\\PaymentMethods\\Ideal' => $baseDir . '/src/PaymentMethods/Ideal.php',
    261305    'Mollie\\WooCommerce\\PaymentMethods\\In3' => $baseDir . '/src/PaymentMethods/In3.php',
     
    269313    'Mollie\\WooCommerce\\PaymentMethods\\InstructionStrategies\\InstructionStrategyI' => $baseDir . '/src/PaymentMethods/InstructionStrategies/InstructionStrategyI.php',
    270314    'Mollie\\WooCommerce\\PaymentMethods\\InstructionStrategies\\MybankInstructionStrategy' => $baseDir . '/src/PaymentMethods/InstructionStrategies/MybankInstructionStrategy.php',
     315    'Mollie\\WooCommerce\\PaymentMethods\\InstructionStrategies\\OrderInstructionsManager' => $baseDir . '/src/PaymentMethods/InstructionStrategies/OrderInstructionsManager.php',
    271316    'Mollie\\WooCommerce\\PaymentMethods\\InstructionStrategies\\PaypalInstructionStrategy' => $baseDir . '/src/PaymentMethods/InstructionStrategies/PaypalInstructionStrategy.php',
    272317    'Mollie\\WooCommerce\\PaymentMethods\\InstructionStrategies\\Przelewy24InstructionStrategy' => $baseDir . '/src/PaymentMethods/InstructionStrategies/Przelewy24InstructionStrategy.php',
     
    282327    'Mollie\\WooCommerce\\PaymentMethods\\Paybybank' => $baseDir . '/src/PaymentMethods/Paybybank.php',
    283328    'Mollie\\WooCommerce\\PaymentMethods\\Payconiq' => $baseDir . '/src/PaymentMethods/Payconiq.php',
     329    'Mollie\\WooCommerce\\PaymentMethods\\PaymentFieldsStrategies\\AbstractPaymentFieldsRenderer' => $baseDir . '/src/PaymentMethods/PaymentFieldsStrategies/AbstractPaymentFieldsRenderer.php',
    284330    'Mollie\\WooCommerce\\PaymentMethods\\PaymentFieldsStrategies\\BancomatpayFieldsStrategy' => $baseDir . '/src/PaymentMethods/PaymentFieldsStrategies/BancomatpayFieldsStrategy.php',
    285331    'Mollie\\WooCommerce\\PaymentMethods\\PaymentFieldsStrategies\\BillieFieldsStrategy' => $baseDir . '/src/PaymentMethods/PaymentFieldsStrategies/BillieFieldsStrategy.php',
     
    290336    'Mollie\\WooCommerce\\PaymentMethods\\PaymentFieldsStrategies\\IssuersDropdownBehavior' => $baseDir . '/src/PaymentMethods/PaymentFieldsStrategies/IssuersDropdownBehavior.php',
    291337    'Mollie\\WooCommerce\\PaymentMethods\\PaymentFieldsStrategies\\KbcFieldsStrategy' => $baseDir . '/src/PaymentMethods/PaymentFieldsStrategies/KbcFieldsStrategy.php',
     338    'Mollie\\WooCommerce\\PaymentMethods\\PaymentFieldsStrategies\\NoopPaymentFieldsRenderer' => $baseDir . '/src/PaymentMethods/PaymentFieldsStrategies/NoopPaymentFieldsRenderer.php',
    292339    'Mollie\\WooCommerce\\PaymentMethods\\PaymentFieldsStrategies\\PaymentFieldsStrategiesTrait' => $baseDir . '/src/PaymentMethods/PaymentFieldsStrategies/PaymentFieldsStrategiesTrait.php',
    293340    'Mollie\\WooCommerce\\PaymentMethods\\PaymentFieldsStrategies\\PaymentFieldsStrategyI' => $baseDir . '/src/PaymentMethods/PaymentFieldsStrategies/PaymentFieldsStrategyI.php',
     
    313360    'Mollie\\WooCommerce\\Payment\\MolliePayment' => $baseDir . '/src/Payment/MolliePayment.php',
    314361    'Mollie\\WooCommerce\\Payment\\MollieSubscription' => $baseDir . '/src/Payment/MollieSubscription.php',
    315     'Mollie\\WooCommerce\\Payment\\OrderInstructionsService' => $baseDir . '/src/Payment/OrderInstructionsService.php',
    316     'Mollie\\WooCommerce\\Payment\\OrderItemsRefunder' => $baseDir . '/src/Payment/OrderItemsRefunder.php',
    317     'Mollie\\WooCommerce\\Payment\\OrderLineStatus' => $baseDir . '/src/Payment/OrderLineStatus.php',
    318362    'Mollie\\WooCommerce\\Payment\\OrderLines' => $baseDir . '/src/Payment/OrderLines.php',
    319     'Mollie\\WooCommerce\\Payment\\PartialRefundException' => $baseDir . '/src/Payment/PartialRefundException.php',
    320363    'Mollie\\WooCommerce\\Payment\\PaymentCheckoutRedirectService' => $baseDir . '/src/Payment/PaymentCheckoutRedirectService.php',
    321364    'Mollie\\WooCommerce\\Payment\\PaymentFactory' => $baseDir . '/src/Payment/PaymentFactory.php',
    322     'Mollie\\WooCommerce\\Payment\\PaymentFieldsService' => $baseDir . '/src/Payment/PaymentFieldsService.php',
     365    'Mollie\\WooCommerce\\Payment\\PaymentLines' => $baseDir . '/src/Payment/PaymentLines.php',
    323366    'Mollie\\WooCommerce\\Payment\\PaymentModule' => $baseDir . '/src/Payment/PaymentModule.php',
    324     'Mollie\\WooCommerce\\Payment\\PaymentService' => $baseDir . '/src/Payment/PaymentService.php',
    325     'Mollie\\WooCommerce\\Payment\\RefundLineItemsBuilder' => $baseDir . '/src/Payment/RefundLineItemsBuilder.php',
     367    'Mollie\\WooCommerce\\Payment\\PaymentProcessor' => $baseDir . '/src/Payment/PaymentProcessor.php',
     368    'Mollie\\WooCommerce\\Payment\\Request\\Middleware\\AddCustomRequestFieldsMiddleware' => $baseDir . '/src/Payment/Request/Middleware/AddCustomRequestFieldsMiddleware.php',
     369    'Mollie\\WooCommerce\\Payment\\Request\\Middleware\\AddSequenceTypeForSubscriptionsMiddleware' => $baseDir . '/src/Payment/Request/Middleware/AddSequenceTypeForSubscriptionsMiddleware.php',
     370    'Mollie\\WooCommerce\\Payment\\Request\\Middleware\\AddressMiddleware' => $baseDir . '/src/Payment/Request/Middleware/AddressMiddleware.php',
     371    'Mollie\\WooCommerce\\Payment\\Request\\Middleware\\ApplePayTokenMiddleware' => $baseDir . '/src/Payment/Request/Middleware/ApplePayTokenMiddleware.php',
     372    'Mollie\\WooCommerce\\Payment\\Request\\Middleware\\CaptureModeMiddleware' => $baseDir . '/src/Payment/Request/Middleware/CaptureModeMiddleware.php',
     373    'Mollie\\WooCommerce\\Payment\\Request\\Middleware\\CardTokenMiddleware' => $baseDir . '/src/Payment/Request/Middleware/CardTokenMiddleware.php',
     374    'Mollie\\WooCommerce\\Payment\\Request\\Middleware\\CustomerBirthdateMiddleware' => $baseDir . '/src/Payment/Request/Middleware/CustomerBirthdateMiddleware.php',
     375    'Mollie\\WooCommerce\\Payment\\Request\\Middleware\\MiddlewareHandler' => $baseDir . '/src/Payment/Request/Middleware/MiddlewareHandler.php',
     376    'Mollie\\WooCommerce\\Payment\\Request\\Middleware\\OrderLinesMiddleware' => $baseDir . '/src/Payment/Request/Middleware/OrderLinesMiddleware.php',
     377    'Mollie\\WooCommerce\\Payment\\Request\\Middleware\\PaymentDescriptionMiddleware' => $baseDir . '/src/Payment/Request/Middleware/PaymentDescriptionMiddleware.php',
     378    'Mollie\\WooCommerce\\Payment\\Request\\Middleware\\RequestMiddlewareInterface' => $baseDir . '/src/Payment/Request/Middleware/RequestMiddlewareInterface.php',
     379    'Mollie\\WooCommerce\\Payment\\Request\\Middleware\\SelectedIssuerMiddleware' => $baseDir . '/src/Payment/Request/Middleware/SelectedIssuerMiddleware.php',
     380    'Mollie\\WooCommerce\\Payment\\Request\\Middleware\\StoreCustomerMiddleware' => $baseDir . '/src/Payment/Request/Middleware/StoreCustomerMiddleware.php',
     381    'Mollie\\WooCommerce\\Payment\\Request\\Middleware\\UrlMiddleware' => $baseDir . '/src/Payment/Request/Middleware/UrlMiddleware.php',
     382    'Mollie\\WooCommerce\\Payment\\Request\\RequestFactory' => $baseDir . '/src/Payment/Request/RequestFactory.php',
     383    'Mollie\\WooCommerce\\Payment\\Request\\Strategies\\OrderRequestStrategy' => $baseDir . '/src/Payment/Request/Strategies/OrderRequestStrategy.php',
     384    'Mollie\\WooCommerce\\Payment\\Request\\Strategies\\PaymentRequestStrategy' => $baseDir . '/src/Payment/Request/Strategies/PaymentRequestStrategy.php',
     385    'Mollie\\WooCommerce\\Payment\\Request\\Strategies\\RequestStrategyInterface' => $baseDir . '/src/Payment/Request/Strategies/RequestStrategyInterface.php',
    326386    'Mollie\\WooCommerce\\SDK\\Api' => $baseDir . '/src/SDK/Api.php',
    327387    'Mollie\\WooCommerce\\SDK\\CouldNotConnectToMollie' => $baseDir . '/src/SDK/CouldNotConnectToMollie.php',
     
    333393    'Mollie\\WooCommerce\\SDK\\WordPressHttpAdapterPicker' => $baseDir . '/src/SDK/WordPressHttpAdapterPicker.php',
    334394    'Mollie\\WooCommerce\\Settings\\General\\MollieGeneralSettings' => $baseDir . '/src/Settings/General/MollieGeneralSettings.php',
     395    'Mollie\\WooCommerce\\Settings\\General\\MultiCountrySettingsField' => $baseDir . '/src/Settings/General/MultiCountrySettingsField.php',
    335396    'Mollie\\WooCommerce\\Settings\\MollieSettingsPage' => $baseDir . '/src/Settings/MollieSettingsPage.php',
    336397    'Mollie\\WooCommerce\\Settings\\Page\\AbstractPage' => $baseDir . '/src/Settings/Page/AbstractPage.php',
     
    359420    'Mollie\\WooCommerce\\Shared\\SharedModule' => $baseDir . '/src/Shared/SharedModule.php',
    360421    'Mollie\\WooCommerce\\Shared\\Status' => $baseDir . '/src/Shared/Status.php',
    361     'Mollie\\WooCommerce\\Subscription\\MaybeFixSubscription' => $baseDir . '/src/Subscription/MaybeFixSubscription.php',
    362     'Mollie\\WooCommerce\\Subscription\\MollieSepaRecurringGateway' => $baseDir . '/src/Subscription/MollieSepaRecurringGateway.php',
    363     'Mollie\\WooCommerce\\Subscription\\MollieSubscriptionGateway' => $baseDir . '/src/Subscription/MollieSubscriptionGateway.php',
     422    'Mollie\\WooCommerce\\Subscription\\MollieSepaRecurringGatewayHandler' => $baseDir . '/src/Subscription/MollieSepaRecurringGatewayHandler.php',
     423    'Mollie\\WooCommerce\\Subscription\\MollieSubscriptionGatewayHandler' => $baseDir . '/src/Subscription/MollieSubscriptionGatewayHandler.php',
    364424    'Mollie\\WooCommerce\\Subscription\\SubscriptionModule' => $baseDir . '/src/Subscription/SubscriptionModule.php',
    365425    'Mollie\\WooCommerce\\Uninstall\\CleanDb' => $baseDir . '/src/Uninstall/CleanDb.php',
  • mollie-payments-for-woocommerce/trunk/vendor/composer/autoload_psr4.php

    r3164004 r3262577  
    1010    'Mollie\\Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'),
    1111    'Mollie\\Psr\\Container\\' => array($vendorDir . '/psr/container/src'),
     12    'Mollie\\Inpsyde\\PaymentGateway\\' => array($baseDir . '/lib/payment-gateway/src'),
    1213    'Mollie\\Inpsyde\\Modularity\\' => array($vendorDir . '/inpsyde/modularity/src'),
    1314    'Mollie\\Inpsyde\\EnvironmentChecker\\' => array($baseDir . '/pluginEnvironmentChecker'),
     15    'Mollie\\Dhii\\Services\\' => array($vendorDir . '/dhii/services/src'),
    1416    'Mollie\\Api\\' => array($vendorDir . '/mollie/mollie-api-php/src'),
    1517    'Composer\\CaBundle\\' => array($vendorDir . '/composer/ca-bundle/src'),
  • mollie-payments-for-woocommerce/trunk/vendor/composer/autoload_real.php

    r3226701 r3262577  
    33// autoload_real.php @generated by Composer
    44
    5 class ComposerAutoloaderInitc0778a800f6c5eb39482522e8993a1d5
     5class ComposerAutoloaderInitb1e8936703aa6cff296fa891dd9ccf25
    66{
    77    private static $loader;
     
    2525        require __DIR__ . '/platform_check.php';
    2626
    27         spl_autoload_register(array('ComposerAutoloaderInitc0778a800f6c5eb39482522e8993a1d5', 'loadClassLoader'), true, true);
     27        spl_autoload_register(array('ComposerAutoloaderInitb1e8936703aa6cff296fa891dd9ccf25', 'loadClassLoader'), true, true);
    2828        self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
    29         spl_autoload_unregister(array('ComposerAutoloaderInitc0778a800f6c5eb39482522e8993a1d5', 'loadClassLoader'));
     29        spl_autoload_unregister(array('ComposerAutoloaderInitb1e8936703aa6cff296fa891dd9ccf25', 'loadClassLoader'));
    3030
    3131        require __DIR__ . '/autoload_static.php';
    32         call_user_func(\Composer\Autoload\ComposerStaticInitc0778a800f6c5eb39482522e8993a1d5::getInitializer($loader));
     32        call_user_func(\Composer\Autoload\ComposerStaticInitb1e8936703aa6cff296fa891dd9ccf25::getInitializer($loader));
    3333
    3434        $loader->register(true);
  • mollie-payments-for-woocommerce/trunk/vendor/composer/autoload_static.php

    r3242448 r3262577  
    55namespace Composer\Autoload;
    66
    7 class ComposerStaticInitc0778a800f6c5eb39482522e8993a1d5
     7class ComposerStaticInitb1e8936703aa6cff296fa891dd9ccf25
    88{
    99    public static $prefixLengthsPsr4 = array (
     
    1313            'Mollie\\Psr\\Log\\' => 15,
    1414            'Mollie\\Psr\\Container\\' => 21,
     15            'Mollie\\Inpsyde\\PaymentGateway\\' => 30,
    1516            'Mollie\\Inpsyde\\Modularity\\' => 26,
    1617            'Mollie\\Inpsyde\\EnvironmentChecker\\' => 34,
     18            'Mollie\\Dhii\\Services\\' => 21,
    1719            'Mollie\\Api\\' => 11,
    1820        ),
     
    3638            0 => __DIR__ . '/..' . '/psr/container/src',
    3739        ),
     40        'Mollie\\Inpsyde\\PaymentGateway\\' =>
     41        array (
     42            0 => __DIR__ . '/../..' . '/lib/payment-gateway/src',
     43        ),
    3844        'Mollie\\Inpsyde\\Modularity\\' =>
    3945        array (
     
    4349        array (
    4450            0 => __DIR__ . '/../..' . '/pluginEnvironmentChecker',
     51        ),
     52        'Mollie\\Dhii\\Services\\' =>
     53        array (
     54            0 => __DIR__ . '/..' . '/dhii/services/src',
    4555        ),
    4656        'Mollie\\Api\\' =>
     
    202212        'Mollie\\Api\\Types\\SubscriptionStatus' => __DIR__ . '/..' . '/mollie/mollie-api-php/src/Types/SubscriptionStatus.php',
    203213        'Mollie\\Api\\Types\\TerminalStatus' => __DIR__ . '/..' . '/mollie/mollie-api-php/src/Types/TerminalStatus.php',
     214        'Mollie\\Dhii\\Services\\Extension' => __DIR__ . '/..' . '/dhii/services/src/Extension.php',
     215        'Mollie\\Dhii\\Services\\Extensions\\ArrayExtension' => __DIR__ . '/..' . '/dhii/services/src/Extensions/ArrayExtension.php',
     216        'Mollie\\Dhii\\Services\\Factories\\Alias' => __DIR__ . '/..' . '/dhii/services/src/Factories/Alias.php',
     217        'Mollie\\Dhii\\Services\\Factories\\Constructor' => __DIR__ . '/..' . '/dhii/services/src/Factories/Constructor.php',
     218        'Mollie\\Dhii\\Services\\Factories\\FuncService' => __DIR__ . '/..' . '/dhii/services/src/Factories/FuncService.php',
     219        'Mollie\\Dhii\\Services\\Factories\\GlobalVar' => __DIR__ . '/..' . '/dhii/services/src/Factories/GlobalVar.php',
     220        'Mollie\\Dhii\\Services\\Factories\\ServiceList' => __DIR__ . '/..' . '/dhii/services/src/Factories/ServiceList.php',
     221        'Mollie\\Dhii\\Services\\Factories\\StringService' => __DIR__ . '/..' . '/dhii/services/src/Factories/StringService.php',
     222        'Mollie\\Dhii\\Services\\Factories\\Value' => __DIR__ . '/..' . '/dhii/services/src/Factories/Value.php',
     223        'Mollie\\Dhii\\Services\\Factory' => __DIR__ . '/..' . '/dhii/services/src/Factory.php',
     224        'Mollie\\Dhii\\Services\\ResolveKeysCapableTrait' => __DIR__ . '/..' . '/dhii/services/src/ResolveKeysCapableTrait.php',
     225        'Mollie\\Dhii\\Services\\Service' => __DIR__ . '/..' . '/dhii/services/src/Service.php',
    204226        'Mollie\\Inpsyde\\EnvironmentChecker\\ConstraintsCollectionFactory' => __DIR__ . '/../..' . '/pluginEnvironmentChecker/ConstraintsCollectionFactory.php',
    205227        'Mollie\\Inpsyde\\EnvironmentChecker\\ConstraintsCollectionFactoryInterface' => __DIR__ . '/../..' . '/pluginEnvironmentChecker/ConstraintsCollectionFactoryInterface.php',
     
    230252        'Mollie\\Inpsyde\\Modularity\\Properties\\Properties' => __DIR__ . '/..' . '/inpsyde/modularity/src/Properties/Properties.php',
    231253        'Mollie\\Inpsyde\\Modularity\\Properties\\ThemeProperties' => __DIR__ . '/..' . '/inpsyde/modularity/src/Properties/ThemeProperties.php',
     254        'Mollie\\Inpsyde\\PaymentGateway\\DefaultIconsRenderer' => __DIR__ . '/../..' . '/lib/payment-gateway/src/DefaultIconsRenderer.php',
     255        'Mollie\\Inpsyde\\PaymentGateway\\Fields\\ContentField' => __DIR__ . '/../..' . '/lib/payment-gateway/src/Fields/ContentField.php',
     256        'Mollie\\Inpsyde\\PaymentGateway\\GatewayIconsRendererInterface' => __DIR__ . '/../..' . '/lib/payment-gateway/src/GatewayIconsRendererInterface.php',
     257        'Mollie\\Inpsyde\\PaymentGateway\\I18n' => __DIR__ . '/../..' . '/lib/payment-gateway/src/I18n.php',
     258        'Mollie\\Inpsyde\\PaymentGateway\\Icon' => __DIR__ . '/../..' . '/lib/payment-gateway/src/Icon.php',
     259        'Mollie\\Inpsyde\\PaymentGateway\\IconProviderInterface' => __DIR__ . '/../..' . '/lib/payment-gateway/src/IconProviderInterface.php',
     260        'Mollie\\Inpsyde\\PaymentGateway\\Method\\CustomSettingsFields' => __DIR__ . '/../..' . '/lib/payment-gateway/src/Method/CustomSettingsFields.php',
     261        'Mollie\\Inpsyde\\PaymentGateway\\Method\\CustomSettingsFieldsDefinition' => __DIR__ . '/../..' . '/lib/payment-gateway/src/Method/CustomSettingsFieldsDefinition.php',
     262        'Mollie\\Inpsyde\\PaymentGateway\\Method\\DefaultPaymentMethodDefinitionTrait' => __DIR__ . '/../..' . '/lib/payment-gateway/src/Method/DefaultPaymentMethodDefinitionTrait.php',
     263        'Mollie\\Inpsyde\\PaymentGateway\\Method\\PaymentMethodDefinition' => __DIR__ . '/../..' . '/lib/payment-gateway/src/Method/PaymentMethodDefinition.php',
     264        'Mollie\\Inpsyde\\PaymentGateway\\NoopPaymentProcessor' => __DIR__ . '/../..' . '/lib/payment-gateway/src/NoopPaymentProcessor.php',
     265        'Mollie\\Inpsyde\\PaymentGateway\\NoopPaymentRequestValidator' => __DIR__ . '/../..' . '/lib/payment-gateway/src/NoopPaymentRequestValidator.php',
     266        'Mollie\\Inpsyde\\PaymentGateway\\NoopRefundProcessor' => __DIR__ . '/../..' . '/lib/payment-gateway/src/NoopRefundProcessor.php',
     267        'Mollie\\Inpsyde\\PaymentGateway\\PaymentFieldsRendererInterface' => __DIR__ . '/../..' . '/lib/payment-gateway/src/PaymentFieldsRendererInterface.php',
     268        'Mollie\\Inpsyde\\PaymentGateway\\PaymentGateway' => __DIR__ . '/../..' . '/lib/payment-gateway/src/PaymentGateway.php',
     269        'Mollie\\Inpsyde\\PaymentGateway\\PaymentGatewayBlocks' => __DIR__ . '/../..' . '/lib/payment-gateway/src/PaymentGatewayBlocks.php',
     270        'Mollie\\Inpsyde\\PaymentGateway\\PaymentGatewayModule' => __DIR__ . '/../..' . '/lib/payment-gateway/src/PaymentGatewayModule.php',
     271        'Mollie\\Inpsyde\\PaymentGateway\\PaymentGatewayValidator' => __DIR__ . '/../..' . '/lib/payment-gateway/src/PaymentGatewayValidator.php',
     272        'Mollie\\Inpsyde\\PaymentGateway\\PaymentMethodServiceProviderTrait' => __DIR__ . '/../..' . '/lib/payment-gateway/src/PaymentMethodServiceProviderTrait.php',
     273        'Mollie\\Inpsyde\\PaymentGateway\\PaymentProcessorInterface' => __DIR__ . '/../..' . '/lib/payment-gateway/src/PaymentProcessorInterface.php',
     274        'Mollie\\Inpsyde\\PaymentGateway\\PaymentRequestValidatorInterface' => __DIR__ . '/../..' . '/lib/payment-gateway/src/PaymentRequestValidatorInterface.php',
     275        'Mollie\\Inpsyde\\PaymentGateway\\RefundProcessorInterface' => __DIR__ . '/../..' . '/lib/payment-gateway/src/RefundProcessorInterface.php',
     276        'Mollie\\Inpsyde\\PaymentGateway\\ServiceKeyGenerator' => __DIR__ . '/../..' . '/lib/payment-gateway/src/ServiceKeyGenerator.php',
     277        'Mollie\\Inpsyde\\PaymentGateway\\SettingsFieldRendererInterface' => __DIR__ . '/../..' . '/lib/payment-gateway/src/SettingsFieldRendererInterface.php',
     278        'Mollie\\Inpsyde\\PaymentGateway\\SettingsFieldSanitizerInterface' => __DIR__ . '/../..' . '/lib/payment-gateway/src/SettingsFieldSanitizerInterface.php',
     279        'Mollie\\Inpsyde\\PaymentGateway\\StaticIconProvider' => __DIR__ . '/../..' . '/lib/payment-gateway/src/StaticIconProvider.php',
    232280        'Mollie\\Psr\\Container\\ContainerExceptionInterface' => __DIR__ . '/..' . '/psr/container/src/ContainerExceptionInterface.php',
    233281        'Mollie\\Psr\\Container\\ContainerInterface' => __DIR__ . '/..' . '/psr/container/src/ContainerInterface.php',
     
    265313        'Mollie\\WooCommerce\\Components\\ComponentsStyles' => __DIR__ . '/../..' . '/src/Components/ComponentsStyles.php',
    266314        'Mollie\\WooCommerce\\Components\\StylesPropertiesDictionary' => __DIR__ . '/../..' . '/src/Components/StylesPropertiesDictionary.php',
     315        'Mollie\\WooCommerce\\Gateway\\DeprecatedGatewayBuilder' => __DIR__ . '/../..' . '/src/Gateway/DeprecatedGatewayBuilder.php',
    267316        'Mollie\\WooCommerce\\Gateway\\GatewayModule' => __DIR__ . '/../..' . '/src/Gateway/GatewayModule.php',
    268         'Mollie\\WooCommerce\\Gateway\\MolliePaymentGateway' => __DIR__ . '/../..' . '/src/Gateway/MolliePaymentGateway.php',
    269         'Mollie\\WooCommerce\\Gateway\\MolliePaymentGatewayI' => __DIR__ . '/../..' . '/src/Gateway/MolliePaymentGatewayI.php',
     317        'Mollie\\WooCommerce\\Gateway\\MolliePaymentGatewayHandler' => __DIR__ . '/../..' . '/src/Gateway/MolliePaymentGatewayHandler.php',
    270318        'Mollie\\WooCommerce\\Gateway\\OrderMandatoryGatewayDisabler' => __DIR__ . '/../..' . '/src/Gateway/OrderMandatoryGatewayDisabler.php',
     319        'Mollie\\WooCommerce\\Gateway\\Refund\\OrderItemsRefunder' => __DIR__ . '/../..' . '/src/Gateway/Refund/OrderItemsRefunder.php',
     320        'Mollie\\WooCommerce\\Gateway\\Refund\\OrderLineStatus' => __DIR__ . '/../..' . '/src/Gateway/Refund/OrderLineStatus.php',
     321        'Mollie\\WooCommerce\\Gateway\\Refund\\PartialRefundException' => __DIR__ . '/../..' . '/src/Gateway/Refund/PartialRefundException.php',
     322        'Mollie\\WooCommerce\\Gateway\\Refund\\RefundLineItemsBuilder' => __DIR__ . '/../..' . '/src/Gateway/Refund/RefundLineItemsBuilder.php',
     323        'Mollie\\WooCommerce\\Gateway\\Refund\\RefundProcessor' => __DIR__ . '/../..' . '/src/Gateway/Refund/RefundProcessor.php',
    271324        'Mollie\\WooCommerce\\Gateway\\Surcharge' => __DIR__ . '/../..' . '/src/Gateway/Surcharge.php',
    272325        'Mollie\\WooCommerce\\Gateway\\Voucher\\MaybeDisableGateway' => __DIR__ . '/../..' . '/src/Gateway/Voucher/MaybeDisableGateway.php',
     
    306359        'Mollie\\WooCommerce\\PaymentMethods\\Giropay' => __DIR__ . '/../..' . '/src/PaymentMethods/Giropay.php',
    307360        'Mollie\\WooCommerce\\PaymentMethods\\IconFactory' => __DIR__ . '/../..' . '/src/PaymentMethods/IconFactory.php',
     361        'Mollie\\WooCommerce\\PaymentMethods\\Icon\\GatewayIconsRenderer' => __DIR__ . '/../..' . '/src/PaymentMethods/Icon/GatewayIconsRenderer.php',
    308362        'Mollie\\WooCommerce\\PaymentMethods\\Ideal' => __DIR__ . '/../..' . '/src/PaymentMethods/Ideal.php',
    309363        'Mollie\\WooCommerce\\PaymentMethods\\In3' => __DIR__ . '/../..' . '/src/PaymentMethods/In3.php',
     
    317371        'Mollie\\WooCommerce\\PaymentMethods\\InstructionStrategies\\InstructionStrategyI' => __DIR__ . '/../..' . '/src/PaymentMethods/InstructionStrategies/InstructionStrategyI.php',
    318372        'Mollie\\WooCommerce\\PaymentMethods\\InstructionStrategies\\MybankInstructionStrategy' => __DIR__ . '/../..' . '/src/PaymentMethods/InstructionStrategies/MybankInstructionStrategy.php',
     373        'Mollie\\WooCommerce\\PaymentMethods\\InstructionStrategies\\OrderInstructionsManager' => __DIR__ . '/../..' . '/src/PaymentMethods/InstructionStrategies/OrderInstructionsManager.php',
    319374        'Mollie\\WooCommerce\\PaymentMethods\\InstructionStrategies\\PaypalInstructionStrategy' => __DIR__ . '/../..' . '/src/PaymentMethods/InstructionStrategies/PaypalInstructionStrategy.php',
    320375        'Mollie\\WooCommerce\\PaymentMethods\\InstructionStrategies\\Przelewy24InstructionStrategy' => __DIR__ . '/../..' . '/src/PaymentMethods/InstructionStrategies/Przelewy24InstructionStrategy.php',
     
    330385        'Mollie\\WooCommerce\\PaymentMethods\\Paybybank' => __DIR__ . '/../..' . '/src/PaymentMethods/Paybybank.php',
    331386        'Mollie\\WooCommerce\\PaymentMethods\\Payconiq' => __DIR__ . '/../..' . '/src/PaymentMethods/Payconiq.php',
     387        'Mollie\\WooCommerce\\PaymentMethods\\PaymentFieldsStrategies\\AbstractPaymentFieldsRenderer' => __DIR__ . '/../..' . '/src/PaymentMethods/PaymentFieldsStrategies/AbstractPaymentFieldsRenderer.php',
    332388        'Mollie\\WooCommerce\\PaymentMethods\\PaymentFieldsStrategies\\BancomatpayFieldsStrategy' => __DIR__ . '/../..' . '/src/PaymentMethods/PaymentFieldsStrategies/BancomatpayFieldsStrategy.php',
    333389        'Mollie\\WooCommerce\\PaymentMethods\\PaymentFieldsStrategies\\BillieFieldsStrategy' => __DIR__ . '/../..' . '/src/PaymentMethods/PaymentFieldsStrategies/BillieFieldsStrategy.php',
     
    338394        'Mollie\\WooCommerce\\PaymentMethods\\PaymentFieldsStrategies\\IssuersDropdownBehavior' => __DIR__ . '/../..' . '/src/PaymentMethods/PaymentFieldsStrategies/IssuersDropdownBehavior.php',
    339395        'Mollie\\WooCommerce\\PaymentMethods\\PaymentFieldsStrategies\\KbcFieldsStrategy' => __DIR__ . '/../..' . '/src/PaymentMethods/PaymentFieldsStrategies/KbcFieldsStrategy.php',
     396        'Mollie\\WooCommerce\\PaymentMethods\\PaymentFieldsStrategies\\NoopPaymentFieldsRenderer' => __DIR__ . '/../..' . '/src/PaymentMethods/PaymentFieldsStrategies/NoopPaymentFieldsRenderer.php',
    340397        'Mollie\\WooCommerce\\PaymentMethods\\PaymentFieldsStrategies\\PaymentFieldsStrategiesTrait' => __DIR__ . '/../..' . '/src/PaymentMethods/PaymentFieldsStrategies/PaymentFieldsStrategiesTrait.php',
    341398        'Mollie\\WooCommerce\\PaymentMethods\\PaymentFieldsStrategies\\PaymentFieldsStrategyI' => __DIR__ . '/../..' . '/src/PaymentMethods/PaymentFieldsStrategies/PaymentFieldsStrategyI.php',
     
    361418        'Mollie\\WooCommerce\\Payment\\MolliePayment' => __DIR__ . '/../..' . '/src/Payment/MolliePayment.php',
    362419        'Mollie\\WooCommerce\\Payment\\MollieSubscription' => __DIR__ . '/../..' . '/src/Payment/MollieSubscription.php',
    363         'Mollie\\WooCommerce\\Payment\\OrderInstructionsService' => __DIR__ . '/../..' . '/src/Payment/OrderInstructionsService.php',
    364         'Mollie\\WooCommerce\\Payment\\OrderItemsRefunder' => __DIR__ . '/../..' . '/src/Payment/OrderItemsRefunder.php',
    365         'Mollie\\WooCommerce\\Payment\\OrderLineStatus' => __DIR__ . '/../..' . '/src/Payment/OrderLineStatus.php',
    366420        'Mollie\\WooCommerce\\Payment\\OrderLines' => __DIR__ . '/../..' . '/src/Payment/OrderLines.php',
    367         'Mollie\\WooCommerce\\Payment\\PartialRefundException' => __DIR__ . '/../..' . '/src/Payment/PartialRefundException.php',
    368421        'Mollie\\WooCommerce\\Payment\\PaymentCheckoutRedirectService' => __DIR__ . '/../..' . '/src/Payment/PaymentCheckoutRedirectService.php',
    369422        'Mollie\\WooCommerce\\Payment\\PaymentFactory' => __DIR__ . '/../..' . '/src/Payment/PaymentFactory.php',
    370         'Mollie\\WooCommerce\\Payment\\PaymentFieldsService' => __DIR__ . '/../..' . '/src/Payment/PaymentFieldsService.php',
     423        'Mollie\\WooCommerce\\Payment\\PaymentLines' => __DIR__ . '/../..' . '/src/Payment/PaymentLines.php',
    371424        'Mollie\\WooCommerce\\Payment\\PaymentModule' => __DIR__ . '/../..' . '/src/Payment/PaymentModule.php',
    372         'Mollie\\WooCommerce\\Payment\\PaymentService' => __DIR__ . '/../..' . '/src/Payment/PaymentService.php',
    373         'Mollie\\WooCommerce\\Payment\\RefundLineItemsBuilder' => __DIR__ . '/../..' . '/src/Payment/RefundLineItemsBuilder.php',
     425        'Mollie\\WooCommerce\\Payment\\PaymentProcessor' => __DIR__ . '/../..' . '/src/Payment/PaymentProcessor.php',
     426        'Mollie\\WooCommerce\\Payment\\Request\\Middleware\\AddCustomRequestFieldsMiddleware' => __DIR__ . '/../..' . '/src/Payment/Request/Middleware/AddCustomRequestFieldsMiddleware.php',
     427        'Mollie\\WooCommerce\\Payment\\Request\\Middleware\\AddSequenceTypeForSubscriptionsMiddleware' => __DIR__ . '/../..' . '/src/Payment/Request/Middleware/AddSequenceTypeForSubscriptionsMiddleware.php',
     428        'Mollie\\WooCommerce\\Payment\\Request\\Middleware\\AddressMiddleware' => __DIR__ . '/../..' . '/src/Payment/Request/Middleware/AddressMiddleware.php',
     429        'Mollie\\WooCommerce\\Payment\\Request\\Middleware\\ApplePayTokenMiddleware' => __DIR__ . '/../..' . '/src/Payment/Request/Middleware/ApplePayTokenMiddleware.php',
     430        'Mollie\\WooCommerce\\Payment\\Request\\Middleware\\CaptureModeMiddleware' => __DIR__ . '/../..' . '/src/Payment/Request/Middleware/CaptureModeMiddleware.php',
     431        'Mollie\\WooCommerce\\Payment\\Request\\Middleware\\CardTokenMiddleware' => __DIR__ . '/../..' . '/src/Payment/Request/Middleware/CardTokenMiddleware.php',
     432        'Mollie\\WooCommerce\\Payment\\Request\\Middleware\\CustomerBirthdateMiddleware' => __DIR__ . '/../..' . '/src/Payment/Request/Middleware/CustomerBirthdateMiddleware.php',
     433        'Mollie\\WooCommerce\\Payment\\Request\\Middleware\\MiddlewareHandler' => __DIR__ . '/../..' . '/src/Payment/Request/Middleware/MiddlewareHandler.php',
     434        'Mollie\\WooCommerce\\Payment\\Request\\Middleware\\OrderLinesMiddleware' => __DIR__ . '/../..' . '/src/Payment/Request/Middleware/OrderLinesMiddleware.php',
     435        'Mollie\\WooCommerce\\Payment\\Request\\Middleware\\PaymentDescriptionMiddleware' => __DIR__ . '/../..' . '/src/Payment/Request/Middleware/PaymentDescriptionMiddleware.php',
     436        'Mollie\\WooCommerce\\Payment\\Request\\Middleware\\RequestMiddlewareInterface' => __DIR__ . '/../..' . '/src/Payment/Request/Middleware/RequestMiddlewareInterface.php',
     437        'Mollie\\WooCommerce\\Payment\\Request\\Middleware\\SelectedIssuerMiddleware' => __DIR__ . '/../..' . '/src/Payment/Request/Middleware/SelectedIssuerMiddleware.php',
     438        'Mollie\\WooCommerce\\Payment\\Request\\Middleware\\StoreCustomerMiddleware' => __DIR__ . '/../..' . '/src/Payment/Request/Middleware/StoreCustomerMiddleware.php',
     439        'Mollie\\WooCommerce\\Payment\\Request\\Middleware\\UrlMiddleware' => __DIR__ . '/../..' . '/src/Payment/Request/Middleware/UrlMiddleware.php',
     440        'Mollie\\WooCommerce\\Payment\\Request\\RequestFactory' => __DIR__ . '/../..' . '/src/Payment/Request/RequestFactory.php',
     441        'Mollie\\WooCommerce\\Payment\\Request\\Strategies\\OrderRequestStrategy' => __DIR__ . '/../..' . '/src/Payment/Request/Strategies/OrderRequestStrategy.php',
     442        'Mollie\\WooCommerce\\Payment\\Request\\Strategies\\PaymentRequestStrategy' => __DIR__ . '/../..' . '/src/Payment/Request/Strategies/PaymentRequestStrategy.php',
     443        'Mollie\\WooCommerce\\Payment\\Request\\Strategies\\RequestStrategyInterface' => __DIR__ . '/../..' . '/src/Payment/Request/Strategies/RequestStrategyInterface.php',
    374444        'Mollie\\WooCommerce\\SDK\\Api' => __DIR__ . '/../..' . '/src/SDK/Api.php',
    375445        'Mollie\\WooCommerce\\SDK\\CouldNotConnectToMollie' => __DIR__ . '/../..' . '/src/SDK/CouldNotConnectToMollie.php',
     
    381451        'Mollie\\WooCommerce\\SDK\\WordPressHttpAdapterPicker' => __DIR__ . '/../..' . '/src/SDK/WordPressHttpAdapterPicker.php',
    382452        'Mollie\\WooCommerce\\Settings\\General\\MollieGeneralSettings' => __DIR__ . '/../..' . '/src/Settings/General/MollieGeneralSettings.php',
     453        'Mollie\\WooCommerce\\Settings\\General\\MultiCountrySettingsField' => __DIR__ . '/../..' . '/src/Settings/General/MultiCountrySettingsField.php',
    383454        'Mollie\\WooCommerce\\Settings\\MollieSettingsPage' => __DIR__ . '/../..' . '/src/Settings/MollieSettingsPage.php',
    384455        'Mollie\\WooCommerce\\Settings\\Page\\AbstractPage' => __DIR__ . '/../..' . '/src/Settings/Page/AbstractPage.php',
     
    407478        'Mollie\\WooCommerce\\Shared\\SharedModule' => __DIR__ . '/../..' . '/src/Shared/SharedModule.php',
    408479        'Mollie\\WooCommerce\\Shared\\Status' => __DIR__ . '/../..' . '/src/Shared/Status.php',
    409         'Mollie\\WooCommerce\\Subscription\\MaybeFixSubscription' => __DIR__ . '/../..' . '/src/Subscription/MaybeFixSubscription.php',
    410         'Mollie\\WooCommerce\\Subscription\\MollieSepaRecurringGateway' => __DIR__ . '/../..' . '/src/Subscription/MollieSepaRecurringGateway.php',
    411         'Mollie\\WooCommerce\\Subscription\\MollieSubscriptionGateway' => __DIR__ . '/../..' . '/src/Subscription/MollieSubscriptionGateway.php',
     480        'Mollie\\WooCommerce\\Subscription\\MollieSepaRecurringGatewayHandler' => __DIR__ . '/../..' . '/src/Subscription/MollieSepaRecurringGatewayHandler.php',
     481        'Mollie\\WooCommerce\\Subscription\\MollieSubscriptionGatewayHandler' => __DIR__ . '/../..' . '/src/Subscription/MollieSubscriptionGatewayHandler.php',
    412482        'Mollie\\WooCommerce\\Subscription\\SubscriptionModule' => __DIR__ . '/../..' . '/src/Subscription/SubscriptionModule.php',
    413483        'Mollie\\WooCommerce\\Uninstall\\CleanDb' => __DIR__ . '/../..' . '/src/Uninstall/CleanDb.php',
     
    418488    {
    419489        return \Closure::bind(function () use ($loader) {
    420             $loader->prefixLengthsPsr4 = ComposerStaticInitc0778a800f6c5eb39482522e8993a1d5::$prefixLengthsPsr4;
    421             $loader->prefixDirsPsr4 = ComposerStaticInitc0778a800f6c5eb39482522e8993a1d5::$prefixDirsPsr4;
    422             $loader->classMap = ComposerStaticInitc0778a800f6c5eb39482522e8993a1d5::$classMap;
     490            $loader->prefixLengthsPsr4 = ComposerStaticInitb1e8936703aa6cff296fa891dd9ccf25::$prefixLengthsPsr4;
     491            $loader->prefixDirsPsr4 = ComposerStaticInitb1e8936703aa6cff296fa891dd9ccf25::$prefixDirsPsr4;
     492            $loader->classMap = ComposerStaticInitb1e8936703aa6cff296fa891dd9ccf25::$classMap;
    423493
    424494        }, null, ClassLoader::class);
  • mollie-payments-for-woocommerce/trunk/vendor/composer/ca-bundle/res/cacert.pem

    r3226701 r3262577  
    22## Bundle of CA Root Certificates
    33##
    4 ## Certificate data from Mozilla as of: Tue Nov 26 13:58:25 2024 GMT
     4## Certificate data from Mozilla as of: Tue Dec 31 04:12:05 2024 GMT
    55##
    66## Find updated versions here: https://curl.se/docs/caextract.html
     
    1717##
    1818## Conversion done with mk-ca-bundle.pl version 1.29.
    19 ## SHA256: 36105b01631f9fc03b1eca779b44a30a1a5890b9bf8dc07ccb001a07301e01cf
     19## SHA256: c99d6d3f8d3d4e47719ba2b648992f5b58b150128d3aca3c05c566d8dc98e116
    2020##
    2121
     
    583583NwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2XjG4Kvte9nHfRCaexOYNkbQu
    584584dZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E=
    585 -----END CERTIFICATE-----
    586 
    587 SecureSign RootCA11
    588 ===================
    589 -----BEGIN CERTIFICATE-----
    590 MIIDbTCCAlWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJKUDErMCkGA1UEChMi
    591 SmFwYW4gQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcywgSW5jLjEcMBoGA1UEAxMTU2VjdXJlU2lnbiBS
    592 b290Q0ExMTAeFw0wOTA0MDgwNDU2NDdaFw0yOTA0MDgwNDU2NDdaMFgxCzAJBgNVBAYTAkpQMSsw
    593 KQYDVQQKEyJKYXBhbiBDZXJ0aWZpY2F0aW9uIFNlcnZpY2VzLCBJbmMuMRwwGgYDVQQDExNTZWN1
    594 cmVTaWduIFJvb3RDQTExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/XeqpRyQBTvL
    595 TJszi1oURaTnkBbR31fSIRCkF/3frNYfp+TbfPfs37gD2pRY/V1yfIw/XwFndBWW4wI8h9uuywGO
    596 wvNmxoVF9ALGOrVisq/6nL+k5tSAMJjzDbaTj6nU2DbysPyKyiyhFTOVMdrAG/LuYpmGYz+/3ZMq
    597 g6h2uRMft85OQoWPIucuGvKVCbIFtUROd6EgvanyTgp9UK31BQ1FT0Zx/Sg+U/sE2C3XZR1KG/rP
    598 O7AxmjVuyIsG0wCR8pQIZUyxNAYAeoni8McDWc/V1uinMrPmmECGxc0nEovMe863ETxiYAcjPitA
    599 bpSACW22s293bzUIUPsCh8U+iQIDAQABo0IwQDAdBgNVHQ4EFgQUW/hNT7KlhtQ60vFjmqC+CfZX
    600 t94wDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAKCh
    601 OBZmLqdWHyGcBvod7bkixTgm2E5P7KN/ed5GIaGHd48HCJqypMWvDzKYC3xmKbabfSVSSUOrTC4r
    602 bnpwrxYO4wJs+0LmGJ1F2FXI6Dvd5+H0LgscNFxsWEr7jIhQX5Ucv+2rIrVls4W6ng+4reV6G4pQ
    603 Oh29Dbx7VFALuUKvVaAYga1lme++5Jy/xIWrQbJUb9wlze144o4MjQlJ3WN7WmmWAiGovVJZ6X01
    604 y8hSyn+B/tlr0/cR7SXf+Of5pPpyl4RTDaXQMhhRdlkUbA/r7F+AjHVDg8OFmP9Mni0N5HeDk061
    605 lgeLKBObjBmNQSdJQO7e5iNEOdyhIta6A/I=
    606585-----END CERTIFICATE-----
    607586
     
    23202299-----END CERTIFICATE-----
    23212300
    2322 Entrust Root Certification Authority - G4
    2323 =========================================
    2324 -----BEGIN CERTIFICATE-----
    2325 MIIGSzCCBDOgAwIBAgIRANm1Q3+vqTkPAAAAAFVlrVgwDQYJKoZIhvcNAQELBQAwgb4xCzAJBgNV
    2326 BAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3Qu
    2327 bmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxNSBFbnRydXN0LCBJbmMuIC0gZm9yIGF1
    2328 dGhvcml6ZWQgdXNlIG9ubHkxMjAwBgNVBAMTKUVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1
    2329 dGhvcml0eSAtIEc0MB4XDTE1MDUyNzExMTExNloXDTM3MTIyNzExNDExNlowgb4xCzAJBgNVBAYT
    2330 AlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0
    2331 L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxNSBFbnRydXN0LCBJbmMuIC0gZm9yIGF1dGhv
    2332 cml6ZWQgdXNlIG9ubHkxMjAwBgNVBAMTKUVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhv
    2333 cml0eSAtIEc0MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAsewsQu7i0TD/pZJH4i3D
    2334 umSXbcr3DbVZwbPLqGgZ2K+EbTBwXX7zLtJTmeH+H17ZSK9dE43b/2MzTdMAArzE+NEGCJR5WIoV
    2335 3imz/f3ET+iq4qA7ec2/a0My3dl0ELn39GjUu9CH1apLiipvKgS1sqbHoHrmSKvS0VnM1n4j5pds
    2336 8ELl3FFLFUHtSUrJ3hCX1nbB76W1NhSXNdh4IjVS70O92yfbYVaCNNzLiGAMC1rlLAHGVK/XqsEQ
    2337 e9IFWrhAnoanw5CGAlZSCXqc0ieCU0plUmr1POeo8pyvi73TDtTUXm6Hnmo9RR3RXRv06QqsYJn7
    2338 ibT/mCzPfB3pAqoEmh643IhuJbNsZvc8kPNXwbMv9W3y+8qh+CmdRouzavbmZwe+LGcKKh9asj5X
    2339 xNMhIWNlUpEbsZmOeX7m640A2Vqq6nPopIICR5b+W45UYaPrL0swsIsjdXJ8ITzI9vF01Bx7owVV
    2340 7rtNOzK+mndmnqxpkCIHH2E6lr7lmk/MBTwoWdPBDFSoWWG9yHJM6Nyfh3+9nEg2XpWjDrk4JFX8
    2341 dWbrAuMINClKxuMrLzOg2qOGpRKX/YAr2hRC45K9PvJdXmd0LhyIRyk0X+IyqJwlN4y6mACXi0mW
    2342 Hv0liqzc2thddG5msP9E36EYxr5ILzeUePiVSj9/E15dWf10hkNjc0kCAwEAAaNCMEAwDwYDVR0T
    2343 AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJ84xFYjwznooHFs6FRM5Og6sb9n
    2344 MA0GCSqGSIb3DQEBCwUAA4ICAQAS5UKme4sPDORGpbZgQIeMJX6tuGguW8ZAdjwD+MlZ9POrYs4Q
    2345 jbRaZIxowLByQzTSGwv2LFPSypBLhmb8qoMi9IsabyZIrHZ3CL/FmFz0Jomee8O5ZDIBf9PD3Vht
    2346 7LGrhFV0d4QEJ1JrhkzO3bll/9bGXp+aEJlLdWr+aumXIOTkdnrG0CSqkM0gkLpHZPt/B7NTeLUK
    2347 YvJzQ85BK4FqLoUWlFPUa19yIqtRLULVAJyZv967lDtX/Zr1hstWO1uIAeV8KEsD+UmDfLJ/fOPt
    2348 jqF/YFOOVZ1QNBIPt5d7bIdKROf1beyAN/BYGW5KaHbwH5Lk6rWS02FREAutp9lfx1/cH6NcjKF+
    2349 m7ee01ZvZl4HliDtC3T7Zk6LERXpgUl+b7DUUH8i119lAg2m9IUe2K4GS0qn0jFmwvjO5QimpAKW
    2350 RGhXxNUzzxkvFMSUHHuk2fCfDrGA4tGeEWSpiBE6doLlYsKA2KSD7ZPvfC+QsDJMlhVoSFLUmQjA
    2351 JOgc47OlIQ6SwJAfzyBfyjs4x7dtOvPmRLgOMWuIjnDrnBdSqEGULoe256YSxXXfW8AKbnuk5F6G
    2352 +TaU33fD6Q3AOfF5u0aOq0NZJ7cguyPpVkAh7DE9ZapD8j3fcEThuk0mEDuYn/PIjhs4ViFqUZPT
    2353 kcpG2om3PVODLAgfi49T3f+sHw==
    2354 -----END CERTIFICATE-----
    2355 
    23562301Microsoft ECC Root Certificate Authority 2017
    23572302=============================================
     
    31713116-----END CERTIFICATE-----
    31723117
    3173 Security Communication RootCA3
    3174 ==============================
    3175 -----BEGIN CERTIFICATE-----
    3176 MIIFfzCCA2egAwIBAgIJAOF8N0D9G/5nMA0GCSqGSIb3DQEBDAUAMF0xCzAJBgNVBAYTAkpQMSUw
    3177 IwYDVQQKExxTRUNPTSBUcnVzdCBTeXN0ZW1zIENPLixMVEQuMScwJQYDVQQDEx5TZWN1cml0eSBD
    3178 b21tdW5pY2F0aW9uIFJvb3RDQTMwHhcNMTYwNjE2MDYxNzE2WhcNMzgwMTE4MDYxNzE2WjBdMQsw
    3179 CQYDVQQGEwJKUDElMCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UE
    3180 AxMeU2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBSb290Q0EzMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A
    3181 MIICCgKCAgEA48lySfcw3gl8qUCBWNO0Ot26YQ+TUG5pPDXC7ltzkBtnTCHsXzW7OT4rCmDvu20r
    3182 hvtxosis5FaU+cmvsXLUIKx00rgVrVH+hXShuRD+BYD5UpOzQD11EKzAlrenfna84xtSGc4RHwsE
    3183 NPXY9Wk8d/Nk9A2qhd7gCVAEF5aEt8iKvE1y/By7z/MGTfmfZPd+pmaGNXHIEYBMwXFAWB6+oHP2
    3184 /D5Q4eAvJj1+XCO1eXDe+uDRpdYMQXF79+qMHIjH7Iv10S9VlkZ8WjtYO/u62C21Jdp6Ts9EriGm
    3185 npjKIG58u4iFW/vAEGK78vknR+/RiTlDxN/e4UG/VHMgly1s2vPUB6PmudhvrvyMGS7TZ2crldtY
    3186 XLVqAvO4g160a75BflcJdURQVc1aEWEhCmHCqYj9E7wtiS/NYeCVvsq1e+F7NGcLH7YMx3weGVPK
    3187 p7FKFSBWFHA9K4IsD50VHUeAR/94mQ4xr28+j+2GaR57GIgUssL8gjMunEst+3A7caoreyYn8xrC
    3188 3PsXuKHqy6C0rtOUfnrQq8PsOC0RLoi/1D+tEjtCrI8Cbn3M0V9hvqG8OmpI6iZVIhZdXw3/JzOf
    3189 GAN0iltSIEdrRU0id4xVJ/CvHozJgyJUt5rQT9nO/NkuHJYosQLTA70lUhw0Zk8jq/R3gpYd0Vcw
    3190 CBEF/VfR2ccCAwEAAaNCMEAwHQYDVR0OBBYEFGQUfPxYchamCik0FW8qy7z8r6irMA4GA1UdDwEB
    3191 /wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBDAUAA4ICAQDcAiMI4u8hOscNtybS
    3192 YpOnpSNyByCCYN8Y11StaSWSntkUz5m5UoHPrmyKO1o5yGwBQ8IibQLwYs1OY0PAFNr0Y/Dq9HHu
    3193 Tofjcan0yVflLl8cebsjqodEV+m9NU1Bu0soo5iyG9kLFwfl9+qd9XbXv8S2gVj/yP9kaWJ5rW4O
    3194 H3/uHWnlt3Jxs/6lATWUVCvAUm2PVcTJ0rjLyjQIUYWg9by0F1jqClx6vWPGOi//lkkZhOpn2ASx
    3195 YfQAW0q3nHE3GYV5v4GwxxMOdnE+OoAGrgYWp421wsTL/0ClXI2lyTrtcoHKXJg80jQDdwj98ClZ
    3196 XSEIx2C/pHF7uNkegr4Jr2VvKKu/S7XuPghHJ6APbw+LP6yVGPO5DtxnVW5inkYO0QR4ynKudtml
    3197 +LLfiAlhi+8kTtFZP1rUPcmTPCtk9YENFpb3ksP+MW/oKjJ0DvRMmEoYDjBU1cXrvMUVnuiZIesn
    3198 KwkK2/HmcBhWuwzkvvnoEKQTkrgc4NtnHVMDpCKn3F2SEDzq//wbEBrD2NCcnWXL0CsnMQMeNuE9
    3199 dnUM/0Umud1RvCPHX9jYhxBAEg09ODfnRDwYwFMJZI//1ZqmfHAuc1Uh6N//g7kdPjIe1qZ9LPFm
    3200 6Vwdp6POXiUyK+OVrCoHzrQoeIY8LaadTdJ0MN1kURXbg4NR16/9M51NZg==
    3201 -----END CERTIFICATE-----
    3202 
    32033118Security Communication ECC RootCA1
    32043119==================================
  • mollie-payments-for-woocommerce/trunk/vendor/composer/installed.json

    r3226701 r3262577  
    33        {
    44            "name": "composer\/ca-bundle",
    5             "version": "1.5.4",
    6             "version_normalized": "1.5.4.0",
     5            "version": "1.5.5",
     6            "version_normalized": "1.5.5.0",
    77            "source": {
    88                "type": "git",
    99                "url": "https:\/\/github.com\/composer\/ca-bundle.git",
    10                 "reference": "bc0593537a463e55cadf45fd938d23b75095b7e1"
    11             },
    12             "dist": {
    13                 "type": "zip",
    14                 "url": "https:\/\/api.github.com\/repos\/composer\/ca-bundle\/zipball\/bc0593537a463e55cadf45fd938d23b75095b7e1",
    15                 "reference": "bc0593537a463e55cadf45fd938d23b75095b7e1",
     10                "reference": "08c50d5ec4c6ced7d0271d2862dec8c1033283e6"
     11            },
     12            "dist": {
     13                "type": "zip",
     14                "url": "https:\/\/api.github.com\/repos\/composer\/ca-bundle\/zipball\/08c50d5ec4c6ced7d0271d2862dec8c1033283e6",
     15                "reference": "08c50d5ec4c6ced7d0271d2862dec8c1033283e6",
    1616                "shasum": ""
    1717            },
     
    2727                "symfony\/process": "^4.0 || ^5.0 || ^6.0 || ^7.0"
    2828            },
    29             "time": "2024-11-27T15:35:25+00:00",
     29            "time": "2025-01-08T16:17:16+00:00",
    3030            "type": "library",
    3131            "extra": {
     
    6262                "irc": "irc:\/\/irc.freenode.org\/composer",
    6363                "issues": "https:\/\/github.com\/composer\/ca-bundle\/issues",
    64                 "source": "https:\/\/github.com\/composer\/ca-bundle\/tree\/1.5.4"
     64                "source": "https:\/\/github.com\/composer\/ca-bundle\/tree\/1.5.5"
    6565            },
    6666            "funding": [
     
    7979            ],
    8080            "install-path": ".\/ca-bundle"
     81        },
     82        {
     83            "name": "dhii\/services",
     84            "version": "v0.1.0",
     85            "version_normalized": "0.1.0.0",
     86            "source": {
     87                "type": "git",
     88                "url": "https:\/\/github.com\/Dhii\/services.git",
     89                "reference": "09cad8199a59d2003ad19126213075aefecaf17b"
     90            },
     91            "dist": {
     92                "type": "zip",
     93                "url": "https:\/\/api.github.com\/repos\/Dhii\/services\/zipball\/09cad8199a59d2003ad19126213075aefecaf17b",
     94                "reference": "09cad8199a59d2003ad19126213075aefecaf17b",
     95                "shasum": ""
     96            },
     97            "require": {
     98                "php": "^7.1 | ^8.0",
     99                "psr\/container": "^1.0"
     100            },
     101            "require-dev": {
     102                "codeclimate\/php-test-reporter": "<=0.3.2",
     103                "phpunit\/phpunit": "^7.0 | ^8.0 | ^9.0",
     104                "slevomat\/coding-standard": "^6.0",
     105                "vimeo\/psalm": "^4.0"
     106            },
     107            "time": "2022-01-06T14:57:20+00:00",
     108            "type": "library",
     109            "installation-source": "dist",
     110            "autoload": {
     111                "psr-4": {
     112                    "Mollie\\Dhii\\Services\\": "src"
     113                }
     114            },
     115            "notification-url": "https:\/\/packagist.org\/downloads\/",
     116            "license": [
     117                "MIT"
     118            ],
     119            "authors": [
     120                {
     121                    "name": "Dhii Team",
     122                    "email": "[email protected]"
     123                }
     124            ],
     125            "description": "A collection of useful DI service implementations.",
     126            "support": {
     127                "issues": "https:\/\/github.com\/Dhii\/services\/issues",
     128                "source": "https:\/\/github.com\/Dhii\/services\/tree\/v0.1.0"
     129            },
     130            "install-path": "..\/dhii\/services"
    81131        },
    82132        {
     
    143193        {
    144194            "name": "mollie\/mollie-api-php",
    145             "version": "v2.76.0",
    146             "version_normalized": "2.76.0.0",
     195            "version": "v2.76.1",
     196            "version_normalized": "2.76.1.0",
    147197            "source": {
    148198                "type": "git",
    149199                "url": "https:\/\/github.com\/mollie\/mollie-api-php.git",
    150                 "reference": "b6e9848e4893d1d306fba54da3ac6f4a31a40368"
    151             },
    152             "dist": {
    153                 "type": "zip",
    154                 "url": "https:\/\/api.github.com\/repos\/mollie\/mollie-api-php\/zipball\/b6e9848e4893d1d306fba54da3ac6f4a31a40368",
    155                 "reference": "b6e9848e4893d1d306fba54da3ac6f4a31a40368",
     200                "reference": "2a90a9224e6dcc25569e572edfe57ba75455e435"
     201            },
     202            "dist": {
     203                "type": "zip",
     204                "url": "https:\/\/api.github.com\/repos\/mollie\/mollie-api-php\/zipball\/2a90a9224e6dcc25569e572edfe57ba75455e435",
     205                "reference": "2a90a9224e6dcc25569e572edfe57ba75455e435",
    156206                "shasum": ""
    157207            },
     
    173223                "mollie\/oauth2-mollie-php": "Use OAuth to authenticate with the Mollie API. This is needed for some endpoints. Visit https:\/\/docs.mollie.com\/ for more information."
    174224            },
    175             "time": "2024-12-18T12:26:03+00:00",
     225            "time": "2025-01-24T14:59:44+00:00",
    176226            "type": "library",
    177227            "installation-source": "dist",
     
    232282            "support": {
    233283                "issues": "https:\/\/github.com\/mollie\/mollie-api-php\/issues",
    234                 "source": "https:\/\/github.com\/mollie\/mollie-api-php\/tree\/v2.76.0"
     284                "source": "https:\/\/github.com\/mollie\/mollie-api-php\/tree\/v2.76.1"
    235285            },
    236286            "install-path": "..\/mollie\/mollie-api-php"
  • mollie-payments-for-woocommerce/trunk/vendor/composer/installed.php

    r3242448 r3262577  
    33namespace Mollie;
    44
    5 return array('root' => array('name' => 'mollie/mollie-woocommerce', 'pretty_version' => 'dev-develop', 'version' => 'dev-develop', 'reference' => '4c05485f591d8cdba6a58fd5a9982b258649e4c2', 'type' => 'wordpress-plugin', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), 'dev' => \false), 'versions' => array('composer/ca-bundle' => array('pretty_version' => '1.5.4', 'version' => '1.5.4.0', 'reference' => 'bc0593537a463e55cadf45fd938d23b75095b7e1', 'type' => 'library', 'install_path' => __DIR__ . '/./ca-bundle', 'aliases' => array(), 'dev_requirement' => \false), 'inpsyde/modularity' => array('pretty_version' => '1.11.0', 'version' => '1.11.0.0', 'reference' => 'c79bb3682f55e1a2ece67f36e70d04fa2ab8c65d', 'type' => 'library', 'install_path' => __DIR__ . '/../inpsyde/modularity', 'aliases' => array(), 'dev_requirement' => \false), 'mollie/mollie-api-php' => array('pretty_version' => 'v2.76.0', 'version' => '2.76.0.0', 'reference' => 'b6e9848e4893d1d306fba54da3ac6f4a31a40368', 'type' => 'library', 'install_path' => __DIR__ . '/../mollie/mollie-api-php', 'aliases' => array(), 'dev_requirement' => \false), 'mollie/mollie-woocommerce' => array('pretty_version' => 'dev-develop', 'version' => 'dev-develop', 'reference' => '4c05485f591d8cdba6a58fd5a9982b258649e4c2', 'type' => 'wordpress-plugin', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), 'dev_requirement' => \false), 'psr/container' => array('pretty_version' => '1.1.0', 'version' => '1.1.0.0', 'reference' => '9fc7aab7a78057a124384358ebae8a1711b6f6fc', 'type' => 'library', 'install_path' => __DIR__ . '/../psr/container', 'aliases' => array(), 'dev_requirement' => \false), 'psr/log' => array('pretty_version' => '1.1.4', 'version' => '1.1.4.0', 'reference' => 'd49695b909c3b7628b6289db5479a1c204601f11', 'type' => 'library', 'install_path' => __DIR__ . '/../psr/log', 'aliases' => array(), 'dev_requirement' => \false), 'sniccowp/php-scoper-wordpress-excludes' => array('pretty_version' => '6.7.1', 'version' => '6.7.1.0', 'reference' => 'd8e6b5fdc9e42300a8ab18b44b775836a7b52363', 'type' => 'library', 'install_path' => __DIR__ . '/../sniccowp/php-scoper-wordpress-excludes', 'aliases' => array(), 'dev_requirement' => \false)));
     5return array('root' => array('name' => 'mollie/mollie-woocommerce', 'pretty_version' => 'dev-develop', 'version' => 'dev-develop', 'reference' => 'f04128ceada3f2294561dce9cc3caa9722c4fbb1', 'type' => 'wordpress-plugin', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), 'dev' => \false), 'versions' => array('composer/ca-bundle' => array('pretty_version' => '1.5.5', 'version' => '1.5.5.0', 'reference' => '08c50d5ec4c6ced7d0271d2862dec8c1033283e6', 'type' => 'library', 'install_path' => __DIR__ . '/./ca-bundle', 'aliases' => array(), 'dev_requirement' => \false), 'dhii/services' => array('pretty_version' => 'v0.1.0', 'version' => '0.1.0.0', 'reference' => '09cad8199a59d2003ad19126213075aefecaf17b', 'type' => 'library', 'install_path' => __DIR__ . '/../dhii/services', 'aliases' => array(), 'dev_requirement' => \false), 'inpsyde/modularity' => array('pretty_version' => '1.11.0', 'version' => '1.11.0.0', 'reference' => 'c79bb3682f55e1a2ece67f36e70d04fa2ab8c65d', 'type' => 'library', 'install_path' => __DIR__ . '/../inpsyde/modularity', 'aliases' => array(), 'dev_requirement' => \false), 'mollie/mollie-api-php' => array('pretty_version' => 'v2.76.1', 'version' => '2.76.1.0', 'reference' => '2a90a9224e6dcc25569e572edfe57ba75455e435', 'type' => 'library', 'install_path' => __DIR__ . '/../mollie/mollie-api-php', 'aliases' => array(), 'dev_requirement' => \false), 'mollie/mollie-woocommerce' => array('pretty_version' => 'dev-develop', 'version' => 'dev-develop', 'reference' => 'f04128ceada3f2294561dce9cc3caa9722c4fbb1', 'type' => 'wordpress-plugin', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), 'dev_requirement' => \false), 'psr/container' => array('pretty_version' => '1.1.0', 'version' => '1.1.0.0', 'reference' => '9fc7aab7a78057a124384358ebae8a1711b6f6fc', 'type' => 'library', 'install_path' => __DIR__ . '/../psr/container', 'aliases' => array(), 'dev_requirement' => \false), 'psr/log' => array('pretty_version' => '1.1.4', 'version' => '1.1.4.0', 'reference' => 'd49695b909c3b7628b6289db5479a1c204601f11', 'type' => 'library', 'install_path' => __DIR__ . '/../psr/log', 'aliases' => array(), 'dev_requirement' => \false), 'sniccowp/php-scoper-wordpress-excludes' => array('pretty_version' => '6.7.1', 'version' => '6.7.1.0', 'reference' => 'd8e6b5fdc9e42300a8ab18b44b775836a7b52363', 'type' => 'library', 'install_path' => __DIR__ . '/../sniccowp/php-scoper-wordpress-excludes', 'aliases' => array(), 'dev_requirement' => \false)));
  • mollie-payments-for-woocommerce/trunk/vendor/mollie/mollie-api-php/src/Endpoints/CustomerEndpoint.php

    r3164004 r3262577  
    7676    {
    7777        if (empty($customerId) || strpos($customerId, self::RESOURCE_ID_PREFIX) !== 0) {
    78             throw new ApiException("Invalid order ID: '{$customerId}'. An order ID should start with '" . self::RESOURCE_ID_PREFIX . "'.");
     78            throw new ApiException("Invalid customer ID: '{$customerId}'. A customer ID should start with '" . self::RESOURCE_ID_PREFIX . "'.");
    7979        }
    8080        return parent::rest_update($customerId, $data);
  • mollie-payments-for-woocommerce/trunk/vendor/mollie/mollie-api-php/src/Endpoints/ProfileEndpoint.php

    r3164004 r3262577  
    8282    {
    8383        if (empty($profileId) || strpos($profileId, self::RESOURCE_ID_PREFIX) !== 0) {
    84             throw new ApiException("Invalid profile id: '{$profileId}'. An profile id should start with '" . self::RESOURCE_ID_PREFIX . "'.");
     84            throw new ApiException("Invalid profile ID: '{$profileId}'. A profile ID should start with '" . self::RESOURCE_ID_PREFIX . "'.");
    8585        }
    8686        return parent::rest_update($profileId, $data);
  • mollie-payments-for-woocommerce/trunk/vendor/mollie/mollie-api-php/src/Endpoints/ShipmentEndpoint.php

    r3164004 r3262577  
    111111    {
    112112        if (empty($shipmentId) || strpos($shipmentId, self::RESOURCE_ID_PREFIX) !== 0) {
    113             throw new ApiException("Invalid subscription ID: '{$shipmentId}'. An subscription ID should start with '" . self::RESOURCE_ID_PREFIX . "'.");
     113            throw new ApiException("Invalid shipment ID: '{$shipmentId}'. A shipment ID should start with '" . self::RESOURCE_ID_PREFIX . "'.");
    114114        }
    115115        $this->parentId = $orderId;
  • mollie-payments-for-woocommerce/trunk/vendor/mollie/mollie-api-php/src/Endpoints/SubscriptionEndpoint.php

    r3226701 r3262577  
    8282    {
    8383        if (empty($subscriptionId) || strpos($subscriptionId, self::RESOURCE_ID_PREFIX) !== 0) {
    84             throw new ApiException("Invalid subscription ID: '{$subscriptionId}'. An subscription ID should start with '" . self::RESOURCE_ID_PREFIX . "'.");
     84            throw new ApiException("Invalid subscription ID: '{$subscriptionId}'. A subscription ID should start with '" . self::RESOURCE_ID_PREFIX . "'.");
    8585        }
    8686        $this->parentId = $customerId;
  • mollie-payments-for-woocommerce/trunk/vendor/mollie/mollie-api-php/src/MollieApiClient.php

    r3226701 r3262577  
    5555     * Version of our client.
    5656     */
    57     public const CLIENT_VERSION = "2.76.0";
     57    public const CLIENT_VERSION = "2.76.1";
    5858    /**
    5959     * Endpoint of the remote API.
Note: See TracChangeset for help on using the changeset viewer.