APE Price: $1.12 (-1.85%)

Contract

0x9A1D001A842c5e6C74b33F2aeEdEc07F0Cb20BC4

Overview

APE Balance

Apechain LogoApechain LogoApechain Logo0 APE

APE Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To

There are no matching entries

Please try again later

Latest 1 internal transaction

Parent Transaction Hash Block From To
46202002024-11-18 23:39:0015 hrs ago1731973140  Contract Creation0 APE

Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
CollectionSettingsRegistry

Compiler Version
v0.8.24+commit.e11b9ed9

Optimization Enabled:
Yes with 40000 runs

Other Settings:
cancun EvmVersion, None license
File 1 of 8 : CollectionSettingsRegistry.sol
//SPDX-License-Identifier: LicenseRef-PolyForm-Strict-1.0.0
pragma solidity 0.8.24;

import "./Errors.sol";
import "./SettingsConstants.sol";
import "./SettingsDataTypes.sol";
import "./IPaymentProcessorSettings.sol";
import "./ICollectionSettingsRegistry.sol";
import "@limitbreak/tm-core-lib/src/utils/structs/EnumerableSet.sol";
import "@limitbreak/tm-core-lib/src/licenses/LicenseRef-PolyForm-Strict-1.0.0.sol";

/** 
* @title CollectionSettingsRegistry
* @custom:version 3.0.0
* @author Limit Break, Inc.
*/ 
contract CollectionSettingsRegistry is ICollectionSettingsRegistry {
    using EnumerableSet for EnumerableSet.AddressSet;

    uint32 public lastPaymentMethodWhitelistId;

    // Core Settings Available For All Payment Processor Versions (3.0+)
    mapping (address collection => CollectionRegistryPaymentSettings) private _collectionPaymentSettings;
    mapping (address => address) private _collectionExclusiveBountyReceivers;
    mapping (address => address) private _collectionBoundedPricingPaymentMethods;
    mapping (address => RegistryPricingBounds) private _collectionPricingBounds;
    mapping (address => mapping (uint256 => RegistryPricingBounds)) private _tokenPricingBounds;
    mapping (address => EnumerableSet.AddressSet) private _collectionTrustedChannels;

    /// @dev An enumerable set of trusted permit processors that may be used with a Payment Processor.
    EnumerableSet.AddressSet private _trustedPermitProcessors;

    // Payment Method Whitelists
    mapping (uint32 => address) private _paymentMethodWhitelistOwners;
    mapping (uint32 => EnumerableSet.AddressSet) private _paymentMethodWhitelists;

    // Extended Settings Available For All Future Payment Processor Versions (3.0+)
    mapping (address collection => mapping (bytes32 extension => bytes data)) private _collectionSettingsExtensionData;
    mapping (address collection => mapping (bytes32 extension => bytes32 word)) private _collectionSettingsExtensionWords;

    constructor(address defaultContractOwner_) {
        unchecked {
            uint32 paymentMethodWhitelistId = lastPaymentMethodWhitelistId++;
            if (paymentMethodWhitelistId != DEFAULT_PAYMENT_METHOD_WHITELIST_ID || 
                lastPaymentMethodWhitelistId <= DEFAULT_PAYMENT_METHOD_WHITELIST_ID) {
                revert CollectionSettingsRegistry__PaymentMethodWhitelistInvalidState();
            }
            _paymentMethodWhitelistOwners[paymentMethodWhitelistId] = defaultContractOwner_;
            emit CreatedPaymentMethodWhitelist(paymentMethodWhitelistId, defaultContractOwner_, "Default Payment Methods");
        }
    }

    /**
     * @notice Allows any user to create a new custom payment method whitelist.
     *
     * @dev    <h4>Postconditions:</h4>
     * @dev    1. The payment method whitelist id tracker has been incremented by `1`.
     * @dev    2. The caller has been assigned as the owner of the payment method whitelist.
     * @dev    3. A `CollectionSettingsRegistry__CreatedPaymentMethodWhitelist` event has been emitted.
     *
     * @param  whitelistName             The name of the payment method whitelist.
     * @return paymentMethodWhitelistId  The id of the newly created payment method whitelist.
     */
    function createPaymentMethodWhitelist(
        string calldata whitelistName
    ) external returns (uint32 paymentMethodWhitelistId) {
        address listCreator = msg.sender;
        paymentMethodWhitelistId = lastPaymentMethodWhitelistId++;
        _paymentMethodWhitelistOwners[paymentMethodWhitelistId] = listCreator;
        emit CreatedPaymentMethodWhitelist(paymentMethodWhitelistId, listCreator, whitelistName);
    }

    /**
     * @notice Transfer ownership of a payment method whitelist list to a new owner.
     *
     * @dev Throws when the new owner is the zero address.
     * @dev Throws when the caller does not own the specified list.
     *
     * @dev <h4>Postconditions:</h4>
     *      1. The payment method whitelist list ownership is transferred to the new owner.
     *      2. A `ReassignedPaymentMethodWhitelistOwnership` event is emitted.
     *
     * @param id       The id of the payment method whitelist.
     * @param newOwner The address of the new owner.
     */
    function reassignOwnershipOfPaymentMethodWhitelist(uint32 id, address newOwner) external {
        if(newOwner == address(0)) {
            revert CollectionSettingsRegistry__PaymentMethodWhitelistOwnershipCannotBeTransferredToZeroAddress();
        }

        _reassignOwnershipOfPaymentMethodWhitelist(id, newOwner);
    }

    /**
     * @notice Renounce the ownership of a payment method whitelist, rendering the list immutable.
     *
     * @dev Throws when the caller does not own the specified list.
     *
     * @dev <h4>Postconditions:</h4>
     *      1. The ownership of the specified payment method whitelist is renounced.
     *      2. A `ReassignedPaymentMethodWhitelistOwnership` event is emitted.
     *
     * @param id The id of the payment method whitelist.
     */
    function renounceOwnershipOfPaymentMethodWhitelist(uint32 id) external {
        _reassignOwnershipOfPaymentMethodWhitelist(id, address(0));
    }

    /**
     * @notice Allows custom payment method whitelist owners to approve a new coin for use as a payment currency.
     *
     * @dev    Throws when caller is not the owner of the specified payment method whitelist.
     * @dev    Throws when the specified coin is already whitelisted under the specified whitelist id.
     *
     * @dev    <h4>Postconditions:</h4>
     * @dev    1. `paymentMethod` has been approved in `paymentMethodWhitelist` mapping.
     * @dev    2. A `PaymentMethodAddedToWhitelist` event has been emitted.
     *
     * @param  paymentMethodWhitelistId The id of the payment method whitelist to update.
     * @param  paymentMethods           The address of the payment method to whitelist.
     */
    function whitelistPaymentMethod(
        uint32 paymentMethodWhitelistId, 
        address[] calldata paymentMethods,
        address[] calldata paymentProcessorsToSync
    ) external {
        _requireCallerOwnsPaymentMethodWhitelist(paymentMethodWhitelistId);

        EnumerableSet.AddressSet storage ptrPaymentMethods = _paymentMethodWhitelists[paymentMethodWhitelistId];
        for (uint256 i; i < paymentMethods.length;) {
            address paymentMethod = paymentMethods[i];

            if (ptrPaymentMethods.add(paymentMethod)) {
                emit PaymentMethodAddedToWhitelist(paymentMethodWhitelistId, paymentMethod);
            }

            unchecked {
                ++i;
            }
        }

        for (uint256 i; i < paymentProcessorsToSync.length;) {
            IPaymentProcessorSettings(paymentProcessorsToSync[i]).registryUpdateWhitelistPaymentMethods(paymentMethodWhitelistId, paymentMethods, true);

            unchecked {
                ++i;
            }
        }
    }

    /**
     * @notice Allows custom payment method whitelist owners to remove a coin from the list of approved payment 
     *         currencies.
     *
     * @dev    Throws when caller is not the owner of the specified payment method whitelist.
     * @dev    Throws when the specified coin is not currently whitelisted under the specified whitelist id.
     *
     * @dev    <h4>Postconditions:</h4>
     * @dev    1. `paymentMethod` has been removed from the `paymentMethodWhitelist` mapping.
     * @dev    2. A `CollectionSettingsRegistry__PaymentMethodRemovedFromWhitelist` event has been emitted.
     *
     * @param  paymentMethodWhitelistId  The id of the payment method whitelist to update.
     * @param  paymentMethods             The address of the payment method to unwhitelist.
     */
    function unwhitelistPaymentMethod(
        uint32 paymentMethodWhitelistId, 
        address[] calldata paymentMethods,
        address[] calldata paymentProcessorsToSync
    ) external {
        _requireCallerOwnsPaymentMethodWhitelist(paymentMethodWhitelistId);

        EnumerableSet.AddressSet storage ptrPaymentMethods = _paymentMethodWhitelists[paymentMethodWhitelistId];
        for (uint256 i; i < paymentMethods.length;) {
            address paymentMethod = paymentMethods[i];

            if (ptrPaymentMethods.remove(paymentMethod)) {
                emit PaymentMethodRemovedFromWhitelist(paymentMethodWhitelistId, paymentMethod);
            }

            unchecked {
                ++i;
            }
        }

        for (uint256 i; i < paymentProcessorsToSync.length;) {
            IPaymentProcessorSettings(paymentProcessorsToSync[i]).registryUpdateWhitelistPaymentMethods(paymentMethodWhitelistId, paymentMethods, false);

            unchecked {
                ++i;
            }
        }
    }

    /**
     * @notice Forces sync of removed payment methods from the whitelist. This is unowned to allow for anyone to trigger updates of removed payment methods.
     *
     * @dev    Leaving this unowned allows for anyone to trigger the removal of payment methods from the whitelist.
     * @dev    If there is an issue with a payment method, this allows for a quick removal from all payment processors.
     * @dev    Throws when the specified payment method is still whitelisted under the specified whitelist id.
     * 
     * @dev    <h4>Postconditions:</h4>
     * @dev    1. `paymentMethod` has been removed from each payment processor in the `paymentProcessorsToSync` array.
     * @dev    2. X * Y `PaymentMethodRemovedFromWhitelist` events have been emitted where X is the number of payment methods and Y is the number of payment processors to sync.
     *
     * @param  paymentMethodWhitelistId   The id of the payment method whitelist to update.
     * @param  paymentMethods             An array of payment method addresses to remove.
     * @param  paymentProcessorsToSync    An array of the payment processors to sync the removal with.
     */
    function syncRemovedPaymentMethodsFromWhitelist(
        uint32 paymentMethodWhitelistId, 
        address[] calldata paymentMethods,
        address[] calldata paymentProcessorsToSync
    ) external {
        EnumerableSet.AddressSet storage ptrPaymentMethods = _paymentMethodWhitelists[paymentMethodWhitelistId];
        for (uint256 i; i < paymentMethods.length;) {
            if (ptrPaymentMethods.contains(paymentMethods[i])) {
                revert CollectionSettingsRegistry__CannotSyncRemovalOfWhitelistedPaymentMethod();
            }

            unchecked {
                ++i;
            }
        }

        for (uint256 i; i < paymentProcessorsToSync.length;) {
            IPaymentProcessorSettings(paymentProcessorsToSync[i]).registryUpdateWhitelistPaymentMethods(paymentMethodWhitelistId, paymentMethods, false);

            unchecked {
                ++i;
            }
        }
    }

    /**
     * @notice Allows the trusted permit processor list owner to add a new trusted permit processor and sync.
     *
     * @dev    Throws when caller is not the owner of the trusted permit processor list.
     *
     * @dev    <h4>Postconditions:</h4>
     * @dev    1. `trustedPermitProcessor` has been approved in `_trustedPermitProcessors` list.
     * @dev    2. A `TrustedPermitProcessorAdded` event has been emitted.
     *
     * @param  permitProcessors           The addresses of trusted permit processors to add to the list.
     * @param  paymentProcessorsToSync    An array of the payment processors to sync the removal with.
     */
    function addTrustedPermitProcessors(
        address[] calldata permitProcessors,
        address[] calldata paymentProcessorsToSync
    ) external {
        _requireCallerOwnsTrustedPermitProcessorList();

        for (uint256 i; i < permitProcessors.length;) {
            address trustedPermitProcessor = permitProcessors[i];

            if (_trustedPermitProcessors.add(trustedPermitProcessor)) {
                emit TrustedPermitProcessorAdded(trustedPermitProcessor);
            }

            unchecked {
                ++i;
            }
        }

        for (uint256 i; i < paymentProcessorsToSync.length;) {
            IPaymentProcessorSettings(paymentProcessorsToSync[i]).registryUpdateTrustedPermitProcessors(permitProcessors, true);

            unchecked {
                ++i;
            }
        }
    }

    /**
     * @notice Allows the trusted permit processor list owner to remove a trusted permit processor and sync.
     *
     * @dev    Throws when caller is not the owner of the trusted permit processor list.
     *
     * @dev    <h4>Postconditions:</h4>
     * @dev    1. `trustedPermitProcessor` has been removed from the `_trustedPermitProcessors` list.
     * @dev    2. A `TrustedPermitProcessorRemoved` event has been emitted.
     *
     * @param  permitProcessors           The addresses of trusted permit processors to remove from the list.
     * @param  paymentProcessorsToSync    An array of the payment processors to sync the removal with.
     */
    function removeTrustedPermitProcessors(
        address[] calldata permitProcessors,
        address[] calldata paymentProcessorsToSync
    ) external {
        _requireCallerOwnsTrustedPermitProcessorList();

        for (uint256 i; i < permitProcessors.length;) {
            address trustedPermitProcessor = permitProcessors[i];

            if (_trustedPermitProcessors.remove(trustedPermitProcessor)) {
                emit TrustedPermitProcessorRemoved(trustedPermitProcessor);
            }

            unchecked {
                ++i;
            }
        }

        for (uint256 i; i < paymentProcessorsToSync.length;) {
            IPaymentProcessorSettings(paymentProcessorsToSync[i]).registryUpdateTrustedPermitProcessors(permitProcessors, false);

            unchecked {
                ++i;
            }
        }
    }

    /**
     * @notice Allows the smart contract, the contract owner, or the contract admin of any NFT collection to 
     *         specify the payment settings for their collections.
     *
     * @dev    Throws when the specified tokenAddress is address(0).
     * @dev    Throws when the caller is not the contract, the owner or the administrator of the specified tokenAddress.
     * @dev    Throws when the royalty backfill numerator is greater than 10,000.
     * @dev    Throws when the royalty bounty numerator is greater than 10,000.
     * @dev    Throws when the specified payment method whitelist id does not exist.
     * 
     * @dev    <h4>Postconditions:</h4>
     * @dev    1. The `PaymentSettings` type for the collection has been set.
     * @dev    2. The `paymentMethodWhitelistId` for the collection has been set, if applicable.
     * @dev    3. The `constrainedPricingPaymentMethod` for the collection has been set, if applicable.
     * @dev    4. The `royaltyBackfillNumerator` for the collection has been set.
     * @dev    5. The `royaltyBackfillReceiver` for the collection has been set.
     * @dev    6. The `royaltyBountyNumerator` for the collection has been set.
     * @dev    7. The `exclusiveBountyReceiver` for the collection has been set.
     * @dev    8. The `blockTradesFromUntrustedChannels` for the collection has been set.
     * @dev    8. An `UpdatedCollectionPaymentSettings` event has been emitted.
     *
     * @param  tokenAddress             The smart contract address of the NFT collection.
     * @param  params                   The payment settings parameters for the collection.
     * @param  dataExtensions           The data extensions to set.
     * @param  dataSettings             The data settings to set.
     * @param  wordExtensions           The word extensions to set.
     * @param  wordSettings             The word settings to set.
     * @param  paymentProcessorsToSync  An array of the payment processors to sync the removal with.
     */
    function setCollectionPaymentSettings(
        address tokenAddress, 
        CollectionPaymentSettingsParams memory params,
        bytes32[] memory dataExtensions, 
        bytes[] memory dataSettings,
        bytes32[] memory wordExtensions,
        bytes32[] memory wordSettings,
        address[] calldata paymentProcessorsToSync
    ) external {
        _requireCallerIsNFTOrContractOwnerOrAdmin(tokenAddress);

        if (dataExtensions.length != dataSettings.length) {
            revert CollectionSettingsRegistry__InputArrayLengthMismatch();
        }

        if (wordExtensions.length != wordSettings.length) {
            revert CollectionSettingsRegistry__InputArrayLengthMismatch();
        }

        if (params.royaltyBackfillNumerator > FEE_DENOMINATOR) {
            revert CollectionSettingsRegistry__RoyaltyBackfillNumeratorCannotExceedFeeDenominator();
        }

        if (params.royaltyBountyNumerator > FEE_DENOMINATOR) {
            revert CollectionSettingsRegistry__RoyaltyBountyNumeratorCannotExceedFeeDenominator();
        }

        RegistryPricingBounds memory pricingBounds;

        if (
            params.paymentSettings == PAYMENT_SETTINGS_DEFAULT_WHITELIST || 
            params.paymentSettings == PAYMENT_SETTINGS_ALLOW_ANY
        ) {
            params.paymentMethodWhitelistId = 0;
            params.constrainedPricingPaymentMethod = address(0);
        } else if (params.paymentSettings == PAYMENT_SETTINGS_CUSTOM_WHITELIST) {
            params.constrainedPricingPaymentMethod = address(0);
        } else if (params.paymentSettings == PAYMENT_SETTINGS_PRICING_CONSTRAINTS || 
            params.paymentSettings == PAYMENT_SETTINGS_PRICING_CONSTRAINTS_COLLECTION_ONLY) {
            params.paymentMethodWhitelistId = 0;

            if(params.collectionMinimumFloorPrice > params.collectionMaximumCeilingPrice) {
                revert CollectionSettingsRegistry__CeilingPriceMustBeGreaterThanFloorPrice();
            }

            pricingBounds.ceilingPrice = params.collectionMaximumCeilingPrice;
            pricingBounds.floorPrice = params.collectionMinimumFloorPrice;
            pricingBounds.isSet = true;
        }

        if (params.paymentMethodWhitelistId > lastPaymentMethodWhitelistId) {
            revert CollectionSettingsRegistry__PaymentMethodWhitelistDoesNotExist();
        }

        _collectionPricingBounds[tokenAddress] = pricingBounds;
        _collectionBoundedPricingPaymentMethods[tokenAddress] = params.constrainedPricingPaymentMethod;
        _collectionExclusiveBountyReceivers[tokenAddress] = params.exclusiveBountyReceiver;

        _collectionPaymentSettings[tokenAddress] = CollectionRegistryPaymentSettings({
            initialized: true, 
            paymentSettingsType: params.paymentSettings,
            paymentMethodWhitelistId: params.paymentMethodWhitelistId,
            royaltyBackfillReceiver: params.royaltyBackfillReceiver,
            royaltyBackfillNumerator: params.royaltyBackfillNumerator,
            royaltyBountyNumerator: params.royaltyBountyNumerator,
            extraData: params.extraData
        });

        if (dataExtensions.length > 0) {
            mapping (bytes32 => bytes) storage ptrSettingsForCollection = _collectionSettingsExtensionData[tokenAddress];

            for (uint256 i = 0; i < dataExtensions.length;) {
                ptrSettingsForCollection[dataExtensions[i]] = dataSettings[i];

                unchecked {
                    ++i;
                }
            }
        }

        if (wordExtensions.length > 0) {
            mapping (bytes32 => bytes32) storage ptrSettingsForCollection = _collectionSettingsExtensionWords[tokenAddress];

            for (uint256 i = 0; i < wordExtensions.length;) {
                ptrSettingsForCollection[wordExtensions[i]] = wordSettings[i];

                unchecked {
                    ++i;
                }
            }
        }

        for (uint256 i; i < paymentProcessorsToSync.length;) {
            IPaymentProcessorSettings(paymentProcessorsToSync[i]).registrySyncSettings(tokenAddress);

            unchecked {
                ++i;
            }
        }
        
        emit UpdatedCollectionPaymentSettings(tokenAddress, params);
    }

    /**
     * @notice Allows the smart contract, the contract owner, or the contract admin of any NFT collection to 
     *         specify their own bounded price at the individual token level.
     *
     * @dev    Throws when the specified tokenAddress is address(0).
     * @dev    Throws when the caller is not the contract, the owner or the administrator of the specified tokenAddress.
     * @dev    Throws when the lengths of the tokenIds and pricingBounds array don't match.
     * @dev    Throws when the tokenIds or pricingBounds array length is zero. 
     * @dev    Throws when the any of the specified floor prices is greater than the ceiling price for that token id.
     * 
     * @dev    <h4>Postconditions:</h4>
     * @dev    1. The token-level pricing bounds for the specified tokenAddress and token ids has been set.
     * @dev    2. An `UpdatedTokenLevelPricingBoundaries` event has been emitted.
     *
     * @param  tokenAddress             The smart contract address of the NFT collection.
     * @param  tokenIds                 An array of token ids for which pricing bounds are being set.
     * @param  pricingBounds            An array of pricing bounds used to set the floor and ceiling per token.
     * @param  paymentProcessorsToSync  An array of the payment processors to sync the removal with.
     */
    function setTokenPricingBounds(
        address tokenAddress, 
        uint256[] calldata tokenIds, 
        RegistryPricingBounds[] calldata pricingBounds,
        address[] calldata paymentProcessorsToSync
    ) external {
        _requireCallerIsNFTOrContractOwnerOrAdmin(tokenAddress);

        if(tokenIds.length != pricingBounds.length) {
            revert CollectionSettingsRegistry__InputArrayLengthMismatch();
        }

        if(tokenIds.length == 0) {
            revert CollectionSettingsRegistry__InputArrayLengthCannotBeZero();
        }

        mapping (uint256 => RegistryPricingBounds) storage ptrTokenPricingBounds = 
            _tokenPricingBounds[tokenAddress];

        uint256 tokenId;
        for(uint256 i = 0; i < tokenIds.length;) {
            tokenId = tokenIds[i];
            RegistryPricingBounds calldata pricingBounds_ = pricingBounds[i];

            if(pricingBounds_.floorPrice > pricingBounds_.ceilingPrice) {
                revert CollectionSettingsRegistry__CeilingPriceMustBeGreaterThanFloorPrice();
            }

            ptrTokenPricingBounds[tokenId] = pricingBounds_;

            emit UpdatedTokenLevelPricingBoundaries(
                tokenAddress, 
                tokenId, 
                pricingBounds_.floorPrice, 
                pricingBounds_.ceilingPrice);
            
            unchecked {
                ++i;
            }
        }

        for (uint256 i; i < paymentProcessorsToSync.length;) {
            IPaymentProcessorSettings(paymentProcessorsToSync[i]).registryUpdateTokenPricingBounds(tokenAddress, tokenIds, pricingBounds);

            unchecked {
                ++i;
            }
        }
    }

    /**
     * @notice Allows trusted channels to be added to a collection.
     *
     * @dev    Throws when the specified tokenAddress is address(0).
     * @dev    Throws when the caller is not the contract, the owner or the administrator of the specified tokenAddress.
     * @dev    Throws when the specified address is not a trusted forwarder.
     *
     * @dev    <h4>Postconditions:</h4>
     * @dev    1. `channel` has been approved for trusted forwarding of trades on a collection.
     * @dev    2. A `TrustedChannelAddedForCollection` event has been emitted.
     *
     * @param  tokenAddress             The smart contract address of the NFT collection.
     * @param  channels                 The smart contract address of the trusted channel.
     * @param  paymentProcessorsToSync  An array of the payment processors to sync the addition with.
     */
    function addTrustedChannelForCollection(
        address tokenAddress, 
        address[] calldata channels,
        address[] calldata paymentProcessorsToSync
    ) external {
        _requireCallerIsNFTOrContractOwnerOrAdmin(tokenAddress);

        EnumerableSet.AddressSet storage ptrCollectionTrustedChannels = _collectionTrustedChannels[tokenAddress];
        for (uint256 i; i < channels.length;) {
            address channel = channels[i];
            if (ptrCollectionTrustedChannels.add(channel)) {
                emit TrustedChannelAddedForCollection(tokenAddress, channel);
            }

            unchecked {
                ++i;
            }
        }

        for (uint256 i; i < paymentProcessorsToSync.length;) {
            IPaymentProcessorSettings(paymentProcessorsToSync[i]).registryUpdateTrustedChannels(tokenAddress, channels, true);

            unchecked {
                ++i;
            }
        }
    }

    /**
     * @notice Allows trusted channels to be removed from a collection.
     *
     * @dev    Throws when the specified tokenAddress is address(0).
     * @dev    Throws when the caller is not the contract, the owner or the administrator of the specified tokenAddress.
     *
     * @dev    <h4>Postconditions:</h4>
     * @dev    1. `channel` has been dis-approved for trusted forwarding of trades on a collection.
     * @dev    2. A `TrustedChannelRemovedForCollection` event has been emitted.
     *
     * @param  tokenAddress             The smart contract address of the NFT collection.
     * @param  channels                 The smart contract address of the trusted channel to remove.
     * @param  paymentProcessorsToSync  The payment processors to sync with.
     */
    function removeTrustedChannelForCollection(
        address tokenAddress, 
        address[] calldata channels,
        address[] calldata paymentProcessorsToSync
    ) external {
        _requireCallerIsNFTOrContractOwnerOrAdmin(tokenAddress);

        EnumerableSet.AddressSet storage ptrCollectionTrustedChannels = _collectionTrustedChannels[tokenAddress];
        for (uint256 i; i < channels.length;) {
            address channel = channels[i];
            if (ptrCollectionTrustedChannels.remove(channel)) {
                emit TrustedChannelRemovedForCollection(tokenAddress, channel);
            }

            unchecked {
                ++i;
            }
        }

        for (uint256 i; i < paymentProcessorsToSync.length;) {
            IPaymentProcessorSettings(paymentProcessorsToSync[i]).registryUpdateTrustedChannels(tokenAddress, channels, false);

            unchecked {
                ++i;
            }
        }
    }

    /**
     * @notice Returns if the collection settings have been initialized.
     *
     * @param  tokenAddress   The smart contract address of the NFT collection.
     * @return isInitialized  True if the collection settings have been initialized.
     */
    function isCollectionSettingsInitialized(address tokenAddress) external view returns (bool isInitialized) {
        isInitialized = _collectionPaymentSettings[tokenAddress].initialized;
    }

    /**
     * @notice Returns the settings for a collection.
     *
     * @param  tokenAddress     The smart contract address of the NFT collection.
     * @param  dataExtensions   The data extensions to retrieve.
     * @param  wordExtensions   The word extensions to retrieve.
     */
    function getCollectionSettings(
        address tokenAddress,
        bytes32[] calldata dataExtensions,
        bytes32[] calldata wordExtensions
    ) external view returns (
        CollectionRegistryPaymentSettings memory collectionCoreSettings,
        RegistryPricingBounds memory collectionPricingBounds,
        address constrainedPricingPaymentMethod,
        address exclusiveBountyReceiver,
        bytes[] memory data, 
        bytes32[] memory words
    ) {
        collectionCoreSettings = _collectionPaymentSettings[tokenAddress];

        if (collectionCoreSettings.paymentSettingsType == PAYMENT_SETTINGS_PRICING_CONSTRAINTS || 
            collectionCoreSettings.paymentSettingsType == PAYMENT_SETTINGS_PRICING_CONSTRAINTS_COLLECTION_ONLY) {
            collectionPricingBounds = _collectionPricingBounds[tokenAddress];
            constrainedPricingPaymentMethod = _collectionBoundedPricingPaymentMethods[tokenAddress];
        }

        if (_isFlagSet(uint8(collectionCoreSettings.extraData), FLAG_IS_ROYALTY_BOUNTY_EXCLUSIVE)) {
            exclusiveBountyReceiver = _collectionExclusiveBountyReceivers[tokenAddress];
        }

        data = getCollectionSettingsExtendedData(tokenAddress, dataExtensions);
        words = getCollectionSettingsExtendedWords(tokenAddress, wordExtensions);
    }

    /**
     * @notice Returns only the extended data for a collection.
     *
     * @param  tokenAddress     The smart contract address of the NFT collection.
     * @param  extensions       The extensions to retrieve.
     */
    function getCollectionSettingsExtendedData(
        address tokenAddress, 
        bytes32[] calldata extensions
    ) public view returns (bytes[] memory data) {
        if(extensions.length > 0) {
            mapping (bytes32 => bytes) storage ptrSettingsForCollection = _collectionSettingsExtensionData[tokenAddress];

            data = new bytes[](extensions.length);
            for (uint256 i = 0; i < extensions.length;) {
                data[i] = ptrSettingsForCollection[extensions[i]];

                unchecked {
                    ++i;
                }
            }
        }
    }

    /**
     * @notice Returns only the extended words for a collection.
     *
     * @param  tokenAddress     The smart contract address of the NFT collection.
     * @param  extensions       The extensions to retrieve.
     */
    function getCollectionSettingsExtendedWords(
        address tokenAddress, 
        bytes32[] calldata extensions
    ) public view returns (bytes32[] memory words) {
        if(extensions.length > 0) {
            mapping (bytes32 => bytes32) storage ptrSettingsForCollection = _collectionSettingsExtensionWords[tokenAddress];

            words = new bytes32[](extensions.length);
            for (uint256 i = 0; i < extensions.length;) {
                words[i] = ptrSettingsForCollection[extensions[i]];

                unchecked {
                    ++i;
                }
            }
        }
    }

    /**
     * @notice Returns if the `paymentMethod` is whitelisted for the specified `whitelistId`.
     *
     * @param  whitelistId    The id of the payment method whitelist.
     * @param  paymentMethod  The address of the payment method to check.
     */
    function isWhitelistedPaymentMethod(
        uint32 whitelistId,
        address paymentMethod
    ) external view returns (bool paymentMethodWhitelisted) {
        paymentMethodWhitelisted = _paymentMethodWhitelists[whitelistId].contains(paymentMethod);
    }

    /**
     * @notice Returns if the `channel` is trusted for the specified `tokenAddress`.
     *
     * @param  tokenAddress The smart contract address of the NFT collection.
     * @param  channel      The address of the channel to check.
     */
    function isTrustedChannelForCollection(
        address tokenAddress,
        address channel
    ) external view returns (bool channelIsTrusted) {
        channelIsTrusted = _collectionTrustedChannels[tokenAddress].contains(channel);
    }

    /**
     * @notice Returns if the `permitProcessor` is trusted.
     * 
     * @param  permitProcessor The address of the permit processor to check.
     */
    function isTrustedPermitProcessor(
        address permitProcessor
    ) external view returns (bool isTrusted) {
        isTrusted = _trustedPermitProcessors.contains(permitProcessor);
    }

    /**
     * @notice Returns the pricing bounds for the provided `tokenAddress` and `tokenId` combination.
     *
     * @param  tokenAddress The smart contract address of the NFT collection.
     * @param  tokenId      The id of the token.
     */
    function getTokenBoundPricing(
        address tokenAddress,
        uint256 tokenId
    ) external view returns (RegistryPricingBounds memory pricingBounds) {
        pricingBounds = _tokenPricingBounds[tokenAddress][tokenId];
    }

    /**
     * @notice Returns the address of the account that owns the specified payment method whitelist id.
     */
    function paymentMethodWhitelistOwners(uint32 paymentMethodWhitelistId) external view returns (address) {
        return _paymentMethodWhitelistOwners[paymentMethodWhitelistId];
    }

    /**
     * @notice Returns true if the specified payment method is whitelisted for the specified payment method whitelist.
     */
    function isPaymentMethodWhitelisted(uint32 paymentMethodWhitelistId, address paymentMethod) external view returns (bool) {
        return _paymentMethodWhitelists[paymentMethodWhitelistId].contains(paymentMethod);
    }

    /**
     * @notice Returns the set of payment methods for a given payment method whitelist.
     */
    function getWhitelistedPaymentMethods(uint32 paymentMethodWhitelistId) external view returns (address[] memory) {
        return _paymentMethodWhitelists[paymentMethodWhitelistId].values();
    }

    /**
     * @notice Returns the set of trusted channels for a given collection.
     */
    function getTrustedChannels(address tokenAddress) external view returns (address[] memory) {
        return _collectionTrustedChannels[tokenAddress].values();
    }

    /**
     * @notice Transfers ownership of a payment method whitelist.
     * 
     * @dev    Throws when the caller is not the owner of the payment method whitelist.
     *
     * @param id       The payment method whitelist id to transfer ownership of.
     * @param newOwner The address to transfer ownership to.
     */
    function _reassignOwnershipOfPaymentMethodWhitelist(uint32 id, address newOwner) internal {
        _requireCallerOwnsPaymentMethodWhitelist(id);
        _paymentMethodWhitelistOwners[id] = newOwner;
        emit ReassignedPaymentMethodWhitelistOwnership(id, newOwner);
    }

    /**
     * @notice Reverts the transaction if the caller is not the owner of the payment method whitelist.
     *
     * @dev    Throws when the caller is not the owner of the payment method whitelist.
     *
     * @param paymentMethodWhitelistId The payment method whitelist id to check ownership for.
     */
    function _requireCallerOwnsPaymentMethodWhitelist(uint32 paymentMethodWhitelistId) internal view {
        if(msg.sender != _paymentMethodWhitelistOwners[paymentMethodWhitelistId]) {
            revert CollectionSettingsRegistry__CallerDoesNotOwnPaymentMethodWhitelist();
        }
    }

    /**
     * @notice Reverts the transaction if the caller is not the owner of the trusted permit processor list.
     * @notice The owner of the trusted permit processor list is the owner of the default payment method whitelist.
     *
     * @dev    Throws when the caller is not the owner of the trusted permit processor list.
     */
    function _requireCallerOwnsTrustedPermitProcessorList() internal view {
        if (msg.sender != _paymentMethodWhitelistOwners[DEFAULT_PAYMENT_METHOD_WHITELIST_ID]) {
            revert CollectionSettingsRegistry__CallerDoesNotOwnTrustedPermitProcessorList();
        }
    }

    /**
     * @notice Reverts the transaction if the caller is not the owner or assigned the default
     * @notice admin role of the contract at `tokenAddress`.
     *
     * @dev    Throws when the caller is neither owner nor assigned the default admin role.
     * 
     * @param tokenAddress The smart contract address of the NFT collection to check permissions for.
     */
    function _requireCallerIsNFTOrContractOwnerOrAdmin(address tokenAddress) internal view {
        address caller = msg.sender;
        
        if(caller == tokenAddress) {
            return;
        }

        (address contractOwner,) = _safeOwner(tokenAddress);
        if(caller == contractOwner) {
            return;
        }

        (bool callerIsContractAdmin,) = _safeHasRole(tokenAddress, DEFAULT_ACCESS_CONTROL_ADMIN_ROLE, caller);
        if(callerIsContractAdmin) {
            return;
        }

        revert CollectionSettingsRegistry__CallerMustHaveElevatedPermissionsForSpecifiedNFT();
    }

    /**
     * @notice A gas efficient, and fallback-safe way to call the owner function on a token contract.
     *
     * @dev    This will get the owner if it exists - and when the function is unimplemented, the
     * @dev    presence of a fallback function will not result in halted execution.
     *
     * @param tokenAddress The smart contract address of the NFT collection to check the owner for.
     */
    function _safeOwner(
        address tokenAddress
    ) internal view returns(address owner, bool isError) {
        assembly {
            function _callOwner(_tokenAddress) -> _owner, _isError {
                mstore(0x00, 0x8da5cb5b)
                if and(iszero(lt(returndatasize(), 0x20)), staticcall(gas(), _tokenAddress, 0x1C, 0x04, 0x00, 0x20)) {
                    _owner := mload(0x00)
                    leave
                }
                _isError := true
            }
            owner, isError := _callOwner(tokenAddress)
        }
    }
    
    /**
     * @notice A gas efficient, and fallback-safe way to call the hasRole function on a token contract.
     *
     * @dev    This will check if the account `hasRole` if `hasRole` exists - and when the function is unimplemented, the
     * @dev    presence of a fallback function will not result in halted execution.
     *
     * @param tokenAddress The smart contract address of the NFT collection to check the roles of.
     * @param role         The role to check for.
     * @param account      The account to check for the role.
     */
    function _safeHasRole(
        address tokenAddress,
        bytes32 role,
        address account
    ) internal view returns(bool hasRole, bool isError) {
        assembly {
            function _callHasRole(_tokenAddress, _role, _account) -> _hasRole, _isError {
                let ptr := mload(0x40)
                mstore(0x40, add(ptr, 0x60))
                mstore(ptr, 0x91d14854)
                mstore(add(0x20, ptr), _role)
                mstore(add(0x40, ptr), _account)
                if and(iszero(lt(returndatasize(), 0x20)), staticcall(gas(), _tokenAddress, add(ptr, 0x1C), 0x44, 0x00, 0x20)) {
                    _hasRole := mload(0x00)
                    leave
                }
                _isError := true
            }
            hasRole, isError := _callHasRole(tokenAddress, role, account)
        }
    }

    /**
     * @notice Returns true if the `flagValue` has the `flag` set, false otherwise.
     *
     * @dev    This function uses the bitwise AND operator to check if the `flag` is set in `flagValue`.
     *
     * @param flagValue  The value to check for the presence of the `flag`.
     * @param flag       The flag to check for in the `flagValue`.
     */
    function _isFlagSet(uint8 flagValue, uint8 flag) internal pure returns (bool flagSet) {
        flagSet = (flagValue & flag) != 0;
    }
}

File 2 of 8 : LicenseRef-PolyForm-Strict-1.0.0.sol
//SPDX-License-Identifier: LicenseRef-PolyForm-Strict-1.0.0
pragma solidity ^0.8.0;

/*
# PolyForm Strict License 1.0.0

<https://polyformproject.org/licenses/strict/1.0.0>

## Acceptance

In order to get any license under these terms, you must agree
to them as both strict obligations and conditions to all
your licenses.

## Copyright License

The licensor grants you a copyright license for the software
to do everything you might do with the software that would
otherwise infringe the licensor's copyright in it for any
permitted purpose, other than distributing the software or
making changes or new works based on the software.

## Patent License

The licensor grants you a patent license for the software that
covers patent claims the licensor can license, or becomes able
to license, that you would infringe by using the software.

## Noncommercial Purposes

Any noncommercial purpose is a permitted purpose.

## Personal Uses

Personal use for research, experiment, and testing for
the benefit of public knowledge, personal study, private
entertainment, hobby projects, amateur pursuits, or religious
observance, without any anticipated commercial application,
is use for a permitted purpose.

## Noncommercial Organizations

Use by any charitable organization, educational institution,
public research organization, public safety or health
organization, environmental protection organization,
or government institution is use for a permitted purpose
regardless of the source of funding or obligations resulting
from the funding.

## Fair Use

You may have "fair use" rights for the software under the
law. These terms do not limit them.

## No Other Rights

These terms do not allow you to sublicense or transfer any of
your licenses to anyone else, or prevent the licensor from
granting licenses to anyone else.  These terms do not imply
any other licenses.

## Patent Defense

If you make any written claim that the software infringes or
contributes to infringement of any patent, your patent license
for the software granted under these terms ends immediately. If
your company makes such a claim, your patent license ends
immediately for work on behalf of your company.

## Violations

The first time you are notified in writing that you have
violated any of these terms, or done anything with the software
not covered by your licenses, your licenses can nonetheless
continue if you come into full compliance with these terms,
and take practical steps to correct past violations, within
32 days of receiving notice.  Otherwise, all your licenses
end immediately.

## No Liability

***As far as the law allows, the software comes as is, without
any warranty or condition, and the licensor will not be liable
to you for any damages arising out of these terms or the use
or nature of the software, under any kind of legal claim.***

## Definitions

The **licensor** is the individual or entity offering these
terms, and the **software** is the software the licensor makes
available under these terms.

**You** refers to the individual or entity agreeing to these
terms.

**Your company** is any legal entity, sole proprietorship,
or other kind of organization that you work for, plus all
organizations that have control over, are under the control of,
or are under common control with that organization.  **Control**
means ownership of substantially all the assets of an entity,
or the power to direct its management and policies by vote,
contract, or otherwise.  Control can be direct or indirect.

**Your licenses** are all the licenses granted to you for the
software under these terms.

**Use** means anything you do with the software requiring one
of your licenses.
*/

File 3 of 8 : EnumerableSet.sol
pragma solidity ^0.8.4;

/**
 * @dev Library for managing
 * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
 * types.
 *
 * Sets have the following properties:
 *
 * - Elements are added, removed, and checked for existence in constant time
 * (O(1)).
 * - Elements are enumerated in O(n). No guarantees are made on the ordering.
 *
 * ```solidity
 * contract Example {
 *     // Add the library methods
 *     using EnumerableSet for EnumerableSet.AddressSet;
 *
 *     // Declare a set state variable
 *     EnumerableSet.AddressSet private mySet;
 * }
 * ```
 *
 * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
 * and `uint256` (`UintSet`) are supported.
 *
 * [WARNING]
 * ====
 * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure
 * unusable.
 * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.
 *
 * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an
 * array of EnumerableSet.
 * ====
 */
library EnumerableSet {
    // To implement this library for multiple types with as little code
    // repetition as possible, we write it in terms of a generic Set type with
    // bytes32 values.
    // The Set implementation uses private functions, and user-facing
    // implementations (such as AddressSet) are just wrappers around the
    // underlying Set.
    // This means that we can only create new EnumerableSets for types that fit
    // in bytes32.

    struct Set {
        // Storage of set values
        bytes32[] _values;
        // Position is the index of the value in the `values` array plus 1.
        // Position 0 is used to mean a value is not in the set.
        mapping(bytes32 value => uint256) _positions;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function _add(Set storage set, bytes32 value) private returns (bool) {
        if (!_contains(set, value)) {
            set._values.push(value);
            // The value is stored at length-1, but we add 1 to all indexes
            // and use 0 as a sentinel value
            set._positions[value] = set._values.length;
            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function _remove(Set storage set, bytes32 value) private returns (bool) {
        // We cache the value's position to prevent multiple reads from the same storage slot
        uint256 position = set._positions[value];

        if (position != 0) {
            // Equivalent to contains(set, value)
            // To delete an element from the _values array in O(1), we swap the element to delete with the last one in
            // the array, and then remove the last element (sometimes called as 'swap and pop').
            // This modifies the order of the array, as noted in {at}.

            uint256 valueIndex = position - 1;
            uint256 lastIndex = set._values.length - 1;

            if (valueIndex != lastIndex) {
                bytes32 lastValue = set._values[lastIndex];

                // Move the lastValue to the index where the value to delete is
                set._values[valueIndex] = lastValue;
                // Update the tracked position of the lastValue (that was just moved)
                set._positions[lastValue] = position;
            }

            // Delete the slot where the moved value was stored
            set._values.pop();

            // Delete the tracked position for the deleted slot
            delete set._positions[value];

            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function _contains(Set storage set, bytes32 value) private view returns (bool) {
        return set._positions[value] != 0;
    }

    /**
     * @dev Returns the number of values on the set. O(1).
     */
    function _length(Set storage set) private view returns (uint256) {
        return set._values.length;
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function _at(Set storage set, uint256 index) private view returns (bytes32) {
        return set._values[index];
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function _values(Set storage set) private view returns (bytes32[] memory) {
        return set._values;
    }

    // Bytes32Set

    struct Bytes32Set {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
        return _add(set._inner, value);
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
        return _remove(set._inner, value);
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
        return _contains(set._inner, value);
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(Bytes32Set storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
        return _at(set._inner, index);
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {
        bytes32[] memory store = _values(set._inner);
        bytes32[] memory result;

        /// @solidity memory-safe-assembly
        assembly {
            result := store
        }

        return result;
    }

    // AddressSet

    struct AddressSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(AddressSet storage set, address value) internal returns (bool) {
        return _add(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(AddressSet storage set, address value) internal returns (bool) {
        return _remove(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(AddressSet storage set, address value) internal view returns (bool) {
        return _contains(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(AddressSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(AddressSet storage set, uint256 index) internal view returns (address) {
        return address(uint160(uint256(_at(set._inner, index))));
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(AddressSet storage set) internal view returns (address[] memory) {
        bytes32[] memory store = _values(set._inner);
        address[] memory result;

        /// @solidity memory-safe-assembly
        assembly {
            result := store
        }

        return result;
    }

    // UintSet

    struct UintSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(UintSet storage set, uint256 value) internal returns (bool) {
        return _add(set._inner, bytes32(value));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(UintSet storage set, uint256 value) internal returns (bool) {
        return _remove(set._inner, bytes32(value));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(UintSet storage set, uint256 value) internal view returns (bool) {
        return _contains(set._inner, bytes32(value));
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(UintSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(UintSet storage set, uint256 index) internal view returns (uint256) {
        return uint256(_at(set._inner, index));
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(UintSet storage set) internal view returns (uint256[] memory) {
        bytes32[] memory store = _values(set._inner);
        uint256[] memory result;

        /// @solidity memory-safe-assembly
        assembly {
            result := store
        }

        return result;
    }
}

File 4 of 8 : Errors.sol
//SPDX-License-Identifier: LicenseRef-PolyForm-Strict-1.0.0
pragma solidity 0.8.24;

/// @dev Thrown when ownership of a payment method whitelist is transferred to the zero address.
error CollectionSettingsRegistry__PaymentMethodWhitelistOwnershipCannotBeTransferredToZeroAddress();

/// @dev Thrown when a payment method whitelist is referenced that does not exist.
error CollectionSettingsRegistry__PaymentMethodWhitelistDoesNotExist();

/// @dev Thrown when a royalty bounty numerator exceeds the fee denominator.
error CollectionSettingsRegistry__RoyaltyBountyNumeratorCannotExceedFeeDenominator();

/// @dev Thrown when a royalty backfill numerator exceeds the fee denominator.
error CollectionSettingsRegistry__RoyaltyBackfillNumeratorCannotExceedFeeDenominator();

/// @dev Thrown when a function requires the caller to have owner or admin privileges.
error CollectionSettingsRegistry__CallerMustHaveElevatedPermissionsForSpecifiedNFT();

/// @dev Thrown when a function requires the caller owns a payment method whitelist.
error CollectionSettingsRegistry__CallerDoesNotOwnPaymentMethodWhitelist();

/// @dev Thrown when the ceiling price is trying to be set lower than the floor price.
error CollectionSettingsRegistry__CeilingPriceMustBeGreaterThanFloorPrice();

/// @dev Thrown when a provided array is empty.
error CollectionSettingsRegistry__InputArrayLengthCannotBeZero();

/// @dev Thrown when the lengths of two arrays do not match.
error CollectionSettingsRegistry__InputArrayLengthMismatch();

/// @dev Thrown when a sync is attempted to remove a whitelisted payment method that is still approved.
error CollectionSettingsRegistry__CannotSyncRemovalOfWhitelistedPaymentMethod();

/// @dev Thrown when a function requires the caller to own a trusted permit processor list.
error CollectionSettingsRegistry__CallerDoesNotOwnTrustedPermitProcessorList();

/// @dev Thrown when a payment method whitelist is in an invalid state.
error CollectionSettingsRegistry__PaymentMethodWhitelistInvalidState();

File 5 of 8 : ICollectionSettingsRegistry.sol
//SPDX-License-Identifier: LicenseRef-PolyForm-Strict-1.0.0
pragma solidity 0.8.24;

import "./IPaymentProcessorSettings.sol";
import "./SettingsDataTypes.sol";

/** 
* @title ICollectionSettingsRegistry
* @custom:version 3.0.0
* @author Limit Break, Inc.
*/ 
interface ICollectionSettingsRegistry {

    /// @notice Emitted when a new payment method whitelist is created.
    event CreatedPaymentMethodWhitelist(
        uint32 indexed paymentMethodWhitelistId, 
        address indexed whitelistOwner,
        string whitelistName);

    /// @notice Emitted when a coin is added to the approved coins mapping for a whitelist.
    event PaymentMethodAddedToWhitelist(
        uint32 indexed paymentMethodWhitelistId, 
        address indexed paymentMethod);

    /// @notice Emitted when a coin is removed from the approved coins mapping for a whitelist.
    event PaymentMethodRemovedFromWhitelist(
        uint32 indexed paymentMethodWhitelistId, 
        address indexed paymentMethod);

    /// @notice Emitted when a permit processor is added to the trusted permit processor list.
    event TrustedPermitProcessorAdded(address indexed permitProcessor);

    /// @notice Emitted when a permit processor is removed from the trusted permit processor list.
    event TrustedPermitProcessorRemoved(address indexed permitProcessor);

    /// @notice Emitted when payment settings are updated for a collection.
    event UpdatedCollectionPaymentSettings(
        address indexed tokenAddress,
        CollectionPaymentSettingsParams params
    );

    /// @notice Emitted whenever pricing bounds change at a token level for price-constrained collections.
    event UpdatedTokenLevelPricingBoundaries(
        address indexed tokenAddress, 
        uint256 indexed tokenId, 
        uint256 floorPrice, 
        uint256 ceilingPrice);

    /// @notice Emitted when a trusted channel is removed for a collection.
    event TrustedChannelRemovedForCollection(
        address indexed tokenAddress, 
        address indexed channel);

    /// @notice Emitted when a trusted channel is added for a collection.
    event TrustedChannelAddedForCollection(
        address indexed tokenAddress, 
        address indexed channel);

    /// @notice Emitted when a payment method whitelist is reassigned to a new owner.
    event ReassignedPaymentMethodWhitelistOwnership(uint32 indexed id, address indexed newOwner);

    function isCollectionSettingsInitialized(address tokenAddress) external view returns (bool);

    function getCollectionSettings(
        address tokenAddress,
        bytes32[] calldata dataExtensions,
        bytes32[] calldata wordExtensions
    ) external view returns (
        CollectionRegistryPaymentSettings memory collectionCoreSettings,
        RegistryPricingBounds memory collectionPricingBounds,
        address constrainedPricingPaymentMethod,
        address exclusiveBountyReceiver,
        bytes[] memory data, 
        bytes32[] memory words
    );

    function getCollectionSettingsExtendedData(
        address tokenAddress, 
        bytes32[] calldata extensions
    ) external view returns (bytes[] memory data);

    function getCollectionSettingsExtendedWords(
        address tokenAddress, 
        bytes32[] calldata extensions
    ) external view returns (bytes32[] memory words);

    function isWhitelistedPaymentMethod(
        uint32 whitelistId,
        address paymentMethod
    ) external view returns (bool paymentMethodWhitelisted);

    function isTrustedChannelForCollection(
        address tokenAddress,
        address channel
    ) external view returns (bool channelIsTrusted);

    function isTrustedPermitProcessor(
        address permitProcessor
    ) external view returns (bool isTrusted);

    function getTokenBoundPricing(
        address tokenAddress,
        uint256 tokenId
    ) external view returns (RegistryPricingBounds memory);
}

File 6 of 8 : IPaymentProcessorSettings.sol
//SPDX-License-Identifier: LicenseRef-PolyForm-Strict-1.0.0
pragma solidity 0.8.24;

import "./SettingsDataTypes.sol";

/** 
* @title IPaymentProcessorSettings
* @custom:version 3.0.0
* @author Limit Break, Inc.
*/ 
interface IPaymentProcessorSettings {
    function registrySyncSettings(address tokenAddress) external;

    function registryUpdateWhitelistPaymentMethods(
        uint32 paymentMethodWhitelistId,
        address[] calldata paymentMethods,
        bool paymentMethodsAdded
    ) external;

    function registryUpdateTrustedChannels(
        address tokenAddress,
        address[] calldata channelsToUpdate,
        bool channelsAdded
    ) external;

    function registryUpdateTokenPricingBounds(
        address tokenAddress, 
        uint256[] calldata tokenIds, 
        RegistryPricingBounds[] calldata pricingBounds
    ) external;

    function registryUpdateTrustedPermitProcessors(
        address[] calldata permitProcessors,
        bool permitProcessorsAdded
    ) external;

    function checkSyncCollectionSettings(
        address tokenAddress
    ) external;

    function checkSyncTokenPricingBounds(
        address tokenAddress,
        uint256 tokenId
    ) external returns (uint256, uint256);
    
    function checkWhitelistedPaymentMethod(
        uint32 whitelistId,
        address paymentMethod
    ) external returns (bool isWhitelisted);
    
    function checkCollectionTrustedChannels(
        address tokenAddress,
        address channel
    ) external returns (bool isAllowed);
    
    function checkTrustedPermitProcessors(
        address permitProcessor
    ) external returns (bool isTrusted);
}

File 7 of 8 : SettingsConstants.sol
//SPDX-License-Identifier: LicenseRef-PolyForm-Strict-1.0.0
pragma solidity 0.8.24;

// The denominator used when calculating the marketplace fee.
// 0.5% fee numerator is 50, 1% fee numerator is 100, 10% fee numerator is 1,000 and so on.
uint256 constant FEE_DENOMINATOR = 100_00;

// Default Payment Method Whitelist Id
uint32 constant DEFAULT_PAYMENT_METHOD_WHITELIST_ID = 0;

// The default admin role for NFT collections using Access Control.
bytes32 constant DEFAULT_ACCESS_CONTROL_ADMIN_ROLE = 0x00;

/**************************************************************/
/*                           FLAGS                            */
/**************************************************************/

// Flags are used to efficiently store and retrieve boolean values in a single uint8.
// Each flag is a power of 2, so they can be combined using bitwise OR (|) and checked using bitwise AND (&).
// For example, to set the first and third flags, you would use: flags = FLAG1 | FLAG3;
// To check if the first flag is set, you would use: if (flags & FLAG1 != 0) { ... }
uint8 constant FLAG_IS_ROYALTY_BOUNTY_EXCLUSIVE = 1 << 0;
uint8 constant FLAG_BLOCK_TRADES_FROM_UNTRUSTED_CHANNELS = 1 << 1;
uint8 constant FLAG_USE_BACKFILL_AS_ROYALTY_SOURCE = 1 << 2;

/**************************************************************/
/*                   PAYMENT SETTINGS TYPES                   */
/**************************************************************/

uint8 constant PAYMENT_SETTINGS_DEFAULT_WHITELIST = 0;
uint8 constant PAYMENT_SETTINGS_ALLOW_ANY = 1;
uint8 constant PAYMENT_SETTINGS_CUSTOM_WHITELIST = 2;
uint8 constant PAYMENT_SETTINGS_PRICING_CONSTRAINTS_COLLECTION_ONLY = 3;
uint8 constant PAYMENT_SETTINGS_PRICING_CONSTRAINTS = 4;
uint8 constant PAYMENT_SETTINGS_PAUSED = 5;

File 8 of 8 : SettingsDataTypes.sol
//SPDX-License-Identifier: LicenseRef-PolyForm-Strict-1.0.0
pragma solidity 0.8.24;


/**
 * @dev This struct defines the payment settings for a collection.
 * 
 * @dev **initialized**: True if the payment settings have been initialized, false otherwise.
 * @dev **paymentSettingsType**: The type of payment settings for the collection.
 * @dev **paymentMethodWhitelistId**: The ID of the payment method whitelist to use for the collection.
 * @dev **royaltyBackfillReceiver**: The address to use as the royalty backfill receiver.
 * @dev **royaltyBackfillNumerator**: The numerator to use for the royalty backfill.
 * @dev **royaltyBountyNumerator**: The numerator to use for the royalty bounty.
 * @dev **extraData**: Extra data for the payment settings.
 */
struct CollectionRegistryPaymentSettings {
    bool initialized;
    uint8 paymentSettingsType;
    uint32 paymentMethodWhitelistId;
    address royaltyBackfillReceiver;
    uint16 royaltyBackfillNumerator;
    uint16 royaltyBountyNumerator;
    uint16 extraData;
}

/**
 * @dev This struct defines the parameters for collection payment settings.
 *
 * @dev **paymentSettings**: The payment settings for the collection.
 * @dev **paymentMethodWhitelistId**: The ID of the payment method whitelist to use for the collection.
 * @dev **constrainedPricingPaymentMethod**: The payment method to use for constrained pricing.
 * @dev **royaltyBackfillNumerator**: The numerator to use for the royalty backfill.
 * @dev **royaltyBackfillReceiver**: The address to use as the royalty backfill receiver.
 * @dev **royaltyBountyNumerator**: The numerator to use for the royalty bounty.
 * @dev **exclusiveBountyReceiver**: The address to use as the exclusive bounty receiver.
 * @dev **extraData**: Extra data for the payment settings.
 * @dev **collectionMinimumFloorPrice**: The minimum floor price for the collection.
 * @dev **collectionMaximumCeilingPrice**: The maximum ceiling price for the collection.
 * @dev **flags**: The flags for the payment settings.
 */
struct CollectionPaymentSettingsParams {
    uint8 paymentSettings;
    uint32 paymentMethodWhitelistId;
    address constrainedPricingPaymentMethod;
    uint16 royaltyBackfillNumerator;
    address royaltyBackfillReceiver;
    uint16 royaltyBountyNumerator;
    address exclusiveBountyReceiver;
    uint16 extraData;
    uint120 collectionMinimumFloorPrice;
    uint120 collectionMaximumCeilingPrice;
}

/**
 * @dev This struct defines the pricing bounds for a registry.
 *
 * @dev **isSet**: True if the pricing bounds are set, false otherwise.
 * @dev **floorPrice**: The floor price for the registry.
 * @dev **ceilingPrice**: The ceiling price for the registry.
 */
struct RegistryPricingBounds {
    bool isSet;
    uint120 floorPrice;
    uint120 ceilingPrice;
}

Settings
{
  "remappings": [
    "ds-test/=lib/forge-std/lib/ds-test/src/",
    "forge-std/=lib/forge-std/src/",
    "@openzeppelin/=lib/openzeppelin-contracts/",
    "@rari-capital/solmate/=lib/solmate/",
    "murky/=lib/murky/src/",
    "@limitbreak/trusted-forwarder/=lib/TrustedForwarder/src/",
    "@limitbreak/permit-c/=lib/PermitC/src/",
    "@limitbreak/tm-core-lib/=lib/tm-core-lib/",
    "@limitbreak/wrapped-native/=lib/wrapped-native/src/",
    "@limitbreak/tm-role-server/=lib/tm-role-server/src/",
    "PermitC/=lib/PermitC/",
    "TrustedForwarder/=lib/TrustedForwarder/",
    "erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
    "forge-gas-metering/=lib/PermitC/lib/forge-gas-metering/",
    "openzeppelin-contracts/=lib/openzeppelin-contracts/",
    "openzeppelin/=lib/openzeppelin-contracts/contracts/",
    "solady/=lib/PermitC/lib/forge-gas-metering/lib/solady/",
    "solmate/=lib/solmate/src/",
    "tm-core-lib/=lib/tm-core-lib/src/",
    "tm-role-server/=lib/tm-role-server/src/",
    "wrapped-native/=lib/wrapped-native/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 40000
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "ipfs",
    "appendCBOR": true
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "abi"
      ]
    }
  },
  "evmVersion": "cancun",
  "viaIR": false,
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"defaultContractOwner_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"CollectionSettingsRegistry__CallerDoesNotOwnPaymentMethodWhitelist","type":"error"},{"inputs":[],"name":"CollectionSettingsRegistry__CallerDoesNotOwnTrustedPermitProcessorList","type":"error"},{"inputs":[],"name":"CollectionSettingsRegistry__CallerMustHaveElevatedPermissionsForSpecifiedNFT","type":"error"},{"inputs":[],"name":"CollectionSettingsRegistry__CannotSyncRemovalOfWhitelistedPaymentMethod","type":"error"},{"inputs":[],"name":"CollectionSettingsRegistry__CeilingPriceMustBeGreaterThanFloorPrice","type":"error"},{"inputs":[],"name":"CollectionSettingsRegistry__InputArrayLengthCannotBeZero","type":"error"},{"inputs":[],"name":"CollectionSettingsRegistry__InputArrayLengthMismatch","type":"error"},{"inputs":[],"name":"CollectionSettingsRegistry__PaymentMethodWhitelistDoesNotExist","type":"error"},{"inputs":[],"name":"CollectionSettingsRegistry__PaymentMethodWhitelistInvalidState","type":"error"},{"inputs":[],"name":"CollectionSettingsRegistry__PaymentMethodWhitelistOwnershipCannotBeTransferredToZeroAddress","type":"error"},{"inputs":[],"name":"CollectionSettingsRegistry__RoyaltyBackfillNumeratorCannotExceedFeeDenominator","type":"error"},{"inputs":[],"name":"CollectionSettingsRegistry__RoyaltyBountyNumeratorCannotExceedFeeDenominator","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"paymentMethodWhitelistId","type":"uint32"},{"indexed":true,"internalType":"address","name":"whitelistOwner","type":"address"},{"indexed":false,"internalType":"string","name":"whitelistName","type":"string"}],"name":"CreatedPaymentMethodWhitelist","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"paymentMethodWhitelistId","type":"uint32"},{"indexed":true,"internalType":"address","name":"paymentMethod","type":"address"}],"name":"PaymentMethodAddedToWhitelist","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"paymentMethodWhitelistId","type":"uint32"},{"indexed":true,"internalType":"address","name":"paymentMethod","type":"address"}],"name":"PaymentMethodRemovedFromWhitelist","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"id","type":"uint32"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"ReassignedPaymentMethodWhitelistOwnership","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"tokenAddress","type":"address"},{"indexed":true,"internalType":"address","name":"channel","type":"address"}],"name":"TrustedChannelAddedForCollection","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"tokenAddress","type":"address"},{"indexed":true,"internalType":"address","name":"channel","type":"address"}],"name":"TrustedChannelRemovedForCollection","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"permitProcessor","type":"address"}],"name":"TrustedPermitProcessorAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"permitProcessor","type":"address"}],"name":"TrustedPermitProcessorRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"tokenAddress","type":"address"},{"components":[{"internalType":"uint8","name":"paymentSettings","type":"uint8"},{"internalType":"uint32","name":"paymentMethodWhitelistId","type":"uint32"},{"internalType":"address","name":"constrainedPricingPaymentMethod","type":"address"},{"internalType":"uint16","name":"royaltyBackfillNumerator","type":"uint16"},{"internalType":"address","name":"royaltyBackfillReceiver","type":"address"},{"internalType":"uint16","name":"royaltyBountyNumerator","type":"uint16"},{"internalType":"address","name":"exclusiveBountyReceiver","type":"address"},{"internalType":"uint16","name":"extraData","type":"uint16"},{"internalType":"uint120","name":"collectionMinimumFloorPrice","type":"uint120"},{"internalType":"uint120","name":"collectionMaximumCeilingPrice","type":"uint120"}],"indexed":false,"internalType":"struct CollectionPaymentSettingsParams","name":"params","type":"tuple"}],"name":"UpdatedCollectionPaymentSettings","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"tokenAddress","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"floorPrice","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"ceilingPrice","type":"uint256"}],"name":"UpdatedTokenLevelPricingBoundaries","type":"event"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"address[]","name":"channels","type":"address[]"},{"internalType":"address[]","name":"paymentProcessorsToSync","type":"address[]"}],"name":"addTrustedChannelForCollection","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"permitProcessors","type":"address[]"},{"internalType":"address[]","name":"paymentProcessorsToSync","type":"address[]"}],"name":"addTrustedPermitProcessors","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"whitelistName","type":"string"}],"name":"createPaymentMethodWhitelist","outputs":[{"internalType":"uint32","name":"paymentMethodWhitelistId","type":"uint32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"bytes32[]","name":"dataExtensions","type":"bytes32[]"},{"internalType":"bytes32[]","name":"wordExtensions","type":"bytes32[]"}],"name":"getCollectionSettings","outputs":[{"components":[{"internalType":"bool","name":"initialized","type":"bool"},{"internalType":"uint8","name":"paymentSettingsType","type":"uint8"},{"internalType":"uint32","name":"paymentMethodWhitelistId","type":"uint32"},{"internalType":"address","name":"royaltyBackfillReceiver","type":"address"},{"internalType":"uint16","name":"royaltyBackfillNumerator","type":"uint16"},{"internalType":"uint16","name":"royaltyBountyNumerator","type":"uint16"},{"internalType":"uint16","name":"extraData","type":"uint16"}],"internalType":"struct CollectionRegistryPaymentSettings","name":"collectionCoreSettings","type":"tuple"},{"components":[{"internalType":"bool","name":"isSet","type":"bool"},{"internalType":"uint120","name":"floorPrice","type":"uint120"},{"internalType":"uint120","name":"ceilingPrice","type":"uint120"}],"internalType":"struct RegistryPricingBounds","name":"collectionPricingBounds","type":"tuple"},{"internalType":"address","name":"constrainedPricingPaymentMethod","type":"address"},{"internalType":"address","name":"exclusiveBountyReceiver","type":"address"},{"internalType":"bytes[]","name":"data","type":"bytes[]"},{"internalType":"bytes32[]","name":"words","type":"bytes32[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"bytes32[]","name":"extensions","type":"bytes32[]"}],"name":"getCollectionSettingsExtendedData","outputs":[{"internalType":"bytes[]","name":"data","type":"bytes[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"bytes32[]","name":"extensions","type":"bytes32[]"}],"name":"getCollectionSettingsExtendedWords","outputs":[{"internalType":"bytes32[]","name":"words","type":"bytes32[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getTokenBoundPricing","outputs":[{"components":[{"internalType":"bool","name":"isSet","type":"bool"},{"internalType":"uint120","name":"floorPrice","type":"uint120"},{"internalType":"uint120","name":"ceilingPrice","type":"uint120"}],"internalType":"struct RegistryPricingBounds","name":"pricingBounds","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"}],"name":"getTrustedChannels","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"paymentMethodWhitelistId","type":"uint32"}],"name":"getWhitelistedPaymentMethods","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"}],"name":"isCollectionSettingsInitialized","outputs":[{"internalType":"bool","name":"isInitialized","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"paymentMethodWhitelistId","type":"uint32"},{"internalType":"address","name":"paymentMethod","type":"address"}],"name":"isPaymentMethodWhitelisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"address","name":"channel","type":"address"}],"name":"isTrustedChannelForCollection","outputs":[{"internalType":"bool","name":"channelIsTrusted","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"permitProcessor","type":"address"}],"name":"isTrustedPermitProcessor","outputs":[{"internalType":"bool","name":"isTrusted","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"whitelistId","type":"uint32"},{"internalType":"address","name":"paymentMethod","type":"address"}],"name":"isWhitelistedPaymentMethod","outputs":[{"internalType":"bool","name":"paymentMethodWhitelisted","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastPaymentMethodWhitelistId","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"paymentMethodWhitelistId","type":"uint32"}],"name":"paymentMethodWhitelistOwners","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"id","type":"uint32"},{"internalType":"address","name":"newOwner","type":"address"}],"name":"reassignOwnershipOfPaymentMethodWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"address[]","name":"channels","type":"address[]"},{"internalType":"address[]","name":"paymentProcessorsToSync","type":"address[]"}],"name":"removeTrustedChannelForCollection","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"permitProcessors","type":"address[]"},{"internalType":"address[]","name":"paymentProcessorsToSync","type":"address[]"}],"name":"removeTrustedPermitProcessors","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"id","type":"uint32"}],"name":"renounceOwnershipOfPaymentMethodWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"components":[{"internalType":"uint8","name":"paymentSettings","type":"uint8"},{"internalType":"uint32","name":"paymentMethodWhitelistId","type":"uint32"},{"internalType":"address","name":"constrainedPricingPaymentMethod","type":"address"},{"internalType":"uint16","name":"royaltyBackfillNumerator","type":"uint16"},{"internalType":"address","name":"royaltyBackfillReceiver","type":"address"},{"internalType":"uint16","name":"royaltyBountyNumerator","type":"uint16"},{"internalType":"address","name":"exclusiveBountyReceiver","type":"address"},{"internalType":"uint16","name":"extraData","type":"uint16"},{"internalType":"uint120","name":"collectionMinimumFloorPrice","type":"uint120"},{"internalType":"uint120","name":"collectionMaximumCeilingPrice","type":"uint120"}],"internalType":"struct CollectionPaymentSettingsParams","name":"params","type":"tuple"},{"internalType":"bytes32[]","name":"dataExtensions","type":"bytes32[]"},{"internalType":"bytes[]","name":"dataSettings","type":"bytes[]"},{"internalType":"bytes32[]","name":"wordExtensions","type":"bytes32[]"},{"internalType":"bytes32[]","name":"wordSettings","type":"bytes32[]"},{"internalType":"address[]","name":"paymentProcessorsToSync","type":"address[]"}],"name":"setCollectionPaymentSettings","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"components":[{"internalType":"bool","name":"isSet","type":"bool"},{"internalType":"uint120","name":"floorPrice","type":"uint120"},{"internalType":"uint120","name":"ceilingPrice","type":"uint120"}],"internalType":"struct RegistryPricingBounds[]","name":"pricingBounds","type":"tuple[]"},{"internalType":"address[]","name":"paymentProcessorsToSync","type":"address[]"}],"name":"setTokenPricingBounds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"paymentMethodWhitelistId","type":"uint32"},{"internalType":"address[]","name":"paymentMethods","type":"address[]"},{"internalType":"address[]","name":"paymentProcessorsToSync","type":"address[]"}],"name":"syncRemovedPaymentMethodsFromWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"paymentMethodWhitelistId","type":"uint32"},{"internalType":"address[]","name":"paymentMethods","type":"address[]"},{"internalType":"address[]","name":"paymentProcessorsToSync","type":"address[]"}],"name":"unwhitelistPaymentMethod","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"paymentMethodWhitelistId","type":"uint32"},{"internalType":"address[]","name":"paymentMethods","type":"address[]"},{"internalType":"address[]","name":"paymentProcessorsToSync","type":"address[]"}],"name":"whitelistPaymentMethod","outputs":[],"stateMutability":"nonpayable","type":"function"}]

608060405234801562000010575f80fd5b50604051620037413803806200374183398101604081905262000033916200012b565b5f805463ffffffff198116600163ffffffff92831690810190921617909155801515806200006657505f5463ffffffff16155b15620000855760405163222e45ad60e11b815260040160405180910390fd5b63ffffffff81165f818152600960205260409081902080546001600160a01b0386166001600160a01b0319909116811790915590519091907f56f762dca0ade902d8ba2510acde4d509e51d041e7ffaf54ea830637d3564752906200011b9060208082526017908201527f44656661756c74205061796d656e74204d6574686f6473000000000000000000604082015260600190565b60405180910390a350506200015a565b5f602082840312156200013c575f80fd5b81516001600160a01b038116811462000153575f80fd5b9392505050565b6135d980620001685f395ff3fe608060405234801561000f575f80fd5b506004361061019a575f3560e01c8063a797a263116100e8578063e49174fa11610093578063f34368771161006e578063f34368771461048e578063f7d0968914610271578063f83116c9146104a1578063f88770c9146104b4575f80fd5b8063e49174fa14610423578063e788323814610443578063ebcaeaef1461047b575f80fd5b8063b74ff31a116100c3578063b74ff31a1461034a578063b8208ec4146103fd578063d65a8f6614610410575f80fd5b8063a797a26314610300578063b01f89ef14610313578063b1cf555714610337575f80fd5b80637d7aaac211610148578063a1e6917e11610123578063a1e6917e146102c7578063a219ea1c146102da578063a7923cf4146102ed575f80fd5b80637d7aaac2146102715780639a002068146102945780639b95711f146102a7575f80fd5b80632161c229116101785780632161c2291461022b57806341e6da9a1461024b578063698c0d231461025e575f80fd5b806303f50cae1461019e5780630557e27e146101b35780630886702e14610218575b5f80fd5b6101b16101ac3660046124a8565b6104d9565b005b6101ee6101c1366004612527565b63ffffffff165f9081526009602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6101b1610226366004612527565b61061d565b61023e610239366004612563565b61062a565b60405161020f91906125ec565b6101b16102593660046125fe565b6106fd565b6101b161026c366004612679565b610882565b61028461027f366004612696565b6109b8565b604051901515815260200161020f565b6101b16102a23660046126c7565b6109dc565b6102ba6102b5366004612798565b610c99565b60405161020f91906127b1565b6101b16102d5366004612696565b610ccf565b6101b16102e83660046125fe565b610d2a565b6101b16102fb366004612b47565b610ea7565b6102ba61030e366004612527565b6116ec565b5f546103229063ffffffff1681565b60405163ffffffff909116815260200161020f565b6101b1610345366004612679565b61170c565b6103f0610358366004612c3d565b60408051606080820183525f808352602080840182905292840181905273ffffffffffffffffffffffffffffffffffffffff9590951685526005825282852093855292815292819020815192830182525460ff8116151583526effffffffffffffffffffffffffffff610100820481169484019490945270010000000000000000000000000000000090049092169181019190915290565b60405161020f9190612c65565b61028461040b366004612798565b611866565b6101b161041e3660046124a8565b611872565b610436610431366004612563565b6119ae565b60405161020f9190612d41565b610284610451366004612798565b73ffffffffffffffffffffffffffffffffffffffff165f9081526001602052604090205460ff1690565b6101b1610489366004612679565b611b07565b61028461049c366004612d53565b611c62565b6103226104af366004612d6d565b611c90565b6104c76104c23660046125fe565b611d59565b60405161020f96959493929190612dd9565b6104e1611f8d565b5f5b8381101561056f575f8585838181106104fe576104fe612efc565b90506020020160208101906105139190612798565b9050610520600782612007565b156105665760405173ffffffffffffffffffffffffffffffffffffffff8216907f87e3ea20ad9ddd46ae425cd3172041816da71e77478078f7c324cee1ffde3bc3905f90a25b506001016104e3565b505f5b818110156106165782828281811061058c5761058c612efc565b90506020020160208101906105a19190612798565b73ffffffffffffffffffffffffffffffffffffffff1663175605b2868660016040518463ffffffff1660e01b81526004016105de93929190612f70565b5f604051808303815f87803b1580156105f5575f80fd5b505af1158015610607573d5f803e3d5ffd5b50505050806001019050610572565b5050505050565b610627815f612028565b50565b606081156106f65773ffffffffffffffffffffffffffffffffffffffff84165f908152600c602052604090208267ffffffffffffffff81111561066f5761066f61280a565b604051908082528060200260200182016040528015610698578160200160208202803683370190505b5091505f5b838110156106f357815f8686848181106106b9576106b9612efc565b9050602002013581526020019081526020015f20548382815181106106e0576106e0612efc565b602090810291909101015260010161069d565b50505b9392505050565b610706856120b3565b73ffffffffffffffffffffffffffffffffffffffff85165f908152600660205260408120905b848110156107d1575f86868381811061074757610747612efc565b905060200201602081019061075c9190612798565b90506107688382612166565b156107c8578073ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167f0382d3027908b0aa4d45d9765995d6c2915b38ec25c4d1ae2f5bd8dce74a5b1660405160405180910390a35b5060010161072c565b505f5b82811015610879578383828181106107ee576107ee612efc565b90506020020160208101906108039190612798565b73ffffffffffffffffffffffffffffffffffffffff166315987f148888885f6040518563ffffffff1660e01b81526004016108419493929190612f95565b5f604051808303815f87803b158015610858575f80fd5b505af115801561086a573d5f803e3d5ffd5b505050508060010190506107d4565b50505050505050565b63ffffffff85165f908152600a60205260408120905b84811015610910576108d18686838181106108b5576108b5612efc565b90506020020160208101906108ca9190612798565b8390612187565b15610908576040517f5f3f500b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600101610898565b505f5b828110156108795783838281811061092d5761092d612efc565b90506020020160208101906109429190612798565b73ffffffffffffffffffffffffffffffffffffffff16636f1622aa8888885f6040518563ffffffff1660e01b81526004016109809493929190612fd7565b5f604051808303815f87803b158015610997575f80fd5b505af11580156109a9573d5f803e3d5ffd5b50505050806001019050610913565b63ffffffff8083165f908152600a6020526040812090916106f69190849061218716565b6109e5876120b3565b848314610a1e576040517fb20809cd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f859003610a58576040517fb0788dde00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff87165f90815260056020526040812090805b87811015610be357888882818110610a9957610a99612efc565b90506020020135915036878783818110610ab557610ab5612efc565b9050606002019050806040016020810190610ad09190612ff6565b6effffffffffffffffffffffffffffff16610af16040830160208401612ff6565b6effffffffffffffffffffffffffffff161115610b3a576040517f5aa9936a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f8381526020859052604090208190610b53828261301e565b5083905073ffffffffffffffffffffffffffffffffffffffff8c167f38d88037c7f872f6e5d89332cdae804370cd604776bfcabf8da1f2e11945e271610b9f6040850160208601612ff6565b610baf6060860160408701612ff6565b604080516effffffffffffffffffffffffffffff93841681529290911660208301520160405180910390a350600101610a7f565b505f5b83811015610c8d57848482818110610c0057610c00612efc565b9050602002016020810190610c159190612798565b73ffffffffffffffffffffffffffffffffffffffff1663dec49fc38b8b8b8b8b6040518663ffffffff1660e01b8152600401610c5595949392919061310d565b5f604051808303815f87803b158015610c6c575f80fd5b505af1158015610c7e573d5f803e3d5ffd5b50505050806001019050610be6565b50505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff81165f908152600660205260409020606090610cc9906121b5565b92915050565b73ffffffffffffffffffffffffffffffffffffffff8116610d1c576040517f67c81f7100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610d268282612028565b5050565b610d33856120b3565b73ffffffffffffffffffffffffffffffffffffffff85165f908152600660205260408120905b84811015610dfe575f868683818110610d7457610d74612efc565b9050602002016020810190610d899190612798565b9050610d958382612007565b15610df5578073ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167f5ad5afe7f91207e8a3eba0274c5fb0599a0cc2b72709ec47fa5e157ae8375ba560405160405180910390a35b50600101610d59565b505f5b8281101561087957838382818110610e1b57610e1b612efc565b9050602002016020810190610e309190612798565b73ffffffffffffffffffffffffffffffffffffffff166315987f1488888860016040518563ffffffff1660e01b8152600401610e6f9493929190612f95565b5f604051808303815f87803b158015610e86575f80fd5b505af1158015610e98573d5f803e3d5ffd5b50505050806001019050610e01565b610eb0886120b3565b8451865114610eeb576040517fb20809cd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8251845114610f26576040517fb20809cd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612710876060015161ffff161115610f6a576040517f78d70ddb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6127108760a0015161ffff161115610fae576040517fe8cfc04600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516060810182525f8082526020820181905291810191909152875160ff161580610fdf5750875160ff166001145b15610ff6575f6020890181905260408901526110d6565b875160ff167ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0161102c575f60408901526110d6565b875160ff16600414806110435750875160ff166003145b156110d6575f60208901526101208801516101008901516effffffffffffffffffffffffffffff918216911611156110a7576040517f5aa9936a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101208801516effffffffffffffffffffffffffffff9081166040830152610100890151166020820152600181525b5f54602089015163ffffffff9182169116111561111f576040517f64ea29c100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060045f8b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f820151815f015f6101000a81548160ff0219169083151502179055506020820151815f0160016101000a8154816effffffffffffffffffffffffffffff02191690836effffffffffffffffffffffffffffff1602179055506040820151815f0160106101000a8154816effffffffffffffffffffffffffffff02191690836effffffffffffffffffffffffffffff160217905550905050876040015160035f8b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508760c0015160025f8b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506040518060e00160405280600115158152602001895f015160ff168152602001896020015163ffffffff168152602001896080015173ffffffffffffffffffffffffffffffffffffffff168152602001896060015161ffff1681526020018960a0015161ffff1681526020018960e0015161ffff1681525060015f8b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f820151815f015f6101000a81548160ff0219169083151502179055506020820151815f0160016101000a81548160ff021916908360ff1602179055506040820151815f0160026101000a81548163ffffffff021916908363ffffffff1602179055506060820151815f0160066101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506080820151815f01601a6101000a81548161ffff021916908361ffff16021790555060a0820151815f01601c6101000a81548161ffff021916908361ffff16021790555060c0820151815f01601e6101000a81548161ffff021916908361ffff1602179055509050505f8751111561154d5773ffffffffffffffffffffffffffffffffffffffff89165f908152600b60205260408120905b885181101561154a5787818151811061150457611504612efc565b6020026020010151825f8b848151811061152057611520612efc565b602002602001015181526020019081526020015f209081611541919061329a565b506001016114e9565b50505b8451156115d85773ffffffffffffffffffffffffffffffffffffffff89165f908152600c60205260408120905b86518110156115d55785818151811061159557611595612efc565b6020026020010151825f8984815181106115b1576115b1612efc565b602002602001015181526020019081526020015f208190555080600101905061157a565b50505b5f5b82811015611692578383828181106115f4576115f4612efc565b90506020020160208101906116099190612798565b6040517f1330d35400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8c811660048301529190911690631330d354906024015f604051808303815f87803b158015611671575f80fd5b505af1158015611683573d5f803e3d5ffd5b505050508060010190506115da565b508873ffffffffffffffffffffffffffffffffffffffff167feaf57121971ac856f0b31d134b2bdcd5dd3ab07eb6af881e273da2901b86f9d8896040516116d991906133b6565b60405180910390a2505050505050505050565b63ffffffff81165f908152600a60205260409020606090610cc9906121b5565b611715856121c1565b63ffffffff85165f908152600a60205260408120905b848110156117be575f86868381811061174657611746612efc565b905060200201602081019061175b9190612798565b90506117678382612166565b156117b55760405173ffffffffffffffffffffffffffffffffffffffff82169063ffffffff8a16907ff156bd3efe5d358c94cc34b12810b94f524f03ef4e7f71158e22b6775ef75ba3905f90a35b5060010161172b565b505f5b82811015610879578383828181106117db576117db612efc565b90506020020160208101906117f09190612798565b73ffffffffffffffffffffffffffffffffffffffff16636f1622aa8888885f6040518563ffffffff1660e01b815260040161182e9493929190612fd7565b5f604051808303815f87803b158015611845575f80fd5b505af1158015611857573d5f803e3d5ffd5b505050508060010190506117c1565b5f610cc9600783612187565b61187a611f8d565b5f5b83811015611908575f85858381811061189757611897612efc565b90506020020160208101906118ac9190612798565b90506118b9600782612166565b156118ff5760405173ffffffffffffffffffffffffffffffffffffffff8216907f92d437702b2a3273d49d74c7da439c911015b857dbfaff40c36b78e903ab09d1905f90a25b5060010161187c565b505f5b818110156106165782828281811061192557611925612efc565b905060200201602081019061193a9190612798565b73ffffffffffffffffffffffffffffffffffffffff1663175605b286865f6040518463ffffffff1660e01b815260040161197693929190612f70565b5f604051808303815f87803b15801561198d575f80fd5b505af115801561199f573d5f803e3d5ffd5b5050505080600101905061190b565b606081156106f65773ffffffffffffffffffffffffffffffffffffffff84165f908152600b602052604090208267ffffffffffffffff8111156119f3576119f361280a565b604051908082528060200260200182016040528015611a2657816020015b6060815260200190600190039081611a115790505b5091505f5b838110156106f357815f868684818110611a4757611a47612efc565b9050602002013581526020019081526020015f208054611a6690613200565b80601f0160208091040260200160405190810160405280929190818152602001828054611a9290613200565b8015611add5780601f10611ab457610100808354040283529160200191611add565b820191905f5260205f20905b815481529060010190602001808311611ac057829003601f168201915b5050505050838281518110611af457611af4612efc565b6020908102919091010152600101611a2b565b611b10856121c1565b63ffffffff85165f908152600a60205260408120905b84811015611bb9575f868683818110611b4157611b41612efc565b9050602002016020810190611b569190612798565b9050611b628382612007565b15611bb05760405173ffffffffffffffffffffffffffffffffffffffff82169063ffffffff8a16907fab066026be9f5f930c1018a7e9eeddf7921b9026531b1b9935a66eb62d163fe8905f90a35b50600101611b26565b505f5b8281101561087957838382818110611bd657611bd6612efc565b9050602002016020810190611beb9190612798565b73ffffffffffffffffffffffffffffffffffffffff16636f1622aa88888860016040518563ffffffff1660e01b8152600401611c2a9493929190612fd7565b5f604051808303815f87803b158015611c41575f80fd5b505af1158015611c53573d5f803e3d5ffd5b50505050806001019050611bbc565b73ffffffffffffffffffffffffffffffffffffffff82165f9081526006602052604081206106f69083612187565b5f8054339063ffffffff168280611ca6836134f5565b82546101009290920a63ffffffff81810219909316918316021790915581165f818152600960205260409081902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff86169081179091559051929450917f56f762dca0ade902d8ba2510acde4d509e51d041e7ffaf54ea830637d356475290611d4a9088908890613517565b60405180910390a35092915050565b6040805160e080820183525f80835260208084018290528385018290526060808501839052608080860184905260a080870185905260c09687018590528751808401895285815280850186905280890186905273ffffffffffffffffffffffffffffffffffffffff8e81168752600186528987208a519889018b525460ff80821615158a5261010082041696890187905263ffffffff620100008204169a89019a909a5266010000000000008a04168785015261ffff7a0100000000000000000000000000000000000000000000000000008a048116938801939093527c010000000000000000000000000000000000000000000000000000000089048316918701919091527e0100000000000000000000000000000000000000000000000000000000000090970416948401949094529193929091829190819060041480611ea95750602086015160ff166003145b15611f2f5773ffffffffffffffffffffffffffffffffffffffff808c165f8181526004602090815260408083208151606081018352905460ff8116151582526effffffffffffffffffffffffffffff6101008204811683860152700100000000000000000000000000000000909104168183015293835260039091529020549096501693505b60c086015160011615611f665773ffffffffffffffffffffffffffffffffffffffff808c165f908152600260205260409020541692505b611f718b8b8b6119ae565b9150611f7e8b898961062a565b90509550955095509550955095565b5f805260096020527fec8156718a8372b1db44bb411437d0870f3e3790d4a08526d024ce1b0b668f6b5473ffffffffffffffffffffffffffffffffffffffff163314612005576040517f884f68ec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b5f6106f68373ffffffffffffffffffffffffffffffffffffffff8416612224565b612031826121c1565b63ffffffff82165f8181526009602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff861690811790915590519092917f51dfcd1cce7b066cb6b6c54dead5b9201cbb434bcfa6f7ee9acf7a3ef1c7b07d91a35050565b3373ffffffffffffffffffffffffffffffffffffffff821681036120d5575050565b5f6120df83612270565b5090508073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361211a57505050565b5f6121268482856122b8565b50905080156121355750505050565b6040517e11731e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f6106f68373ffffffffffffffffffffffffffffffffffffffff8416612324565b73ffffffffffffffffffffffffffffffffffffffff81165f90815260018301602052604081205415156106f6565b60605f6106f683612407565b63ffffffff81165f9081526009602052604090205473ffffffffffffffffffffffffffffffffffffffff163314610627576040517fecd2535900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f81815260018301602052604081205461226957508154600181810184555f848152602080822090930184905584548482528286019093526040902091909155610cc9565b505f610cc9565b5f806122a6565b638da5cb5b5f525f8060205f6004601c865afa60203d1015161561229e575f519150915091565b509160019150565b6122af83612277565b91509150915091565b5f8061230d565b5f80604051606081016040526391d14854815284816020015285816040015260205f6044601c8401875afa60203d101516156122ff575f51925050612305565b50600190505b935093915050565b6123188385876122bf565b91509150935093915050565b5f81815260018301602052604081205480156123fe575f612346600183613563565b85549091505f9061235990600190613563565b90508082146123b8575f865f01828154811061237757612377612efc565b905f5260205f200154905080875f01848154811061239757612397612efc565b5f918252602080832090910192909255918252600188019052604090208390555b85548690806123c9576123c9613576565b600190038181905f5260205f20015f90559055856001015f8681526020019081526020015f205f905560019350505050610cc9565b5f915050610cc9565b6060815f0180548060200260200160405190810160405280929190818152602001828054801561245457602002820191905f5260205f20905b815481526020019060010190808311612440575b50505050509050919050565b5f8083601f840112612470575f80fd5b50813567ffffffffffffffff811115612487575f80fd5b6020830191508360208260051b85010111156124a1575f80fd5b9250929050565b5f805f80604085870312156124bb575f80fd5b843567ffffffffffffffff808211156124d2575f80fd5b6124de88838901612460565b909650945060208701359150808211156124f6575f80fd5b5061250387828801612460565b95989497509550505050565b803563ffffffff81168114612522575f80fd5b919050565b5f60208284031215612537575f80fd5b6106f68261250f565b803573ffffffffffffffffffffffffffffffffffffffff81168114612522575f80fd5b5f805f60408486031215612575575f80fd5b61257e84612540565b9250602084013567ffffffffffffffff811115612599575f80fd5b6125a586828701612460565b9497909650939450505050565b5f815180845260208085019450602084015f5b838110156125e1578151875295820195908201906001016125c5565b509495945050505050565b602081525f6106f660208301846125b2565b5f805f805f60608688031215612612575f80fd5b61261b86612540565b9450602086013567ffffffffffffffff80821115612637575f80fd5b61264389838a01612460565b9096509450604088013591508082111561265b575f80fd5b5061266888828901612460565b969995985093965092949392505050565b5f805f805f6060868803121561268d575f80fd5b61261b8661250f565b5f80604083850312156126a7575f80fd5b6126b08361250f565b91506126be60208401612540565b90509250929050565b5f805f805f805f6080888a0312156126dd575f80fd5b6126e688612540565b9650602088013567ffffffffffffffff80821115612702575f80fd5b61270e8b838c01612460565b909850965060408a0135915080821115612726575f80fd5b818a0191508a601f830112612739575f80fd5b813581811115612747575f80fd5b8b602060608302850101111561275b575f80fd5b6020830196508095505060608a0135915080821115612778575f80fd5b506127858a828b01612460565b989b979a50959850939692959293505050565b5f602082840312156127a8575f80fd5b6106f682612540565b602080825282518282018190525f9190848201906040850190845b818110156127fe57835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016127cc565b50909695505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b604051610140810167ffffffffffffffff8111828210171561285b5761285b61280a565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156128a8576128a861280a565b604052919050565b803560ff81168114612522575f80fd5b803561ffff81168114612522575f80fd5b6effffffffffffffffffffffffffffff81168114610627575f80fd5b8035612522816128d1565b5f6101408284031215612909575f80fd5b612911612837565b905061291c826128b0565b815261292a6020830161250f565b602082015261293b60408301612540565b604082015261294c606083016128c0565b606082015261295d60808301612540565b608082015261296e60a083016128c0565b60a082015261297f60c08301612540565b60c082015261299060e083016128c0565b60e08201526101006129a38184016128ed565b908201526101206129b58382016128ed565b9082015292915050565b5f67ffffffffffffffff8211156129d8576129d861280a565b5060051b60200190565b5f82601f8301126129f1575f80fd5b81356020612a06612a01836129bf565b612861565b8083825260208201915060208460051b870101935086841115612a27575f80fd5b602086015b84811015612a435780358352918301918301612a2c565b509695505050505050565b5f601f83601f840112612a5f575f80fd5b82356020612a6f612a01836129bf565b82815260059290921b85018101918181019087841115612a8d575f80fd5b8287015b84811015612b3b57803567ffffffffffffffff80821115612ab0575f80fd5b818a0191508a603f830112612ac3575f80fd5b85820135604082821115612ad957612ad961280a565b612b08887fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08c85011601612861565b92508183528c81838601011115612b1d575f80fd5b8181850189850137505f908201870152845250918301918301612a91565b50979650505050505050565b5f805f805f805f80610200898b031215612b5f575f80fd5b612b6889612540565b9750612b778a60208b016128f8565b965061016089013567ffffffffffffffff80821115612b94575f80fd5b612ba08c838d016129e2565b97506101808b0135915080821115612bb6575f80fd5b612bc28c838d01612a4e565b96506101a08b0135915080821115612bd8575f80fd5b612be48c838d016129e2565b95506101c08b0135915080821115612bfa575f80fd5b612c068c838d016129e2565b94506101e08b0135915080821115612c1c575f80fd5b50612c298b828c01612460565b999c989b5096995094979396929594505050565b5f8060408385031215612c4e575f80fd5b612c5783612540565b946020939093013593505050565b60608101610cc982848051151582526020808201516effffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b5f82825180855260208086019550808260051b8401018186015f5b84811015612d34577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe080878503018a52825180518086525f5b81811015612d0f578281018801518782018901528701612cf4565b505f8682018801529a86019a601f019091169093018401925090830190600101612cbb565b5090979650505050505050565b602081525f6106f66020830184612ca0565b5f8060408385031215612d64575f80fd5b6126b083612540565b5f8060208385031215612d7e575f80fd5b823567ffffffffffffffff80821115612d95575f80fd5b818501915085601f830112612da8575f80fd5b813581811115612db6575f80fd5b866020828501011115612dc7575f80fd5b60209290920196919550909350505050565b5f6101c088511515835260ff60208a015116602084015263ffffffff60408a015116604084015273ffffffffffffffffffffffffffffffffffffffff60608a015116606084015261ffff60808a015116608084015260a0890151612e4360a085018261ffff169052565b5060c0890151612e5960c085018261ffff169052565b508751151560e084015260208801516effffffffffffffffffffffffffffff90811661010085015260408901511661012084015273ffffffffffffffffffffffffffffffffffffffff871661014084015273ffffffffffffffffffffffffffffffffffffffff861661016084015280610180840152612eda81840186612ca0565b90508281036101a0840152612eef81856125b2565b9998505050505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b8183525f60208085019450825f5b858110156125e15773ffffffffffffffffffffffffffffffffffffffff612f5d83612540565b1687529582019590820190600101612f37565b604081525f612f83604083018587612f29565b90508215156020830152949350505050565b73ffffffffffffffffffffffffffffffffffffffff85168152606060208201525f612fc4606083018587612f29565b9050821515604083015295945050505050565b63ffffffff85168152606060208201525f612fc4606083018587612f29565b5f60208284031215613006575f80fd5b81356106f6816128d1565b8015158114610627575f80fd5b813561302981613011565b81547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00811691151560ff1691821783556020840135613067816128d1565b6fffffffffffffffffffffffffffffff008160081b16905080837fffffffffffffffffffffffffffffffff0000000000000000000000000000000084161717845560408501356130b6816128d1565b7effffffffffffffffffffffffffffff000000000000000000000000000000008160801b16847fff000000000000000000000000000000000000000000000000000000000000008516178317178555505050505050565b5f606073ffffffffffffffffffffffffffffffffffffffff881683526020606060208501528660608501527f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff871115613164575f80fd5b8660051b808960808701376080908501858103820160408088019190915291810187905287915f9160a0015b888310156131f05783356131a381613011565b15158152838501356131b4816128d1565b6effffffffffffffffffffffffffffff9081168287015284830135906131d9826128d1565b168183015292850192600192909201918501613190565b9c9b505050505050505050505050565b600181811c9082168061321457607f821691505b60208210810361324b577f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b50919050565b601f82111561329557805f5260205f20601f840160051c810160208510156132765750805b601f840160051c820191505b81811015610616575f8155600101613282565b505050565b815167ffffffffffffffff8111156132b4576132b461280a565b6132c8816132c28454613200565b84613251565b602080601f83116001811461331a575f84156132e45750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556133ae565b5f858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561336657888601518255948401946001909101908401613347565b50858210156133a257878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b505060018460011b0185555b505050505050565b815160ff168152610140810160208301516133d9602084018263ffffffff169052565b506040830151613401604084018273ffffffffffffffffffffffffffffffffffffffff169052565b506060830151613417606084018261ffff169052565b50608083015161343f608084018273ffffffffffffffffffffffffffffffffffffffff169052565b5060a083015161345560a084018261ffff169052565b5060c083015161347d60c084018273ffffffffffffffffffffffffffffffffffffffff169052565b5060e083015161349360e084018261ffff169052565b50610100838101516effffffffffffffffffffffffffffff908116918401919091526101209384015116929091019190915290565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f63ffffffff80831681810361350d5761350d6134c8565b6001019392505050565b60208152816020820152818360408301375f818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b81810381811115610cc957610cc96134c8565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603160045260245ffdfea2646970667358221220e8b78b6c2956ff19642da661b79da51ac5cdc202b1551506669da2e6c02fbe7464736f6c63430008180033000000000000000000000000591aa9dff01b8144dc17cb416001d9ac84b951cd

Deployed Bytecode

0x608060405234801561000f575f80fd5b506004361061019a575f3560e01c8063a797a263116100e8578063e49174fa11610093578063f34368771161006e578063f34368771461048e578063f7d0968914610271578063f83116c9146104a1578063f88770c9146104b4575f80fd5b8063e49174fa14610423578063e788323814610443578063ebcaeaef1461047b575f80fd5b8063b74ff31a116100c3578063b74ff31a1461034a578063b8208ec4146103fd578063d65a8f6614610410575f80fd5b8063a797a26314610300578063b01f89ef14610313578063b1cf555714610337575f80fd5b80637d7aaac211610148578063a1e6917e11610123578063a1e6917e146102c7578063a219ea1c146102da578063a7923cf4146102ed575f80fd5b80637d7aaac2146102715780639a002068146102945780639b95711f146102a7575f80fd5b80632161c229116101785780632161c2291461022b57806341e6da9a1461024b578063698c0d231461025e575f80fd5b806303f50cae1461019e5780630557e27e146101b35780630886702e14610218575b5f80fd5b6101b16101ac3660046124a8565b6104d9565b005b6101ee6101c1366004612527565b63ffffffff165f9081526009602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6101b1610226366004612527565b61061d565b61023e610239366004612563565b61062a565b60405161020f91906125ec565b6101b16102593660046125fe565b6106fd565b6101b161026c366004612679565b610882565b61028461027f366004612696565b6109b8565b604051901515815260200161020f565b6101b16102a23660046126c7565b6109dc565b6102ba6102b5366004612798565b610c99565b60405161020f91906127b1565b6101b16102d5366004612696565b610ccf565b6101b16102e83660046125fe565b610d2a565b6101b16102fb366004612b47565b610ea7565b6102ba61030e366004612527565b6116ec565b5f546103229063ffffffff1681565b60405163ffffffff909116815260200161020f565b6101b1610345366004612679565b61170c565b6103f0610358366004612c3d565b60408051606080820183525f808352602080840182905292840181905273ffffffffffffffffffffffffffffffffffffffff9590951685526005825282852093855292815292819020815192830182525460ff8116151583526effffffffffffffffffffffffffffff610100820481169484019490945270010000000000000000000000000000000090049092169181019190915290565b60405161020f9190612c65565b61028461040b366004612798565b611866565b6101b161041e3660046124a8565b611872565b610436610431366004612563565b6119ae565b60405161020f9190612d41565b610284610451366004612798565b73ffffffffffffffffffffffffffffffffffffffff165f9081526001602052604090205460ff1690565b6101b1610489366004612679565b611b07565b61028461049c366004612d53565b611c62565b6103226104af366004612d6d565b611c90565b6104c76104c23660046125fe565b611d59565b60405161020f96959493929190612dd9565b6104e1611f8d565b5f5b8381101561056f575f8585838181106104fe576104fe612efc565b90506020020160208101906105139190612798565b9050610520600782612007565b156105665760405173ffffffffffffffffffffffffffffffffffffffff8216907f87e3ea20ad9ddd46ae425cd3172041816da71e77478078f7c324cee1ffde3bc3905f90a25b506001016104e3565b505f5b818110156106165782828281811061058c5761058c612efc565b90506020020160208101906105a19190612798565b73ffffffffffffffffffffffffffffffffffffffff1663175605b2868660016040518463ffffffff1660e01b81526004016105de93929190612f70565b5f604051808303815f87803b1580156105f5575f80fd5b505af1158015610607573d5f803e3d5ffd5b50505050806001019050610572565b5050505050565b610627815f612028565b50565b606081156106f65773ffffffffffffffffffffffffffffffffffffffff84165f908152600c602052604090208267ffffffffffffffff81111561066f5761066f61280a565b604051908082528060200260200182016040528015610698578160200160208202803683370190505b5091505f5b838110156106f357815f8686848181106106b9576106b9612efc565b9050602002013581526020019081526020015f20548382815181106106e0576106e0612efc565b602090810291909101015260010161069d565b50505b9392505050565b610706856120b3565b73ffffffffffffffffffffffffffffffffffffffff85165f908152600660205260408120905b848110156107d1575f86868381811061074757610747612efc565b905060200201602081019061075c9190612798565b90506107688382612166565b156107c8578073ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167f0382d3027908b0aa4d45d9765995d6c2915b38ec25c4d1ae2f5bd8dce74a5b1660405160405180910390a35b5060010161072c565b505f5b82811015610879578383828181106107ee576107ee612efc565b90506020020160208101906108039190612798565b73ffffffffffffffffffffffffffffffffffffffff166315987f148888885f6040518563ffffffff1660e01b81526004016108419493929190612f95565b5f604051808303815f87803b158015610858575f80fd5b505af115801561086a573d5f803e3d5ffd5b505050508060010190506107d4565b50505050505050565b63ffffffff85165f908152600a60205260408120905b84811015610910576108d18686838181106108b5576108b5612efc565b90506020020160208101906108ca9190612798565b8390612187565b15610908576040517f5f3f500b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600101610898565b505f5b828110156108795783838281811061092d5761092d612efc565b90506020020160208101906109429190612798565b73ffffffffffffffffffffffffffffffffffffffff16636f1622aa8888885f6040518563ffffffff1660e01b81526004016109809493929190612fd7565b5f604051808303815f87803b158015610997575f80fd5b505af11580156109a9573d5f803e3d5ffd5b50505050806001019050610913565b63ffffffff8083165f908152600a6020526040812090916106f69190849061218716565b6109e5876120b3565b848314610a1e576040517fb20809cd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f859003610a58576040517fb0788dde00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff87165f90815260056020526040812090805b87811015610be357888882818110610a9957610a99612efc565b90506020020135915036878783818110610ab557610ab5612efc565b9050606002019050806040016020810190610ad09190612ff6565b6effffffffffffffffffffffffffffff16610af16040830160208401612ff6565b6effffffffffffffffffffffffffffff161115610b3a576040517f5aa9936a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f8381526020859052604090208190610b53828261301e565b5083905073ffffffffffffffffffffffffffffffffffffffff8c167f38d88037c7f872f6e5d89332cdae804370cd604776bfcabf8da1f2e11945e271610b9f6040850160208601612ff6565b610baf6060860160408701612ff6565b604080516effffffffffffffffffffffffffffff93841681529290911660208301520160405180910390a350600101610a7f565b505f5b83811015610c8d57848482818110610c0057610c00612efc565b9050602002016020810190610c159190612798565b73ffffffffffffffffffffffffffffffffffffffff1663dec49fc38b8b8b8b8b6040518663ffffffff1660e01b8152600401610c5595949392919061310d565b5f604051808303815f87803b158015610c6c575f80fd5b505af1158015610c7e573d5f803e3d5ffd5b50505050806001019050610be6565b50505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff81165f908152600660205260409020606090610cc9906121b5565b92915050565b73ffffffffffffffffffffffffffffffffffffffff8116610d1c576040517f67c81f7100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610d268282612028565b5050565b610d33856120b3565b73ffffffffffffffffffffffffffffffffffffffff85165f908152600660205260408120905b84811015610dfe575f868683818110610d7457610d74612efc565b9050602002016020810190610d899190612798565b9050610d958382612007565b15610df5578073ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167f5ad5afe7f91207e8a3eba0274c5fb0599a0cc2b72709ec47fa5e157ae8375ba560405160405180910390a35b50600101610d59565b505f5b8281101561087957838382818110610e1b57610e1b612efc565b9050602002016020810190610e309190612798565b73ffffffffffffffffffffffffffffffffffffffff166315987f1488888860016040518563ffffffff1660e01b8152600401610e6f9493929190612f95565b5f604051808303815f87803b158015610e86575f80fd5b505af1158015610e98573d5f803e3d5ffd5b50505050806001019050610e01565b610eb0886120b3565b8451865114610eeb576040517fb20809cd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8251845114610f26576040517fb20809cd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612710876060015161ffff161115610f6a576040517f78d70ddb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6127108760a0015161ffff161115610fae576040517fe8cfc04600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516060810182525f8082526020820181905291810191909152875160ff161580610fdf5750875160ff166001145b15610ff6575f6020890181905260408901526110d6565b875160ff167ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0161102c575f60408901526110d6565b875160ff16600414806110435750875160ff166003145b156110d6575f60208901526101208801516101008901516effffffffffffffffffffffffffffff918216911611156110a7576040517f5aa9936a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101208801516effffffffffffffffffffffffffffff9081166040830152610100890151166020820152600181525b5f54602089015163ffffffff9182169116111561111f576040517f64ea29c100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060045f8b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f820151815f015f6101000a81548160ff0219169083151502179055506020820151815f0160016101000a8154816effffffffffffffffffffffffffffff02191690836effffffffffffffffffffffffffffff1602179055506040820151815f0160106101000a8154816effffffffffffffffffffffffffffff02191690836effffffffffffffffffffffffffffff160217905550905050876040015160035f8b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508760c0015160025f8b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506040518060e00160405280600115158152602001895f015160ff168152602001896020015163ffffffff168152602001896080015173ffffffffffffffffffffffffffffffffffffffff168152602001896060015161ffff1681526020018960a0015161ffff1681526020018960e0015161ffff1681525060015f8b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f820151815f015f6101000a81548160ff0219169083151502179055506020820151815f0160016101000a81548160ff021916908360ff1602179055506040820151815f0160026101000a81548163ffffffff021916908363ffffffff1602179055506060820151815f0160066101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506080820151815f01601a6101000a81548161ffff021916908361ffff16021790555060a0820151815f01601c6101000a81548161ffff021916908361ffff16021790555060c0820151815f01601e6101000a81548161ffff021916908361ffff1602179055509050505f8751111561154d5773ffffffffffffffffffffffffffffffffffffffff89165f908152600b60205260408120905b885181101561154a5787818151811061150457611504612efc565b6020026020010151825f8b848151811061152057611520612efc565b602002602001015181526020019081526020015f209081611541919061329a565b506001016114e9565b50505b8451156115d85773ffffffffffffffffffffffffffffffffffffffff89165f908152600c60205260408120905b86518110156115d55785818151811061159557611595612efc565b6020026020010151825f8984815181106115b1576115b1612efc565b602002602001015181526020019081526020015f208190555080600101905061157a565b50505b5f5b82811015611692578383828181106115f4576115f4612efc565b90506020020160208101906116099190612798565b6040517f1330d35400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8c811660048301529190911690631330d354906024015f604051808303815f87803b158015611671575f80fd5b505af1158015611683573d5f803e3d5ffd5b505050508060010190506115da565b508873ffffffffffffffffffffffffffffffffffffffff167feaf57121971ac856f0b31d134b2bdcd5dd3ab07eb6af881e273da2901b86f9d8896040516116d991906133b6565b60405180910390a2505050505050505050565b63ffffffff81165f908152600a60205260409020606090610cc9906121b5565b611715856121c1565b63ffffffff85165f908152600a60205260408120905b848110156117be575f86868381811061174657611746612efc565b905060200201602081019061175b9190612798565b90506117678382612166565b156117b55760405173ffffffffffffffffffffffffffffffffffffffff82169063ffffffff8a16907ff156bd3efe5d358c94cc34b12810b94f524f03ef4e7f71158e22b6775ef75ba3905f90a35b5060010161172b565b505f5b82811015610879578383828181106117db576117db612efc565b90506020020160208101906117f09190612798565b73ffffffffffffffffffffffffffffffffffffffff16636f1622aa8888885f6040518563ffffffff1660e01b815260040161182e9493929190612fd7565b5f604051808303815f87803b158015611845575f80fd5b505af1158015611857573d5f803e3d5ffd5b505050508060010190506117c1565b5f610cc9600783612187565b61187a611f8d565b5f5b83811015611908575f85858381811061189757611897612efc565b90506020020160208101906118ac9190612798565b90506118b9600782612166565b156118ff5760405173ffffffffffffffffffffffffffffffffffffffff8216907f92d437702b2a3273d49d74c7da439c911015b857dbfaff40c36b78e903ab09d1905f90a25b5060010161187c565b505f5b818110156106165782828281811061192557611925612efc565b905060200201602081019061193a9190612798565b73ffffffffffffffffffffffffffffffffffffffff1663175605b286865f6040518463ffffffff1660e01b815260040161197693929190612f70565b5f604051808303815f87803b15801561198d575f80fd5b505af115801561199f573d5f803e3d5ffd5b5050505080600101905061190b565b606081156106f65773ffffffffffffffffffffffffffffffffffffffff84165f908152600b602052604090208267ffffffffffffffff8111156119f3576119f361280a565b604051908082528060200260200182016040528015611a2657816020015b6060815260200190600190039081611a115790505b5091505f5b838110156106f357815f868684818110611a4757611a47612efc565b9050602002013581526020019081526020015f208054611a6690613200565b80601f0160208091040260200160405190810160405280929190818152602001828054611a9290613200565b8015611add5780601f10611ab457610100808354040283529160200191611add565b820191905f5260205f20905b815481529060010190602001808311611ac057829003601f168201915b5050505050838281518110611af457611af4612efc565b6020908102919091010152600101611a2b565b611b10856121c1565b63ffffffff85165f908152600a60205260408120905b84811015611bb9575f868683818110611b4157611b41612efc565b9050602002016020810190611b569190612798565b9050611b628382612007565b15611bb05760405173ffffffffffffffffffffffffffffffffffffffff82169063ffffffff8a16907fab066026be9f5f930c1018a7e9eeddf7921b9026531b1b9935a66eb62d163fe8905f90a35b50600101611b26565b505f5b8281101561087957838382818110611bd657611bd6612efc565b9050602002016020810190611beb9190612798565b73ffffffffffffffffffffffffffffffffffffffff16636f1622aa88888860016040518563ffffffff1660e01b8152600401611c2a9493929190612fd7565b5f604051808303815f87803b158015611c41575f80fd5b505af1158015611c53573d5f803e3d5ffd5b50505050806001019050611bbc565b73ffffffffffffffffffffffffffffffffffffffff82165f9081526006602052604081206106f69083612187565b5f8054339063ffffffff168280611ca6836134f5565b82546101009290920a63ffffffff81810219909316918316021790915581165f818152600960205260409081902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff86169081179091559051929450917f56f762dca0ade902d8ba2510acde4d509e51d041e7ffaf54ea830637d356475290611d4a9088908890613517565b60405180910390a35092915050565b6040805160e080820183525f80835260208084018290528385018290526060808501839052608080860184905260a080870185905260c09687018590528751808401895285815280850186905280890186905273ffffffffffffffffffffffffffffffffffffffff8e81168752600186528987208a519889018b525460ff80821615158a5261010082041696890187905263ffffffff620100008204169a89019a909a5266010000000000008a04168785015261ffff7a0100000000000000000000000000000000000000000000000000008a048116938801939093527c010000000000000000000000000000000000000000000000000000000089048316918701919091527e0100000000000000000000000000000000000000000000000000000000000090970416948401949094529193929091829190819060041480611ea95750602086015160ff166003145b15611f2f5773ffffffffffffffffffffffffffffffffffffffff808c165f8181526004602090815260408083208151606081018352905460ff8116151582526effffffffffffffffffffffffffffff6101008204811683860152700100000000000000000000000000000000909104168183015293835260039091529020549096501693505b60c086015160011615611f665773ffffffffffffffffffffffffffffffffffffffff808c165f908152600260205260409020541692505b611f718b8b8b6119ae565b9150611f7e8b898961062a565b90509550955095509550955095565b5f805260096020527fec8156718a8372b1db44bb411437d0870f3e3790d4a08526d024ce1b0b668f6b5473ffffffffffffffffffffffffffffffffffffffff163314612005576040517f884f68ec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b5f6106f68373ffffffffffffffffffffffffffffffffffffffff8416612224565b612031826121c1565b63ffffffff82165f8181526009602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff861690811790915590519092917f51dfcd1cce7b066cb6b6c54dead5b9201cbb434bcfa6f7ee9acf7a3ef1c7b07d91a35050565b3373ffffffffffffffffffffffffffffffffffffffff821681036120d5575050565b5f6120df83612270565b5090508073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361211a57505050565b5f6121268482856122b8565b50905080156121355750505050565b6040517e11731e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f6106f68373ffffffffffffffffffffffffffffffffffffffff8416612324565b73ffffffffffffffffffffffffffffffffffffffff81165f90815260018301602052604081205415156106f6565b60605f6106f683612407565b63ffffffff81165f9081526009602052604090205473ffffffffffffffffffffffffffffffffffffffff163314610627576040517fecd2535900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f81815260018301602052604081205461226957508154600181810184555f848152602080822090930184905584548482528286019093526040902091909155610cc9565b505f610cc9565b5f806122a6565b638da5cb5b5f525f8060205f6004601c865afa60203d1015161561229e575f519150915091565b509160019150565b6122af83612277565b91509150915091565b5f8061230d565b5f80604051606081016040526391d14854815284816020015285816040015260205f6044601c8401875afa60203d101516156122ff575f51925050612305565b50600190505b935093915050565b6123188385876122bf565b91509150935093915050565b5f81815260018301602052604081205480156123fe575f612346600183613563565b85549091505f9061235990600190613563565b90508082146123b8575f865f01828154811061237757612377612efc565b905f5260205f200154905080875f01848154811061239757612397612efc565b5f918252602080832090910192909255918252600188019052604090208390555b85548690806123c9576123c9613576565b600190038181905f5260205f20015f90559055856001015f8681526020019081526020015f205f905560019350505050610cc9565b5f915050610cc9565b6060815f0180548060200260200160405190810160405280929190818152602001828054801561245457602002820191905f5260205f20905b815481526020019060010190808311612440575b50505050509050919050565b5f8083601f840112612470575f80fd5b50813567ffffffffffffffff811115612487575f80fd5b6020830191508360208260051b85010111156124a1575f80fd5b9250929050565b5f805f80604085870312156124bb575f80fd5b843567ffffffffffffffff808211156124d2575f80fd5b6124de88838901612460565b909650945060208701359150808211156124f6575f80fd5b5061250387828801612460565b95989497509550505050565b803563ffffffff81168114612522575f80fd5b919050565b5f60208284031215612537575f80fd5b6106f68261250f565b803573ffffffffffffffffffffffffffffffffffffffff81168114612522575f80fd5b5f805f60408486031215612575575f80fd5b61257e84612540565b9250602084013567ffffffffffffffff811115612599575f80fd5b6125a586828701612460565b9497909650939450505050565b5f815180845260208085019450602084015f5b838110156125e1578151875295820195908201906001016125c5565b509495945050505050565b602081525f6106f660208301846125b2565b5f805f805f60608688031215612612575f80fd5b61261b86612540565b9450602086013567ffffffffffffffff80821115612637575f80fd5b61264389838a01612460565b9096509450604088013591508082111561265b575f80fd5b5061266888828901612460565b969995985093965092949392505050565b5f805f805f6060868803121561268d575f80fd5b61261b8661250f565b5f80604083850312156126a7575f80fd5b6126b08361250f565b91506126be60208401612540565b90509250929050565b5f805f805f805f6080888a0312156126dd575f80fd5b6126e688612540565b9650602088013567ffffffffffffffff80821115612702575f80fd5b61270e8b838c01612460565b909850965060408a0135915080821115612726575f80fd5b818a0191508a601f830112612739575f80fd5b813581811115612747575f80fd5b8b602060608302850101111561275b575f80fd5b6020830196508095505060608a0135915080821115612778575f80fd5b506127858a828b01612460565b989b979a50959850939692959293505050565b5f602082840312156127a8575f80fd5b6106f682612540565b602080825282518282018190525f9190848201906040850190845b818110156127fe57835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016127cc565b50909695505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b604051610140810167ffffffffffffffff8111828210171561285b5761285b61280a565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156128a8576128a861280a565b604052919050565b803560ff81168114612522575f80fd5b803561ffff81168114612522575f80fd5b6effffffffffffffffffffffffffffff81168114610627575f80fd5b8035612522816128d1565b5f6101408284031215612909575f80fd5b612911612837565b905061291c826128b0565b815261292a6020830161250f565b602082015261293b60408301612540565b604082015261294c606083016128c0565b606082015261295d60808301612540565b608082015261296e60a083016128c0565b60a082015261297f60c08301612540565b60c082015261299060e083016128c0565b60e08201526101006129a38184016128ed565b908201526101206129b58382016128ed565b9082015292915050565b5f67ffffffffffffffff8211156129d8576129d861280a565b5060051b60200190565b5f82601f8301126129f1575f80fd5b81356020612a06612a01836129bf565b612861565b8083825260208201915060208460051b870101935086841115612a27575f80fd5b602086015b84811015612a435780358352918301918301612a2c565b509695505050505050565b5f601f83601f840112612a5f575f80fd5b82356020612a6f612a01836129bf565b82815260059290921b85018101918181019087841115612a8d575f80fd5b8287015b84811015612b3b57803567ffffffffffffffff80821115612ab0575f80fd5b818a0191508a603f830112612ac3575f80fd5b85820135604082821115612ad957612ad961280a565b612b08887fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08c85011601612861565b92508183528c81838601011115612b1d575f80fd5b8181850189850137505f908201870152845250918301918301612a91565b50979650505050505050565b5f805f805f805f80610200898b031215612b5f575f80fd5b612b6889612540565b9750612b778a60208b016128f8565b965061016089013567ffffffffffffffff80821115612b94575f80fd5b612ba08c838d016129e2565b97506101808b0135915080821115612bb6575f80fd5b612bc28c838d01612a4e565b96506101a08b0135915080821115612bd8575f80fd5b612be48c838d016129e2565b95506101c08b0135915080821115612bfa575f80fd5b612c068c838d016129e2565b94506101e08b0135915080821115612c1c575f80fd5b50612c298b828c01612460565b999c989b5096995094979396929594505050565b5f8060408385031215612c4e575f80fd5b612c5783612540565b946020939093013593505050565b60608101610cc982848051151582526020808201516effffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b5f82825180855260208086019550808260051b8401018186015f5b84811015612d34577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe080878503018a52825180518086525f5b81811015612d0f578281018801518782018901528701612cf4565b505f8682018801529a86019a601f019091169093018401925090830190600101612cbb565b5090979650505050505050565b602081525f6106f66020830184612ca0565b5f8060408385031215612d64575f80fd5b6126b083612540565b5f8060208385031215612d7e575f80fd5b823567ffffffffffffffff80821115612d95575f80fd5b818501915085601f830112612da8575f80fd5b813581811115612db6575f80fd5b866020828501011115612dc7575f80fd5b60209290920196919550909350505050565b5f6101c088511515835260ff60208a015116602084015263ffffffff60408a015116604084015273ffffffffffffffffffffffffffffffffffffffff60608a015116606084015261ffff60808a015116608084015260a0890151612e4360a085018261ffff169052565b5060c0890151612e5960c085018261ffff169052565b508751151560e084015260208801516effffffffffffffffffffffffffffff90811661010085015260408901511661012084015273ffffffffffffffffffffffffffffffffffffffff871661014084015273ffffffffffffffffffffffffffffffffffffffff861661016084015280610180840152612eda81840186612ca0565b90508281036101a0840152612eef81856125b2565b9998505050505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b8183525f60208085019450825f5b858110156125e15773ffffffffffffffffffffffffffffffffffffffff612f5d83612540565b1687529582019590820190600101612f37565b604081525f612f83604083018587612f29565b90508215156020830152949350505050565b73ffffffffffffffffffffffffffffffffffffffff85168152606060208201525f612fc4606083018587612f29565b9050821515604083015295945050505050565b63ffffffff85168152606060208201525f612fc4606083018587612f29565b5f60208284031215613006575f80fd5b81356106f6816128d1565b8015158114610627575f80fd5b813561302981613011565b81547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00811691151560ff1691821783556020840135613067816128d1565b6fffffffffffffffffffffffffffffff008160081b16905080837fffffffffffffffffffffffffffffffff0000000000000000000000000000000084161717845560408501356130b6816128d1565b7effffffffffffffffffffffffffffff000000000000000000000000000000008160801b16847fff000000000000000000000000000000000000000000000000000000000000008516178317178555505050505050565b5f606073ffffffffffffffffffffffffffffffffffffffff881683526020606060208501528660608501527f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff871115613164575f80fd5b8660051b808960808701376080908501858103820160408088019190915291810187905287915f9160a0015b888310156131f05783356131a381613011565b15158152838501356131b4816128d1565b6effffffffffffffffffffffffffffff9081168287015284830135906131d9826128d1565b168183015292850192600192909201918501613190565b9c9b505050505050505050505050565b600181811c9082168061321457607f821691505b60208210810361324b577f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b50919050565b601f82111561329557805f5260205f20601f840160051c810160208510156132765750805b601f840160051c820191505b81811015610616575f8155600101613282565b505050565b815167ffffffffffffffff8111156132b4576132b461280a565b6132c8816132c28454613200565b84613251565b602080601f83116001811461331a575f84156132e45750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556133ae565b5f858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561336657888601518255948401946001909101908401613347565b50858210156133a257878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b505060018460011b0185555b505050505050565b815160ff168152610140810160208301516133d9602084018263ffffffff169052565b506040830151613401604084018273ffffffffffffffffffffffffffffffffffffffff169052565b506060830151613417606084018261ffff169052565b50608083015161343f608084018273ffffffffffffffffffffffffffffffffffffffff169052565b5060a083015161345560a084018261ffff169052565b5060c083015161347d60c084018273ffffffffffffffffffffffffffffffffffffffff169052565b5060e083015161349360e084018261ffff169052565b50610100838101516effffffffffffffffffffffffffffff908116918401919091526101209384015116929091019190915290565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f63ffffffff80831681810361350d5761350d6134c8565b6001019392505050565b60208152816020820152818360408301375f818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b81810381811115610cc957610cc96134c8565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603160045260245ffdfea2646970667358221220e8b78b6c2956ff19642da661b79da51ac5cdc202b1551506669da2e6c02fbe7464736f6c63430008180033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

000000000000000000000000591aa9dff01b8144dc17cb416001d9ac84b951cd

-----Decoded View---------------
Arg [0] : defaultContractOwner_ (address): 0x591Aa9dfF01B8144DC17Cb416001D9aC84b951cd

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000591aa9dff01b8144dc17cb416001d9ac84b951cd


Deployed Bytecode Sourcemap

514:38757:2:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11508:828;;;;;;:::i;:::-;;:::i;:::-;;32442:182;;;;;;:::i;:::-;32562:55;;32536:7;32562:55;;;:29;:55;;;;;;;;;32442:182;;;;1829:42:8;1817:55;;;1799:74;;1787:2;1772:18;32442:182:2;;;;;;;;5043:146;;;;;;:::i;:::-;;:::i;29835:610::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;25748:946::-;;;;;;:::i;:::-;;:::i;9938:909::-;;;;;;:::i;:::-;;:::i;30712:260::-;;;;;;:::i;:::-;;:::i;:::-;;;5441:14:8;;5434:22;5416:41;;5404:2;5389:18;30712:260:2;5276:187:8;21458:1683:2;;;;;;:::i;:::-;;:::i;33386:164::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;4251:324::-;;;;;;:::i;:::-;;:::i;24017:937::-;;;;;;:::i;:::-;;:::i;15867:4244::-;;;;;;:::i;:::-;;:::i;33094:195::-;;;;;;:::i;:::-;;:::i;642:42::-;;;;;;;;;;;;14199:10:8;14187:23;;;14169:42;;14157:2;14142:18;642:42:2;14025:192:8;7748:1021:2;;;;;;:::i;:::-;;:::i;32084:233::-;;;;;;:::i;:::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;32268:33:2;;;;;;;:19;:33;;;;;:42;;;;;;;;;;32252:58;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32084:233;;;;;;;;:::i;31636:191::-;;;;;;:::i;:::-;;:::i;13008:837::-;;;;;;:::i;:::-;;:::i;29000:599::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;26961:191::-;;;;;;:::i;:::-;27093:40;;27047:18;27093:40;;;:26;:40;;;;;:52;;;;26961:191;5926:1011;;;;;;:::i;:::-;;:::i;31229:240::-;;;;;;:::i;:::-;;:::i;3245:427::-;;;;;;:::i;:::-;;:::i;27447:1318::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;;;:::i;11508:828::-;11666:46;:44;:46::i;:::-;11728:9;11723:344;11739:27;;;11723:344;;;11783:30;11816:16;;11833:1;11816:19;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;11783:52;-1:-1:-1;11854:52:2;:24;11783:52;11854:28;:52::i;:::-;11850:147;;;11931:51;;;;;;;;;;;11850:147;-1:-1:-1;12039:3:2;;11723:344;;;;12082:9;12077:253;12093:34;;;12077:253;;;12170:23;;12194:1;12170:26;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;12144:91;;;12236:16;;12254:4;12144:115;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12302:3;;;;;12077:253;;;;11508:828;;;;:::o;5043:146::-;5124:58;5167:2;5179:1;5124:42;:58::i;:::-;5043:146;:::o;29835:610::-;29976:22;30013:21;;30010:429;;30114:47;;;30050:61;30114:47;;;:33;:47;;;;;30198:10;30184:32;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;30184:32:2;;30176:40;;30235:9;30230:199;30250:21;;;30230:199;;;30303:24;:39;30328:10;;30339:1;30328:13;;;;;;;:::i;:::-;;;;;;;30303:39;;;;;;;;;;;;30292:5;30298:1;30292:8;;;;;;;;:::i;:::-;;;;;;;;;;:50;30393:3;;30230:199;;;;30036:403;30010:429;29835:610;;;;;:::o;25748:946::-;25936:55;25978:12;25936:41;:55::i;:::-;26066:40;;;26002:61;26066:40;;;:26;:40;;;;;;26116:310;26132:19;;;26116:310;;;26168:15;26186:8;;26195:1;26186:11;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;26168:29;-1:-1:-1;26215:44:2;:28;26168:29;26215:35;:44::i;:::-;26211:145;;;26333:7;26284:57;;26319:12;26284:57;;;;;;;;;;;;26211:145;-1:-1:-1;26398:3:2;;26116:310;;;;26441:9;26436:252;26452:34;;;26436:252;;;26529:23;;26553:1;26529:26;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;26503:83;;;26587:12;26601:8;;26611:5;26503:114;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26660:3;;;;;26436:252;;;;25926:768;25748:946;;;;;:::o;9938:909::-;10201:50;;;10148;10201;;;:24;:50;;;;;;10261:292;10277:25;;;10261:292;;;10323:45;10350:14;;10365:1;10350:17;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;10323;;:26;:45::i;:::-;10319:164;;;10395:73;;;;;;;;;;;;;;10319:164;10525:3;;10261:292;;;;10568:9;10563:278;10579:34;;;10563:278;;;10656:23;;10680:1;10656:26;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;10630:91;;;10722:24;10748:14;;10764:5;10630:140;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10813:3;;;;;10563:278;;30712:260;30904:37;;;;30836:29;30904:37;;;:24;:37;;;;;30836:29;;30904:61;;:37;30951:13;;30904:46;:61;:::i;21458:1683::-;21691:55;21733:12;21691:41;:55::i;:::-;21760:39;;;21757:130;;21822:54;;;;;;;;;;;;;;21757:130;21919:1;21900:20;;;21897:115;;21943:58;;;;;;;;;;;;;;21897:115;22110:33;;;22022:72;22110:33;;;:19;:33;;;;;;22022:72;22179:683;22198:19;;;22179:683;;;22244:8;;22253:1;22244:11;;;;;;;:::i;:::-;;;;;;;22234:21;;22269:45;22317:13;;22331:1;22317:16;;;;;;;:::i;:::-;;;;;;22269:64;;22379:14;:27;;;;;;;;;;:::i;:::-;22351:55;;:25;;;;;;;;:::i;:::-;:55;;;22348:169;;;22433:69;;;;;;;;;;;;;;22348:169;22531:30;;;;;;;;;;;22564:14;;22531:47;22564:14;22531:30;:47;:::i;:::-;-1:-1:-1;22681:7:2;;-1:-1:-1;22598:181:2;;;;22707:25;;;;;;;;:::i;:::-;22751:27;;;;;;;;:::i;:::-;22598:181;;;23684:32:8;23743:15;;;23725:34;;23795:15;;;;23790:2;23775:18;;23768:43;23647:18;22598:181:2;;;;;;;-1:-1:-1;22834:3:2;;22179:683;;;;22877:9;22872:263;22888:34;;;22872:263;;;22965:23;;22989:1;22965:26;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;22939:86;;;23026:12;23040:8;;23050:13;;22939:125;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23107:3;;;;;22872:263;;;;21681:1460;;21458:1683;;;;;;;:::o;33386:164::-;33494:40;;;;;;;:26;:40;;;;;33459:16;;33494:49;;:47;:49::i;:::-;33487:56;33386:164;-1:-1:-1;;33386:164:2:o;4251:324::-;4353:22;;;4350:152;;4398:93;;;;;;;;;;;;;;4350:152;4512:56;4555:2;4559:8;4512:42;:56::i;:::-;4251:324;;:::o;24017:937::-;24202:55;24244:12;24202:41;:55::i;:::-;24332:40;;;24268:61;24332:40;;;:26;:40;;;;;;24382:305;24398:19;;;24382:305;;;24434:15;24452:8;;24461:1;24452:11;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;24434:29;-1:-1:-1;24481:41:2;:28;24434:29;24481:32;:41::i;:::-;24477:140;;;24594:7;24547:55;;24580:12;24547:55;;;;;;;;;;;;24477:140;-1:-1:-1;24659:3:2;;24382:305;;;;24702:9;24697:251;24713:34;;;24697:251;;;24790:23;;24814:1;24790:26;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;24764:83;;;24848:12;24862:8;;24872:4;24764:113;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24920:3;;;;;24697:251;;15867:4244;16227:55;16269:12;16227:41;:55::i;:::-;16322:12;:19;16297:14;:21;:44;16293:136;;16364:54;;;;;;;;;;;;;;16293:136;16468:12;:19;16443:14;:21;:44;16439:136;;16510:54;;;;;;;;;;;;;;16439:136;274:6:6;16589::2;:31;;;:49;;;16585:167;;;16661:80;;;;;;;;;;;;;;16585:167;274:6:6;16766::2;:29;;;:47;;;16762:163;;;16836:78;;;;;;;;;;;;;;16762:163;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;17005:22:2;;:60;;;;:129;;-1:-1:-1;17082:22:2;;:52;;1555:1:6;17082:52:2;17005:129;16988:1054;;;17193:1;17159:31;;;:35;;;17208:38;;;:51;16988:1054;;;17280:22;;:59;;;;17276:766;;17404:1;17355:38;;;:51;17276:766;;;17427:22;;:62;;1739:1:6;17427:62:2;;:157;;-1:-1:-1;17506:22:2;;:78;;1682:1:6;17506:78:2;17427:157;17423:619;;;17634:1;17600:31;;;:35;17690:36;;;;17653:34;;;;:73;;;;;;;17650:187;;;17753:69;;;;;;;;;;;;;;17650:187;17880:36;;;;17851:65;;;;:26;;;:65;17957:34;;;;17930:61;:24;;;:61;18027:4;18005:26;;17423:619;18090:28;;18056:31;;;;18090:28;;;;18056:62;;;18052:164;;;18141:64;;;;;;;;;;;;;;18052:164;18267:13;18226:24;:38;18251:12;18226:38;;;;;;;;;;;;;;;:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;18346:6;:38;;;18290:39;:53;18330:12;18290:53;;;;;;;;;;;;;;;;:94;;;;;;;;;;;;;;;;;;18446:6;:30;;;18394:35;:49;18430:12;18394:49;;;;;;;;;;;;;;;;:82;;;;;;;;;;;;;;;;;;18530:453;;;;;;;;18591:4;18530:453;;;;;;18631:6;:22;;;18530:453;;;;;;18693:6;:31;;;18530:453;;;;;;18763:6;:30;;;18530:453;;;;;;18833:6;:31;;;18530:453;;;;;;18902:6;:29;;;18530:453;;;;;;18956:6;:16;;;18530:453;;;;;18487:26;:40;18514:12;18487:40;;;;;;;;;;;;;;;:496;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;19022:1;18998:14;:21;:25;18994:392;;;19101:46;;;19039:59;19101:46;;;:32;:46;;;;;;19162:214;19186:14;:21;19182:1;:25;19162:214;;;19274:12;19287:1;19274:15;;;;;;;;:::i;:::-;;;;;;;19228:24;:43;19253:14;19268:1;19253:17;;;;;;;;:::i;:::-;;;;;;;19228:43;;;;;;;;;;;:61;;;;;;:::i;:::-;-1:-1:-1;19340:3:2;;19162:214;;;;19025:361;18994:392;19400:21;;:25;19396:395;;19505:47;;;19441:61;19505:47;;;:33;:47;;;;;;19567:214;19591:14;:21;19587:1;:25;19567:214;;;19679:12;19692:1;19679:15;;;;;;;;:::i;:::-;;;;;;;19633:24;:43;19658:14;19673:1;19658:17;;;;;;;;:::i;:::-;;;;;;;19633:43;;;;;;;;;;;:61;;;;19745:3;;;;;19567:214;;;;19427:364;19396:395;19806:9;19801:226;19817:34;;;19801:226;;;19894:23;;19918:1;19894:26;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;19868:88;;;;;:74;1817:55:8;;;19868:88:2;;;1799:74:8;19868::2;;;;;;;1772:18:8;;19868:88:2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;19999:3;;;;;19801:226;;;;20083:12;20050:54;;;20097:6;20050:54;;;;;;:::i;:::-;;;;;;;;16217:3894;15867:4244;;;;;;;;:::o;33094:195::-;33223:50;;;;;;;:24;:50;;;;;33188:16;;33223:59;;:57;:59::i;7748:1021::-;7944:66;7985:24;7944:40;:66::i;:::-;8074:50;;;8021;8074;;;:24;:50;;;;;;8134:341;8150:25;;;8134:341;;;8192:21;8216:14;;8231:1;8216:17;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;8192:41;-1:-1:-1;8252:39:2;:17;8192:41;8252:24;:39::i;:::-;8248:157;;;8316:74;;;;;;;;;;;;;;;8248:157;-1:-1:-1;8447:3:2;;8134:341;;;;8490:9;8485:278;8501:34;;;8485:278;;;8578:23;;8602:1;8578:26;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;8552:91;;;8644:24;8670:14;;8686:5;8552:140;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8735:3;;;;;8485:278;;31636:191;31732:14;31770:50;:24;31804:15;31770:33;:50::i;13008:837::-;13169:46;:44;:46::i;:::-;13231:9;13226:349;13242:27;;;13226:349;;;13286:30;13319:16;;13336:1;13319:19;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;13286:52;-1:-1:-1;13357:55:2;:24;13286:52;13357:31;:55::i;:::-;13353:152;;;13437:53;;;;;;;;;;;13353:152;-1:-1:-1;13547:3:2;;13226:349;;;;13590:9;13585:254;13601:34;;;13585:254;;;13678:23;;13702:1;13678:26;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;13652:91;;;13744:16;;13762:5;13652:116;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13811:3;;;;;13585:254;;29000:599;29140:19;29174:21;;29171:422;;29273:46;;;29211:59;29273:46;;;:32;:46;;;;;29353:10;29341:30;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;29334:37;;29390:9;29385:198;29405:21;;;29385:198;;;29457:24;:39;29482:10;;29493:1;29482:13;;;;;;;:::i;:::-;;;;;;;29457:39;;;;;;;;;;;29447:49;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:4;29452:1;29447:7;;;;;;;;:::i;:::-;;;;;;;;;;:49;29547:3;;29385:198;;5926:1011;6120:66;6161:24;6120:40;:66::i;:::-;6250:50;;;6197;6250;;;:24;:50;;;;;;6310:334;6326:25;;;6310:334;;;6368:21;6392:14;;6407:1;6392:17;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;6368:41;-1:-1:-1;6428:36:2;:17;6368:41;6428:21;:36::i;:::-;6424:150;;;6489:70;;;;;;;;;;;;;;;6424:150;-1:-1:-1;6616:3:2;;6310:334;;;;6659:9;6654:277;6670:34;;;6654:277;;;6747:23;;6771:1;6747:26;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;6721:91;;;6813:24;6839:14;;6855:4;6721:139;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6903:3;;;;;6654:277;;31229:240;31404:40;;;31352:21;31404:40;;;:26;:40;;;;;:58;;31454:7;31404:49;:58::i;3245:427::-;3346:31;3458:30;;3411:10;;3458:30;;3346:31;;3458:30;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;3498:55;;-1:-1:-1;3498:55:2;;;:29;:55;;;;;;;:69;;;;;;;;;;;;;3582:83;;3498:55;;-1:-1:-1;3498:69:2;3582:83;;;;3651:13;;;;3582:83;:::i;:::-;;;;;;;;3379:293;3245:427;;;;:::o;27447:1318::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27951:40:2;;;;;;:26;:40;;;;;27926:65;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;1739:1:6;28006:82:2;;:197;;-1:-1:-1;28105:42:2;;;;:98;;1682:1:6;28105:98:2;28006:197;28002:393;;;28245:38;;;;;;;;:24;:38;;;;;;;;28219:64;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28331:53;;;:39;:53;;;;;;28219:64;;-1:-1:-1;28331:53:2;;-1:-1:-1;28002:393:2;28426:32;;;;1123:6:6;39240:16:2;39239:23;28405:191;;28536:49;;;;;;;;:35;:49;;;;;;;;-1:-1:-1;28405:191:2;28613:63;28647:12;28661:14;;28613:33;:63::i;:::-;28606:70;;28694:64;28729:12;28743:14;;28694:34;:64::i;:::-;28686:72;;27447:1318;;;;;;;;;;;:::o;35113:276::-;35211:66;;;:29;:66;;;;;;35197:10;:80;35193:190;;35300:72;;;;;;;;;;;;;;35193:190;35113:276::o;8110:150:1:-;8180:4;8203:50;8208:3;8228:23;;;8203:4;:50::i;33883:275:2:-;33983:44;34024:2;33983:40;:44::i;:::-;34037:33;;;;;;;:29;:33;;;;;;:44;;;;;;;;;;;;;34096:55;;34037:44;;:33;34096:55;;;33883:275;;:::o;35775:611::-;35889:10;35921:22;;;;;35918:58;;35959:7;35775:611;:::o;35918:58::-;35987:21;36013:24;36024:12;36013:10;:24::i;:::-;35986:51;;;36060:13;36050:23;;:6;:23;;;36047:59;;36089:7;;35775:611;:::o;36047:59::-;36117:26;36148:69;36161:12;36117:26;36210:6;36148:12;:69::i;:::-;36116:101;;;36230:21;36227:57;;;36267:7;;;35775:611;:::o;36227:57::-;36301:78;;;;;;;;;;;;;;8428:156:1;8501:4;8524:53;8532:3;8552:23;;;8524:7;:53::i;8665:165::-;8798:23;;;8745:4;4154:21;;;:14;;;:21;;;;;;:26;;8768:55;4058:129;10064:300;10127:16;10155:22;10180:19;10188:3;10180:7;:19::i;34480:287:2:-;34604:55;;;;;;;:29;:55;;;;;;;;34590:10;:69;34587:174;;34682:68;;;;;;;;;;;;;;2035:406:1;2098:4;4154:21;;;:14;;;:21;;;;;;2114:321;;-1:-1:-1;2156:23:1;;;;;;;;:11;:23;;;;;;;;;;;;;2338:18;;2314:21;;;:14;;;:21;;;;;;:42;;;;2370:11;;2114:321;-1:-1:-1;2419:5:1;2412:12;;36806:560:2;36884:13;36899:12;36946:349;;;37032:10;37026:4;37019:24;36984:6;36992:8;37154:4;37148;37142;37136;37121:13;37114:5;37103:56;37095:4;37077:16;37074:26;37067:34;37063:97;37060:188;;;37199:4;37193:11;37183:21;;36946:349;;;:::o;37060:188::-;-1:-1:-1;36946:349:2;37277:4;;-1:-1:-1;36946:349:2:o;:::-;37326:24;37337:12;37326:24;:::i;:::-;37308:42;;;;36806:560;;;:::o;37927:838::-;38054:12;38068;38115:560;;;38172:8;38182;38226:4;38220:11;38270:4;38265:3;38261:14;38255:4;38248:28;38305:10;38300:3;38293:23;38356:5;38350:3;38344:4;38340:14;38333:29;38402:8;38396:3;38390:4;38386:14;38379:32;38532:4;38526;38520;38513;38508:3;38504:14;38489:13;38482:5;38471:66;38463:4;38445:16;38442:26;38435:34;38431:107;38428:200;;;38579:4;38573:11;38561:23;;38605:5;;;38428:200;;38657:4;38645:16;;38115:560;;;;;;;:::o;:::-;38708:41;38741:7;38735:4;38721:12;38708:41;:::i;:::-;38688:61;;;;37927:838;;;;;;:::o;2609:1368:1:-;2675:4;2804:21;;;:14;;;:21;;;;;;2840:13;;2836:1135;;3207:18;3228:12;3239:1;3228:8;:12;:::i;:::-;3274:18;;3207:33;;-1:-1:-1;3254:17:1;;3274:22;;3295:1;;3274:22;:::i;:::-;3254:42;;3329:9;3315:10;:23;3311:378;;3358:17;3378:3;:11;;3390:9;3378:22;;;;;;;;:::i;:::-;;;;;;;;;3358:42;;3525:9;3499:3;:11;;3511:10;3499:23;;;;;;;;:::i;:::-;;;;;;;;;;;;:35;;;;3638:25;;;:14;;;:25;;;;;:36;;;3311:378;3767:17;;:3;;:17;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;3870:3;:14;;:21;3885:5;3870:21;;;;;;;;;;;3863:28;;;3913:4;3906:11;;;;;;;2836:1135;3955:5;3948:12;;;;;5375:109;5431:16;5466:3;:11;;5459:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5375:109;;;:::o;14:367:8:-;77:8;87:6;141:3;134:4;126:6;122:17;118:27;108:55;;159:1;156;149:12;108:55;-1:-1:-1;182:20:8;;225:18;214:30;;211:50;;;257:1;254;247:12;211:50;294:4;286:6;282:17;270:29;;354:3;347:4;337:6;334:1;330:14;322:6;318:27;314:38;311:47;308:67;;;371:1;368;361:12;308:67;14:367;;;;;:::o;386:773::-;508:6;516;524;532;585:2;573:9;564:7;560:23;556:32;553:52;;;601:1;598;591:12;553:52;641:9;628:23;670:18;711:2;703:6;700:14;697:34;;;727:1;724;717:12;697:34;766:70;828:7;819:6;808:9;804:22;766:70;:::i;:::-;855:8;;-1:-1:-1;740:96:8;-1:-1:-1;943:2:8;928:18;;915:32;;-1:-1:-1;959:16:8;;;956:36;;;988:1;985;978:12;956:36;;1027:72;1091:7;1080:8;1069:9;1065:24;1027:72;:::i;:::-;386:773;;;;-1:-1:-1;1118:8:8;-1:-1:-1;;;;386:773:8:o;1164:163::-;1231:20;;1291:10;1280:22;;1270:33;;1260:61;;1317:1;1314;1307:12;1260:61;1164:163;;;:::o;1332:184::-;1390:6;1443:2;1431:9;1422:7;1418:23;1414:32;1411:52;;;1459:1;1456;1449:12;1411:52;1482:28;1500:9;1482:28;:::i;1884:196::-;1952:20;;2012:42;2001:54;;1991:65;;1981:93;;2070:1;2067;2060:12;2085:511;2180:6;2188;2196;2249:2;2237:9;2228:7;2224:23;2220:32;2217:52;;;2265:1;2262;2255:12;2217:52;2288:29;2307:9;2288:29;:::i;:::-;2278:39;;2368:2;2357:9;2353:18;2340:32;2395:18;2387:6;2384:30;2381:50;;;2427:1;2424;2417:12;2381:50;2466:70;2528:7;2519:6;2508:9;2504:22;2466:70;:::i;:::-;2085:511;;2555:8;;-1:-1:-1;2440:96:8;;-1:-1:-1;;;;2085:511:8:o;2601:439::-;2654:3;2692:5;2686:12;2719:6;2714:3;2707:19;2745:4;2774;2769:3;2765:14;2758:21;;2813:4;2806:5;2802:16;2836:1;2846:169;2860:6;2857:1;2854:13;2846:169;;;2921:13;;2909:26;;2955:12;;;;2990:15;;;;2882:1;2875:9;2846:169;;;-1:-1:-1;3031:3:8;;2601:439;-1:-1:-1;;;;;2601:439:8:o;3045:261::-;3224:2;3213:9;3206:21;3187:4;3244:56;3296:2;3285:9;3281:18;3273:6;3244:56;:::i;3311:847::-;3442:6;3450;3458;3466;3474;3527:2;3515:9;3506:7;3502:23;3498:32;3495:52;;;3543:1;3540;3533:12;3495:52;3566:29;3585:9;3566:29;:::i;:::-;3556:39;;3646:2;3635:9;3631:18;3618:32;3669:18;3710:2;3702:6;3699:14;3696:34;;;3726:1;3723;3716:12;3696:34;3765:70;3827:7;3818:6;3807:9;3803:22;3765:70;:::i;:::-;3854:8;;-1:-1:-1;3739:96:8;-1:-1:-1;3942:2:8;3927:18;;3914:32;;-1:-1:-1;3958:16:8;;;3955:36;;;3987:1;3984;3977:12;3955:36;;4026:72;4090:7;4079:8;4068:9;4064:24;4026:72;:::i;:::-;3311:847;;;;-1:-1:-1;3311:847:8;;-1:-1:-1;4117:8:8;;4000:98;3311:847;-1:-1:-1;;;3311:847:8:o;4163:845::-;4293:6;4301;4309;4317;4325;4378:2;4366:9;4357:7;4353:23;4349:32;4346:52;;;4394:1;4391;4384:12;4346:52;4417:28;4435:9;4417:28;:::i;5013:258::-;5080:6;5088;5141:2;5129:9;5120:7;5116:23;5112:32;5109:52;;;5157:1;5154;5147:12;5109:52;5180:28;5198:9;5180:28;:::i;:::-;5170:38;;5227;5261:2;5250:9;5246:18;5227:38;:::i;:::-;5217:48;;5013:258;;;;;:::o;5468:1366::-;5676:6;5684;5692;5700;5708;5716;5724;5777:3;5765:9;5756:7;5752:23;5748:33;5745:53;;;5794:1;5791;5784:12;5745:53;5817:29;5836:9;5817:29;:::i;:::-;5807:39;;5897:2;5886:9;5882:18;5869:32;5920:18;5961:2;5953:6;5950:14;5947:34;;;5977:1;5974;5967:12;5947:34;6016:70;6078:7;6069:6;6058:9;6054:22;6016:70;:::i;:::-;6105:8;;-1:-1:-1;5990:96:8;-1:-1:-1;6193:2:8;6178:18;;6165:32;;-1:-1:-1;6209:16:8;;;6206:36;;;6238:1;6235;6228:12;6206:36;6276:8;6265:9;6261:24;6251:34;;6323:7;6316:4;6312:2;6308:13;6304:27;6294:55;;6345:1;6342;6335:12;6294:55;6385:2;6372:16;6411:2;6403:6;6400:14;6397:34;;;6427:1;6424;6417:12;6397:34;6483:7;6478:2;6470:4;6462:6;6458:17;6454:2;6450:26;6446:35;6443:48;6440:68;;;6504:1;6501;6494:12;6440:68;6535:2;6531;6527:11;6517:21;;6557:6;6547:16;;;6616:4;6605:9;6601:20;6588:34;6572:50;;6647:2;6637:8;6634:16;6631:36;;;6663:1;6660;6653:12;6631:36;;6702:72;6766:7;6755:8;6744:9;6740:24;6702:72;:::i;:::-;5468:1366;;;;-1:-1:-1;5468:1366:8;;-1:-1:-1;5468:1366:8;;;;6676:98;;-1:-1:-1;;;5468:1366:8:o;6839:186::-;6898:6;6951:2;6939:9;6930:7;6926:23;6922:32;6919:52;;;6967:1;6964;6957:12;6919:52;6990:29;7009:9;6990:29;:::i;7030:681::-;7201:2;7253:21;;;7323:13;;7226:18;;;7345:22;;;7172:4;;7201:2;7424:15;;;;7398:2;7383:18;;;7172:4;7467:218;7481:6;7478:1;7475:13;7467:218;;;7546:13;;7561:42;7542:62;7530:75;;7660:15;;;;7625:12;;;;7503:1;7496:9;7467:218;;;-1:-1:-1;7702:3:8;;7030:681;-1:-1:-1;;;;;;7030:681:8:o;7716:184::-;7768:77;7765:1;7758:88;7865:4;7862:1;7855:15;7889:4;7886:1;7879:15;7905:255;7977:2;7971:9;8019:6;8007:19;;8056:18;8041:34;;8077:22;;;8038:62;8035:88;;;8103:18;;:::i;:::-;8139:2;8132:22;7905:255;:::o;8165:334::-;8236:2;8230:9;8292:2;8282:13;;8297:66;8278:86;8266:99;;8395:18;8380:34;;8416:22;;;8377:62;8374:88;;;8442:18;;:::i;:::-;8478:2;8471:22;8165:334;;-1:-1:-1;8165:334:8:o;8504:156::-;8570:20;;8630:4;8619:16;;8609:27;;8599:55;;8650:1;8647;8640:12;8665:159;8732:20;;8792:6;8781:18;;8771:29;;8761:57;;8814:1;8811;8804:12;8829:144;8915:32;8908:5;8904:44;8897:5;8894:55;8884:83;;8963:1;8960;8953:12;8978:134;9046:20;;9075:31;9046:20;9075:31;:::i;9117:934::-;9195:5;9243:6;9231:9;9226:3;9222:19;9218:32;9215:52;;;9263:1;9260;9253:12;9215:52;9285:22;;:::i;:::-;9276:31;;9330:27;9347:9;9330:27;:::i;:::-;9323:5;9316:42;9390:37;9423:2;9412:9;9408:18;9390:37;:::i;:::-;9385:2;9378:5;9374:14;9367:61;9460:38;9494:2;9483:9;9479:18;9460:38;:::i;:::-;9455:2;9448:5;9444:14;9437:62;9531:37;9564:2;9553:9;9549:18;9531:37;:::i;:::-;9526:2;9519:5;9515:14;9508:61;9602:39;9636:3;9625:9;9621:19;9602:39;:::i;:::-;9596:3;9589:5;9585:15;9578:64;9675:38;9708:3;9697:9;9693:19;9675:38;:::i;:::-;9669:3;9662:5;9658:15;9651:63;9747:39;9781:3;9770:9;9766:19;9747:39;:::i;:::-;9741:3;9734:5;9730:15;9723:64;9820:38;9853:3;9842:9;9838:19;9820:38;:::i;:::-;9814:3;9807:5;9803:15;9796:63;9878:3;9913:38;9947:2;9936:9;9932:18;9913:38;:::i;:::-;9897:14;;;9890:62;9971:3;10006:38;10025:18;;;10006:38;:::i;:::-;9990:14;;;9983:62;9994:5;9117:934;-1:-1:-1;;9117:934:8:o;10056:183::-;10116:4;10149:18;10141:6;10138:30;10135:56;;;10171:18;;:::i;:::-;-1:-1:-1;10216:1:8;10212:14;10228:4;10208:25;;10056:183::o;10244:668::-;10298:5;10351:3;10344:4;10336:6;10332:17;10328:27;10318:55;;10369:1;10366;10359:12;10318:55;10405:6;10392:20;10431:4;10455:60;10471:43;10511:2;10471:43;:::i;:::-;10455:60;:::i;:::-;10537:3;10561:2;10556:3;10549:15;10589:4;10584:3;10580:14;10573:21;;10646:4;10640:2;10637:1;10633:10;10625:6;10621:23;10617:34;10603:48;;10674:3;10666:6;10663:15;10660:35;;;10691:1;10688;10681:12;10660:35;10727:4;10719:6;10715:17;10741:142;10757:6;10752:3;10749:15;10741:142;;;10823:17;;10811:30;;10861:12;;;;10774;;10741:142;;;-1:-1:-1;10901:5:8;10244:668;-1:-1:-1;;;;;;10244:668:8:o;10917:1387::-;10969:5;10999:4;11045:3;11038:4;11030:6;11026:17;11022:27;11012:55;;11063:1;11060;11053:12;11012:55;11099:6;11086:20;11125:4;11149:60;11165:43;11205:2;11165:43;:::i;11149:60::-;11243:15;;;11329:1;11325:10;;;;11313:23;;11309:32;;;11274:12;;;;11353:15;;;11350:35;;;11381:1;11378;11371:12;11350:35;11417:2;11409:6;11405:15;11429:846;11445:6;11440:3;11437:15;11429:846;;;11531:3;11518:17;11558:18;11608:2;11595:11;11592:19;11589:39;;;11624:1;11621;11614:12;11589:39;11663:11;11655:6;11651:24;11641:34;;11715:3;11710:2;11706;11702:11;11698:21;11688:49;;11733:1;11730;11723:12;11688:49;11781:2;11777;11773:11;11760:25;11808:2;11833;11829;11826:10;11823:36;;;11839:18;;:::i;:::-;11887:110;11993:2;11924:66;11919:2;11915;11911:11;11907:84;11903:93;11887:110;:::i;:::-;11872:125;;12026:2;12017:7;12010:19;12070:3;12065:2;12060;12056;12052:11;12048:20;12045:29;12042:49;;;12087:1;12084;12077:12;12042:49;12148:2;12143;12139;12135:11;12130:2;12121:7;12117:16;12104:47;-1:-1:-1;12198:1:8;12175:16;;;12171:25;;12164:36;12213:20;;-1:-1:-1;12253:12:8;;;;11462;;11429:846;;;-1:-1:-1;12293:5:8;10917:1387;-1:-1:-1;;;;;;;10917:1387:8:o;12309:1612::-;12607:6;12615;12623;12631;12639;12647;12655;12663;12716:3;12704:9;12695:7;12691:23;12687:33;12684:53;;;12733:1;12730;12723:12;12684:53;12756:29;12775:9;12756:29;:::i;:::-;12746:39;;12804:78;12874:7;12869:2;12858:9;12854:18;12804:78;:::i;:::-;12794:88;;12933:3;12922:9;12918:19;12905:33;12957:18;12998:2;12990:6;12987:14;12984:34;;;13014:1;13011;13004:12;12984:34;13037:61;13090:7;13081:6;13070:9;13066:22;13037:61;:::i;:::-;13027:71;;13151:3;13140:9;13136:19;13123:33;13107:49;;13181:2;13171:8;13168:16;13165:36;;;13197:1;13194;13187:12;13165:36;13220:61;13273:7;13262:8;13251:9;13247:24;13220:61;:::i;:::-;13210:71;;13334:3;13323:9;13319:19;13306:33;13290:49;;13364:2;13354:8;13351:16;13348:36;;;13380:1;13377;13370:12;13348:36;13403:63;13458:7;13447:8;13436:9;13432:24;13403:63;:::i;:::-;13393:73;;13519:3;13508:9;13504:19;13491:33;13475:49;;13549:2;13539:8;13536:16;13533:36;;;13565:1;13562;13555:12;13533:36;13588:63;13643:7;13632:8;13621:9;13617:24;13588:63;:::i;:::-;13578:73;;13704:3;13693:9;13689:19;13676:33;13660:49;;13734:2;13724:8;13721:16;13718:36;;;13750:1;13747;13740:12;13718:36;;13789:72;13853:7;13842:8;13831:9;13827:24;13789:72;:::i;:::-;12309:1612;;;;-1:-1:-1;12309:1612:8;;-1:-1:-1;12309:1612:8;;;;;;13880:8;-1:-1:-1;;;12309:1612:8:o;14222:254::-;14290:6;14298;14351:2;14339:9;14330:7;14326:23;14322:32;14319:52;;;14367:1;14364;14357:12;14319:52;14390:29;14409:9;14390:29;:::i;:::-;14380:39;14466:2;14451:18;;;;14438:32;;-1:-1:-1;;;14222:254:8:o;14952:288::-;15164:2;15149:18;;15176:58;15153:9;15216:6;14704:12;;14697:20;14690:28;14678:41;;14765:4;14754:16;;;14748:23;14790:32;14854:21;;;14838:14;;;14831:45;;;;14929:4;14918:16;;;14912:23;14908:32;14892:14;;14885:56;14603:344;15245:1037;15296:3;15327;15359:5;15353:12;15386:6;15381:3;15374:19;15412:4;15441:2;15436:3;15432:12;15425:19;;15497:2;15487:6;15484:1;15480:14;15473:5;15469:26;15465:35;15534:2;15527:5;15523:14;15555:1;15565:691;15579:6;15576:1;15573:13;15565:691;;;15638:66;15751:2;15743:5;15737:4;15733:16;15729:25;15724:3;15717:38;15784:6;15778:13;15826:2;15820:9;15855:8;15849:4;15842:22;15888:1;15902:155;15918:8;15913:3;15910:17;15902:155;;;16024:12;;;16020:21;;16014:28;15993:14;;;15989:23;;15982:61;15937:12;;15902:155;;;-1:-1:-1;16107:1:8;16081:19;;;16077:28;;16070:39;16234:12;;;;16162:2;16148:17;16144:26;;;16134:37;;;16130:46;;;-1:-1:-1;16199:15:8;;;;15601:1;15594:9;15565:691;;;-1:-1:-1;16272:4:8;;15245:1037;-1:-1:-1;;;;;;;15245:1037:8:o;16287:277::-;16484:2;16473:9;16466:21;16447:4;16504:54;16554:2;16543:9;16539:18;16531:6;16504:54;:::i;16569:260::-;16637:6;16645;16698:2;16686:9;16677:7;16673:23;16669:32;16666:52;;;16714:1;16711;16704:12;16666:52;16737:29;16756:9;16737:29;:::i;16834:592::-;16905:6;16913;16966:2;16954:9;16945:7;16941:23;16937:32;16934:52;;;16982:1;16979;16972:12;16934:52;17022:9;17009:23;17051:18;17092:2;17084:6;17081:14;17078:34;;;17108:1;17105;17098:12;17078:34;17146:6;17135:9;17131:22;17121:32;;17191:7;17184:4;17180:2;17176:13;17172:27;17162:55;;17213:1;17210;17203:12;17162:55;17253:2;17240:16;17279:2;17271:6;17268:14;17265:34;;;17295:1;17292;17285:12;17265:34;17340:7;17335:2;17326:6;17322:2;17318:15;17314:24;17311:37;17308:57;;;17361:1;17358;17351:12;17308:57;17392:2;17384:11;;;;;17414:6;;-1:-1:-1;16834:592:8;;-1:-1:-1;;;;16834:592:8:o;18458:1628::-;18988:4;19017:3;19067:6;19061:13;19054:21;19047:29;19036:9;19029:48;19145:4;19137;19129:6;19125:17;19119:24;19115:35;19108:4;19097:9;19093:20;19086:65;19219:10;19211:4;19203:6;19199:17;19193:24;19189:41;19182:4;19171:9;19167:20;19160:71;19299:42;19291:4;19283:6;19279:17;19273:24;19269:73;19262:4;19251:9;19247:20;19240:103;19411:6;19403:4;19395:6;19391:17;19385:24;19381:37;19374:4;19363:9;19359:20;19352:67;19466:4;19458:6;19454:17;19448:24;19481:53;19528:4;19517:9;19513:20;19499:12;18439:6;18428:18;18416:31;;18363:90;19481:53;;19583:4;19575:6;19571:17;19565:24;19598:55;19647:4;19636:9;19632:20;19616:14;18439:6;18428:18;18416:31;;18363:90;19598:55;-1:-1:-1;14704:12:8;;14697:20;14690:28;19725:3;19710:19;;14678:41;14765:4;14754:16;;14748:23;14790:32;14854:21;;;14838:14;;;14831:45;14929:4;14918:16;;14912:23;14908:32;14892:14;;;14885:56;1598:42;1587:54;;19781:3;19766:19;;1575:67;1598:42;1587:54;;19837:3;19822:19;;1575:67;19879:2;19873:3;19862:9;19858:19;19851:31;19905:54;19955:2;19944:9;19940:18;19932:6;19905:54;:::i;:::-;19891:68;;20008:9;20000:6;19996:22;19990:3;19979:9;19975:19;19968:51;20036:44;20073:6;20065;20036:44;:::i;:::-;20028:52;18458:1628;-1:-1:-1;;;;;;;;;18458:1628:8:o;20091:184::-;20143:77;20140:1;20133:88;20240:4;20237:1;20230:15;20264:4;20261:1;20254:15;20280:472;20380:6;20375:3;20368:19;20350:3;20406:4;20435;20430:3;20426:14;20419:21;;20463:5;20486:1;20496:231;20510:6;20507:1;20504:13;20496:231;;;20603:42;20575:26;20594:6;20575:26;:::i;:::-;20571:75;20559:88;;20667:12;;;;20702:15;;;;20532:1;20525:9;20496:231;;20757:369;20968:2;20957:9;20950:21;20931:4;20988:73;21057:2;21046:9;21042:18;21034:6;21026;20988:73;:::i;:::-;20980:81;;21111:6;21104:14;21097:22;21092:2;21081:9;21077:18;21070:50;20757:369;;;;;;:::o;21131:489::-;21382:42;21374:6;21370:55;21359:9;21352:74;21462:2;21457;21446:9;21442:18;21435:30;21333:4;21482:73;21551:2;21540:9;21536:18;21528:6;21520;21482:73;:::i;:::-;21474:81;;21605:6;21598:14;21591:22;21586:2;21575:9;21571:18;21564:50;21131:489;;;;;;;:::o;21625:455::-;21874:10;21866:6;21862:23;21851:9;21844:42;21922:2;21917;21906:9;21902:18;21895:30;21825:4;21942:73;22011:2;22000:9;21996:18;21988:6;21980;21942:73;:::i;22085:247::-;22144:6;22197:2;22185:9;22176:7;22172:23;22168:32;22165:52;;;22213:1;22210;22203:12;22165:52;22252:9;22239:23;22271:31;22296:5;22271:31;:::i;22337:118::-;22423:5;22416:13;22409:21;22402:5;22399:32;22389:60;;22445:1;22442;22435:12;22460:1035;22653:5;22640:19;22668:30;22690:7;22668:30;:::i;:::-;22717:11;;22813:66;22805:75;;22758:15;;22751:23;22776:3;22747:33;22802:83;;;22789:97;;22934:2;22923:14;;22910:28;22947:33;22910:28;22947:33;:::i;:::-;23026:34;23016:7;23013:1;23009:15;23005:56;22989:72;;23171:8;23166:2;23097:66;23093:2;23089:75;23086:83;23083:97;23077:4;23070:111;23229:2;23222:5;23218:14;23205:28;23242:33;23267:7;23242:33;:::i;:::-;23422:64;23412:7;23407:3;23403:17;23399:88;23393:2;23324:66;23320:2;23316:75;23313:83;23303:8;23300:97;23297:191;23291:4;23284:205;;;;;22460:1035;;:::o;23822:1715::-;24170:4;24199:2;24240:42;24232:6;24228:55;24217:9;24210:74;24303:2;24341;24336;24325:9;24321:18;24314:30;24380:6;24375:2;24364:9;24360:18;24353:34;24410:66;24402:6;24399:78;24396:98;;;24490:1;24487;24480:12;24396:98;24524:6;24521:1;24517:14;24582:6;24574;24568:3;24557:9;24553:19;24540:49;24658:3;24608:22;;;24723:18;;;24719:28;;24681:2;24699:18;;;24692:56;;;;24650:12;;;24780:19;;;24850:6;;24874:1;;24823:3;24815:12;24884:627;24898:6;24895:1;24892:13;24884:627;;;24973:6;24960:20;24993:28;25015:5;24993:28;:::i;:::-;25053:13;25046:21;25034:34;;25109:15;;;25096:29;25138:33;25096:29;25138:33;:::i;:::-;25194:32;25260:16;;;25246:12;;;25239:38;25318:15;;;25305:29;;25347:33;25305:29;25347:33;:::i;:::-;25414:16;25400:12;;;25393:38;25486:15;;;;24920:1;24913:9;;;;;25451:12;;24884:627;;;25528:3;23822:1715;-1:-1:-1;;;;;;;;;;;;23822:1715:8:o;25542:437::-;25621:1;25617:12;;;;25664;;;25685:61;;25739:4;25731:6;25727:17;25717:27;;25685:61;25792:2;25784:6;25781:14;25761:18;25758:38;25755:218;;25829:77;25826:1;25819:88;25930:4;25927:1;25920:15;25958:4;25955:1;25948:15;25755:218;;25542:437;;;:::o;26109:517::-;26210:2;26205:3;26202:11;26199:421;;;26246:5;26243:1;26236:16;26290:4;26287:1;26277:18;26360:2;26348:10;26344:19;26341:1;26337:27;26331:4;26327:38;26396:4;26384:10;26381:20;26378:47;;;-1:-1:-1;26419:4:8;26378:47;26474:2;26469:3;26465:12;26462:1;26458:20;26452:4;26448:31;26438:41;;26529:81;26547:2;26540:5;26537:13;26529:81;;;26606:1;26592:16;;26573:1;26562:13;26529:81;;26199:421;26109:517;;;:::o;26862:1460::-;26986:3;26980:10;27013:18;27005:6;27002:30;26999:56;;;27035:18;;:::i;:::-;27064:96;27153:6;27113:38;27145:4;27139:11;27113:38;:::i;:::-;27107:4;27064:96;:::i;:::-;27215:4;;27272:2;27261:14;;27289:1;27284:781;;;;28109:1;28126:6;28123:89;;;-1:-1:-1;28178:19:8;;;28172:26;28123:89;26768:66;26759:1;26755:11;;;26751:84;26747:89;26737:100;26843:1;26839:11;;;26734:117;28225:81;;27254:1062;;27284:781;26056:1;26049:14;;;26093:4;26080:18;;27332:66;27320:79;;;27496:236;27510:7;27507:1;27504:14;27496:236;;;27599:19;;;27593:26;27578:42;;27691:27;;;;27659:1;27647:14;;;;27526:19;;27496:236;;;27500:3;27760:6;27751:7;27748:19;27745:261;;;27821:19;;;27815:26;27922:66;27904:1;27900:14;;;27916:3;27896:24;27892:97;27888:102;27873:118;27858:134;;27745:261;;;28052:1;28043:6;28040:1;28036:14;28032:22;28026:4;28019:36;27254:1062;;;;;26862:1460;;:::o;28327:1407::-;28589:13;;18350:4;18339:16;18327:29;;28559:3;28544:19;;28661:4;28653:6;28649:17;28643:24;28676:53;28723:4;28712:9;28708:20;28694:12;14002:10;13991:22;13979:35;;13926:94;28676:53;;28778:4;28770:6;28766:17;28760:24;28793:56;28843:4;28832:9;28828:20;28812:14;1598:42;1587:54;1575:67;;1521:127;28793:56;;28898:4;28890:6;28886:17;28880:24;28913:55;28962:4;28951:9;28947:20;28931:14;18439:6;18428:18;18416:31;;18363:90;28913:55;;29017:4;29009:6;29005:17;28999:24;29032:56;29082:4;29071:9;29067:20;29051:14;1598:42;1587:54;1575:67;;1521:127;29032:56;;29137:4;29129:6;29125:17;29119:24;29152:55;29201:4;29190:9;29186:20;29170:14;18439:6;18428:18;18416:31;;18363:90;29152:55;;29256:4;29248:6;29244:17;29238:24;29271:56;29321:4;29310:9;29306:20;29290:14;1598:42;1587:54;1575:67;;1521:127;29271:56;;29376:4;29368:6;29364:17;29358:24;29391:55;29440:4;29429:9;29425:20;29409:14;18439:6;18428:18;18416:31;;18363:90;29391:55;-1:-1:-1;29465:6:8;29508:15;;;29502:22;14558:32;14547:44;;;29568:18;;;14535:57;;;;29606:6;29649:15;;;29643:22;14547:44;29709:18;;;;14535:57;;;;28327:1407;:::o;29739:184::-;29791:77;29788:1;29781:88;29888:4;29885:1;29878:15;29912:4;29909:1;29902:15;29928:201;29966:3;29994:10;30039:2;30032:5;30028:14;30066:2;30057:7;30054:15;30051:41;;30072:18;;:::i;:::-;30121:1;30108:15;;29928:201;-1:-1:-1;;;29928:201:8:o;30134:449::-;30293:2;30282:9;30275:21;30332:6;30327:2;30316:9;30312:18;30305:34;30389:6;30381;30376:2;30365:9;30361:18;30348:48;30445:1;30416:22;;;30440:2;30412:31;;;30405:42;;;;30499:2;30487:15;;;30504:66;30483:88;30468:104;30464:113;;30134:449;-1:-1:-1;30134:449:8:o;30588:128::-;30655:9;;;30676:11;;;30673:37;;;30690:18;;:::i;30721:184::-;30773:77;30770:1;30763:88;30870:4;30867:1;30860:15;30894:4;30891:1;30884:15

Swarm Source

ipfs://e8b78b6c2956ff19642da661b79da51ac5cdc202b1551506669da2e6c02fbe74

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.