ETH Price: $3,260.92 (+4.71%)

Contract

0xDF3969A315e3fC15B89A2752D0915cc76A5bd82D

Overview

ETH Balance

0 ETH

ETH Value

$0.00
Transaction Hash
Method
Block
From
To
Fulfill Advanced...5278692025-01-30 23:01:4510 secs ago1738278105IN
0xDF3969A3...76A5bd82D
0.00097 ETH0.000013350.04525
Fulfill Availabl...5278432025-01-30 23:01:1936 secs ago1738278079IN
0xDF3969A3...76A5bd82D
0.1098 ETH0.000091050.04525
Fulfill Advanced...5278082025-01-30 23:00:441 min ago1738278044IN
0xDF3969A3...76A5bd82D
0.009899 ETH0.000011020.04525
Fulfill Advanced...5278012025-01-30 23:00:371 min ago1738278037IN
0xDF3969A3...76A5bd82D
0.247 ETH0.000011960.04525
Fulfill Advanced...5277172025-01-30 22:59:112 mins ago1738277951IN
0xDF3969A3...76A5bd82D
0.043999 ETH0.000012860.04525
Fulfill Advanced...5277072025-01-30 22:59:012 mins ago1738277941IN
0xDF3969A3...76A5bd82D
0.00739 ETH0.000012140.04525
Fulfill Advanced...5276952025-01-30 22:58:493 mins ago1738277929IN
0xDF3969A3...76A5bd82D
0.242 ETH0.000014380.0565625
Fulfill Advanced...5274992025-01-30 22:55:326 mins ago1738277732IN
0xDF3969A3...76A5bd82D
0.029 ETH0.000012810.04525
Fulfill Availabl...5274992025-01-30 22:55:326 mins ago1738277732IN
0xDF3969A3...76A5bd82D
0.003899 ETH0.000031340.04525
Fulfill Advanced...5274102025-01-30 22:54:017 mins ago1738277641IN
0xDF3969A3...76A5bd82D
0.00739 ETH0.000011150.04525
Fulfill Advanced...5273982025-01-30 22:53:498 mins ago1738277629IN
0xDF3969A3...76A5bd82D
0.0091 ETH0.000011920.04525
Fulfill Advanced...5273472025-01-30 22:52:588 mins ago1738277578IN
0xDF3969A3...76A5bd82D
0.242 ETH0.000012760.04525
Fulfill Advanced...5272572025-01-30 22:51:2710 mins ago1738277487IN
0xDF3969A3...76A5bd82D
0.00739 ETH0.000012140.04525
Fulfill Advanced...5271732025-01-30 22:50:0311 mins ago1738277403IN
0xDF3969A3...76A5bd82D
0.24 ETH0.000011960.04525
Fulfill Availabl...5271652025-01-30 22:49:5512 mins ago1738277395IN
0xDF3969A3...76A5bd82D
0.01478 ETH0.000021090.04525
Fulfill Advanced...5271472025-01-30 22:49:3712 mins ago1738277377IN
0xDF3969A3...76A5bd82D
0.0102 ETH0.000011840.04525
Fulfill Advanced...5271362025-01-30 22:49:2612 mins ago1738277366IN
0xDF3969A3...76A5bd82D
0.24 ETH0.000012390.04525
Fulfill Advanced...5271282025-01-30 22:49:1812 mins ago1738277358IN
0xDF3969A3...76A5bd82D
0.015 ETH0.00001180.04525
Fulfill Advanced...5271092025-01-30 22:48:5712 mins ago1738277337IN
0xDF3969A3...76A5bd82D
0.015 ETH0.000011760.04525
Fulfill Advanced...5270862025-01-30 22:48:3413 mins ago1738277314IN
0xDF3969A3...76A5bd82D
0.0029 ETH0.000012040.04525
Cancel5270522025-01-30 22:48:0013 mins ago1738277280IN
0xDF3969A3...76A5bd82D
0 ETH0.000005060.04525
Fulfill Advanced...5270522025-01-30 22:48:0013 mins ago1738277280IN
0xDF3969A3...76A5bd82D
0.0005 ETH0.000009520.04525
Fulfill Availabl...5270352025-01-30 22:47:4214 mins ago1738277262IN
0xDF3969A3...76A5bd82D
0.0522 ETH0.000024560.04525
Fulfill Advanced...5270312025-01-30 22:47:3814 mins ago1738277258IN
0xDF3969A3...76A5bd82D
0.0002 ETH0.000008450.04525
Fulfill Advanced...5270302025-01-30 22:47:3714 mins ago1738277257IN
0xDF3969A3...76A5bd82D
0.0002 ETH0.000009530.04525
View all transactions

Latest 25 internal transactions (View All)

Parent Transaction Hash Block From To
5278692025-01-30 23:01:4510 secs ago1738278105
0xDF3969A3...76A5bd82D
0.0000194 ETH
5278692025-01-30 23:01:4510 secs ago1738278105
0xDF3969A3...76A5bd82D
0.0009506 ETH
5278692025-01-30 23:01:4510 secs ago1738278105
0xDF3969A3...76A5bd82D
0.0009506 ETH
5278692025-01-30 23:01:4510 secs ago1738278105
0xDF3969A3...76A5bd82D
0.00097 ETH
5278432025-01-30 23:01:1936 secs ago1738278079
0xDF3969A3...76A5bd82D
0.00022 ETH
5278432025-01-30 23:01:1936 secs ago1738278079
0xDF3969A3...76A5bd82D
0.01078 ETH
5278432025-01-30 23:01:1936 secs ago1738278079
0xDF3969A3...76A5bd82D
0.00022 ETH
5278432025-01-30 23:01:1936 secs ago1738278079
0xDF3969A3...76A5bd82D
0.01078 ETH
5278432025-01-30 23:01:1936 secs ago1738278079
0xDF3969A3...76A5bd82D
0.01078 ETH
5278432025-01-30 23:01:1936 secs ago1738278079
0xDF3969A3...76A5bd82D
0.00022 ETH
5278432025-01-30 23:01:1936 secs ago1738278079
0xDF3969A3...76A5bd82D
0.01078 ETH
5278432025-01-30 23:01:1936 secs ago1738278079
0xDF3969A3...76A5bd82D
0.00022 ETH
5278432025-01-30 23:01:1936 secs ago1738278079
0xDF3969A3...76A5bd82D
0.01078 ETH
5278432025-01-30 23:01:1936 secs ago1738278079
0xDF3969A3...76A5bd82D
0.00022 ETH
5278432025-01-30 23:01:1936 secs ago1738278079
0xDF3969A3...76A5bd82D
0.01078 ETH
5278432025-01-30 23:01:1936 secs ago1738278079
0xDF3969A3...76A5bd82D
0.00022 ETH
5278432025-01-30 23:01:1936 secs ago1738278079
0xDF3969A3...76A5bd82D
0.01078 ETH
5278432025-01-30 23:01:1936 secs ago1738278079
0xDF3969A3...76A5bd82D
0.00022 ETH
5278432025-01-30 23:01:1936 secs ago1738278079
0xDF3969A3...76A5bd82D
0.01078 ETH
5278432025-01-30 23:01:1936 secs ago1738278079
0xDF3969A3...76A5bd82D
0.00022 ETH
5278432025-01-30 23:01:1936 secs ago1738278079
0xDF3969A3...76A5bd82D
0.01078 ETH
5278432025-01-30 23:01:1936 secs ago1738278079
0xDF3969A3...76A5bd82D
0.00022 ETH
5278432025-01-30 23:01:1936 secs ago1738278079
0xDF3969A3...76A5bd82D
0.01078 ETH
5278432025-01-30 23:01:1936 secs ago1738278079
0xDF3969A3...76A5bd82D
0.000216 ETH
5278432025-01-30 23:01:1936 secs ago1738278079
0xDF3969A3...76A5bd82D
0.010584 ETH
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Seaport

Compiler Version
v0.8.24+commit.e11b9ed9

ZkSolc Version
v1.5.3

Optimization Enabled:
Yes with Mode 3

Other Settings:
cancun EvmVersion
File 1 of 43 : Seaport.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import {ConsiderationInterface} from "seaport-types/src/interfaces/ConsiderationInterface.sol";

import {OrderType} from "seaport-types/src/lib/ConsiderationEnums.sol";

import {AdvancedOrder, BasicOrderParameters, CriteriaResolver, Execution, Fulfillment, FulfillmentComponent, Order, OrderComponents, OrderParameters} from "seaport-types/src/lib/ConsiderationStructs.sol";

import {ReferenceOrderCombiner} from "./lib/ReferenceOrderCombiner.sol";

import {OrderToExecute} from "./lib/ReferenceConsiderationStructs.sol";

/**
 * @title Seaport
 * @author 0age
 * @custom:coauthor d1ll0n
 * @custom:coauthor transmissions11
 * @custom:coauthor James Wenzel
 * @custom:coauthor Daniel Viau
 * @custom:version 1.6-reference
 * @notice Consideration is a generalized native token/ERC20/ERC721/ERC1155
 *         marketplace. It minimizes external calls to the greatest extent
 *         possible and provides lightweight methods for common routes as well
 *         as more flexible methods for composing advanced orders or groups of
 *         orders. Each order contains an arbitrary number of items that may be
 *         spent (the "offer") along with an arbitrary number of items that must
 *         be received back by the indicated recipients (the "consideration").
 */
contract Seaport is ConsiderationInterface, ReferenceOrderCombiner {
    /**
     * @notice Derive and set hashes, reference chainId, and associated domain
     *         separator during deployment.
     *
     * @param conduitController A contract that deploys conduits, or proxies
     *                          that may optionally be used to transfer approved
     *                          ERC20/721/1155 tokens.
     */
    constructor(
        address conduitController
    ) ReferenceOrderCombiner(conduitController) {}

    /**
     * @notice Accept native token transfers during execution that may then be
     *         used to facilitate native token transfers, where any tokens that
     *         remain will be transferred to the caller. Native tokens are only
     *         acceptable mid-fulfillment (and not during basic fulfillment).
     */
    receive() external payable {
        // Ensure the reentrancy guard is currently set to accept native tokens.
        _assertAcceptingNativeTokens();
    }

    /**
     * @notice Fulfill an order offering an ERC20, ERC721, or ERC1155 item by
     *         supplying Ether (or other native tokens), ERC20 tokens, an ERC721
     *         item, or an ERC1155 item as consideration. Six permutations are
     *         supported: Native token to ERC721, Native token to ERC1155, ERC20
     *         to ERC721, ERC20 to ERC1155, ERC721 to ERC20, and ERC1155 to
     *         ERC20 (with native tokens supplied as msg.value). For an order to
     *         be eligible for fulfillment via this method, it must contain a
     *         single offer item (though that item may have a greater amount if
     *         the item is not an ERC721). An arbitrary number of "additional
     *         recipients" may also be supplied which will each receive native
     *         tokens or ERC20 items from the fulfiller as consideration. Refer
     *         to the documentation for a more comprehensive summary of how to
     *         utilize with this method and what orders are compatible with it.
     *
     * @param parameters Additional information on the fulfilled order. Note
     *                   that the offerer and the fulfiller must first approve
     *                   this contract (or their chosen conduit if indicated)
     *                   before any tokens can be transferred. Also note that
     *                   contract recipients of ERC1155 consideration items must
     *                   implement `onERC1155Received` in order to receive those
     *                   items.
     *
     * @return fulfilled A boolean indicating whether the order has been
     *                   fulfilled.
     */
    function fulfillBasicOrder(
        BasicOrderParameters calldata parameters
    ) external payable override nonReentrant(false) returns (bool fulfilled) {
        // Validate and fulfill the basic order.
        fulfilled = _validateAndFulfillBasicOrder(parameters);
    }

    /**
     * @notice Fulfill an order offering an ERC20, ERC721, or ERC1155 item by
     *         supplying Ether (or other native tokens), ERC20 tokens, an ERC721
     *         item, or an ERC1155 item as consideration. Six permutations are
     *         supported: Native token to ERC721, Native token to ERC1155, ERC20
     *         to ERC721, ERC20 to ERC1155, ERC721 to ERC20, and ERC1155 to
     *         ERC20 (with native tokens supplied as msg.value). For an order to
     *         be eligible for fulfillment via this method, it must contain a
     *         single offer item (though that item may have a greater amount if
     *         the item is not an ERC721). An arbitrary number of "additional
     *         recipients" may also be supplied which will each receive native
     *         tokens or ERC20 items from the fulfiller as consideration. Refer
     *         to the documentation for a more comprehensive summary of how to
     *         utilize with this method and what orders are compatible with it.
     *         Note that this function costs less gas than `fulfillBasicOrder`
     *         due to the zero bytes in the function selector (0x00000000) which
     *         also results in earlier function dispatch.
     *
     * @param parameters Additional information on the fulfilled order. Note
     *                   that the offerer and the fulfiller must first approve
     *                   this contract (or their chosen conduit if indicated)
     *                   before any tokens can be transferred. Also note that
     *                   contract recipients of ERC1155 consideration items must
     *                   implement `onERC1155Received` in order to receive those
     *                   items.
     *
     * @return fulfilled A boolean indicating whether the order has been
     *                   fulfilled.
     */
    function fulfillBasicOrder_efficient_6GL6yc(
        BasicOrderParameters calldata parameters
    ) external payable override nonReentrant(false) returns (bool fulfilled) {
        // Validate and fulfill the basic order.
        fulfilled = _validateAndFulfillBasicOrder(parameters);
    }

    /**
     * @notice Fulfill an order with an arbitrary number of items for offer and
     *         consideration. Note that this function does not support
     *         criteria-based orders or partial filling of orders (though
     *         filling the remainder of a partially-filled order is supported).
     *
     * @param order               The order to fulfill. Note that both the
     *                            offerer and the fulfiller must first approve
     *                            this contract (or the corresponding conduit if
     *                            indicated) to transfer any relevant tokens on
     *                            their behalf and that contracts must implement
     *                            `onERC1155Received` to receive ERC1155 tokens
     *                            as consideration.
     * @param fulfillerConduitKey A bytes32 value indicating what conduit, if
     *                            any, to source the fulfiller's token approvals
     *                            from. The zero hash signifies that no conduit
     *                            should be used (and direct approvals set on
     *                            Consideration).
     *
     * @return fulfilled A boolean indicating whether the order has been
     *                   fulfilled.
     */
    function fulfillOrder(
        Order calldata order,
        bytes32 fulfillerConduitKey
    )
        external
        payable
        override
        nonReentrant(order.parameters.orderType == OrderType.CONTRACT)
        returns (bool fulfilled)
    {
        // Convert order to "advanced" order, then validate and fulfill it.
        fulfilled = _validateAndFulfillAdvancedOrder(
            _convertOrderToAdvanced(order),
            new CriteriaResolver[](0), // No criteria resolvers supplied.
            fulfillerConduitKey,
            msg.sender
        );
    }

    /**
     * @notice Fill an order, fully or partially, with an arbitrary number of
     *         items for offer and consideration alongside criteria resolvers
     *         containing specific token identifiers and associated proofs.
     *
     * @param advancedOrder       The order to fulfill along with the fraction
     *                            of the order to attempt to fill. Note that
     *                            both the offerer and the fulfiller must first
     *                            approve this contract (or their proxy if
     *                            indicated by the order) to transfer any
     *                            relevant tokens on their behalf and that
     *                            contracts must implement `onERC1155Received`
     *                            to receive ERC1155 tokens as consideration.
     *                            Also note that all offer and consideration
     *                            components must have no remainder after
     *                            multiplication of the respective amount with
     *                            the supplied fraction for the partial fill to
     *                            be considered valid.
     * @param criteriaResolvers   An array where each element contains a
     *                            reference to a specific offer or
     *                            consideration, a token identifier, and a proof
     *                            that the supplied token identifier is
     *                            contained in the merkle root held by the item
     *                            in question's criteria element. Note that an
     *                            empty criteria indicates that any
     *                            (transferable) token identifier on the token
     *                            in question is valid and that no associated
     *                            proof needs to be supplied.
     * @param fulfillerConduitKey A bytes32 value indicating what conduit, if
     *                            any, to source the fulfiller's token approvals
     *                            from. The zero hash signifies that no conduit
     *                            should be used (and direct approvals set on
     *                            Consideration).
     * @param recipient           The intended recipient for all received items,
     *                            with `address(0)` indicating that the caller
     *                            should receive the items.
     *
     * @return fulfilled A boolean indicating whether the order has been
     *                   fulfilled.
     */
    function fulfillAdvancedOrder(
        AdvancedOrder calldata advancedOrder,
        CriteriaResolver[] calldata criteriaResolvers,
        bytes32 fulfillerConduitKey,
        address recipient
    )
        external
        payable
        override
        nonReentrant(advancedOrder.parameters.orderType == OrderType.CONTRACT)
        returns (bool fulfilled)
    {
        // Validate and fulfill the order.
        fulfilled = _validateAndFulfillAdvancedOrder(
            advancedOrder,
            criteriaResolvers,
            fulfillerConduitKey,
            recipient == address(0) ? msg.sender : recipient
        );
    }

    /**
     * @notice Attempt to fill a group of orders, each with an arbitrary number
     *         of items for offer and consideration. Any order that is not
     *         currently active, has already been fully filled, or has been
     *         cancelled will be omitted. Remaining offer and consideration
     *         items will then be aggregated where possible as indicated by the
     *         supplied offer and consideration component arrays and aggregated
     *         items will be transferred to the fulfiller or to each intended
     *         recipient, respectively. Note that a failing item transfer or an
     *         issue with order formatting will cause the entire batch to fail.
     *         Note that this function does not support criteria-based orders or
     *         partial filling of orders (though filling the remainder of a
     *         partially-filled order is supported).
     *
     * @param orders                    The orders to fulfill. Note that both
     *                                  the offerer and the fulfiller must first
     *                                  approve this contract (or the
     *                                  corresponding conduit if indicated) to
     *                                  transfer any relevant tokens on their
     *                                  behalf and that contracts must implement
     *                                  `onERC1155Received` to receive ERC1155
     *                                  tokens as consideration.
     * @param offerFulfillments         An array of FulfillmentComponent arrays
     *                                  indicating which offer items to attempt
     *                                  to aggregate when preparing executions.
     * @param considerationFulfillments An array of FulfillmentComponent arrays
     *                                  indicating which consideration items to
     *                                  attempt to aggregate when preparing
     *                                  executions.
     * @param fulfillerConduitKey       A bytes32 value indicating what conduit,
     *                                  if any, to source the fulfiller's token
     *                                  approvals from. The zero hash signifies
     *                                  that no conduit should be used (and
     *                                  direct approvals set on Consideration).
     * @param maximumFulfilled          The maximum number of orders to fulfill.
     *
     * @return availableOrders An array of booleans indicating if each order
     *                         with an index corresponding to the index of the
     *                         returned boolean was fulfillable or not.
     * @return executions      An array of elements indicating the sequence of
     *                         transfers performed as part of matching the given
     *                         orders.
     */
    function fulfillAvailableOrders(
        Order[] calldata orders,
        FulfillmentComponent[][] calldata offerFulfillments,
        FulfillmentComponent[][] calldata considerationFulfillments,
        bytes32 fulfillerConduitKey,
        uint256 maximumFulfilled
    )
        external
        payable
        override
        nonReentrant(true)
        returns (bool[] memory availableOrders, Execution[] memory executions)
    {
        // Convert orders to "advanced" orders.
        AdvancedOrder[] memory advancedOrders = _convertOrdersToAdvanced(
            orders
        );
        // Convert Advanced Orders to Orders To Execute
        OrderToExecute[]
            memory ordersToExecute = _convertAdvancedToOrdersToExecute(
                advancedOrders
            );

        // Fulfill all available orders.
        return
            _fulfillAvailableAdvancedOrders(
                advancedOrders,
                ordersToExecute,
                new CriteriaResolver[](0), // No criteria resolvers supplied.
                offerFulfillments,
                considerationFulfillments,
                fulfillerConduitKey,
                msg.sender,
                maximumFulfilled
            );
    }

    /**
     * @notice Attempt to fill a group of orders, fully or partially, with an
     *         arbitrary number of items for offer and consideration per order
     *         alongside criteria resolvers containing specific token
     *         identifiers and associated proofs. Any order that is not
     *         currently active, has already been fully filled, or has been
     *         cancelled will be omitted. Remaining offer and consideration
     *         items will then be aggregated where possible as indicated by the
     *         supplied offer and consideration component arrays and aggregated
     *         items will be transferred to the fulfiller or to each intended
     *         recipient, respectively. Note that a failing item transfer or an
     *         issue with order formatting will cause the entire batch to fail.
     *
     * @param advancedOrders            The orders to fulfill along with the
     *                                  fraction of those orders to attempt to
     *                                  fill. Note that both the offerer and the
     *                                  fulfiller must first approve this
     *                                  contract (or their proxy if indicated by
     *                                  the order) to transfer any relevant
     *                                  tokens on their behalf and that
     *                                  contracts must implement
     *                                  `onERC1155Received` in order to receive
     *                                  ERC1155 tokens as consideration. Also
     *                                  note that all offer and consideration
     *                                  components must have no remainder after
     *                                  multiplication of the respective amount
     *                                  with the supplied fraction for an
     *                                  order's partial fill amount to be
     *                                  considered valid.
     * @param criteriaResolvers         An array where each element contains a
     *                                  reference to a specific offer or
     *                                  consideration, a token identifier, and a
     *                                  proof that the supplied token identifier
     *                                  is contained in the merkle root held by
     *                                  the item in question's criteria element.
     *                                  Note that an empty criteria indicates
     *                                  that any (transferable) token
     *                                  identifier on the token in question is
     *                                  valid and that no associated proof needs
     *                                  to be supplied.
     * @param offerFulfillments         An array of FulfillmentComponent arrays
     *                                  indicating which offer items to attempt
     *                                  to aggregate when preparing executions.
     * @param considerationFulfillments An array of FulfillmentComponent arrays
     *                                  indicating which consideration items to
     *                                  attempt to aggregate when preparing
     *                                  executions.
     * @param fulfillerConduitKey       A bytes32 value indicating what conduit,
     *                                  if any, to source the fulfiller's token
     *                                  approvals from. The zero hash signifies
     *                                  that no conduit should be used (and
     *                                  direct approvals set on Consideration).
     * @param maximumFulfilled          The maximum number of orders to fulfill.
     *
     * * @return availableOrders An array of booleans indicating if each order
     *                         with an index corresponding to the index of the
     *                         returned boolean was fulfillable or not.
     * @return executions      An array of elements indicating the sequence of
     *                         transfers performed as part of matching the given
     *                         orders.
     */
    function fulfillAvailableAdvancedOrders(
        AdvancedOrder[] memory advancedOrders,
        CriteriaResolver[] calldata criteriaResolvers,
        FulfillmentComponent[][] calldata offerFulfillments,
        FulfillmentComponent[][] calldata considerationFulfillments,
        bytes32 fulfillerConduitKey,
        address recipient,
        uint256 maximumFulfilled
    )
        external
        payable
        override
        nonReentrant(true)
        returns (bool[] memory availableOrders, Execution[] memory executions)
    {
        // Convert Advanced Orders to Orders to Execute
        OrderToExecute[]
            memory ordersToExecute = _convertAdvancedToOrdersToExecute(
                advancedOrders
            );

        // Fulfill all available orders.
        return
            _fulfillAvailableAdvancedOrders(
                advancedOrders,
                ordersToExecute,
                criteriaResolvers,
                offerFulfillments,
                considerationFulfillments,
                fulfillerConduitKey,
                recipient == address(0) ? msg.sender : recipient,
                maximumFulfilled
            );
    }

    /**
     * @notice Match an arbitrary number of orders, each with an arbitrary
     *         number of items for offer and consideration along with a set of
     *         fulfillments allocating offer components to consideration
     *         components. Note that this function does not support
     *         criteria-based or partial filling of orders (though filling the
     *         remainder of a partially-filled order is supported).
     *
     * @param orders        The orders to match. Note that both the offerer and
     *                      fulfiller on each order must first approve this
     *                      contract (or their conduit if indicated by the
     *                      order) to transfer any relevant tokens on their
     *                      behalf and each consideration recipient must
     *                      implement `onERC1155Received` in order to receive
     *                      ERC1155 tokens.
     * @param fulfillments  An array of elements allocating offer components to
     *                      consideration components. Note that each
     *                      consideration component must be fully met in order
     *                      for the match operation to be valid.
     *
     * @return executions  An array of elements indicating the sequence of
     *                     transfers performed as part of matching the given
     *                     orders. Note that unspent offer item amounts or
     *                     native tokens will not be reflected as part of this
     *                     array.
     */
    function matchOrders(
        Order[] calldata orders,
        Fulfillment[] calldata fulfillments
    )
        external
        payable
        override
        nonReentrant(true)
        returns (Execution[] memory executions)
    {
        // Convert to advanced, validate, and match orders using fulfillments.
        return
            _matchAdvancedOrders(
                _convertOrdersToAdvanced(orders),
                new CriteriaResolver[](0), // No criteria resolvers supplied.
                fulfillments,
                msg.sender
            );
    }

    /**
     * @notice Match an arbitrary number of full or partial orders, each with an
     *         arbitrary number of items for offer and consideration, supplying
     *         criteria resolvers containing specific token identifiers and
     *         associated proofs as well as fulfillments allocating offer
     *         components to consideration components.
     *
     * @param advancedOrders    The advanced orders to match. Note that both the
     *                          offerer and fulfiller on each order must first
     *                          approve this contract (or their proxy if
     *                          indicated by the order) to transfer any relevant
     *                          tokens on their behalf and each consideration
     *                          recipient must implement `onERC1155Received` in
     *                          order to receive ERC1155 tokens. Also note that
     *                          the offer and consideration components for each
     *                          order must have no remainder after multiplying
     *                          the respective amount with the supplied fraction
     *                          in order for the group of partial fills to be
     *                          considered valid.
     * @param criteriaResolvers An array where each element contains a reference
     *                          to a specific order as well as that order's
     *                          offer or consideration, a token identifier, and
     *                          a proof that the supplied token identifier is
     *                          contained in the order's merkle root. Note that
     *                          an empty root indicates that any (transferable)
     *                          token identifier is valid and that no associated
     *                          proof needs to be supplied.
     * @param fulfillments      An array of elements allocating offer components
     *                          to consideration components. Note that each
     *                          consideration component must be fully met in
     *                          order for the match operation to be valid.
     * @param recipient         The intended recipient for all unspent offer
     *                          item amounts, or the caller if the null address
     *                          is supplied.
     *
     * @return executions An array of elements indicating the sequence of
     *                    transfers performed as part of matching the given
     *                    orders. Note that unspent offer item amounts or
     *                    native tokens will not be reflected as part of this
     *                    array.
     */
    function matchAdvancedOrders(
        AdvancedOrder[] memory advancedOrders,
        CriteriaResolver[] calldata criteriaResolvers,
        Fulfillment[] calldata fulfillments,
        address recipient
    )
        external
        payable
        override
        nonReentrant(true)
        returns (Execution[] memory executions)
    {
        // Validate and match the advanced orders using supplied fulfillments.
        return
            _matchAdvancedOrders(
                advancedOrders,
                criteriaResolvers,
                fulfillments,
                recipient == address(0) ? msg.sender : recipient
            );
    }

    /**
     * @notice Cancel an arbitrary number of orders. Note that only the offerer
     *         or the zone of a given order may cancel it.
     *
     * @param orders The orders to cancel.
     *
     * @return cancelled A boolean indicating whether the supplied orders have
     *         been successfully cancelled.
     */
    function cancel(
        OrderComponents[] calldata orders
    ) external override notEntered returns (bool cancelled) {
        // Cancel the orders.
        cancelled = _cancel(orders);
    }

    /**
     * @notice Validate an arbitrary number of orders, thereby registering them
     *         as valid and allowing the fulfiller to skip verification. Note
     *         that anyone can validate a signed order but only the offerer can
     *         validate an order without supplying a signature.
     *
     * @param orders The orders to validate.
     *
     * @return validated A boolean indicating whether the supplied orders have
     *         been successfully validated.
     */
    function validate(
        Order[] calldata orders
    ) external override notEntered returns (bool validated) {
        // Validate the orders.
        validated = _validate(orders);
    }

    /**
     * @notice Cancel all orders from a given offerer with a given zone in bulk
     *         by incrementing a counter. Note that only the offerer may
     *         increment the counter.
     *
     * @return newCounter The new counter.
     */
    function incrementCounter()
        external
        override
        notEntered
        returns (uint256 newCounter)
    {
        // Increment current counter for the supplied offerer.
        newCounter = _incrementCounter();
    }

    /**
     * @notice Retrieve the order hash for a given order.
     *
     * @param order The components of the order.
     *
     * @return orderHash the order hash.
     */
    function getOrderHash(
        OrderComponents calldata order
    ) external view override returns (bytes32 orderHash) {
        // Derive order hash by supplying order parameters along with the
        // counter.
        orderHash = _deriveOrderHash(
            OrderParameters(
                order.offerer,
                order.zone,
                order.offer,
                order.consideration,
                order.orderType,
                order.startTime,
                order.endTime,
                order.zoneHash,
                order.salt,
                order.conduitKey,
                order.consideration.length
            ),
            order.counter
        );
    }

    /**
     * @notice Retrieve the status of a given order by hash, including whether
     *         the order has been cancelled or validated and the fraction of the
     *         order that has been filled. Since the _orderStatus[orderHash]
     *         does not get set for contract orders, getOrderStatus will always
     *         return (false, false, 0, 0) for those hashes. Note that this
     *         function is susceptible to view reentrancy and so should be used
     *         with care when calling from other contracts.
     *
     * @param orderHash The order hash in question.
     *
     * @return isValidated A boolean indicating whether the order in question
     *                     has been validated (i.e. previously approved or
     *                     partially filled).
     * @return isCancelled A boolean indicating whether the order in question
     *                     has been cancelled.
     * @return totalFilled The total portion of the order that has been filled
     *                     (i.e. the "numerator").
     * @return totalSize   The total size of the order that is either filled or
     *                     unfilled (i.e. the "denominator").
     */
    function getOrderStatus(
        bytes32 orderHash
    )
        external
        view
        override
        returns (
            bool isValidated,
            bool isCancelled,
            uint256 totalFilled,
            uint256 totalSize
        )
    {
        // Retrieve the order status using the order hash.
        return _getOrderStatus(orderHash);
    }

    /**
     * @notice Retrieve the current counter for a given offerer.
     *
     * @param offerer The offerer in question.
     *
     * @return counter The current counter.
     */
    function getCounter(
        address offerer
    ) external view override returns (uint256 counter) {
        // Return the counter for the supplied offerer.
        counter = _getCounter(offerer);
    }

    /**
     * @notice Retrieve configuration information for this contract.
     *
     * @return version           The contract version.
     * @return domainSeparator   The domain separator for this contract.
     * @return conduitController The conduit Controller set for this contract.
     */
    function information()
        external
        view
        override
        returns (
            string memory version,
            bytes32 domainSeparator,
            address conduitController
        )
    {
        // Return the information for this contract.
        return _information();
    }

    /**
     * @dev Gets the contract offerer nonce for the specified contract offerer.
     *      Note that this function is susceptible to view reentrancy and so
     *      should be used with care when calling from other contracts.
     *
     * @param contractOfferer The contract offerer for which to get the nonce.
     *
     * @return nonce The contract offerer nonce.
     */
    function getContractOffererNonce(
        address contractOfferer
    ) external view override returns (uint256 nonce) {
        nonce = _contractNonces[contractOfferer];
    }

    /**
     * @notice Retrieve the name of this contract.
     *
     * @return contractName The name of this contract.
     */
    function name()
        external
        pure
        override
        returns (string memory contractName)
    {
        // Return the name of the contract.
        contractName = _name();
    }
}

File 2 of 43 : ReferenceConsiderationStructs.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import {
    ItemType,
    OrderType
} from "seaport-types/src/lib/ConsiderationEnums.sol";

import {
    ReceivedItem,
    SpentItem
} from "seaport-types/src/lib/ConsiderationStructs.sol";

import {
    ConduitTransfer
} from "seaport-types/src/conduit/lib/ConduitStructs.sol";

// This file should only be used by the Reference Implementation

/**
 * @dev A struct used to hold the numerator and denominator of an order in-memory
 *      during validation, before it is written to storage when updating order
 *      status.
 */
struct StoredFractions {
    uint256 storedNumerator;
    uint256 storedDenominator;
}

/**
 * @dev An intermediate struct used to hold information about an order after
 *      validation to prepare for execution.
 */
struct OrderValidation {
    bytes32 orderHash;
    uint256 newNumerator;
    uint256 newDenominator;
    OrderToExecute orderToExecute;
}

/**
 * @dev A struct used to hold the parameters used to validate an order.
 */
struct OrderValidationParams {
    bool revertOnInvalid;
    uint256 maximumFulfilled;
    address recipient;
}

/**
 * @dev A struct used to hold Consideration Indexes and Fulfillment validity.
 */
struct ConsiderationItemIndicesAndValidity {
    uint256 orderIndex;
    uint256 itemIndex;
    bool invalidFulfillment;
    bool missingItemAmount;
}

/**
 * @dev A struct used to hold all ItemTypes/Token of a Basic Order Fulfillment
 *       used in _prepareBasicFulfillmentFromCalldata
 */
struct FulfillmentItemTypes {
    OrderType orderType;
    ItemType receivedItemType;
    ItemType additionalRecipientsItemType;
    address additionalRecipientsToken;
    ItemType offeredItemType;
}

/**
 * @dev A struct used to hold all the hashes of a Basic Order Fulfillment
 *       used in _prepareBasicFulfillmentFromCalldata and _hashOrder
 */
struct BasicFulfillmentHashes {
    bytes32 typeHash;
    bytes32 orderHash;
    bytes32 offerItemsHash;
    bytes32[] considerationHashes;
    bytes32 receivedItemsHash;
    bytes32 receivedItemHash;
    bytes32 offerItemHash;
}

/**
 * @dev A struct that is an explicit version of advancedOrders without
 *       memory optimization, that provides an array of spentItems
 *       and receivedItems for fulfillment and event emission.
 */
struct OrderToExecute {
    address offerer;
    SpentItem[] spentItems; // Offer
    ReceivedItem[] receivedItems; // Consideration
    bytes32 conduitKey;
    uint120 numerator;
    uint256[] spentItemOriginalAmounts;
    uint256[] receivedItemOriginalAmounts;
}

/**
 * @dev  A struct containing the data used to apply a
 *       fraction to an order.
 */
struct FractionData {
    uint256 numerator; // The portion of the order that should be filled.
    uint256 denominator; // The total size of the order
    bytes32 fulfillerConduitKey; // The fulfiller's conduit key.
    uint256 startTime; // The start time of the order.
    uint256 endTime; // The end time of the order.
}

/**
 * @dev A struct containing conduit transfer data and its
 *      corresponding conduitKey.
 */
struct AccumulatorStruct {
    bytes32 conduitKey;
    ConduitTransfer[] transfers;
}

File 3 of 43 : ReferenceOrderCombiner.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import {
    ItemType,
    OrderType,
    Side
} from "seaport-types/src/lib/ConsiderationEnums.sol";

import {
    AdvancedOrder,
    ConsiderationItem,
    CriteriaResolver,
    Execution,
    Fulfillment,
    FulfillmentComponent,
    OfferItem,
    OrderParameters,
    ReceivedItem,
    SpentItem
} from "seaport-types/src/lib/ConsiderationStructs.sol";

import {
    SeaportInterface
} from "seaport-types/src/interfaces/SeaportInterface.sol";

import {
    AccumulatorStruct,
    OrderToExecute,
    StoredFractions,
    OrderValidation,
    OrderValidationParams
} from "./ReferenceConsiderationStructs.sol";

import { ReferenceOrderFulfiller } from "./ReferenceOrderFulfiller.sol";

import { ReferenceFulfillmentApplier } from "./ReferenceFulfillmentApplier.sol";

/**
 * @title OrderCombiner
 * @author 0age
 * @notice OrderCombiner contains logic for fulfilling combinations of orders,
 *         either by matching offer items to consideration items or by
 *         fulfilling orders where available.
 */
contract ReferenceOrderCombiner is
    ReferenceOrderFulfiller,
    ReferenceFulfillmentApplier
{
    /**
     * @dev Derive and set hashes, reference chainId, and associated domain
     *      separator during deployment.
     *
     * @param conduitController A contract that deploys conduits, or proxies
     *                          that may optionally be used to transfer approved
     *                          ERC20/721/1155 tokens.
     */
    constructor(
        address conduitController
    ) ReferenceOrderFulfiller(conduitController) {}

    /**
     * @notice Internal function to attempt to fill a group of orders, fully or
     *         partially, with an arbitrary number of items for offer and
     *         consideration per order alongside criteria resolvers containing
     *         specific token identifiers and associated proofs. Any order that
     *         is not currently active, has already been fully filled, or has
     *         been cancelled will be omitted. Remaining offer and consideration
     *         items will then be aggregated where possible as indicated by the
     *         supplied offer and consideration component arrays and aggregated
     *         items will be transferred to the fulfiller or to each intended
     *         recipient, respectively. Note that a failing item transfer or an
     *         issue with order formatting will cause the entire batch to fail.
     *
     * @param advancedOrders            The orders to fulfill along with the
     *                                  fraction of those orders to attempt to
     *                                  fill. Note that both the offerer and the
     *                                  fulfiller must first approve this
     *                                  contract (or their proxy if indicated by
     *                                  the order) to transfer any relevant
     *                                  tokens on their behalf and that
     *                                  contracts must implement
     *                                  `onERC1155Received` in order to receive
     *                                  ERC1155 tokens as consideration. Also
     *                                  note that all offer and consideration
     *                                  components must have no remainder after
     *                                  multiplication of the respective amount
     *                                  with the supplied fraction for an
     *                                  order's partial fill amount to be
     *                                  considered valid.
     *
     * @param ordersToExecute           The orders to execute.  This is an
     *                                  explicit version of advancedOrders
     *                                  without memory optimization, that
     *                                  provides an array of spentItems and
     *                                  receivedItems for fulfillment and
     *                                  event emission.
     *
     * @param criteriaResolvers         An array where each element contains a
     *                                  reference to a specific offer or
     *                                  consideration, a token identifier, and a
     *                                  proof that the supplied token identifier
     *                                  is contained in the merkle root held by
     *                                  the item in question's criteria element.
     *                                  Note that an empty criteria indicates
     *                                  that any (transferable) token
     *                                  identifier on the token in question is
     *                                  valid and that no associated proof needs
     *                                  to be supplied.
     * @param offerFulfillments         An array of FulfillmentComponent arrays
     *                                  indicating which offer items to attempt
     *                                  to aggregate when preparing executions.
     * @param considerationFulfillments An array of FulfillmentComponent arrays
     *                                  indicating which consideration items to
     *                                  attempt to aggregate when preparing
     *                                  executions.
     * @param fulfillerConduitKey       A bytes32 value indicating what conduit,
     *                                  if any, to source the fulfiller's token
     *                                  approvals from. The zero hash signifies
     *                                  that no conduit should be used (and
     *                                  direct approvals set on Consideration).
     * @param recipient                 The intended recipient for all received
     *                                  items.
     * @param maximumFulfilled          The maximum number of orders to fulfill.
     *
     * @return availableOrders          An array of booleans indicating if each
     *                                  order with an index corresponding to the
     *                                  index of the returned boolean was
     *                                  fulfillable or not.
     * @return executions               An array of elements indicating the
     *                                  sequence of transfers performed as part
     *                                  of matching the given orders.
     */
    function _fulfillAvailableAdvancedOrders(
        AdvancedOrder[] memory advancedOrders,
        OrderToExecute[] memory ordersToExecute,
        CriteriaResolver[] memory criteriaResolvers,
        FulfillmentComponent[][] calldata offerFulfillments,
        FulfillmentComponent[][] calldata considerationFulfillments,
        bytes32 fulfillerConduitKey,
        address recipient,
        uint256 maximumFulfilled
    )
        internal
        returns (bool[] memory availableOrders, Execution[] memory executions)
    {
        // Validate orders, apply amounts, & determine if they use conduits.
        (
            bytes32[] memory orderHashes,
            bool containsNonOpen
        ) = _validateOrdersAndPrepareToFulfill(
                advancedOrders,
                ordersToExecute,
                criteriaResolvers,
                OrderValidationParams(
                    false, // Signifies that invalid orders should NOT revert.
                    maximumFulfilled,
                    recipient
                )
            );

        // Execute transfers.
        (availableOrders, executions) = _executeAvailableFulfillments(
            advancedOrders,
            ordersToExecute,
            offerFulfillments,
            considerationFulfillments,
            fulfillerConduitKey,
            recipient,
            orderHashes,
            containsNonOpen
        );

        // Return order fulfillment details and executions.
        return (availableOrders, executions);
    }

    /**
     * @dev Internal function to validate a group of orders, update their
     *      statuses, reduce amounts by their previously filled fractions, apply
     *      criteria resolvers, and emit OrderFulfilled events.
     *
     * @param advancedOrders    The advanced orders to validate and reduce by
     *                          their previously filled amounts.
     * @param ordersToExecute   The orders to validate and execute.
     * @param criteriaResolvers An array where each element contains a reference
     *                          to a specific order as well as that order's
     *                          offer or consideration, a token identifier, and
     *                          a proof that the supplied token identifier is
     *                          contained in the order's merkle root. Note that
     *                          a root of zero indicates that any transferable
     *                          token identifier is valid and that no proof
     *                          needs to be supplied.
     * @param orderValidationParams Various order validation params.
     *
     * @return orderHashes      The hashes of the orders being fulfilled.
     * @return containsNonOpen  A boolean indicating whether any restricted or
     *                          contract orders are present within the provided
     *                          array of advanced orders.
     */
    function _validateOrdersAndPrepareToFulfill(
        AdvancedOrder[] memory advancedOrders,
        OrderToExecute[] memory ordersToExecute,
        CriteriaResolver[] memory criteriaResolvers,
        OrderValidationParams memory orderValidationParams
    ) internal returns (bytes32[] memory orderHashes, bool containsNonOpen) {
        // Track the order hash for each order being fulfilled.
        orderHashes = new bytes32[](advancedOrders.length);

        // Declare a variable for tracking whether native offer items are
        // present on orders that are not contract orders.
        bool anyNativeOfferItemsOnNonContractOrders;

        StoredFractions[] memory storedFractions = new StoredFractions[](
            advancedOrders.length
        );

        // Iterate over each order.
        for (uint256 i = 0; i < advancedOrders.length; ++i) {
            // Retrieve the current order.
            AdvancedOrder memory advancedOrder = advancedOrders[i];

            // Validate the order and determine fraction to fill.
            OrderValidation memory orderValidation = _validateOrder(
                advancedOrder,
                orderValidationParams.revertOnInvalid
            );

            // Do not track hash or adjust prices if order is not fulfilled.
            if (orderValidation.newNumerator == 0) {
                // Mark fill fraction as zero if the order is not fulfilled.
                advancedOrder.numerator = 0;

                // Mark fill fraction as zero as the order will not be used.
                orderValidation.orderToExecute.numerator = 0;
                ordersToExecute[i] = orderValidation.orderToExecute;

                // Continue iterating through the remaining orders.
                continue;
            }

            // Otherwise, track the order hash in question.
            orderHashes[i] = orderValidation.orderHash;

            // Store the numerator and denominator for the order status.
            storedFractions[i] = StoredFractions({
                storedNumerator: orderValidation.newNumerator,
                storedDenominator: orderValidation.newDenominator
            });

            {
                // Retrieve array of offer items for the order in question.
                OfferItem[] memory offer = advancedOrder.parameters.offer;

                // Determine the order type, used to check for eligibility for
                // native token offer items as well as for the presence of
                // restricted and contract orders (or non-open orders).
                OrderType orderType = advancedOrder.parameters.orderType;

                {
                    bool isNonContractOrder = orderType != OrderType.CONTRACT;
                    bool isNonOpenOrder = orderType != OrderType.FULL_OPEN &&
                        orderType != OrderType.PARTIAL_OPEN;

                    if (containsNonOpen == true || isNonOpenOrder == true) {
                        containsNonOpen = true;
                    }

                    // Iterate over each offer item on the order.
                    for (uint256 j = 0; j < offer.length; ++j) {
                        // Retrieve the offer item.
                        OfferItem memory offerItem = offer[j];

                        // Determine if there are any native offer items on
                        // non-contract orders.
                        anyNativeOfferItemsOnNonContractOrders =
                            anyNativeOfferItemsOnNonContractOrders ||
                            (offerItem.itemType == ItemType.NATIVE &&
                                isNonContractOrder);

                        // Apply order fill fraction to offer item end amount.
                        uint256 endAmount = _getFraction(
                            orderValidation.newNumerator,
                            orderValidation.newDenominator,
                            offerItem.endAmount
                        );

                        // Reuse same fraction if start & end amounts are equal.
                        if (offerItem.startAmount == offerItem.endAmount) {
                            // Apply derived amount to both start & end amount.
                            offerItem.startAmount = endAmount;
                        } else {
                            // Apply order fill fraction to item start amount.
                            offerItem.startAmount = _getFraction(
                                orderValidation.newNumerator,
                                orderValidation.newDenominator,
                                offerItem.startAmount
                            );
                        }

                        // Update end amount in memory to match derived amount.
                        offerItem.endAmount = endAmount;

                        // Adjust offer amount using current time; round down.
                        offerItem.startAmount = _locateCurrentAmount(
                            offerItem.startAmount,
                            offerItem.endAmount,
                            advancedOrder.parameters.startTime,
                            advancedOrder.parameters.endTime,
                            false // Round down.
                        );

                        // Modify the OrderToExecute Spent Item Amount.
                        orderValidation
                            .orderToExecute
                            .spentItems[j]
                            .amount = offerItem.startAmount;
                        // Modify the OrderToExecute Spent Item Original amount.
                        orderValidation.orderToExecute.spentItemOriginalAmounts[
                            j
                        ] = (offerItem.startAmount);
                    }
                }

                {
                    // Get array of consideration items for order in question.
                    ConsiderationItem[] memory consideration = (
                        advancedOrder.parameters.consideration
                    );

                    // Iterate over each consideration item on the order.
                    for (uint256 j = 0; j < consideration.length; ++j) {
                        // Retrieve the consideration item.
                        ConsiderationItem memory considerationItem = (
                            consideration[j]
                        );

                        // Apply fraction to consideration item end amount.
                        uint256 endAmount = _getFraction(
                            orderValidation.newNumerator,
                            orderValidation.newDenominator,
                            considerationItem.endAmount
                        );

                        // Reuse same fraction if start & end amounts are equal.
                        if (
                            considerationItem.startAmount ==
                            (considerationItem.endAmount)
                        ) {
                            // Apply derived amount to both start & end amount.
                            considerationItem.startAmount = endAmount;
                        } else {
                            // Apply fraction to item start amount.
                            considerationItem.startAmount = _getFraction(
                                orderValidation.newNumerator,
                                orderValidation.newDenominator,
                                considerationItem.startAmount
                            );
                        }

                        uint256 currentAmount = (
                            _locateCurrentAmount(
                                considerationItem.startAmount,
                                endAmount,
                                advancedOrder.parameters.startTime,
                                advancedOrder.parameters.endTime,
                                true // round up
                            )
                        );

                        considerationItem.startAmount = currentAmount;

                        // Modify the OrderToExecute Received item amount.
                        orderValidation
                            .orderToExecute
                            .receivedItems[j]
                            .amount = considerationItem.startAmount;
                        // Modify OrderToExecute Received item original amount.
                        orderValidation
                            .orderToExecute
                            .receivedItemOriginalAmounts[j] = (
                            considerationItem.startAmount
                        );
                    }
                }
            }

            ordersToExecute[i] = orderValidation.orderToExecute;
        }

        if (
            anyNativeOfferItemsOnNonContractOrders &&
            (msg.sig != SeaportInterface.matchAdvancedOrders.selector &&
                msg.sig != SeaportInterface.matchOrders.selector)
        ) {
            revert InvalidNativeOfferItem();
        }

        // Apply criteria resolvers to each order as applicable.
        _applyCriteriaResolvers(
            advancedOrders,
            ordersToExecute,
            criteriaResolvers
        );

        bool someOrderAvailable;

        // Iterate over each order to check authorization status (for restricted
        // orders), generate orders (for contract orders), and emit events (for
        // all available orders) signifying that they have been fulfilled.
        for (uint256 i = 0; i < advancedOrders.length; ++i) {
            // Do not emit an event if no order hash is present.
            if (orderHashes[i] == bytes32(0)) {
                continue;
            }

            // Determine if max number orders have already been fulfilled.
            if (orderValidationParams.maximumFulfilled == 0) {
                orderHashes[i] = bytes32(0);
                ordersToExecute[i].numerator = 0;

                // Continue iterating through the remaining orders.
                continue;
            }

            // Retrieve parameters for the order in question.
            OrderParameters memory orderParameters = (
                advancedOrders[i].parameters
            );

            // Ensure restricted orders have valid submitter or pass zone check.
            (
                bool valid /* bool checked */,

            ) = _checkRestrictedAdvancedOrderAuthorization(
                    advancedOrders[i],
                    ordersToExecute[i],
                    _shorten(orderHashes, i),
                    orderHashes[i],
                    orderValidationParams.revertOnInvalid
                );

            if (!valid) {
                orderHashes[i] = bytes32(0);
                ordersToExecute[i].numerator = 0;
                continue;
            }

            // Update status if the order is still valid or skip if not checked
            if (orderParameters.orderType != OrderType.CONTRACT) {
                if (
                    !_updateStatus(
                        orderHashes[i],
                        storedFractions[i].storedNumerator,
                        storedFractions[i].storedDenominator,
                        _revertOnFailedUpdate(
                            orderParameters,
                            orderValidationParams.revertOnInvalid
                        )
                    )
                ) {
                    orderHashes[i] = bytes32(0);
                    ordersToExecute[i].numerator = 0;
                    continue;
                }
            } else {
                bytes32 orderHash = _getGeneratedOrder(
                    ordersToExecute[i],
                    orderParameters,
                    advancedOrders[i].extraData,
                    orderValidationParams.revertOnInvalid
                );

                orderHashes[i] = orderHash;

                if (orderHash == bytes32(0)) {
                    ordersToExecute[i].numerator = 0;
                    continue;
                }
            }

            // Decrement the number of fulfilled orders.
            orderValidationParams.maximumFulfilled--;

            // Get the array of spentItems from the orderToExecute struct.
            SpentItem[] memory spentItems = ordersToExecute[i].spentItems;

            // Get the array of spent receivedItems from the
            // orderToExecute struct.
            ReceivedItem[] memory receivedItems = (
                ordersToExecute[i].receivedItems
            );

            // Emit an event signifying that the order has been fulfilled.
            emit OrderFulfilled(
                orderHashes[i],
                orderParameters.offerer,
                orderParameters.zone,
                orderValidationParams.recipient,
                spentItems,
                receivedItems
            );

            someOrderAvailable = true;
        }

        // Revert if no orders are available.
        if (!someOrderAvailable) {
            revert NoSpecifiedOrdersAvailable();
        }
    }

    function _shorten(
        bytes32[] memory orderHashes,
        uint256 index
    ) internal pure returns (bytes32[] memory) {
        bytes32[] memory shortened = new bytes32[](index);
        for (uint256 i = 0; i < index; i++) {
            shortened[i] = orderHashes[i];
        }
        return shortened;
    }

    /**
     * @dev Internal function to fulfill a group of validated orders, fully or
     *      partially, with an arbitrary number of items for offer and
     *      consideration per order and to execute transfers. Any order that is
     *      not currently active, has already been fully filled, or has been
     *      cancelled will be omitted. Remaining offer and consideration items
     *      will then be aggregated where possible as indicated by the supplied
     *      offer and consideration component arrays and aggregated items will
     *      be transferred to the fulfiller or to each intended recipient,
     *      respectively. Note that a failing item transfer or an issue with
     *      order formatting will cause the entire batch to fail.
     *
     * @param ordersToExecute           The orders to execute.  This is an
     *                                  explicit version of advancedOrders
     *                                  without memory optimization, that
     *                                  provides an array of spentItems and
     *                                  receivedItems for fulfillment and
     *                                  event emission.
     *                                  Note that both the offerer and the
     *                                  fulfiller must first approve this
     *                                  contract (or the conduit if indicated
     *                                  by the order) to transfer any relevant
     *                                  tokens on their behalf and that
     *                                  contracts must implement
     *                                  `onERC1155Received` in order to receive
     *                                  ERC1155 tokens as consideration. Also
     *                                  note that all offer and consideration
     *                                  components must have no remainder after
     *                                  multiplication of the respective amount
     *                                  with the supplied fraction for an
     *                                  order's partial fill amount to be
     *                                  considered valid.
     * @param offerFulfillments         An array of FulfillmentComponent arrays
     *                                  indicating which offer items to attempt
     *                                  to aggregate when preparing executions.
     * @param considerationFulfillments An array of FulfillmentComponent arrays
     *                                  indicating which consideration items to
     *                                  attempt to aggregate when preparing
     *                                  executions.
     * @param fulfillerConduitKey       A bytes32 value indicating what conduit,
     *                                  if any, to source the fulfiller's token
     *                                  approvals from. The zero hash signifies
     *                                  that no conduit should be used (and
     *                                  direct approvals set on Consideration).
     * @param recipient                 The intended recipient for all received
     *                                  items.
     * @param orderHashes               An array of order hashes for each order.
     * @param containsNonOpen   A boolean indicating whether any restricted or
     *                          contract orders are present within the provided
     *                          array of advanced orders.
     *
     * @return availableOrders          An array of booleans indicating if each
     *                                  order with an index corresponding to the
     *                                  index of the returned boolean was
     *                                  fulfillable or not.
     * @return executions               An array of elements indicating the
     *                                  sequence of transfers performed as part
     *                                  of matching the given orders.
     */
    function _executeAvailableFulfillments(
        AdvancedOrder[] memory advancedOrders,
        OrderToExecute[] memory ordersToExecute,
        FulfillmentComponent[][] memory offerFulfillments,
        FulfillmentComponent[][] memory considerationFulfillments,
        bytes32 fulfillerConduitKey,
        address recipient,
        bytes32[] memory orderHashes,
        bool containsNonOpen
    )
        internal
        returns (bool[] memory availableOrders, Execution[] memory executions)
    {
        // Retrieve length of offer fulfillments array and place on the stack.
        uint256 totalOfferFulfillments = offerFulfillments.length;

        // Retrieve length of consideration fulfillments array & place on stack.
        uint256 totalConsiderationFulfillments = (
            considerationFulfillments.length
        );

        // Allocate an execution for each offer and consideration fulfillment.
        executions = new Execution[](
            totalOfferFulfillments + totalConsiderationFulfillments
        );

        // Iterate over each offer fulfillment.
        for (uint256 i = 0; i < totalOfferFulfillments; ++i) {
            // Derive aggregated execution corresponding with fulfillment and
            // assign the execution to the executions array.
            executions[i] = _aggregateAvailable(
                ordersToExecute,
                Side.OFFER,
                offerFulfillments[i],
                fulfillerConduitKey,
                recipient
            );
        }

        // Iterate over each consideration fulfillment.
        for (uint256 i = 0; i < totalConsiderationFulfillments; ++i) {
            // Derive aggregated execution corresponding with fulfillment and
            // assign the execution to the executions array.
            executions[i + totalOfferFulfillments] = _aggregateAvailable(
                ordersToExecute,
                Side.CONSIDERATION,
                considerationFulfillments[i],
                fulfillerConduitKey,
                address(0) // unused
            );
        }

        // Perform final checks and compress executions into standard and batch.
        availableOrders = _performFinalChecksAndExecuteOrders(
            advancedOrders,
            ordersToExecute,
            executions,
            orderHashes,
            recipient,
            containsNonOpen
        );

        return (availableOrders, executions);
    }

    /**
     * @dev Internal function to perform a final check that each consideration
     *      item for an arbitrary number of fulfilled orders has been met and to
     *      trigger associated executions, transferring the respective items.
     *
     * @param ordersToExecute    The orders to check and perform executions.
     * @param executions         An array of uncompressed elements indicating
     *                           the sequence of transfers to perform when
     *                           fulfilling the given orders.
     *
     * @param executions         An array of elements indicating the sequence of
     *                           transfers to perform when fulfilling the given
     *                           orders.
     * @param orderHashes        An array of order hashes for each order.
     * @param containsNonOpen    A boolean indicating whether any restricted or
     *                           contract orders are present within the provided
     *                           array of advanced orders.
     *
     * @return availableOrders   An array of booleans indicating if each order
     *                           with an index corresponding to the index of the
     *                           returned boolean was fulfillable or not.
     */
    function _performFinalChecksAndExecuteOrders(
        AdvancedOrder[] memory advancedOrders,
        OrderToExecute[] memory ordersToExecute,
        Execution[] memory executions,
        bytes32[] memory orderHashes,
        address recipient,
        bool containsNonOpen
    ) internal returns (bool[] memory availableOrders) {
        // Retrieve the length of the advanced orders array and place on stack.
        uint256 totalOrders = advancedOrders.length;

        // Initialize array for tracking available orders.
        availableOrders = new bool[](totalOrders);

        // Create the accumulator struct.
        AccumulatorStruct memory accumulatorStruct;

        {
            // Iterate over each execution.
            for (uint256 i = 0; i < executions.length; ++i) {
                // Retrieve the execution and the associated received item.
                Execution memory execution = executions[i];
                ReceivedItem memory item = execution.item;

                // Skip transfers if the execution amount is zero.
                if (item.amount == 0) {
                    continue;
                }

                // If execution transfers native tokens, reduce value available.
                if (item.itemType == ItemType.NATIVE) {
                    // Ensure that sufficient native tokens are still available.
                    if (item.amount > address(this).balance) {
                        revert InsufficientNativeTokensSupplied();
                    }
                }

                // Transfer the item specified by the execution.
                _transfer(
                    item,
                    execution.offerer,
                    execution.conduitKey,
                    accumulatorStruct
                );
            }
        }

        // Duplicate recipient onto stack to avoid stack-too-deep.
        address _recipient = recipient;

        // Iterate over orders to ensure all consideration items are met.
        for (uint256 i = 0; i < ordersToExecute.length; ++i) {
            // Retrieve the order in question.
            OrderToExecute memory orderToExecute = ordersToExecute[i];

            // Skip consideration item checks for order if not fulfilled.
            if (orderToExecute.numerator == 0) {
                // Note: orders do not need to be marked as unavailable as a
                // new memory region has been allocated. Review carefully if
                // altering compiler version or managing memory manually.
                continue;
            }

            // Mark the order as available.
            availableOrders[i] = true;

            // Retrieve the original order in question.
            AdvancedOrder memory advancedOrder = advancedOrders[i];

            // Retrieve the order parameters.
            OrderParameters memory parameters = advancedOrder.parameters;

            {
                // Retrieve offer items.
                SpentItem[] memory offer = orderToExecute.spentItems;

                // Read length of offer array & place on the stack.
                uint256 totalOfferItems = offer.length;

                // Iterate over each offer item to restore it.
                for (uint256 j = 0; j < totalOfferItems; ++j) {
                    SpentItem memory offerSpentItem = offer[j];

                    // Retrieve remaining amount on the offer item.
                    uint256 unspentAmount = offerSpentItem.amount;

                    // Retrieve original amount on the offer item.
                    uint256 originalAmount = (
                        orderToExecute.spentItemOriginalAmounts[j]
                    );

                    // Transfer to recipient if unspent amount is not zero.
                    // Note that the transfer will not be reflected in the
                    // executions array.
                    if (unspentAmount != 0) {
                        _transfer(
                            _convertSpentItemToReceivedItemWithRecipient(
                                offerSpentItem,
                                _recipient
                            ),
                            parameters.offerer,
                            parameters.conduitKey,
                            accumulatorStruct
                        );
                    }

                    // Restore original amount on the offer item.
                    offerSpentItem.amount = originalAmount;
                }
            }

            {
                // Retrieve consideration items to ensure they are fulfilled.
                ReceivedItem[] memory consideration = (
                    orderToExecute.receivedItems
                );

                // Iterate over each consideration item to ensure it is met.
                for (uint256 j = 0; j < consideration.length; ++j) {
                    // Retrieve remaining amount on the consideration item.
                    uint256 unmetAmount = consideration[j].amount;

                    // Revert if the remaining amount is not zero.
                    if (unmetAmount != 0) {
                        revert ConsiderationNotMet(i, j, unmetAmount);
                    }

                    // Restore original amount.
                    consideration[j].amount = (
                        orderToExecute.receivedItemOriginalAmounts[j]
                    );
                }
            }
        }

        // Trigger any remaining accumulated transfers via call to the
        // conduit.
        _triggerIfArmed(accumulatorStruct);

        // If any native token remains after fulfillments, return it to the
        // caller.
        if (address(this).balance != 0) {
            _transferNativeTokens(payable(msg.sender), address(this).balance);
        }

        // If any restricted or contract orders are present in the group of
        // orders being fulfilled, perform any validateOrder or ratifyOrder
        // calls after all executions and related transfers are complete.
        if (containsNonOpen) {
            // Iterate over orders to ensure all consideration items are met.
            for (uint256 i = 0; i < ordersToExecute.length; ++i) {
                // Retrieve the order in question.
                OrderToExecute memory orderToExecute = ordersToExecute[i];

                // Skip consideration item checks for order if not fulfilled.
                if (orderToExecute.numerator == 0) {
                    continue;
                }

                // Retrieve the original order in question.
                AdvancedOrder memory advancedOrder = advancedOrders[i];

                // Ensure restricted orders have valid submitter or pass check.
                _assertRestrictedAdvancedOrderValidity(
                    advancedOrder,
                    orderToExecute,
                    orderHashes,
                    orderHashes[i],
                    advancedOrder.parameters.zoneHash,
                    advancedOrder.parameters.orderType,
                    orderToExecute.offerer,
                    advancedOrder.parameters.zone
                );
            }
        }

        // Return the array containing available orders.
        return availableOrders;
    }

    /**
     * @dev Internal function to convert a spent item to an equivalent
     *      ReceivedItem with a specified recipient.
     *
     * @param offerItem          The "offerItem" represented by a SpentItem
     *                           struct.
     * @param recipient          The intended recipient of the converted
     *                           ReceivedItem
     *
     * @return ReceivedItem      The derived ReceivedItem including the
     *                           specified recipient.
     */
    function _convertSpentItemToReceivedItemWithRecipient(
        SpentItem memory offerItem,
        address recipient
    ) internal pure returns (ReceivedItem memory) {
        address payable _recipient;

        _recipient = payable(recipient);

        return
            ReceivedItem(
                offerItem.itemType,
                offerItem.token,
                offerItem.identifier,
                offerItem.amount,
                _recipient
            );
    }

    /**
     * @dev Internal function to match an arbitrary number of full or partial
     *      orders, each with an arbitrary number of items for offer and
     *      consideration, supplying criteria resolvers containing specific
     *      token identifiers and associated proofs as well as fulfillments
     *      allocating offer components to consideration components.
     *
     * @param advancedOrders    The advanced orders to match. Note that both the
     *                          offerer and fulfiller on each order must first
     *                          approve this contract (or their conduit if
     *                          indicated by the order) to transfer any relevant
     *                          tokens on their behalf and each consideration
     *                          recipient must implement `onERC1155Received` in
     *                          order to receive ERC1155 tokens. Also note that
     *                          the offer and consideration components for each
     *                          order must have no remainder after multiplying
     *                          the respective amount with the supplied fraction
     *                          in order for the group of partial fills to be
     *                          considered valid.
     * @param criteriaResolvers An array where each element contains a reference
     *                          to a specific order as well as that order's
     *                          offer or consideration, a token identifier, and
     *                          a proof that the supplied token identifier is
     *                          contained in the order's merkle root. Note that
     *                          an empty root indicates that any (transferable)
     *                          token identifier is valid and that no associated
     *                          proof needs to be supplied.
     * @param fulfillments      An array of elements allocating offer components
     *                          to consideration components. Note that each
     *                          consideration component must be fully met in
     *                          order for the match operation to be valid.
     * @param recipient         The intended recipient for all unspent offer
     *                          item amounts.
     *
     * @return executions       An array of elements indicating the sequence of
     *                          transfers performed as part of matching the
     *                          given orders.
     */
    function _matchAdvancedOrders(
        AdvancedOrder[] memory advancedOrders,
        CriteriaResolver[] memory criteriaResolvers,
        Fulfillment[] calldata fulfillments,
        address recipient
    ) internal returns (Execution[] memory executions) {
        // Convert Advanced Orders to Orders to Execute
        OrderToExecute[] memory ordersToExecute = (
            _convertAdvancedToOrdersToExecute(advancedOrders)
        );

        // Validate orders, apply amounts, & determine if they utilize conduits.
        (
            bytes32[] memory orderHashes,
            bool containsNonOpen
        ) = _validateOrdersAndPrepareToFulfill(
                advancedOrders,
                ordersToExecute,
                criteriaResolvers,
                OrderValidationParams(
                    true, // Signifies that invalid orders should revert.
                    advancedOrders.length,
                    recipient
                )
            );

        // Emit OrdersMatched event.
        emit OrdersMatched(orderHashes);

        // Fulfill the orders using the supplied fulfillments.
        return
            _fulfillAdvancedOrders(
                advancedOrders,
                ordersToExecute,
                fulfillments,
                orderHashes,
                recipient,
                containsNonOpen
            );
    }

    /**
     * @dev Internal function to fulfill an arbitrary number of orders, either
     *      full or partial, after validating, adjusting amounts, and applying
     *      criteria resolvers.
     *
     * @param ordersToExecute    The orders to match, including a fraction to
     *                           attempt to fill for each order.
     * @param fulfillments       An array of elements allocating offer
     *                           components to consideration components. Note
     *                           that the final amount of each consideration
     *                           component must be zero for a match operation to
     *                           be considered valid.
     * @param orderHashes        An array of order hashes for each order.
     *
     * @param containsNonOpen   A boolean indicating whether any restricted or
     *                          contract orders are present within the provided
     *                          array of advanced orders.
     *
     * @return executions        An array of elements indicating the sequence
     *                           of transfers performed as part of
     *                           matching the given orders.
     */
    function _fulfillAdvancedOrders(
        AdvancedOrder[] memory advancedOrders,
        OrderToExecute[] memory ordersToExecute,
        Fulfillment[] calldata fulfillments,
        bytes32[] memory orderHashes,
        address recipient,
        bool containsNonOpen
    ) internal returns (Execution[] memory executions) {
        // Retrieve fulfillments array length and place on the stack.
        uint256 totalFulfillments = fulfillments.length;

        // Allocate executions by fulfillment and apply them to each execution.
        executions = new Execution[](totalFulfillments);

        // Iterate over each fulfillment.
        for (uint256 i = 0; i < totalFulfillments; ++i) {
            /// Retrieve the fulfillment in question.
            Fulfillment calldata fulfillment = fulfillments[i];

            // Derive the execution corresponding with the fulfillment and
            // assign the execution to the executions array.
            executions[i] = _applyFulfillment(
                ordersToExecute,
                fulfillment.offerComponents,
                fulfillment.considerationComponents,
                i
            );
        }

        // Perform final checks and execute orders.
        _performFinalChecksAndExecuteOrders(
            advancedOrders,
            ordersToExecute,
            executions,
            orderHashes,
            recipient,
            containsNonOpen
        );

        // Return executions.
        return executions;
    }

    /**
     * @dev Internal view function to determine whether a status update failure
     *      should cause a revert or allow a skipped order. The call must revert
     *      if an `authorizeOrder` call has been successfully performed and the
     *      status update cannot be performed, regardless of whether the order
     *      could be otherwise marked as skipped. Note that a revert is not
     *      required on a failed update if the call originates from the zone, as
     *      no `authorizeOrder` call is performed in that case.
     *
     * @param orderParameters The order parameters in question.
     * @param revertOnInvalid A boolean indicating whether the call should
     *                        revert for non-restricted order types.
     *
     * @return revertOnFailedUpdate A boolean indicating whether the order
     *                              should revert on a failed status update.
     */
    function _revertOnFailedUpdate(
        OrderParameters memory orderParameters,
        bool revertOnInvalid
    ) internal view returns (bool revertOnFailedUpdate) {
        OrderType orderType = orderParameters.orderType;
        address zone = orderParameters.zone;
        return (revertOnInvalid ||
            ((orderType == OrderType.FULL_RESTRICTED ||
                orderType == OrderType.PARTIAL_RESTRICTED) &&
                zone != msg.sender));
    }
}

File 4 of 43 : ConsiderationEnums.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

enum OrderType {
    // 0: no partial fills, anyone can execute
    FULL_OPEN,

    // 1: partial fills supported, anyone can execute
    PARTIAL_OPEN,

    // 2: no partial fills, only offerer or zone can execute
    FULL_RESTRICTED,

    // 3: partial fills supported, only offerer or zone can execute
    PARTIAL_RESTRICTED,

    // 4: contract order type
    CONTRACT
}

enum BasicOrderType {
    // 0: no partial fills, anyone can execute
    ETH_TO_ERC721_FULL_OPEN,

    // 1: partial fills supported, anyone can execute
    ETH_TO_ERC721_PARTIAL_OPEN,

    // 2: no partial fills, only offerer or zone can execute
    ETH_TO_ERC721_FULL_RESTRICTED,

    // 3: partial fills supported, only offerer or zone can execute
    ETH_TO_ERC721_PARTIAL_RESTRICTED,

    // 4: no partial fills, anyone can execute
    ETH_TO_ERC1155_FULL_OPEN,

    // 5: partial fills supported, anyone can execute
    ETH_TO_ERC1155_PARTIAL_OPEN,

    // 6: no partial fills, only offerer or zone can execute
    ETH_TO_ERC1155_FULL_RESTRICTED,

    // 7: partial fills supported, only offerer or zone can execute
    ETH_TO_ERC1155_PARTIAL_RESTRICTED,

    // 8: no partial fills, anyone can execute
    ERC20_TO_ERC721_FULL_OPEN,

    // 9: partial fills supported, anyone can execute
    ERC20_TO_ERC721_PARTIAL_OPEN,

    // 10: no partial fills, only offerer or zone can execute
    ERC20_TO_ERC721_FULL_RESTRICTED,

    // 11: partial fills supported, only offerer or zone can execute
    ERC20_TO_ERC721_PARTIAL_RESTRICTED,

    // 12: no partial fills, anyone can execute
    ERC20_TO_ERC1155_FULL_OPEN,

    // 13: partial fills supported, anyone can execute
    ERC20_TO_ERC1155_PARTIAL_OPEN,

    // 14: no partial fills, only offerer or zone can execute
    ERC20_TO_ERC1155_FULL_RESTRICTED,

    // 15: partial fills supported, only offerer or zone can execute
    ERC20_TO_ERC1155_PARTIAL_RESTRICTED,

    // 16: no partial fills, anyone can execute
    ERC721_TO_ERC20_FULL_OPEN,

    // 17: partial fills supported, anyone can execute
    ERC721_TO_ERC20_PARTIAL_OPEN,

    // 18: no partial fills, only offerer or zone can execute
    ERC721_TO_ERC20_FULL_RESTRICTED,

    // 19: partial fills supported, only offerer or zone can execute
    ERC721_TO_ERC20_PARTIAL_RESTRICTED,

    // 20: no partial fills, anyone can execute
    ERC1155_TO_ERC20_FULL_OPEN,

    // 21: partial fills supported, anyone can execute
    ERC1155_TO_ERC20_PARTIAL_OPEN,

    // 22: no partial fills, only offerer or zone can execute
    ERC1155_TO_ERC20_FULL_RESTRICTED,

    // 23: partial fills supported, only offerer or zone can execute
    ERC1155_TO_ERC20_PARTIAL_RESTRICTED
}

enum BasicOrderRouteType {
    // 0: provide Ether (or other native token) to receive offered ERC721 item.
    ETH_TO_ERC721,

    // 1: provide Ether (or other native token) to receive offered ERC1155 item.
    ETH_TO_ERC1155,

    // 2: provide ERC20 item to receive offered ERC721 item.
    ERC20_TO_ERC721,

    // 3: provide ERC20 item to receive offered ERC1155 item.
    ERC20_TO_ERC1155,

    // 4: provide ERC721 item to receive offered ERC20 item.
    ERC721_TO_ERC20,

    // 5: provide ERC1155 item to receive offered ERC20 item.
    ERC1155_TO_ERC20
}

enum ItemType {
    // 0: ETH on mainnet, MATIC on polygon, etc.
    NATIVE,

    // 1: ERC20 items (ERC777 and ERC20 analogues could also technically work)
    ERC20,

    // 2: ERC721 items
    ERC721,

    // 3: ERC1155 items
    ERC1155,

    // 4: ERC721 items where a number of tokenIds are supported
    ERC721_WITH_CRITERIA,

    // 5: ERC1155 items where a number of ids are supported
    ERC1155_WITH_CRITERIA
}

enum Side {
    // 0: Items that can be spent
    OFFER,

    // 1: Items that must be received
    CONSIDERATION
}

File 5 of 43 : ConsiderationStructs.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import {
    BasicOrderType,
    ItemType,
    OrderType,
    Side
} from "./ConsiderationEnums.sol";

import {
    CalldataPointer,
    MemoryPointer
} from "../helpers/PointerLibraries.sol";

/**
 * @dev An order contains eleven components: an offerer, a zone (or account that
 *      can cancel the order or restrict who can fulfill the order depending on
 *      the type), the order type (specifying partial fill support as well as
 *      restricted order status), the start and end time, a hash that will be
 *      provided to the zone when validating restricted orders, a salt, a key
 *      corresponding to a given conduit, a counter, and an arbitrary number of
 *      offer items that can be spent along with consideration items that must
 *      be received by their respective recipient.
 */
struct OrderComponents {
    address offerer;
    address zone;
    OfferItem[] offer;
    ConsiderationItem[] consideration;
    OrderType orderType;
    uint256 startTime;
    uint256 endTime;
    bytes32 zoneHash;
    uint256 salt;
    bytes32 conduitKey;
    uint256 counter;
}

/**
 * @dev An offer item has five components: an item type (ETH or other native
 *      tokens, ERC20, ERC721, and ERC1155, as well as criteria-based ERC721 and
 *      ERC1155), a token address, a dual-purpose "identifierOrCriteria"
 *      component that will either represent a tokenId or a merkle root
 *      depending on the item type, and a start and end amount that support
 *      increasing or decreasing amounts over the duration of the respective
 *      order.
 */
struct OfferItem {
    ItemType itemType;
    address token;
    uint256 identifierOrCriteria;
    uint256 startAmount;
    uint256 endAmount;
}

/**
 * @dev A consideration item has the same five components as an offer item and
 *      an additional sixth component designating the required recipient of the
 *      item.
 */
struct ConsiderationItem {
    ItemType itemType;
    address token;
    uint256 identifierOrCriteria;
    uint256 startAmount;
    uint256 endAmount;
    address payable recipient;
}

/**
 * @dev A spent item is translated from a utilized offer item and has four
 *      components: an item type (ETH or other native tokens, ERC20, ERC721, and
 *      ERC1155), a token address, a tokenId, and an amount.
 */
struct SpentItem {
    ItemType itemType;
    address token;
    uint256 identifier;
    uint256 amount;
}

/**
 * @dev A received item is translated from a utilized consideration item and has
 *      the same four components as a spent item, as well as an additional fifth
 *      component designating the required recipient of the item.
 */
struct ReceivedItem {
    ItemType itemType;
    address token;
    uint256 identifier;
    uint256 amount;
    address payable recipient;
}

/**
 * @dev For basic orders involving ETH / native / ERC20 <=> ERC721 / ERC1155
 *      matching, a group of six functions may be called that only requires a
 *      subset of the usual order arguments. Note the use of a "basicOrderType"
 *      enum; this represents both the usual order type as well as the "route"
 *      of the basic order (a simple derivation function for the basic order
 *      type is `basicOrderType = orderType + (4 * basicOrderRoute)`.)
 */
struct BasicOrderParameters {
    // calldata offset
    address considerationToken; // 0x24
    uint256 considerationIdentifier; // 0x44
    uint256 considerationAmount; // 0x64
    address payable offerer; // 0x84
    address zone; // 0xa4
    address offerToken; // 0xc4
    uint256 offerIdentifier; // 0xe4
    uint256 offerAmount; // 0x104
    BasicOrderType basicOrderType; // 0x124
    uint256 startTime; // 0x144
    uint256 endTime; // 0x164
    bytes32 zoneHash; // 0x184
    uint256 salt; // 0x1a4
    bytes32 offererConduitKey; // 0x1c4
    bytes32 fulfillerConduitKey; // 0x1e4
    uint256 totalOriginalAdditionalRecipients; // 0x204
    AdditionalRecipient[] additionalRecipients; // 0x224
    bytes signature; // 0x244
    // Total length, excluding dynamic array data: 0x264 (580)
}

/**
 * @dev Basic orders can supply any number of additional recipients, with the
 *      implied assumption that they are supplied from the offered ETH (or other
 *      native token) or ERC20 token for the order.
 */
struct AdditionalRecipient {
    uint256 amount;
    address payable recipient;
}

/**
 * @dev The full set of order components, with the exception of the counter,
 *      must be supplied when fulfilling more sophisticated orders or groups of
 *      orders. The total number of original consideration items must also be
 *      supplied, as the caller may specify additional consideration items.
 */
struct OrderParameters {
    address offerer; // 0x00
    address zone; // 0x20
    OfferItem[] offer; // 0x40
    ConsiderationItem[] consideration; // 0x60
    OrderType orderType; // 0x80
    uint256 startTime; // 0xa0
    uint256 endTime; // 0xc0
    bytes32 zoneHash; // 0xe0
    uint256 salt; // 0x100
    bytes32 conduitKey; // 0x120
    uint256 totalOriginalConsiderationItems; // 0x140
    // offer.length                          // 0x160
}

/**
 * @dev Orders require a signature in addition to the other order parameters.
 */
struct Order {
    OrderParameters parameters;
    bytes signature;
}

/**
 * @dev Advanced orders include a numerator (i.e. a fraction to attempt to fill)
 *      and a denominator (the total size of the order) in addition to the
 *      signature and other order parameters. It also supports an optional field
 *      for supplying extra data; this data will be provided to the zone if the
 *      order type is restricted and the zone is not the caller, or will be
 *      provided to the offerer as context for contract order types.
 */
struct AdvancedOrder {
    OrderParameters parameters;
    uint120 numerator;
    uint120 denominator;
    bytes signature;
    bytes extraData;
}

/**
 * @dev Orders can be validated (either explicitly via `validate`, or as a
 *      consequence of a full or partial fill), specifically cancelled (they can
 *      also be cancelled in bulk via incrementing a per-zone counter), and
 *      partially or fully filled (with the fraction filled represented by a
 *      numerator and denominator).
 */
struct OrderStatus {
    bool isValidated;
    bool isCancelled;
    uint120 numerator;
    uint120 denominator;
}

/**
 * @dev A criteria resolver specifies an order, side (offer vs. consideration),
 *      and item index. It then provides a chosen identifier (i.e. tokenId)
 *      alongside a merkle proof demonstrating the identifier meets the required
 *      criteria.
 */
struct CriteriaResolver {
    uint256 orderIndex;
    Side side;
    uint256 index;
    uint256 identifier;
    bytes32[] criteriaProof;
}

/**
 * @dev A fulfillment is applied to a group of orders. It decrements a series of
 *      offer and consideration items, then generates a single execution
 *      element. A given fulfillment can be applied to as many offer and
 *      consideration items as desired, but must contain at least one offer and
 *      at least one consideration that match. The fulfillment must also remain
 *      consistent on all key parameters across all offer items (same offerer,
 *      token, type, tokenId, and conduit preference) as well as across all
 *      consideration items (token, type, tokenId, and recipient).
 */
struct Fulfillment {
    FulfillmentComponent[] offerComponents;
    FulfillmentComponent[] considerationComponents;
}

/**
 * @dev Each fulfillment component contains one index referencing a specific
 *      order and another referencing a specific offer or consideration item.
 */
struct FulfillmentComponent {
    uint256 orderIndex;
    uint256 itemIndex;
}

/**
 * @dev An execution is triggered once all consideration items have been zeroed
 *      out. It sends the item in question from the offerer to the item's
 *      recipient, optionally sourcing approvals from either this contract
 *      directly or from the offerer's chosen conduit if one is specified. An
 *      execution is not provided as an argument, but rather is derived via
 *      orders, criteria resolvers, and fulfillments (where the total number of
 *      executions will be less than or equal to the total number of indicated
 *      fulfillments) and returned as part of `matchOrders`.
 */
struct Execution {
    ReceivedItem item;
    address offerer;
    bytes32 conduitKey;
}

/**
 * @dev Restricted orders are validated post-execution by calling validateOrder
 *      on the zone. This struct provides context about the order fulfillment
 *      and any supplied extraData, as well as all order hashes fulfilled in a
 *      call to a match or fulfillAvailable method.
 */
struct ZoneParameters {
    bytes32 orderHash;
    address fulfiller;
    address offerer;
    SpentItem[] offer;
    ReceivedItem[] consideration;
    bytes extraData;
    bytes32[] orderHashes;
    uint256 startTime;
    uint256 endTime;
    bytes32 zoneHash;
}

/**
 * @dev Zones and contract offerers can communicate which schemas they implement
 *      along with any associated metadata related to each schema.
 */
struct Schema {
    uint256 id;
    bytes metadata;
}

using StructPointers for OrderComponents global;
using StructPointers for OfferItem global;
using StructPointers for ConsiderationItem global;
using StructPointers for SpentItem global;
using StructPointers for ReceivedItem global;
using StructPointers for BasicOrderParameters global;
using StructPointers for AdditionalRecipient global;
using StructPointers for OrderParameters global;
using StructPointers for Order global;
using StructPointers for AdvancedOrder global;
using StructPointers for OrderStatus global;
using StructPointers for CriteriaResolver global;
using StructPointers for Fulfillment global;
using StructPointers for FulfillmentComponent global;
using StructPointers for Execution global;
using StructPointers for ZoneParameters global;

/**
 * @dev This library provides a set of functions for converting structs to
 *      pointers.
 */
library StructPointers {
    /**
     * @dev Get a MemoryPointer from OrderComponents.
     *
     * @param obj The OrderComponents object.
     *
     * @return ptr The MemoryPointer.
     */
    function toMemoryPointer(
        OrderComponents memory obj
    ) internal pure returns (MemoryPointer ptr) {
        assembly {
            ptr := obj
        }
    }

    /**
     * @dev Get a CalldataPointer from OrderComponents.
     *
     * @param obj The OrderComponents object.
     *
     * @return ptr The CalldataPointer.
     */
    function toCalldataPointer(
        OrderComponents calldata obj
    ) internal pure returns (CalldataPointer ptr) {
        assembly {
            ptr := obj
        }
    }

    /**
     * @dev Get a MemoryPointer from OfferItem.
     *
     * @param obj The OfferItem object.
     *
     * @return ptr The MemoryPointer.
     */
    function toMemoryPointer(
        OfferItem memory obj
    ) internal pure returns (MemoryPointer ptr) {
        assembly {
            ptr := obj
        }
    }

    /**
     * @dev Get a CalldataPointer from OfferItem.
     *
     * @param obj The OfferItem object.
     *
     * @return ptr The CalldataPointer.
     */
    function toCalldataPointer(
        OfferItem calldata obj
    ) internal pure returns (CalldataPointer ptr) {
        assembly {
            ptr := obj
        }
    }

    /**
     * @dev Get a MemoryPointer from ConsiderationItem.
     *
     * @param obj The ConsiderationItem object.
     *
     * @return ptr The MemoryPointer.
     */
    function toMemoryPointer(
        ConsiderationItem memory obj
    ) internal pure returns (MemoryPointer ptr) {
        assembly {
            ptr := obj
        }
    }

    /**
     * @dev Get a CalldataPointer from ConsiderationItem.
     *
     * @param obj The ConsiderationItem object.
     *
     * @return ptr The CalldataPointer.
     */
    function toCalldataPointer(
        ConsiderationItem calldata obj
    ) internal pure returns (CalldataPointer ptr) {
        assembly {
            ptr := obj
        }
    }

    /**
     * @dev Get a MemoryPointer from SpentItem.
     *
     * @param obj The SpentItem object.
     *
     * @return ptr The MemoryPointer.
     */
    function toMemoryPointer(
        SpentItem memory obj
    ) internal pure returns (MemoryPointer ptr) {
        assembly {
            ptr := obj
        }
    }

    /**
     * @dev Get a CalldataPointer from SpentItem.
     *
     * @param obj The SpentItem object.
     *
     * @return ptr The CalldataPointer.
     */
    function toCalldataPointer(
        SpentItem calldata obj
    ) internal pure returns (CalldataPointer ptr) {
        assembly {
            ptr := obj
        }
    }

    /**
     * @dev Get a MemoryPointer from ReceivedItem.
     *
     * @param obj The ReceivedItem object.
     *
     * @return ptr The MemoryPointer.
     */
    function toMemoryPointer(
        ReceivedItem memory obj
    ) internal pure returns (MemoryPointer ptr) {
        assembly {
            ptr := obj
        }
    }

    /**
     * @dev Get a CalldataPointer from ReceivedItem.
     *
     * @param obj The ReceivedItem object.
     *
     * @return ptr The CalldataPointer.
     */
    function toCalldataPointer(
        ReceivedItem calldata obj
    ) internal pure returns (CalldataPointer ptr) {
        assembly {
            ptr := obj
        }
    }

    /**
     * @dev Get a MemoryPointer from BasicOrderParameters.
     *
     * @param obj The BasicOrderParameters object.
     *
     * @return ptr The MemoryPointer.
     */
    function toMemoryPointer(
        BasicOrderParameters memory obj
    ) internal pure returns (MemoryPointer ptr) {
        assembly {
            ptr := obj
        }
    }

    /**
     * @dev Get a CalldataPointer from BasicOrderParameters.
     *
     * @param obj The BasicOrderParameters object.
     *
     * @return ptr The CalldataPointer.
     */
    function toCalldataPointer(
        BasicOrderParameters calldata obj
    ) internal pure returns (CalldataPointer ptr) {
        assembly {
            ptr := obj
        }
    }

    /**
     * @dev Get a MemoryPointer from AdditionalRecipient.
     *
     * @param obj The AdditionalRecipient object.
     *
     * @return ptr The MemoryPointer.
     */
    function toMemoryPointer(
        AdditionalRecipient memory obj
    ) internal pure returns (MemoryPointer ptr) {
        assembly {
            ptr := obj
        }
    }

    /**
     * @dev Get a CalldataPointer from AdditionalRecipient.
     *
     * @param obj The AdditionalRecipient object.
     *
     * @return ptr The CalldataPointer.
     */
    function toCalldataPointer(
        AdditionalRecipient calldata obj
    ) internal pure returns (CalldataPointer ptr) {
        assembly {
            ptr := obj
        }
    }

    /**
     * @dev Get a MemoryPointer from OrderParameters.
     *
     * @param obj The OrderParameters object.
     *
     * @return ptr The MemoryPointer.
     */
    function toMemoryPointer(
        OrderParameters memory obj
    ) internal pure returns (MemoryPointer ptr) {
        assembly {
            ptr := obj
        }
    }

    /**
     * @dev Get a CalldataPointer from OrderParameters.
     *
     * @param obj The OrderParameters object.
     *
     * @return ptr The CalldataPointer.
     */
    function toCalldataPointer(
        OrderParameters calldata obj
    ) internal pure returns (CalldataPointer ptr) {
        assembly {
            ptr := obj
        }
    }

    /**
     * @dev Get a MemoryPointer from Order.
     *
     * @param obj The Order object.
     *
     * @return ptr The MemoryPointer.
     */
    function toMemoryPointer(
        Order memory obj
    ) internal pure returns (MemoryPointer ptr) {
        assembly {
            ptr := obj
        }
    }

    /**
     * @dev Get a CalldataPointer from Order.
     *
     * @param obj The Order object.
     *
     * @return ptr The CalldataPointer.
     */
    function toCalldataPointer(
        Order calldata obj
    ) internal pure returns (CalldataPointer ptr) {
        assembly {
            ptr := obj
        }
    }

    /**
     * @dev Get a MemoryPointer from AdvancedOrder.
     *
     * @param obj The AdvancedOrder object.
     *
     * @return ptr The MemoryPointer.
     */
    function toMemoryPointer(
        AdvancedOrder memory obj
    ) internal pure returns (MemoryPointer ptr) {
        assembly {
            ptr := obj
        }
    }

    /**
     * @dev Get a CalldataPointer from AdvancedOrder.
     *
     * @param obj The AdvancedOrder object.
     *
     * @return ptr The CalldataPointer.
     */
    function toCalldataPointer(
        AdvancedOrder calldata obj
    ) internal pure returns (CalldataPointer ptr) {
        assembly {
            ptr := obj
        }
    }

    /**
     * @dev Get a MemoryPointer from OrderStatus.
     *
     * @param obj The OrderStatus object.
     *
     * @return ptr The MemoryPointer.
     */
    function toMemoryPointer(
        OrderStatus memory obj
    ) internal pure returns (MemoryPointer ptr) {
        assembly {
            ptr := obj
        }
    }

    /**
     * @dev Get a CalldataPointer from OrderStatus.
     *
     * @param obj The OrderStatus object.
     *
     * @return ptr The CalldataPointer.
     */
    function toCalldataPointer(
        OrderStatus calldata obj
    ) internal pure returns (CalldataPointer ptr) {
        assembly {
            ptr := obj
        }
    }

    /**
     * @dev Get a MemoryPointer from CriteriaResolver.
     *
     * @param obj The CriteriaResolver object.
     *
     * @return ptr The MemoryPointer.
     */
    function toMemoryPointer(
        CriteriaResolver memory obj
    ) internal pure returns (MemoryPointer ptr) {
        assembly {
            ptr := obj
        }
    }

    /**
     * @dev Get a CalldataPointer from CriteriaResolver.
     *
     * @param obj The CriteriaResolver object.
     *
     * @return ptr The CalldataPointer.
     */
    function toCalldataPointer(
        CriteriaResolver calldata obj
    ) internal pure returns (CalldataPointer ptr) {
        assembly {
            ptr := obj
        }
    }

    /**
     * @dev Get a MemoryPointer from Fulfillment.
     *
     * @param obj The Fulfillment object.
     *
     * @return ptr The MemoryPointer.
     */
    function toMemoryPointer(
        Fulfillment memory obj
    ) internal pure returns (MemoryPointer ptr) {
        assembly {
            ptr := obj
        }
    }

    /**
     * @dev Get a CalldataPointer from Fulfillment.
     *
     * @param obj The Fulfillment object.
     *
     * @return ptr The CalldataPointer.
     */
    function toCalldataPointer(
        Fulfillment calldata obj
    ) internal pure returns (CalldataPointer ptr) {
        assembly {
            ptr := obj
        }
    }

    /**
     * @dev Get a MemoryPointer from FulfillmentComponent.
     *
     * @param obj The FulfillmentComponent object.
     *
     * @return ptr The MemoryPointer.
     */
    function toMemoryPointer(
        FulfillmentComponent memory obj
    ) internal pure returns (MemoryPointer ptr) {
        assembly {
            ptr := obj
        }
    }

    /**
     * @dev Get a CalldataPointer from FulfillmentComponent.
     *
     * @param obj The FulfillmentComponent object.
     *
     * @return ptr The CalldataPointer.
     */
    function toCalldataPointer(
        FulfillmentComponent calldata obj
    ) internal pure returns (CalldataPointer ptr) {
        assembly {
            ptr := obj
        }
    }

    /**
     * @dev Get a MemoryPointer from Execution.
     *
     * @param obj The Execution object.
     *
     * @return ptr The MemoryPointer.
     */
    function toMemoryPointer(
        Execution memory obj
    ) internal pure returns (MemoryPointer ptr) {
        assembly {
            ptr := obj
        }
    }

    /**
     * @dev Get a CalldataPointer from Execution.
     *
     * @param obj The Execution object.
     *
     * @return ptr The CalldataPointer.
     */
    function toCalldataPointer(
        Execution calldata obj
    ) internal pure returns (CalldataPointer ptr) {
        assembly {
            ptr := obj
        }
    }

    /**
     * @dev Get a MemoryPointer from ZoneParameters.
     *
     * @param obj The ZoneParameters object.
     *
     * @return ptr The MemoryPointer.
     */
    function toMemoryPointer(
        ZoneParameters memory obj
    ) internal pure returns (MemoryPointer ptr) {
        assembly {
            ptr := obj
        }
    }

    /**
     * @dev Get a CalldataPointer from ZoneParameters.
     *
     * @param obj The ZoneParameters object.
     *
     * @return ptr The CalldataPointer.
     */
    function toCalldataPointer(
        ZoneParameters calldata obj
    ) internal pure returns (CalldataPointer ptr) {
        assembly {
            ptr := obj
        }
    }
}

File 6 of 43 : ConsiderationInterface.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import {
    AdvancedOrder,
    BasicOrderParameters,
    CriteriaResolver,
    Execution,
    Fulfillment,
    FulfillmentComponent,
    Order,
    OrderComponents
} from "../lib/ConsiderationStructs.sol";

/**
 * @title ConsiderationInterface
 * @author 0age
 * @custom:version 1.6
 * @notice Consideration is a generalized native token/ERC20/ERC721/ERC1155
 *         marketplace. It minimizes external calls to the greatest extent
 *         possible and provides lightweight methods for common routes as well
 *         as more flexible methods for composing advanced orders.
 *
 * @dev ConsiderationInterface contains all external function interfaces for
 *      Consideration.
 */
interface ConsiderationInterface {
    /**
     * @notice Fulfill an order offering an ERC721 token by supplying Ether (or
     *         the native token for the given chain) as consideration for the
     *         order. An arbitrary number of "additional recipients" may also be
     *         supplied which will each receive native tokens from the fulfiller
     *         as consideration.
     *
     * @param parameters Additional information on the fulfilled order. Note
     *                   that the offerer must first approve this contract (or
     *                   their preferred conduit if indicated by the order) for
     *                   their offered ERC721 token to be transferred.
     *
     * @return fulfilled A boolean indicating whether the order has been
     *                   successfully fulfilled.
     */
    function fulfillBasicOrder(
        BasicOrderParameters calldata parameters
    ) external payable returns (bool fulfilled);

    /**
     * @notice Fulfill an order with an arbitrary number of items for offer and
     *         consideration. Note that this function does not support
     *         criteria-based orders or partial filling of orders (though
     *         filling the remainder of a partially-filled order is supported).
     *
     * @param order               The order to fulfill. Note that both the
     *                            offerer and the fulfiller must first approve
     *                            this contract (or the corresponding conduit if
     *                            indicated) to transfer any relevant tokens on
     *                            their behalf and that contracts must implement
     *                            `onERC1155Received` to receive ERC1155 tokens
     *                            as consideration.
     * @param fulfillerConduitKey A bytes32 value indicating what conduit, if
     *                            any, to source the fulfiller's token approvals
     *                            from. The zero hash signifies that no conduit
     *                            should be used, with direct approvals set on
     *                            Consideration.
     *
     * @return fulfilled A boolean indicating whether the order has been
     *                   successfully fulfilled.
     */
    function fulfillOrder(
        Order calldata order,
        bytes32 fulfillerConduitKey
    ) external payable returns (bool fulfilled);

    /**
     * @notice Fill an order, fully or partially, with an arbitrary number of
     *         items for offer and consideration alongside criteria resolvers
     *         containing specific token identifiers and associated proofs.
     *
     * @param advancedOrder       The order to fulfill along with the fraction
     *                            of the order to attempt to fill. Note that
     *                            both the offerer and the fulfiller must first
     *                            approve this contract (or their preferred
     *                            conduit if indicated by the order) to transfer
     *                            any relevant tokens on their behalf and that
     *                            contracts must implement `onERC1155Received`
     *                            to receive ERC1155 tokens as consideration.
     *                            Also note that all offer and consideration
     *                            components must have no remainder after
     *                            multiplication of the respective amount with
     *                            the supplied fraction for the partial fill to
     *                            be considered valid.
     * @param criteriaResolvers   An array where each element contains a
     *                            reference to a specific offer or
     *                            consideration, a token identifier, and a proof
     *                            that the supplied token identifier is
     *                            contained in the merkle root held by the item
     *                            in question's criteria element. Note that an
     *                            empty criteria indicates that any
     *                            (transferable) token identifier on the token
     *                            in question is valid and that no associated
     *                            proof needs to be supplied.
     * @param fulfillerConduitKey A bytes32 value indicating what conduit, if
     *                            any, to source the fulfiller's token approvals
     *                            from. The zero hash signifies that no conduit
     *                            should be used, with direct approvals set on
     *                            Consideration.
     * @param recipient           The intended recipient for all received items,
     *                            with `address(0)` indicating that the caller
     *                            should receive the items.
     *
     * @return fulfilled A boolean indicating whether the order has been
     *                   successfully fulfilled.
     */
    function fulfillAdvancedOrder(
        AdvancedOrder calldata advancedOrder,
        CriteriaResolver[] calldata criteriaResolvers,
        bytes32 fulfillerConduitKey,
        address recipient
    ) external payable returns (bool fulfilled);

    /**
     * @notice Attempt to fill a group of orders, each with an arbitrary number
     *         of items for offer and consideration. Any order that is not
     *         currently active, has already been fully filled, or has been
     *         cancelled will be omitted. Remaining offer and consideration
     *         items will then be aggregated where possible as indicated by the
     *         supplied offer and consideration component arrays and aggregated
     *         items will be transferred to the fulfiller or to each intended
     *         recipient, respectively. Note that a failing item transfer or an
     *         issue with order formatting will cause the entire batch to fail.
     *         Note that this function does not support criteria-based orders or
     *         partial filling of orders (though filling the remainder of a
     *         partially-filled order is supported).
     *
     * @param orders                    The orders to fulfill. Note that both
     *                                  the offerer and the fulfiller must first
     *                                  approve this contract (or the
     *                                  corresponding conduit if indicated) to
     *                                  transfer any relevant tokens on their
     *                                  behalf and that contracts must implement
     *                                  `onERC1155Received` to receive ERC1155
     *                                  tokens as consideration.
     * @param offerFulfillments         An array of FulfillmentComponent arrays
     *                                  indicating which offer items to attempt
     *                                  to aggregate when preparing executions.
     * @param considerationFulfillments An array of FulfillmentComponent arrays
     *                                  indicating which consideration items to
     *                                  attempt to aggregate when preparing
     *                                  executions.
     * @param fulfillerConduitKey       A bytes32 value indicating what conduit,
     *                                  if any, to source the fulfiller's token
     *                                  approvals from. The zero hash signifies
     *                                  that no conduit should be used, with
     *                                  direct approvals set on this contract.
     * @param maximumFulfilled          The maximum number of orders to fulfill.
     *
     * @return availableOrders An array of booleans indicating if each order
     *                         with an index corresponding to the index of the
     *                         returned boolean was fulfillable or not.
     * @return executions      An array of elements indicating the sequence of
     *                         transfers performed as part of matching the given
     *                         orders. Note that unspent offer item amounts or
     *                         native tokens will not be reflected as part of
     *                         this array.
     */
    function fulfillAvailableOrders(
        Order[] calldata orders,
        FulfillmentComponent[][] calldata offerFulfillments,
        FulfillmentComponent[][] calldata considerationFulfillments,
        bytes32 fulfillerConduitKey,
        uint256 maximumFulfilled
    )
        external
        payable
        returns (bool[] memory availableOrders, Execution[] memory executions);

    /**
     * @notice Attempt to fill a group of orders, fully or partially, with an
     *         arbitrary number of items for offer and consideration per order
     *         alongside criteria resolvers containing specific token
     *         identifiers and associated proofs. Any order that is not
     *         currently active, has already been fully filled, or has been
     *         cancelled will be omitted. Remaining offer and consideration
     *         items will then be aggregated where possible as indicated by the
     *         supplied offer and consideration component arrays and aggregated
     *         items will be transferred to the fulfiller or to each intended
     *         recipient, respectively. Note that a failing item transfer or an
     *         issue with order formatting will cause the entire batch to fail.
     *
     * @param advancedOrders            The orders to fulfill along with the
     *                                  fraction of those orders to attempt to
     *                                  fill. Note that both the offerer and the
     *                                  fulfiller must first approve this
     *                                  contract (or their preferred conduit if
     *                                  indicated by the order) to transfer any
     *                                  relevant tokens on their behalf and that
     *                                  contracts must implement
     *                                  `onERC1155Received` to enable receipt of
     *                                  ERC1155 tokens as consideration. Also
     *                                  note that all offer and consideration
     *                                  components must have no remainder after
     *                                  multiplication of the respective amount
     *                                  with the supplied fraction for an
     *                                  order's partial fill amount to be
     *                                  considered valid.
     * @param criteriaResolvers         An array where each element contains a
     *                                  reference to a specific offer or
     *                                  consideration, a token identifier, and a
     *                                  proof that the supplied token identifier
     *                                  is contained in the merkle root held by
     *                                  the item in question's criteria element.
     *                                  Note that an empty criteria indicates
     *                                  that any (transferable) token
     *                                  identifier on the token in question is
     *                                  valid and that no associated proof needs
     *                                  to be supplied.
     * @param offerFulfillments         An array of FulfillmentComponent arrays
     *                                  indicating which offer items to attempt
     *                                  to aggregate when preparing executions.
     * @param considerationFulfillments An array of FulfillmentComponent arrays
     *                                  indicating which consideration items to
     *                                  attempt to aggregate when preparing
     *                                  executions.
     * @param fulfillerConduitKey       A bytes32 value indicating what conduit,
     *                                  if any, to source the fulfiller's token
     *                                  approvals from. The zero hash signifies
     *                                  that no conduit should be used, with
     *                                  direct approvals set on this contract.
     * @param recipient                 The intended recipient for all received
     *                                  items, with `address(0)` indicating that
     *                                  the caller should receive the items.
     * @param maximumFulfilled          The maximum number of orders to fulfill.
     *
     * @return availableOrders An array of booleans indicating if each order
     *                         with an index corresponding to the index of the
     *                         returned boolean was fulfillable or not.
     * @return executions      An array of elements indicating the sequence of
     *                         transfers performed as part of matching the given
     *                         orders. Note that unspent offer item amounts or
     *                         native tokens will not be reflected as part of
     *                         this array.
     */
    function fulfillAvailableAdvancedOrders(
        AdvancedOrder[] calldata advancedOrders,
        CriteriaResolver[] calldata criteriaResolvers,
        FulfillmentComponent[][] calldata offerFulfillments,
        FulfillmentComponent[][] calldata considerationFulfillments,
        bytes32 fulfillerConduitKey,
        address recipient,
        uint256 maximumFulfilled
    )
        external
        payable
        returns (bool[] memory availableOrders, Execution[] memory executions);

    /**
     * @notice Match an arbitrary number of orders, each with an arbitrary
     *         number of items for offer and consideration along with a set of
     *         fulfillments allocating offer components to consideration
     *         components. Note that this function does not support
     *         criteria-based or partial filling of orders (though filling the
     *         remainder of a partially-filled order is supported). Any unspent
     *         offer item amounts or native tokens will be transferred to the
     *         caller.
     *
     * @param orders       The orders to match. Note that both the offerer and
     *                     fulfiller on each order must first approve this
     *                     contract (or their conduit if indicated by the order)
     *                     to transfer any relevant tokens on their behalf and
     *                     each consideration recipient must implement
     *                     `onERC1155Received` to enable ERC1155 token receipt.
     * @param fulfillments An array of elements allocating offer components to
     *                     consideration components. Note that each
     *                     consideration component must be fully met for the
     *                     match operation to be valid.
     *
     * @return executions An array of elements indicating the sequence of
     *                    transfers performed as part of matching the given
     *                    orders. Note that unspent offer item amounts or
     *                    native tokens will not be reflected as part of this
     *                    array.
     */
    function matchOrders(
        Order[] calldata orders,
        Fulfillment[] calldata fulfillments
    ) external payable returns (Execution[] memory executions);

    /**
     * @notice Match an arbitrary number of full or partial orders, each with an
     *         arbitrary number of items for offer and consideration, supplying
     *         criteria resolvers containing specific token identifiers and
     *         associated proofs as well as fulfillments allocating offer
     *         components to consideration components. Any unspent offer item
     *         amounts will be transferred to the designated recipient (with the
     *         null address signifying to use the caller) and any unspent native
     *         tokens will be returned to the caller.
     *
     * @param orders            The advanced orders to match. Note that both the
     *                          offerer and fulfiller on each order must first
     *                          approve this contract (or a preferred conduit if
     *                          indicated by the order) to transfer any relevant
     *                          tokens on their behalf and each consideration
     *                          recipient must implement `onERC1155Received` in
     *                          order to receive ERC1155 tokens. Also note that
     *                          the offer and consideration components for each
     *                          order must have no remainder after multiplying
     *                          the respective amount with the supplied fraction
     *                          in order for the group of partial fills to be
     *                          considered valid.
     * @param criteriaResolvers An array where each element contains a reference
     *                          to a specific order as well as that order's
     *                          offer or consideration, a token identifier, and
     *                          a proof that the supplied token identifier is
     *                          contained in the order's merkle root. Note that
     *                          an empty root indicates that any (transferable)
     *                          token identifier is valid and that no associated
     *                          proof needs to be supplied.
     * @param fulfillments      An array of elements allocating offer components
     *                          to consideration components. Note that each
     *                          consideration component must be fully met in
     *                          order for the match operation to be valid.
     * @param recipient         The intended recipient for all unspent offer
     *                          item amounts, or the caller if the null address
     *                          is supplied.
     *
     * @return executions An array of elements indicating the sequence of
     *                    transfers performed as part of matching the given
     *                    orders. Note that unspent offer item amounts or native
     *                    tokens will not be reflected as part of this array.
     */
    function matchAdvancedOrders(
        AdvancedOrder[] calldata orders,
        CriteriaResolver[] calldata criteriaResolvers,
        Fulfillment[] calldata fulfillments,
        address recipient
    ) external payable returns (Execution[] memory executions);

    /**
     * @notice Cancel an arbitrary number of orders. Note that only the offerer
     *         or the zone of a given order may cancel it. Callers should ensure
     *         that the intended order was cancelled by calling `getOrderStatus`
     *         and confirming that `isCancelled` returns `true`.
     *
     * @param orders The orders to cancel.
     *
     * @return cancelled A boolean indicating whether the supplied orders have
     *                   been successfully cancelled.
     */
    function cancel(
        OrderComponents[] calldata orders
    ) external returns (bool cancelled);

    /**
     * @notice Validate an arbitrary number of orders, thereby registering their
     *         signatures as valid and allowing the fulfiller to skip signature
     *         verification on fulfillment. Note that validated orders may still
     *         be unfulfillable due to invalid item amounts or other factors;
     *         callers should determine whether validated orders are fulfillable
     *         by simulating the fulfillment call prior to execution. Also note
     *         that anyone can validate a signed order, but only the offerer can
     *         validate an order without supplying a signature.
     *
     * @param orders The orders to validate.
     *
     * @return validated A boolean indicating whether the supplied orders have
     *                   been successfully validated.
     */
    function validate(
        Order[] calldata orders
    ) external returns (bool validated);

    /**
     * @notice Cancel all orders from a given offerer with a given zone in bulk
     *         by incrementing a counter. Note that only the offerer may
     *         increment the counter.
     *
     * @return newCounter The new counter.
     */
    function incrementCounter() external returns (uint256 newCounter);

    /**
     * @notice Fulfill an order offering an ERC721 token by supplying Ether (or
     *         the native token for the given chain) as consideration for the
     *         order. An arbitrary number of "additional recipients" may also be
     *         supplied which will each receive native tokens from the fulfiller
     *         as consideration. Note that this function costs less gas than
     *         `fulfillBasicOrder` due to the zero bytes in the function
     *         selector (0x00000000) which also results in earlier function
     *         dispatch.
     *
     * @param parameters Additional information on the fulfilled order. Note
     *                   that the offerer must first approve this contract (or
     *                   their preferred conduit if indicated by the order) for
     *                   their offered ERC721 token to be transferred.
     *
     * @return fulfilled A boolean indicating whether the order has been
     *                   successfully fulfilled.
     */
    function fulfillBasicOrder_efficient_6GL6yc(
        BasicOrderParameters calldata parameters
    ) external payable returns (bool fulfilled);

    /**
     * @notice Retrieve the order hash for a given order.
     *
     * @param order The components of the order.
     *
     * @return orderHash The order hash.
     */
    function getOrderHash(
        OrderComponents calldata order
    ) external view returns (bytes32 orderHash);

    /**
     * @notice Retrieve the status of a given order by hash, including whether
     *         the order has been cancelled or validated and the fraction of the
     *         order that has been filled.
     *
     * @param orderHash The order hash in question.
     *
     * @return isValidated A boolean indicating whether the order in question
     *                     has been validated (i.e. previously approved or
     *                     partially filled).
     * @return isCancelled A boolean indicating whether the order in question
     *                     has been cancelled.
     * @return totalFilled The total portion of the order that has been filled
     *                     (i.e. the "numerator").
     * @return totalSize   The total size of the order that is either filled or
     *                     unfilled (i.e. the "denominator").
     */
    function getOrderStatus(
        bytes32 orderHash
    )
        external
        view
        returns (
            bool isValidated,
            bool isCancelled,
            uint256 totalFilled,
            uint256 totalSize
        );

    /**
     * @notice Retrieve the current counter for a given offerer.
     *
     * @param offerer The offerer in question.
     *
     * @return counter The current counter.
     */
    function getCounter(
        address offerer
    ) external view returns (uint256 counter);

    /**
     * @notice Retrieve configuration information for this contract.
     *
     * @return version           The contract version.
     * @return domainSeparator   The domain separator for this contract.
     * @return conduitController The conduit Controller set for this contract.
     */
    function information()
        external
        view
        returns (
            string memory version,
            bytes32 domainSeparator,
            address conduitController
        );

    function getContractOffererNonce(
        address contractOfferer
    ) external view returns (uint256 nonce);

    /**
     * @notice Retrieve the name of this contract.
     *
     * @return contractName The name of this contract.
     */
    function name() external view returns (string memory contractName);
}

File 7 of 43 : PointerLibraries.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

type CalldataPointer is uint256;

type ReturndataPointer is uint256;

type MemoryPointer is uint256;

using CalldataPointerLib for CalldataPointer global;
using MemoryPointerLib for MemoryPointer global;
using ReturndataPointerLib for ReturndataPointer global;

using CalldataReaders for CalldataPointer global;
using ReturndataReaders for ReturndataPointer global;
using MemoryReaders for MemoryPointer global;
using MemoryWriters for MemoryPointer global;

CalldataPointer constant CalldataStart = CalldataPointer.wrap(0x04);
MemoryPointer constant FreeMemoryPPtr = MemoryPointer.wrap(0x40);
MemoryPointer constant ZeroSlotPtr = MemoryPointer.wrap(0x60);
uint256 constant IdentityPrecompileAddress = 0x4;
uint256 constant OffsetOrLengthMask = 0xffffffff;
uint256 constant _OneWord = 0x20;
uint256 constant _FreeMemoryPointerSlot = 0x40;

/// @dev Allocates `size` bytes in memory by increasing the free memory pointer
///    and returns the memory pointer to the first byte of the allocated region.
// (Free functions cannot have visibility.)
// solhint-disable-next-line func-visibility
function malloc(uint256 size) pure returns (MemoryPointer mPtr) {
    assembly {
        mPtr := mload(_FreeMemoryPointerSlot)
        mstore(_FreeMemoryPointerSlot, add(mPtr, size))
    }
}

// (Free functions cannot have visibility.)
// solhint-disable-next-line func-visibility
function getFreeMemoryPointer() pure returns (MemoryPointer mPtr) {
    mPtr = FreeMemoryPPtr.readMemoryPointer();
}

// (Free functions cannot have visibility.)
// solhint-disable-next-line func-visibility
function setFreeMemoryPointer(MemoryPointer mPtr) pure {
    FreeMemoryPPtr.write(mPtr);
}

library CalldataPointerLib {
    function lt(
        CalldataPointer a,
        CalldataPointer b
    ) internal pure returns (bool c) {
        assembly {
            c := lt(a, b)
        }
    }

    function gt(
        CalldataPointer a,
        CalldataPointer b
    ) internal pure returns (bool c) {
        assembly {
            c := gt(a, b)
        }
    }

    function eq(
        CalldataPointer a,
        CalldataPointer b
    ) internal pure returns (bool c) {
        assembly {
            c := eq(a, b)
        }
    }

    function isNull(CalldataPointer a) internal pure returns (bool b) {
        assembly {
            b := iszero(a)
        }
    }

    /// @dev Resolves an offset stored at `cdPtr + headOffset` to a calldata.
    ///      pointer `cdPtr` must point to some parent object with a dynamic
    ///      type's head stored at `cdPtr + headOffset`.
    function pptrOffset(
        CalldataPointer cdPtr,
        uint256 headOffset
    ) internal pure returns (CalldataPointer cdPtrChild) {
        cdPtrChild = cdPtr.offset(
            cdPtr.offset(headOffset).readUint256() & OffsetOrLengthMask
        );
    }

    /// @dev Resolves an offset stored at `cdPtr` to a calldata pointer.
    ///      `cdPtr` must point to some parent object with a dynamic type as its
    ///      first member, e.g. `struct { bytes data; }`
    function pptr(
        CalldataPointer cdPtr
    ) internal pure returns (CalldataPointer cdPtrChild) {
        cdPtrChild = cdPtr.offset(cdPtr.readUint256() & OffsetOrLengthMask);
    }

    /// @dev Returns the calldata pointer one word after `cdPtr`.
    function next(
        CalldataPointer cdPtr
    ) internal pure returns (CalldataPointer cdPtrNext) {
        assembly {
            cdPtrNext := add(cdPtr, _OneWord)
        }
    }

    /// @dev Returns the calldata pointer `_offset` bytes after `cdPtr`.
    function offset(
        CalldataPointer cdPtr,
        uint256 _offset
    ) internal pure returns (CalldataPointer cdPtrNext) {
        assembly {
            cdPtrNext := add(cdPtr, _offset)
        }
    }

    /// @dev Copies `size` bytes from calldata starting at `src` to memory at
    ///      `dst`.
    function copy(
        CalldataPointer src,
        MemoryPointer dst,
        uint256 size
    ) internal pure {
        assembly {
            calldatacopy(dst, src, size)
        }
    }
}

library ReturndataPointerLib {
    function lt(
        ReturndataPointer a,
        ReturndataPointer b
    ) internal pure returns (bool c) {
        assembly {
            c := lt(a, b)
        }
    }

    function gt(
        ReturndataPointer a,
        ReturndataPointer b
    ) internal pure returns (bool c) {
        assembly {
            c := gt(a, b)
        }
    }

    function eq(
        ReturndataPointer a,
        ReturndataPointer b
    ) internal pure returns (bool c) {
        assembly {
            c := eq(a, b)
        }
    }

    function isNull(ReturndataPointer a) internal pure returns (bool b) {
        assembly {
            b := iszero(a)
        }
    }

    /// @dev Resolves an offset stored at `rdPtr + headOffset` to a returndata
    ///      pointer. `rdPtr` must point to some parent object with a dynamic
    ///      type's head stored at `rdPtr + headOffset`.
    function pptrOffset(
        ReturndataPointer rdPtr,
        uint256 headOffset
    ) internal pure returns (ReturndataPointer rdPtrChild) {
        rdPtrChild = rdPtr.offset(
            rdPtr.offset(headOffset).readUint256() & OffsetOrLengthMask
        );
    }

    /// @dev Resolves an offset stored at `rdPtr` to a returndata pointer.
    ///    `rdPtr` must point to some parent object with a dynamic type as its
    ///    first member, e.g. `struct { bytes data; }`
    function pptr(
        ReturndataPointer rdPtr
    ) internal pure returns (ReturndataPointer rdPtrChild) {
        rdPtrChild = rdPtr.offset(rdPtr.readUint256() & OffsetOrLengthMask);
    }

    /// @dev Returns the returndata pointer one word after `cdPtr`.
    function next(
        ReturndataPointer rdPtr
    ) internal pure returns (ReturndataPointer rdPtrNext) {
        assembly {
            rdPtrNext := add(rdPtr, _OneWord)
        }
    }

    /// @dev Returns the returndata pointer `_offset` bytes after `cdPtr`.
    function offset(
        ReturndataPointer rdPtr,
        uint256 _offset
    ) internal pure returns (ReturndataPointer rdPtrNext) {
        assembly {
            rdPtrNext := add(rdPtr, _offset)
        }
    }

    /// @dev Copies `size` bytes from returndata starting at `src` to memory at
    /// `dst`.
    function copy(
        ReturndataPointer src,
        MemoryPointer dst,
        uint256 size
    ) internal pure {
        assembly {
            returndatacopy(dst, src, size)
        }
    }
}

library MemoryPointerLib {
    function copy(
        MemoryPointer src,
        MemoryPointer dst,
        uint256 size
    ) internal view {
        assembly {
            let success := staticcall(
                gas(),
                IdentityPrecompileAddress,
                src,
                size,
                dst,
                size
            )
            if or(iszero(returndatasize()), iszero(success)) {
                revert(0, 0)
            }
        }
    }

    function lt(
        MemoryPointer a,
        MemoryPointer b
    ) internal pure returns (bool c) {
        assembly {
            c := lt(a, b)
        }
    }

    function gt(
        MemoryPointer a,
        MemoryPointer b
    ) internal pure returns (bool c) {
        assembly {
            c := gt(a, b)
        }
    }

    function eq(
        MemoryPointer a,
        MemoryPointer b
    ) internal pure returns (bool c) {
        assembly {
            c := eq(a, b)
        }
    }

    function isNull(MemoryPointer a) internal pure returns (bool b) {
        assembly {
            b := iszero(a)
        }
    }

    function hash(
        MemoryPointer ptr,
        uint256 length
    ) internal pure returns (bytes32 _hash) {
        assembly {
            _hash := keccak256(ptr, length)
        }
    }

    /// @dev Returns the memory pointer one word after `mPtr`.
    function next(
        MemoryPointer mPtr
    ) internal pure returns (MemoryPointer mPtrNext) {
        assembly {
            mPtrNext := add(mPtr, _OneWord)
        }
    }

    /// @dev Returns the memory pointer `_offset` bytes after `mPtr`.
    function offset(
        MemoryPointer mPtr,
        uint256 _offset
    ) internal pure returns (MemoryPointer mPtrNext) {
        assembly {
            mPtrNext := add(mPtr, _offset)
        }
    }

    /// @dev Resolves a pointer at `mPtr + headOffset` to a memory
    ///    pointer. `mPtr` must point to some parent object with a dynamic
    ///    type's pointer stored at `mPtr + headOffset`.
    function pptrOffset(
        MemoryPointer mPtr,
        uint256 headOffset
    ) internal pure returns (MemoryPointer mPtrChild) {
        mPtrChild = mPtr.offset(headOffset).readMemoryPointer();
    }

    /// @dev Resolves a pointer stored at `mPtr` to a memory pointer.
    ///    `mPtr` must point to some parent object with a dynamic type as its
    ///    first member, e.g. `struct { bytes data; }`
    function pptr(
        MemoryPointer mPtr
    ) internal pure returns (MemoryPointer mPtrChild) {
        mPtrChild = mPtr.readMemoryPointer();
    }
}

library CalldataReaders {
    /// @dev Reads the value at `cdPtr` and applies a mask to return only the
    ///    last 4 bytes.
    function readMaskedUint256(
        CalldataPointer cdPtr
    ) internal pure returns (uint256 value) {
        value = cdPtr.readUint256() & OffsetOrLengthMask;
    }

    /// @dev Reads the bool at `cdPtr` in calldata.
    function readBool(
        CalldataPointer cdPtr
    ) internal pure returns (bool value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the address at `cdPtr` in calldata.
    function readAddress(
        CalldataPointer cdPtr
    ) internal pure returns (address value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the bytes1 at `cdPtr` in calldata.
    function readBytes1(
        CalldataPointer cdPtr
    ) internal pure returns (bytes1 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the bytes2 at `cdPtr` in calldata.
    function readBytes2(
        CalldataPointer cdPtr
    ) internal pure returns (bytes2 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the bytes3 at `cdPtr` in calldata.
    function readBytes3(
        CalldataPointer cdPtr
    ) internal pure returns (bytes3 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the bytes4 at `cdPtr` in calldata.
    function readBytes4(
        CalldataPointer cdPtr
    ) internal pure returns (bytes4 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the bytes5 at `cdPtr` in calldata.
    function readBytes5(
        CalldataPointer cdPtr
    ) internal pure returns (bytes5 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the bytes6 at `cdPtr` in calldata.
    function readBytes6(
        CalldataPointer cdPtr
    ) internal pure returns (bytes6 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the bytes7 at `cdPtr` in calldata.
    function readBytes7(
        CalldataPointer cdPtr
    ) internal pure returns (bytes7 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the bytes8 at `cdPtr` in calldata.
    function readBytes8(
        CalldataPointer cdPtr
    ) internal pure returns (bytes8 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the bytes9 at `cdPtr` in calldata.
    function readBytes9(
        CalldataPointer cdPtr
    ) internal pure returns (bytes9 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the bytes10 at `cdPtr` in calldata.
    function readBytes10(
        CalldataPointer cdPtr
    ) internal pure returns (bytes10 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the bytes11 at `cdPtr` in calldata.
    function readBytes11(
        CalldataPointer cdPtr
    ) internal pure returns (bytes11 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the bytes12 at `cdPtr` in calldata.
    function readBytes12(
        CalldataPointer cdPtr
    ) internal pure returns (bytes12 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the bytes13 at `cdPtr` in calldata.
    function readBytes13(
        CalldataPointer cdPtr
    ) internal pure returns (bytes13 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the bytes14 at `cdPtr` in calldata.
    function readBytes14(
        CalldataPointer cdPtr
    ) internal pure returns (bytes14 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the bytes15 at `cdPtr` in calldata.
    function readBytes15(
        CalldataPointer cdPtr
    ) internal pure returns (bytes15 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the bytes16 at `cdPtr` in calldata.
    function readBytes16(
        CalldataPointer cdPtr
    ) internal pure returns (bytes16 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the bytes17 at `cdPtr` in calldata.
    function readBytes17(
        CalldataPointer cdPtr
    ) internal pure returns (bytes17 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the bytes18 at `cdPtr` in calldata.
    function readBytes18(
        CalldataPointer cdPtr
    ) internal pure returns (bytes18 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the bytes19 at `cdPtr` in calldata.
    function readBytes19(
        CalldataPointer cdPtr
    ) internal pure returns (bytes19 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the bytes20 at `cdPtr` in calldata.
    function readBytes20(
        CalldataPointer cdPtr
    ) internal pure returns (bytes20 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the bytes21 at `cdPtr` in calldata.
    function readBytes21(
        CalldataPointer cdPtr
    ) internal pure returns (bytes21 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the bytes22 at `cdPtr` in calldata.
    function readBytes22(
        CalldataPointer cdPtr
    ) internal pure returns (bytes22 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the bytes23 at `cdPtr` in calldata.
    function readBytes23(
        CalldataPointer cdPtr
    ) internal pure returns (bytes23 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the bytes24 at `cdPtr` in calldata.
    function readBytes24(
        CalldataPointer cdPtr
    ) internal pure returns (bytes24 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the bytes25 at `cdPtr` in calldata.
    function readBytes25(
        CalldataPointer cdPtr
    ) internal pure returns (bytes25 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the bytes26 at `cdPtr` in calldata.
    function readBytes26(
        CalldataPointer cdPtr
    ) internal pure returns (bytes26 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the bytes27 at `cdPtr` in calldata.
    function readBytes27(
        CalldataPointer cdPtr
    ) internal pure returns (bytes27 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the bytes28 at `cdPtr` in calldata.
    function readBytes28(
        CalldataPointer cdPtr
    ) internal pure returns (bytes28 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the bytes29 at `cdPtr` in calldata.
    function readBytes29(
        CalldataPointer cdPtr
    ) internal pure returns (bytes29 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the bytes30 at `cdPtr` in calldata.
    function readBytes30(
        CalldataPointer cdPtr
    ) internal pure returns (bytes30 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the bytes31 at `cdPtr` in calldata.
    function readBytes31(
        CalldataPointer cdPtr
    ) internal pure returns (bytes31 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the bytes32 at `cdPtr` in calldata.
    function readBytes32(
        CalldataPointer cdPtr
    ) internal pure returns (bytes32 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the uint8 at `cdPtr` in calldata.
    function readUint8(
        CalldataPointer cdPtr
    ) internal pure returns (uint8 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the uint16 at `cdPtr` in calldata.
    function readUint16(
        CalldataPointer cdPtr
    ) internal pure returns (uint16 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the uint24 at `cdPtr` in calldata.
    function readUint24(
        CalldataPointer cdPtr
    ) internal pure returns (uint24 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the uint32 at `cdPtr` in calldata.
    function readUint32(
        CalldataPointer cdPtr
    ) internal pure returns (uint32 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the uint40 at `cdPtr` in calldata.
    function readUint40(
        CalldataPointer cdPtr
    ) internal pure returns (uint40 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the uint48 at `cdPtr` in calldata.
    function readUint48(
        CalldataPointer cdPtr
    ) internal pure returns (uint48 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the uint56 at `cdPtr` in calldata.
    function readUint56(
        CalldataPointer cdPtr
    ) internal pure returns (uint56 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the uint64 at `cdPtr` in calldata.
    function readUint64(
        CalldataPointer cdPtr
    ) internal pure returns (uint64 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the uint72 at `cdPtr` in calldata.
    function readUint72(
        CalldataPointer cdPtr
    ) internal pure returns (uint72 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the uint80 at `cdPtr` in calldata.
    function readUint80(
        CalldataPointer cdPtr
    ) internal pure returns (uint80 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the uint88 at `cdPtr` in calldata.
    function readUint88(
        CalldataPointer cdPtr
    ) internal pure returns (uint88 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the uint96 at `cdPtr` in calldata.
    function readUint96(
        CalldataPointer cdPtr
    ) internal pure returns (uint96 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the uint104 at `cdPtr` in calldata.
    function readUint104(
        CalldataPointer cdPtr
    ) internal pure returns (uint104 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the uint112 at `cdPtr` in calldata.
    function readUint112(
        CalldataPointer cdPtr
    ) internal pure returns (uint112 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the uint120 at `cdPtr` in calldata.
    function readUint120(
        CalldataPointer cdPtr
    ) internal pure returns (uint120 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the uint128 at `cdPtr` in calldata.
    function readUint128(
        CalldataPointer cdPtr
    ) internal pure returns (uint128 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the uint136 at `cdPtr` in calldata.
    function readUint136(
        CalldataPointer cdPtr
    ) internal pure returns (uint136 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the uint144 at `cdPtr` in calldata.
    function readUint144(
        CalldataPointer cdPtr
    ) internal pure returns (uint144 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the uint152 at `cdPtr` in calldata.
    function readUint152(
        CalldataPointer cdPtr
    ) internal pure returns (uint152 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the uint160 at `cdPtr` in calldata.
    function readUint160(
        CalldataPointer cdPtr
    ) internal pure returns (uint160 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the uint168 at `cdPtr` in calldata.
    function readUint168(
        CalldataPointer cdPtr
    ) internal pure returns (uint168 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the uint176 at `cdPtr` in calldata.
    function readUint176(
        CalldataPointer cdPtr
    ) internal pure returns (uint176 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the uint184 at `cdPtr` in calldata.
    function readUint184(
        CalldataPointer cdPtr
    ) internal pure returns (uint184 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the uint192 at `cdPtr` in calldata.
    function readUint192(
        CalldataPointer cdPtr
    ) internal pure returns (uint192 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the uint200 at `cdPtr` in calldata.
    function readUint200(
        CalldataPointer cdPtr
    ) internal pure returns (uint200 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the uint208 at `cdPtr` in calldata.
    function readUint208(
        CalldataPointer cdPtr
    ) internal pure returns (uint208 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the uint216 at `cdPtr` in calldata.
    function readUint216(
        CalldataPointer cdPtr
    ) internal pure returns (uint216 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the uint224 at `cdPtr` in calldata.
    function readUint224(
        CalldataPointer cdPtr
    ) internal pure returns (uint224 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the uint232 at `cdPtr` in calldata.
    function readUint232(
        CalldataPointer cdPtr
    ) internal pure returns (uint232 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the uint240 at `cdPtr` in calldata.
    function readUint240(
        CalldataPointer cdPtr
    ) internal pure returns (uint240 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the uint248 at `cdPtr` in calldata.
    function readUint248(
        CalldataPointer cdPtr
    ) internal pure returns (uint248 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the uint256 at `cdPtr` in calldata.
    function readUint256(
        CalldataPointer cdPtr
    ) internal pure returns (uint256 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the int8 at `cdPtr` in calldata.
    function readInt8(
        CalldataPointer cdPtr
    ) internal pure returns (int8 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the int16 at `cdPtr` in calldata.
    function readInt16(
        CalldataPointer cdPtr
    ) internal pure returns (int16 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the int24 at `cdPtr` in calldata.
    function readInt24(
        CalldataPointer cdPtr
    ) internal pure returns (int24 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the int32 at `cdPtr` in calldata.
    function readInt32(
        CalldataPointer cdPtr
    ) internal pure returns (int32 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the int40 at `cdPtr` in calldata.
    function readInt40(
        CalldataPointer cdPtr
    ) internal pure returns (int40 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the int48 at `cdPtr` in calldata.
    function readInt48(
        CalldataPointer cdPtr
    ) internal pure returns (int48 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the int56 at `cdPtr` in calldata.
    function readInt56(
        CalldataPointer cdPtr
    ) internal pure returns (int56 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the int64 at `cdPtr` in calldata.
    function readInt64(
        CalldataPointer cdPtr
    ) internal pure returns (int64 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the int72 at `cdPtr` in calldata.
    function readInt72(
        CalldataPointer cdPtr
    ) internal pure returns (int72 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the int80 at `cdPtr` in calldata.
    function readInt80(
        CalldataPointer cdPtr
    ) internal pure returns (int80 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the int88 at `cdPtr` in calldata.
    function readInt88(
        CalldataPointer cdPtr
    ) internal pure returns (int88 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the int96 at `cdPtr` in calldata.
    function readInt96(
        CalldataPointer cdPtr
    ) internal pure returns (int96 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the int104 at `cdPtr` in calldata.
    function readInt104(
        CalldataPointer cdPtr
    ) internal pure returns (int104 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the int112 at `cdPtr` in calldata.
    function readInt112(
        CalldataPointer cdPtr
    ) internal pure returns (int112 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the int120 at `cdPtr` in calldata.
    function readInt120(
        CalldataPointer cdPtr
    ) internal pure returns (int120 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the int128 at `cdPtr` in calldata.
    function readInt128(
        CalldataPointer cdPtr
    ) internal pure returns (int128 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the int136 at `cdPtr` in calldata.
    function readInt136(
        CalldataPointer cdPtr
    ) internal pure returns (int136 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the int144 at `cdPtr` in calldata.
    function readInt144(
        CalldataPointer cdPtr
    ) internal pure returns (int144 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the int152 at `cdPtr` in calldata.
    function readInt152(
        CalldataPointer cdPtr
    ) internal pure returns (int152 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the int160 at `cdPtr` in calldata.
    function readInt160(
        CalldataPointer cdPtr
    ) internal pure returns (int160 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the int168 at `cdPtr` in calldata.
    function readInt168(
        CalldataPointer cdPtr
    ) internal pure returns (int168 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the int176 at `cdPtr` in calldata.
    function readInt176(
        CalldataPointer cdPtr
    ) internal pure returns (int176 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the int184 at `cdPtr` in calldata.
    function readInt184(
        CalldataPointer cdPtr
    ) internal pure returns (int184 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the int192 at `cdPtr` in calldata.
    function readInt192(
        CalldataPointer cdPtr
    ) internal pure returns (int192 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the int200 at `cdPtr` in calldata.
    function readInt200(
        CalldataPointer cdPtr
    ) internal pure returns (int200 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the int208 at `cdPtr` in calldata.
    function readInt208(
        CalldataPointer cdPtr
    ) internal pure returns (int208 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the int216 at `cdPtr` in calldata.
    function readInt216(
        CalldataPointer cdPtr
    ) internal pure returns (int216 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the int224 at `cdPtr` in calldata.
    function readInt224(
        CalldataPointer cdPtr
    ) internal pure returns (int224 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the int232 at `cdPtr` in calldata.
    function readInt232(
        CalldataPointer cdPtr
    ) internal pure returns (int232 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the int240 at `cdPtr` in calldata.
    function readInt240(
        CalldataPointer cdPtr
    ) internal pure returns (int240 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the int248 at `cdPtr` in calldata.
    function readInt248(
        CalldataPointer cdPtr
    ) internal pure returns (int248 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }

    /// @dev Reads the int256 at `cdPtr` in calldata.
    function readInt256(
        CalldataPointer cdPtr
    ) internal pure returns (int256 value) {
        assembly {
            value := calldataload(cdPtr)
        }
    }
}

library ReturndataReaders {
    /// @dev Reads value at `rdPtr` & applies a mask to return only last 4 bytes
    function readMaskedUint256(
        ReturndataPointer rdPtr
    ) internal pure returns (uint256 value) {
        value = rdPtr.readUint256() & OffsetOrLengthMask;
    }

    /// @dev Reads the bool at `rdPtr` in returndata.
    function readBool(
        ReturndataPointer rdPtr
    ) internal pure returns (bool value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the address at `rdPtr` in returndata.
    function readAddress(
        ReturndataPointer rdPtr
    ) internal pure returns (address value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the bytes1 at `rdPtr` in returndata.
    function readBytes1(
        ReturndataPointer rdPtr
    ) internal pure returns (bytes1 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the bytes2 at `rdPtr` in returndata.
    function readBytes2(
        ReturndataPointer rdPtr
    ) internal pure returns (bytes2 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the bytes3 at `rdPtr` in returndata.
    function readBytes3(
        ReturndataPointer rdPtr
    ) internal pure returns (bytes3 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the bytes4 at `rdPtr` in returndata.
    function readBytes4(
        ReturndataPointer rdPtr
    ) internal pure returns (bytes4 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the bytes5 at `rdPtr` in returndata.
    function readBytes5(
        ReturndataPointer rdPtr
    ) internal pure returns (bytes5 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the bytes6 at `rdPtr` in returndata.
    function readBytes6(
        ReturndataPointer rdPtr
    ) internal pure returns (bytes6 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the bytes7 at `rdPtr` in returndata.
    function readBytes7(
        ReturndataPointer rdPtr
    ) internal pure returns (bytes7 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the bytes8 at `rdPtr` in returndata.
    function readBytes8(
        ReturndataPointer rdPtr
    ) internal pure returns (bytes8 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the bytes9 at `rdPtr` in returndata.
    function readBytes9(
        ReturndataPointer rdPtr
    ) internal pure returns (bytes9 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the bytes10 at `rdPtr` in returndata.
    function readBytes10(
        ReturndataPointer rdPtr
    ) internal pure returns (bytes10 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the bytes11 at `rdPtr` in returndata.
    function readBytes11(
        ReturndataPointer rdPtr
    ) internal pure returns (bytes11 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the bytes12 at `rdPtr` in returndata.
    function readBytes12(
        ReturndataPointer rdPtr
    ) internal pure returns (bytes12 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the bytes13 at `rdPtr` in returndata.
    function readBytes13(
        ReturndataPointer rdPtr
    ) internal pure returns (bytes13 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the bytes14 at `rdPtr` in returndata.
    function readBytes14(
        ReturndataPointer rdPtr
    ) internal pure returns (bytes14 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the bytes15 at `rdPtr` in returndata.
    function readBytes15(
        ReturndataPointer rdPtr
    ) internal pure returns (bytes15 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the bytes16 at `rdPtr` in returndata.
    function readBytes16(
        ReturndataPointer rdPtr
    ) internal pure returns (bytes16 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the bytes17 at `rdPtr` in returndata.
    function readBytes17(
        ReturndataPointer rdPtr
    ) internal pure returns (bytes17 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the bytes18 at `rdPtr` in returndata.
    function readBytes18(
        ReturndataPointer rdPtr
    ) internal pure returns (bytes18 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the bytes19 at `rdPtr` in returndata.
    function readBytes19(
        ReturndataPointer rdPtr
    ) internal pure returns (bytes19 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the bytes20 at `rdPtr` in returndata.
    function readBytes20(
        ReturndataPointer rdPtr
    ) internal pure returns (bytes20 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the bytes21 at `rdPtr` in returndata.
    function readBytes21(
        ReturndataPointer rdPtr
    ) internal pure returns (bytes21 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the bytes22 at `rdPtr` in returndata.
    function readBytes22(
        ReturndataPointer rdPtr
    ) internal pure returns (bytes22 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the bytes23 at `rdPtr` in returndata.
    function readBytes23(
        ReturndataPointer rdPtr
    ) internal pure returns (bytes23 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the bytes24 at `rdPtr` in returndata.
    function readBytes24(
        ReturndataPointer rdPtr
    ) internal pure returns (bytes24 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the bytes25 at `rdPtr` in returndata.
    function readBytes25(
        ReturndataPointer rdPtr
    ) internal pure returns (bytes25 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the bytes26 at `rdPtr` in returndata.
    function readBytes26(
        ReturndataPointer rdPtr
    ) internal pure returns (bytes26 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the bytes27 at `rdPtr` in returndata.
    function readBytes27(
        ReturndataPointer rdPtr
    ) internal pure returns (bytes27 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the bytes28 at `rdPtr` in returndata.
    function readBytes28(
        ReturndataPointer rdPtr
    ) internal pure returns (bytes28 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the bytes29 at `rdPtr` in returndata.
    function readBytes29(
        ReturndataPointer rdPtr
    ) internal pure returns (bytes29 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the bytes30 at `rdPtr` in returndata.
    function readBytes30(
        ReturndataPointer rdPtr
    ) internal pure returns (bytes30 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the bytes31 at `rdPtr` in returndata.
    function readBytes31(
        ReturndataPointer rdPtr
    ) internal pure returns (bytes31 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the bytes32 at `rdPtr` in returndata.
    function readBytes32(
        ReturndataPointer rdPtr
    ) internal pure returns (bytes32 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the uint8 at `rdPtr` in returndata.
    function readUint8(
        ReturndataPointer rdPtr
    ) internal pure returns (uint8 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the uint16 at `rdPtr` in returndata.
    function readUint16(
        ReturndataPointer rdPtr
    ) internal pure returns (uint16 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the uint24 at `rdPtr` in returndata.
    function readUint24(
        ReturndataPointer rdPtr
    ) internal pure returns (uint24 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the uint32 at `rdPtr` in returndata.
    function readUint32(
        ReturndataPointer rdPtr
    ) internal pure returns (uint32 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the uint40 at `rdPtr` in returndata.
    function readUint40(
        ReturndataPointer rdPtr
    ) internal pure returns (uint40 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the uint48 at `rdPtr` in returndata.
    function readUint48(
        ReturndataPointer rdPtr
    ) internal pure returns (uint48 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the uint56 at `rdPtr` in returndata.
    function readUint56(
        ReturndataPointer rdPtr
    ) internal pure returns (uint56 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the uint64 at `rdPtr` in returndata.
    function readUint64(
        ReturndataPointer rdPtr
    ) internal pure returns (uint64 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the uint72 at `rdPtr` in returndata.
    function readUint72(
        ReturndataPointer rdPtr
    ) internal pure returns (uint72 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the uint80 at `rdPtr` in returndata.
    function readUint80(
        ReturndataPointer rdPtr
    ) internal pure returns (uint80 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the uint88 at `rdPtr` in returndata.
    function readUint88(
        ReturndataPointer rdPtr
    ) internal pure returns (uint88 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the uint96 at `rdPtr` in returndata.
    function readUint96(
        ReturndataPointer rdPtr
    ) internal pure returns (uint96 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the uint104 at `rdPtr` in returndata.
    function readUint104(
        ReturndataPointer rdPtr
    ) internal pure returns (uint104 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the uint112 at `rdPtr` in returndata.
    function readUint112(
        ReturndataPointer rdPtr
    ) internal pure returns (uint112 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the uint120 at `rdPtr` in returndata.
    function readUint120(
        ReturndataPointer rdPtr
    ) internal pure returns (uint120 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the uint128 at `rdPtr` in returndata.
    function readUint128(
        ReturndataPointer rdPtr
    ) internal pure returns (uint128 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the uint136 at `rdPtr` in returndata.
    function readUint136(
        ReturndataPointer rdPtr
    ) internal pure returns (uint136 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the uint144 at `rdPtr` in returndata.
    function readUint144(
        ReturndataPointer rdPtr
    ) internal pure returns (uint144 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the uint152 at `rdPtr` in returndata.
    function readUint152(
        ReturndataPointer rdPtr
    ) internal pure returns (uint152 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the uint160 at `rdPtr` in returndata.
    function readUint160(
        ReturndataPointer rdPtr
    ) internal pure returns (uint160 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the uint168 at `rdPtr` in returndata.
    function readUint168(
        ReturndataPointer rdPtr
    ) internal pure returns (uint168 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the uint176 at `rdPtr` in returndata.
    function readUint176(
        ReturndataPointer rdPtr
    ) internal pure returns (uint176 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the uint184 at `rdPtr` in returndata.
    function readUint184(
        ReturndataPointer rdPtr
    ) internal pure returns (uint184 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the uint192 at `rdPtr` in returndata.
    function readUint192(
        ReturndataPointer rdPtr
    ) internal pure returns (uint192 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the uint200 at `rdPtr` in returndata.
    function readUint200(
        ReturndataPointer rdPtr
    ) internal pure returns (uint200 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the uint208 at `rdPtr` in returndata.
    function readUint208(
        ReturndataPointer rdPtr
    ) internal pure returns (uint208 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the uint216 at `rdPtr` in returndata.
    function readUint216(
        ReturndataPointer rdPtr
    ) internal pure returns (uint216 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the uint224 at `rdPtr` in returndata.
    function readUint224(
        ReturndataPointer rdPtr
    ) internal pure returns (uint224 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the uint232 at `rdPtr` in returndata.
    function readUint232(
        ReturndataPointer rdPtr
    ) internal pure returns (uint232 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the uint240 at `rdPtr` in returndata.
    function readUint240(
        ReturndataPointer rdPtr
    ) internal pure returns (uint240 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the uint248 at `rdPtr` in returndata.
    function readUint248(
        ReturndataPointer rdPtr
    ) internal pure returns (uint248 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the uint256 at `rdPtr` in returndata.
    function readUint256(
        ReturndataPointer rdPtr
    ) internal pure returns (uint256 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the int8 at `rdPtr` in returndata.
    function readInt8(
        ReturndataPointer rdPtr
    ) internal pure returns (int8 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the int16 at `rdPtr` in returndata.
    function readInt16(
        ReturndataPointer rdPtr
    ) internal pure returns (int16 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the int24 at `rdPtr` in returndata.
    function readInt24(
        ReturndataPointer rdPtr
    ) internal pure returns (int24 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the int32 at `rdPtr` in returndata.
    function readInt32(
        ReturndataPointer rdPtr
    ) internal pure returns (int32 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the int40 at `rdPtr` in returndata.
    function readInt40(
        ReturndataPointer rdPtr
    ) internal pure returns (int40 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the int48 at `rdPtr` in returndata.
    function readInt48(
        ReturndataPointer rdPtr
    ) internal pure returns (int48 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the int56 at `rdPtr` in returndata.
    function readInt56(
        ReturndataPointer rdPtr
    ) internal pure returns (int56 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the int64 at `rdPtr` in returndata.
    function readInt64(
        ReturndataPointer rdPtr
    ) internal pure returns (int64 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the int72 at `rdPtr` in returndata.
    function readInt72(
        ReturndataPointer rdPtr
    ) internal pure returns (int72 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the int80 at `rdPtr` in returndata.
    function readInt80(
        ReturndataPointer rdPtr
    ) internal pure returns (int80 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the int88 at `rdPtr` in returndata.
    function readInt88(
        ReturndataPointer rdPtr
    ) internal pure returns (int88 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the int96 at `rdPtr` in returndata.
    function readInt96(
        ReturndataPointer rdPtr
    ) internal pure returns (int96 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the int104 at `rdPtr` in returndata.
    function readInt104(
        ReturndataPointer rdPtr
    ) internal pure returns (int104 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the int112 at `rdPtr` in returndata.
    function readInt112(
        ReturndataPointer rdPtr
    ) internal pure returns (int112 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the int120 at `rdPtr` in returndata.
    function readInt120(
        ReturndataPointer rdPtr
    ) internal pure returns (int120 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the int128 at `rdPtr` in returndata.
    function readInt128(
        ReturndataPointer rdPtr
    ) internal pure returns (int128 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the int136 at `rdPtr` in returndata.
    function readInt136(
        ReturndataPointer rdPtr
    ) internal pure returns (int136 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the int144 at `rdPtr` in returndata.
    function readInt144(
        ReturndataPointer rdPtr
    ) internal pure returns (int144 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the int152 at `rdPtr` in returndata.
    function readInt152(
        ReturndataPointer rdPtr
    ) internal pure returns (int152 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the int160 at `rdPtr` in returndata.
    function readInt160(
        ReturndataPointer rdPtr
    ) internal pure returns (int160 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the int168 at `rdPtr` in returndata.
    function readInt168(
        ReturndataPointer rdPtr
    ) internal pure returns (int168 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the int176 at `rdPtr` in returndata.
    function readInt176(
        ReturndataPointer rdPtr
    ) internal pure returns (int176 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the int184 at `rdPtr` in returndata.
    function readInt184(
        ReturndataPointer rdPtr
    ) internal pure returns (int184 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the int192 at `rdPtr` in returndata.
    function readInt192(
        ReturndataPointer rdPtr
    ) internal pure returns (int192 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the int200 at `rdPtr` in returndata.
    function readInt200(
        ReturndataPointer rdPtr
    ) internal pure returns (int200 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the int208 at `rdPtr` in returndata.
    function readInt208(
        ReturndataPointer rdPtr
    ) internal pure returns (int208 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the int216 at `rdPtr` in returndata.
    function readInt216(
        ReturndataPointer rdPtr
    ) internal pure returns (int216 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the int224 at `rdPtr` in returndata.
    function readInt224(
        ReturndataPointer rdPtr
    ) internal pure returns (int224 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the int232 at `rdPtr` in returndata.
    function readInt232(
        ReturndataPointer rdPtr
    ) internal pure returns (int232 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the int240 at `rdPtr` in returndata.
    function readInt240(
        ReturndataPointer rdPtr
    ) internal pure returns (int240 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the int248 at `rdPtr` in returndata.
    function readInt248(
        ReturndataPointer rdPtr
    ) internal pure returns (int248 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }

    /// @dev Reads the int256 at `rdPtr` in returndata.
    function readInt256(
        ReturndataPointer rdPtr
    ) internal pure returns (int256 value) {
        assembly {
            returndatacopy(0, rdPtr, _OneWord)
            value := mload(0)
        }
    }
}

library MemoryReaders {
    /// @dev Reads the memory pointer at `mPtr` in memory.
    function readMemoryPointer(
        MemoryPointer mPtr
    ) internal pure returns (MemoryPointer value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads value at `mPtr` & applies a mask to return only last 4 bytes
    function readMaskedUint256(
        MemoryPointer mPtr
    ) internal pure returns (uint256 value) {
        value = mPtr.readUint256() & OffsetOrLengthMask;
    }

    /// @dev Reads the bool at `mPtr` in memory.
    function readBool(MemoryPointer mPtr) internal pure returns (bool value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the address at `mPtr` in memory.
    function readAddress(
        MemoryPointer mPtr
    ) internal pure returns (address value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the bytes1 at `mPtr` in memory.
    function readBytes1(
        MemoryPointer mPtr
    ) internal pure returns (bytes1 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the bytes2 at `mPtr` in memory.
    function readBytes2(
        MemoryPointer mPtr
    ) internal pure returns (bytes2 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the bytes3 at `mPtr` in memory.
    function readBytes3(
        MemoryPointer mPtr
    ) internal pure returns (bytes3 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the bytes4 at `mPtr` in memory.
    function readBytes4(
        MemoryPointer mPtr
    ) internal pure returns (bytes4 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the bytes5 at `mPtr` in memory.
    function readBytes5(
        MemoryPointer mPtr
    ) internal pure returns (bytes5 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the bytes6 at `mPtr` in memory.
    function readBytes6(
        MemoryPointer mPtr
    ) internal pure returns (bytes6 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the bytes7 at `mPtr` in memory.
    function readBytes7(
        MemoryPointer mPtr
    ) internal pure returns (bytes7 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the bytes8 at `mPtr` in memory.
    function readBytes8(
        MemoryPointer mPtr
    ) internal pure returns (bytes8 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the bytes9 at `mPtr` in memory.
    function readBytes9(
        MemoryPointer mPtr
    ) internal pure returns (bytes9 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the bytes10 at `mPtr` in memory.
    function readBytes10(
        MemoryPointer mPtr
    ) internal pure returns (bytes10 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the bytes11 at `mPtr` in memory.
    function readBytes11(
        MemoryPointer mPtr
    ) internal pure returns (bytes11 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the bytes12 at `mPtr` in memory.
    function readBytes12(
        MemoryPointer mPtr
    ) internal pure returns (bytes12 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the bytes13 at `mPtr` in memory.
    function readBytes13(
        MemoryPointer mPtr
    ) internal pure returns (bytes13 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the bytes14 at `mPtr` in memory.
    function readBytes14(
        MemoryPointer mPtr
    ) internal pure returns (bytes14 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the bytes15 at `mPtr` in memory.
    function readBytes15(
        MemoryPointer mPtr
    ) internal pure returns (bytes15 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the bytes16 at `mPtr` in memory.
    function readBytes16(
        MemoryPointer mPtr
    ) internal pure returns (bytes16 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the bytes17 at `mPtr` in memory.
    function readBytes17(
        MemoryPointer mPtr
    ) internal pure returns (bytes17 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the bytes18 at `mPtr` in memory.
    function readBytes18(
        MemoryPointer mPtr
    ) internal pure returns (bytes18 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the bytes19 at `mPtr` in memory.
    function readBytes19(
        MemoryPointer mPtr
    ) internal pure returns (bytes19 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the bytes20 at `mPtr` in memory.
    function readBytes20(
        MemoryPointer mPtr
    ) internal pure returns (bytes20 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the bytes21 at `mPtr` in memory.
    function readBytes21(
        MemoryPointer mPtr
    ) internal pure returns (bytes21 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the bytes22 at `mPtr` in memory.
    function readBytes22(
        MemoryPointer mPtr
    ) internal pure returns (bytes22 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the bytes23 at `mPtr` in memory.
    function readBytes23(
        MemoryPointer mPtr
    ) internal pure returns (bytes23 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the bytes24 at `mPtr` in memory.
    function readBytes24(
        MemoryPointer mPtr
    ) internal pure returns (bytes24 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the bytes25 at `mPtr` in memory.
    function readBytes25(
        MemoryPointer mPtr
    ) internal pure returns (bytes25 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the bytes26 at `mPtr` in memory.
    function readBytes26(
        MemoryPointer mPtr
    ) internal pure returns (bytes26 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the bytes27 at `mPtr` in memory.
    function readBytes27(
        MemoryPointer mPtr
    ) internal pure returns (bytes27 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the bytes28 at `mPtr` in memory.
    function readBytes28(
        MemoryPointer mPtr
    ) internal pure returns (bytes28 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the bytes29 at `mPtr` in memory.
    function readBytes29(
        MemoryPointer mPtr
    ) internal pure returns (bytes29 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the bytes30 at `mPtr` in memory.
    function readBytes30(
        MemoryPointer mPtr
    ) internal pure returns (bytes30 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the bytes31 at `mPtr` in memory.
    function readBytes31(
        MemoryPointer mPtr
    ) internal pure returns (bytes31 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the bytes32 at `mPtr` in memory.
    function readBytes32(
        MemoryPointer mPtr
    ) internal pure returns (bytes32 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the uint8 at `mPtr` in memory.
    function readUint8(MemoryPointer mPtr) internal pure returns (uint8 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the uint16 at `mPtr` in memory.
    function readUint16(
        MemoryPointer mPtr
    ) internal pure returns (uint16 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the uint24 at `mPtr` in memory.
    function readUint24(
        MemoryPointer mPtr
    ) internal pure returns (uint24 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the uint32 at `mPtr` in memory.
    function readUint32(
        MemoryPointer mPtr
    ) internal pure returns (uint32 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the uint40 at `mPtr` in memory.
    function readUint40(
        MemoryPointer mPtr
    ) internal pure returns (uint40 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the uint48 at `mPtr` in memory.
    function readUint48(
        MemoryPointer mPtr
    ) internal pure returns (uint48 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the uint56 at `mPtr` in memory.
    function readUint56(
        MemoryPointer mPtr
    ) internal pure returns (uint56 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the uint64 at `mPtr` in memory.
    function readUint64(
        MemoryPointer mPtr
    ) internal pure returns (uint64 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the uint72 at `mPtr` in memory.
    function readUint72(
        MemoryPointer mPtr
    ) internal pure returns (uint72 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the uint80 at `mPtr` in memory.
    function readUint80(
        MemoryPointer mPtr
    ) internal pure returns (uint80 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the uint88 at `mPtr` in memory.
    function readUint88(
        MemoryPointer mPtr
    ) internal pure returns (uint88 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the uint96 at `mPtr` in memory.
    function readUint96(
        MemoryPointer mPtr
    ) internal pure returns (uint96 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the uint104 at `mPtr` in memory.
    function readUint104(
        MemoryPointer mPtr
    ) internal pure returns (uint104 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the uint112 at `mPtr` in memory.
    function readUint112(
        MemoryPointer mPtr
    ) internal pure returns (uint112 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the uint120 at `mPtr` in memory.
    function readUint120(
        MemoryPointer mPtr
    ) internal pure returns (uint120 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the uint128 at `mPtr` in memory.
    function readUint128(
        MemoryPointer mPtr
    ) internal pure returns (uint128 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the uint136 at `mPtr` in memory.
    function readUint136(
        MemoryPointer mPtr
    ) internal pure returns (uint136 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the uint144 at `mPtr` in memory.
    function readUint144(
        MemoryPointer mPtr
    ) internal pure returns (uint144 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the uint152 at `mPtr` in memory.
    function readUint152(
        MemoryPointer mPtr
    ) internal pure returns (uint152 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the uint160 at `mPtr` in memory.
    function readUint160(
        MemoryPointer mPtr
    ) internal pure returns (uint160 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the uint168 at `mPtr` in memory.
    function readUint168(
        MemoryPointer mPtr
    ) internal pure returns (uint168 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the uint176 at `mPtr` in memory.
    function readUint176(
        MemoryPointer mPtr
    ) internal pure returns (uint176 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the uint184 at `mPtr` in memory.
    function readUint184(
        MemoryPointer mPtr
    ) internal pure returns (uint184 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the uint192 at `mPtr` in memory.
    function readUint192(
        MemoryPointer mPtr
    ) internal pure returns (uint192 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the uint200 at `mPtr` in memory.
    function readUint200(
        MemoryPointer mPtr
    ) internal pure returns (uint200 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the uint208 at `mPtr` in memory.
    function readUint208(
        MemoryPointer mPtr
    ) internal pure returns (uint208 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the uint216 at `mPtr` in memory.
    function readUint216(
        MemoryPointer mPtr
    ) internal pure returns (uint216 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the uint224 at `mPtr` in memory.
    function readUint224(
        MemoryPointer mPtr
    ) internal pure returns (uint224 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the uint232 at `mPtr` in memory.
    function readUint232(
        MemoryPointer mPtr
    ) internal pure returns (uint232 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the uint240 at `mPtr` in memory.
    function readUint240(
        MemoryPointer mPtr
    ) internal pure returns (uint240 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the uint248 at `mPtr` in memory.
    function readUint248(
        MemoryPointer mPtr
    ) internal pure returns (uint248 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the uint256 at `mPtr` in memory.
    function readUint256(
        MemoryPointer mPtr
    ) internal pure returns (uint256 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the int8 at `mPtr` in memory.
    function readInt8(MemoryPointer mPtr) internal pure returns (int8 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the int16 at `mPtr` in memory.
    function readInt16(MemoryPointer mPtr) internal pure returns (int16 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the int24 at `mPtr` in memory.
    function readInt24(MemoryPointer mPtr) internal pure returns (int24 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the int32 at `mPtr` in memory.
    function readInt32(MemoryPointer mPtr) internal pure returns (int32 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the int40 at `mPtr` in memory.
    function readInt40(MemoryPointer mPtr) internal pure returns (int40 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the int48 at `mPtr` in memory.
    function readInt48(MemoryPointer mPtr) internal pure returns (int48 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the int56 at `mPtr` in memory.
    function readInt56(MemoryPointer mPtr) internal pure returns (int56 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the int64 at `mPtr` in memory.
    function readInt64(MemoryPointer mPtr) internal pure returns (int64 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the int72 at `mPtr` in memory.
    function readInt72(MemoryPointer mPtr) internal pure returns (int72 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the int80 at `mPtr` in memory.
    function readInt80(MemoryPointer mPtr) internal pure returns (int80 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the int88 at `mPtr` in memory.
    function readInt88(MemoryPointer mPtr) internal pure returns (int88 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the int96 at `mPtr` in memory.
    function readInt96(MemoryPointer mPtr) internal pure returns (int96 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the int104 at `mPtr` in memory.
    function readInt104(
        MemoryPointer mPtr
    ) internal pure returns (int104 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the int112 at `mPtr` in memory.
    function readInt112(
        MemoryPointer mPtr
    ) internal pure returns (int112 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the int120 at `mPtr` in memory.
    function readInt120(
        MemoryPointer mPtr
    ) internal pure returns (int120 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the int128 at `mPtr` in memory.
    function readInt128(
        MemoryPointer mPtr
    ) internal pure returns (int128 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the int136 at `mPtr` in memory.
    function readInt136(
        MemoryPointer mPtr
    ) internal pure returns (int136 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the int144 at `mPtr` in memory.
    function readInt144(
        MemoryPointer mPtr
    ) internal pure returns (int144 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the int152 at `mPtr` in memory.
    function readInt152(
        MemoryPointer mPtr
    ) internal pure returns (int152 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the int160 at `mPtr` in memory.
    function readInt160(
        MemoryPointer mPtr
    ) internal pure returns (int160 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the int168 at `mPtr` in memory.
    function readInt168(
        MemoryPointer mPtr
    ) internal pure returns (int168 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the int176 at `mPtr` in memory.
    function readInt176(
        MemoryPointer mPtr
    ) internal pure returns (int176 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the int184 at `mPtr` in memory.
    function readInt184(
        MemoryPointer mPtr
    ) internal pure returns (int184 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the int192 at `mPtr` in memory.
    function readInt192(
        MemoryPointer mPtr
    ) internal pure returns (int192 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the int200 at `mPtr` in memory.
    function readInt200(
        MemoryPointer mPtr
    ) internal pure returns (int200 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the int208 at `mPtr` in memory.
    function readInt208(
        MemoryPointer mPtr
    ) internal pure returns (int208 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the int216 at `mPtr` in memory.
    function readInt216(
        MemoryPointer mPtr
    ) internal pure returns (int216 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the int224 at `mPtr` in memory.
    function readInt224(
        MemoryPointer mPtr
    ) internal pure returns (int224 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the int232 at `mPtr` in memory.
    function readInt232(
        MemoryPointer mPtr
    ) internal pure returns (int232 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the int240 at `mPtr` in memory.
    function readInt240(
        MemoryPointer mPtr
    ) internal pure returns (int240 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the int248 at `mPtr` in memory.
    function readInt248(
        MemoryPointer mPtr
    ) internal pure returns (int248 value) {
        assembly {
            value := mload(mPtr)
        }
    }

    /// @dev Reads the int256 at `mPtr` in memory.
    function readInt256(
        MemoryPointer mPtr
    ) internal pure returns (int256 value) {
        assembly {
            value := mload(mPtr)
        }
    }
}

library MemoryWriters {
    /// @dev Writes `valuePtr` to memory at `mPtr`.
    function write(MemoryPointer mPtr, MemoryPointer valuePtr) internal pure {
        assembly {
            mstore(mPtr, valuePtr)
        }
    }

    /// @dev Writes a boolean `value` to `mPtr` in memory.
    function write(MemoryPointer mPtr, bool value) internal pure {
        assembly {
            mstore(mPtr, value)
        }
    }

    /// @dev Writes an address `value` to `mPtr` in memory.
    function write(MemoryPointer mPtr, address value) internal pure {
        assembly {
            mstore(mPtr, value)
        }
    }

    /// @dev Writes a bytes32 `value` to `mPtr` in memory.
    /// Separate name to disambiguate literal write parameters.
    function writeBytes32(MemoryPointer mPtr, bytes32 value) internal pure {
        assembly {
            mstore(mPtr, value)
        }
    }

    /// @dev Writes a uint256 `value` to `mPtr` in memory.
    function write(MemoryPointer mPtr, uint256 value) internal pure {
        assembly {
            mstore(mPtr, value)
        }
    }

    /// @dev Writes an int256 `value` to `mPtr` in memory.
    /// Separate name to disambiguate literal write parameters.
    function writeInt(MemoryPointer mPtr, int256 value) internal pure {
        assembly {
            mstore(mPtr, value)
        }
    }
}

File 8 of 43 : ReferenceFulfillmentApplier.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import { ItemType, Side } from "seaport-types/src/lib/ConsiderationEnums.sol";

import {
    Execution,
    FulfillmentComponent,
    ReceivedItem,
    SpentItem
} from "seaport-types/src/lib/ConsiderationStructs.sol";

import {
    ConsiderationItemIndicesAndValidity,
    OrderToExecute
} from "./ReferenceConsiderationStructs.sol";

import {
    FulfillmentApplicationErrors
} from "seaport-types/src/interfaces/FulfillmentApplicationErrors.sol";

import {
    TokenTransferrerErrors
} from "seaport-types/src/interfaces/TokenTransferrerErrors.sol";

/**
 * @title FulfillmentApplier
 * @author 0age
 * @notice FulfillmentApplier contains logic related to applying fulfillments,
 *         both as part of order matching (where offer items are matched to
 *         consideration items) as well as fulfilling available orders (where
 *         order items and consideration items are independently aggregated).
 */
contract ReferenceFulfillmentApplier is
    FulfillmentApplicationErrors,
    TokenTransferrerErrors
{
    /**
     * @dev Internal pure function to match offer items to consideration items
     *      on a group of orders via a supplied fulfillment.
     *
     * @param ordersToExecute         The orders to match.
     * @param offerComponents         An array designating offer components to
     *                                match to consideration components.
     * @param considerationComponents An array designating consideration
     *                                components to match to offer components.
     *                                Note that each consideration amount must
     *                                be zero in order for the match operation
     *                                to be valid.
     * @param fulfillmentIndex        The index of the fulfillment component
     *                                that does not match the initial offer
     *                                item.
     *
     * @return execution The transfer performed as a result of the fulfillment.
     */
    function _applyFulfillment(
        OrderToExecute[] memory ordersToExecute,
        FulfillmentComponent[] memory offerComponents,
        FulfillmentComponent[] memory considerationComponents,
        uint256 fulfillmentIndex
    ) internal pure returns (Execution memory execution) {
        // Ensure 1+ of both offer and consideration components are supplied.
        if (
            offerComponents.length == 0 || considerationComponents.length == 0
        ) {
            revert OfferAndConsiderationRequiredOnFulfillment();
        }

        // Recipient does not need to be specified because it will always be set
        // to that of the consideration.
        // Validate and aggregate consideration items and store the result as a
        // ReceivedItem.
        ReceivedItem memory considerationItem = (
            _aggregateValidFulfillmentConsiderationItems(
                ordersToExecute,
                considerationComponents
            )
        );

        // Skip aggregating offer items if no consideration items are available.
        if (considerationItem.amount == 0) {
            return execution;
        }

        // Validate & aggregate offer items and store result as an Execution.
        (
            execution
            /**
             * ItemType itemType,
             * address token,
             * uint256 identifier,
             * address offerer,
             * bytes32 conduitKey,
             * uint256 offerAmount
             */
        ) = _aggregateValidFulfillmentOfferItems(
            ordersToExecute,
            offerComponents,
            address(0) // unused
        );

        // Ensure offer and consideration share types, tokens and identifiers.
        if (
            execution.item.itemType != considerationItem.itemType ||
            execution.item.token != considerationItem.token ||
            execution.item.identifier != considerationItem.identifier
        ) {
            revert MismatchedFulfillmentOfferAndConsiderationComponents(
                fulfillmentIndex
            );
        }

        // If total consideration amount exceeds the offer amount...
        if (considerationItem.amount > execution.item.amount) {
            // Retrieve the first consideration component from the fulfillment.
            FulfillmentComponent memory targetComponent = (
                considerationComponents[0]
            );

            // Add excess consideration item amount to original array of orders.
            ordersToExecute[targetComponent.orderIndex]
                .receivedItems[targetComponent.itemIndex]
                .amount = considerationItem.amount - execution.item.amount;

            // Reduce total consideration amount to equal the offer amount.
            considerationItem.amount = execution.item.amount;
        } else {
            // Retrieve the first offer component from the fulfillment.
            FulfillmentComponent memory targetComponent = (offerComponents[0]);

            // Add excess offer item amount to the original array of orders.
            ordersToExecute[targetComponent.orderIndex]
                .spentItems[targetComponent.itemIndex]
                .amount = execution.item.amount - considerationItem.amount;
        }

        // Reuse execution struct with consideration amount and recipient.
        // Only set the recipient if the item amount is non-zero.
        execution.item.amount = considerationItem.amount;
        if (execution.item.amount != 0) {
            execution.item.recipient = considerationItem.recipient;
        }

        // Return the final execution that will be triggered for relevant items.
        return execution; // Execution(execution, offerer, conduitKey);
    }

    /**
     * @dev Internal view function to aggregate offer or consideration items
     *      from a group of orders into a single execution via a supplied array
     *      of fulfillment components. Items that are not available to aggregate
     *      will not be included in the aggregated execution.
     *
     * @param ordersToExecute       The orders to aggregate.
     * @param side                  The side (i.e. offer or consideration).
     * @param fulfillmentComponents An array designating item components to
     *                              aggregate if part of an available order.
     * @param fulfillerConduitKey   A bytes32 value indicating what conduit, if
     *                              any, to source the fulfiller's token
     *                              approvals from. The zero hash signifies that
     *                              no conduit should be used (and direct
     *                              approvals set on Consideration)
     * @param recipient             The intended recipient for all received
     *                              items.
     *
     * @return _execution The transfer performed as a result of the fulfillment.
     */
    function _aggregateAvailable(
        OrderToExecute[] memory ordersToExecute,
        Side side,
        FulfillmentComponent[] memory fulfillmentComponents,
        bytes32 fulfillerConduitKey,
        address recipient
    ) internal view returns (Execution memory _execution) {
        // Retrieve fulfillment components array length and place on stack.
        uint256 totalFulfillmentComponents = fulfillmentComponents.length;

        // Ensure at least one fulfillment component has been supplied.
        if (totalFulfillmentComponents == 0) {
            revert MissingFulfillmentComponentOnAggregation(side);
        }

        Execution memory execution;

        // If the fulfillment components are offer components...
        if (side == Side.OFFER) {
            // Return execution for aggregated items provided by offerer.
            execution = _aggregateValidFulfillmentOfferItems(
                ordersToExecute,
                fulfillmentComponents,
                recipient
            );
        } else {
            // Otherwise, fulfillment components are consideration
            // components. Return execution for aggregated items provided by
            // the fulfiller.
            execution = _aggregateConsiderationItems(
                ordersToExecute,
                fulfillmentComponents,
                fulfillerConduitKey
            );
        }

        return execution;
    }

    /**
     * @dev Internal pure function to check the indicated offer item
     *      matches original item.
     *
     * @param orderToExecute The order to compare.
     * @param offer          The offer to compare.
     * @param execution      The aggregated offer item.
     *
     * @return invalidFulfillment A boolean indicating whether the
     *                            fulfillment is invalid.
     */
    function _checkMatchingOffer(
        OrderToExecute memory orderToExecute,
        SpentItem memory offer,
        Execution memory execution
    ) internal pure returns (bool invalidFulfillment) {
        return
            execution.item.identifier != offer.identifier ||
            execution.offerer != orderToExecute.offerer ||
            execution.conduitKey != orderToExecute.conduitKey ||
            execution.item.itemType != offer.itemType ||
            execution.item.token != offer.token;
    }

    /**
     * @dev Internal pure function to aggregate a group of offer items using
     *      supplied directives on which component items are candidates for
     *      aggregation, skipping items on orders that are not available.
     *
     * @param ordersToExecute The orders to aggregate offer items from.
     * @param offerComponents An array of FulfillmentComponent structs
     *                        indicating the order index and item index of each
     *                        candidate offer item for aggregation.
     * @param recipient       The recipient for the aggregated offer items.
     *
     * @return execution The aggregated offer items.
     */
    function _aggregateValidFulfillmentOfferItems(
        OrderToExecute[] memory ordersToExecute,
        FulfillmentComponent[] memory offerComponents,
        address recipient
    ) internal pure returns (Execution memory execution) {
        bool foundItem = false;

        // Get the order index and item index of the offer component.
        uint256 orderIndex;
        uint256 itemIndex;

        OrderToExecute memory orderToExecute;

        // Declare variables indicating whether the aggregation is invalid.
        // Ensure that the order index is not out of range.
        bool invalidFulfillment;

        // Ensure that no available items have missing amounts.
        bool missingItemAmount;

        // Loop through the offer components, checking for validity.
        for (uint256 i = 0; i < offerComponents.length; ++i) {
            // Get the order index and item index of the offer component.
            orderIndex = offerComponents[i].orderIndex;
            itemIndex = offerComponents[i].itemIndex;

            // Ensure that the order index is not out of range.
            invalidFulfillment = orderIndex >= ordersToExecute.length;
            // Break if invalid.
            if (invalidFulfillment) {
                break;
            }

            // Get the order based on offer components order index.
            orderToExecute = ordersToExecute[orderIndex];
            if (
                orderToExecute.numerator != 0 &&
                itemIndex < orderToExecute.spentItems.length
            ) {
                // Get the spent item based on the offer components item index.
                SpentItem memory offer = orderToExecute.spentItems[itemIndex];

                if (!foundItem) {
                    foundItem = true;

                    // Create the Execution.
                    execution = Execution(
                        ReceivedItem(
                            offer.itemType,
                            offer.token,
                            offer.identifier,
                            offer.amount,
                            payable(recipient)
                        ),
                        orderToExecute.offerer,
                        orderToExecute.conduitKey
                    );

                    // If component index > 0, swap component pointer with
                    // pointer to first component so that any remainder after
                    // fulfillment can be added back to the first item.
                    if (i != 0) {
                        FulfillmentComponent
                            memory firstComponent = offerComponents[0];
                        offerComponents[0] = offerComponents[i];
                        offerComponents[i] = firstComponent;
                    }
                } else {
                    // Update the Received Item amount.
                    execution.item.amount =
                        execution.item.amount +
                        offer.amount;

                    // Ensure indicated offer item matches original item.
                    invalidFulfillment = _checkMatchingOffer(
                        orderToExecute,
                        offer,
                        execution
                    );
                }

                // Ensure the item has a nonzero amount.
                missingItemAmount = offer.amount == 0;
                invalidFulfillment = invalidFulfillment || missingItemAmount;

                // Zero out amount on original offerItem to indicate it's spent.
                offer.amount = 0;

                // Break if invalid.
                if (invalidFulfillment) {
                    break;
                }
            }
        }

        // Revert if an order/item was out of range or was not aggregatable.
        if (invalidFulfillment) {
            if (missingItemAmount) {
                revert MissingItemAmount();
            }
            revert InvalidFulfillmentComponentData();
        }
    }

    /**
     * @dev Internal view function to aggregate consideration items from a group
     *      of orders into a single execution via a supplied components array.
     *      Consideration items that are not available to aggregate will not be
     *      included in the aggregated execution.
     *
     * @param ordersToExecute         The orders to aggregate.
     * @param considerationComponents An array designating consideration
     *                                components to aggregate if part of an
     *                                available order.
     * @param fulfillerConduitKey     A bytes32 value indicating what conduit,
     *                                if any, to source the fulfiller's token
     *                                approvals from. The zero hash signifies
     *                                that no conduit should be used (and direct
     *                                approvals set on Consideration)
     *
     * @return execution The transfer performed as a result of the fulfillment.
     */
    function _aggregateConsiderationItems(
        OrderToExecute[] memory ordersToExecute,
        FulfillmentComponent[] memory considerationComponents,
        bytes32 fulfillerConduitKey
    ) internal view returns (Execution memory execution) {
        // Validate and aggregate consideration items on available orders and
        // store result as a ReceivedItem.
        ReceivedItem memory receiveConsiderationItem = (
            _aggregateValidFulfillmentConsiderationItems(
                ordersToExecute,
                considerationComponents
            )
        );

        if (receiveConsiderationItem.amount != 0) {
            // Return execution for aggregated items provided by the fulfiller.
            execution = Execution(
                receiveConsiderationItem,
                msg.sender,
                fulfillerConduitKey
            );
        } else {
            // Return an empty execution if the received item amount is zero.
            execution = Execution(
                receiveConsiderationItem,
                address(0),
                bytes32(0)
            );
        }
    }

    /**
     * @dev Internal pure function to check the indicated consideration item
     *      matches original item.
     *
     * @param consideration The consideration to compare.
     * @param receivedItem  The aggregated received item.
     *
     * @return invalidFulfillment A boolean indicating whether the fulfillment
     *                            is invalid.
     */
    function _checkMatchingConsideration(
        ReceivedItem memory consideration,
        ReceivedItem memory receivedItem
    ) internal pure returns (bool invalidFulfillment) {
        return
            receivedItem.recipient != consideration.recipient ||
            receivedItem.itemType != consideration.itemType ||
            receivedItem.token != consideration.token ||
            receivedItem.identifier != consideration.identifier;
    }

    /**
     * @dev Internal pure function to aggregate a group of consideration items
     *      using supplied directives on which component items are candidates
     *      for aggregation, skipping items on orders that are not available.
     *
     * @param ordersToExecute         The orders to aggregate consideration
     *                                items from.
     * @param considerationComponents An array of FulfillmentComponent structs
     *                                indicating the order index and item index
     *                                of each candidate consideration item for
     *                                aggregation.
     *
     * @return receivedItem The aggregated consideration items.
     */
    function _aggregateValidFulfillmentConsiderationItems(
        OrderToExecute[] memory ordersToExecute,
        FulfillmentComponent[] memory considerationComponents
    ) internal pure returns (ReceivedItem memory receivedItem) {
        bool foundItem = false;

        // Declare struct in memory to avoid declaring multiple local variables.
        ConsiderationItemIndicesAndValidity memory potentialCandidate;

        ReceivedItem memory consideration;

        OrderToExecute memory orderToExecute;

        // Loop through the consideration components and validate
        // their fulfillment.
        for (uint256 i = 0; i < considerationComponents.length; ++i) {
            // Get the order index and item index of the consideration
            // component.
            potentialCandidate.orderIndex = considerationComponents[i]
                .orderIndex;
            potentialCandidate.itemIndex = considerationComponents[i].itemIndex;

            /// Ensure that the order index is not out of range.
            potentialCandidate.invalidFulfillment =
                potentialCandidate.orderIndex >= ordersToExecute.length;

            // Break if invalid.
            if (potentialCandidate.invalidFulfillment) {
                break;
            }

            // Get order based on consideration components order index.
            orderToExecute = ordersToExecute[potentialCandidate.orderIndex];

            // Confirm that the order is being fulfilled.
            if (
                orderToExecute.numerator != 0 &&
                potentialCandidate.itemIndex <
                orderToExecute.receivedItems.length
            ) {
                // Retrieve relevant item using item index.
                consideration = orderToExecute.receivedItems[
                    potentialCandidate.itemIndex
                ];

                if (!foundItem) {
                    foundItem = true;

                    // Create the received item.
                    receivedItem = ReceivedItem(
                        consideration.itemType,
                        consideration.token,
                        consideration.identifier,
                        consideration.amount,
                        consideration.recipient
                    );

                    // If component index > 0, swap component pointer with
                    // pointer to first component so that any remainder after
                    // fulfillment can be added back to the first item.
                    if (i != 0) {
                        FulfillmentComponent
                            memory firstComponent = considerationComponents[0];
                        considerationComponents[0] = considerationComponents[i];
                        considerationComponents[i] = firstComponent;
                    }
                } else {
                    // Update Received Item amount.
                    receivedItem.amount =
                        receivedItem.amount +
                        consideration.amount;

                    // Ensure the indicated consideration item matches
                    // original item.
                    potentialCandidate
                        .invalidFulfillment = _checkMatchingConsideration(
                        consideration,
                        receivedItem
                    );
                }

                // Ensure the item has a nonzero amount.
                potentialCandidate.missingItemAmount =
                    consideration.amount == 0;
                potentialCandidate.invalidFulfillment =
                    potentialCandidate.invalidFulfillment ||
                    potentialCandidate.missingItemAmount;

                // Zero out amount on original consideration item to
                // indicate it is spent.
                consideration.amount = 0;

                // Break if invalid.
                if (potentialCandidate.invalidFulfillment) {
                    break;
                }
            }
        }

        // Revert if an order/item was out of range or was not aggregatable.
        if (potentialCandidate.invalidFulfillment) {
            if (potentialCandidate.missingItemAmount) {
                revert MissingItemAmount();
            }
            revert InvalidFulfillmentComponentData();
        }
    }
}

File 9 of 43 : ReferenceOrderFulfiller.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import {
    ItemType,
    OrderType
} from "seaport-types/src/lib/ConsiderationEnums.sol";

import {
    AdvancedOrder,
    ConsiderationItem,
    CriteriaResolver,
    OfferItem,
    Order,
    OrderParameters,
    ReceivedItem,
    SpentItem
} from "seaport-types/src/lib/ConsiderationStructs.sol";

import {
    AccumulatorStruct,
    FractionData,
    OrderToExecute,
    OrderValidation
} from "./ReferenceConsiderationStructs.sol";

import {
    ReferenceBasicOrderFulfiller
} from "./ReferenceBasicOrderFulfiller.sol";

import { ReferenceCriteriaResolution } from "./ReferenceCriteriaResolution.sol";

import { ReferenceAmountDeriver } from "./ReferenceAmountDeriver.sol";

/**
 * @title OrderFulfiller
 * @author 0age
 * @notice OrderFulfiller contains logic related to order fulfillment.
 */
contract ReferenceOrderFulfiller is
    ReferenceBasicOrderFulfiller,
    ReferenceCriteriaResolution,
    ReferenceAmountDeriver
{
    /**
     * @dev Derive and set hashes, reference chainId, and associated domain
     *      separator during deployment.
     *
     * @param conduitController A contract that deploys conduits, or proxies
     *                          that may optionally be used to transfer approved
     *                          ERC20/721/1155 tokens.
     */
    constructor(
        address conduitController
    ) ReferenceBasicOrderFulfiller(conduitController) {}

    /**
     * @dev Internal function to validate an order and update its status, adjust
     *      prices based on current time, apply criteria resolvers, determine
     *      what portion to fill, and transfer relevant tokens.
     *
     * @param advancedOrder       The order to fulfill as well as the fraction
     *                            to fill. Note that all offer and consideration
     *                            components must divide with no remainder for
     *                            the partial fill to be valid.
     * @param criteriaResolvers   An array where each element contains a
     *                            reference to a specific offer or
     *                            consideration, a token identifier, and a proof
     *                            that the supplied token identifier is
     *                            contained in the order's merkle root. Note
     *                            that a criteria of zero indicates that any
     *                            (transferable) token identifier is valid and
     *                            that no proof needs to be supplied.
     * @param fulfillerConduitKey A bytes32 value indicating what conduit, if
     *                            any, to source the fulfiller's token approvals
     *                            from. The zero hash signifies that no conduit
     *                            should be used (and direct approvals set on
     *                            Consideration).
     * @param recipient           The intended recipient for all received items.
     *
     * @return A boolean indicating whether the order has been fulfilled.
     */
    function _validateAndFulfillAdvancedOrder(
        AdvancedOrder memory advancedOrder,
        CriteriaResolver[] memory criteriaResolvers,
        bytes32 fulfillerConduitKey,
        address recipient
    ) internal returns (bool) {
        // Validate the order and revert if it's invalid.
        OrderValidation memory orderValidation = _validateOrder(
            advancedOrder,
            true
        );

        // Apply criteria resolvers using generated orders and details arrays.
        _applyCriteriaResolversAdvanced(advancedOrder, criteriaResolvers);

        // Retrieve the order parameters after applying criteria resolvers.
        OrderParameters memory orderParameters = advancedOrder.parameters;

        // Perform each item transfer with the appropriate fractional amount.
        orderValidation.orderToExecute = _applyFractions(
            orderParameters,
            orderValidation.newNumerator,
            orderValidation.newDenominator
        );

        // Declare empty bytes32 array.
        bytes32[] memory priorOrderHashes = new bytes32[](0);

        if (orderParameters.orderType != OrderType.CONTRACT) {
            // Ensure restricted orders have valid submitter or pass zone check.
            _assertRestrictedAdvancedOrderAuthorization(
                advancedOrder,
                orderValidation.orderToExecute,
                priorOrderHashes,
                orderValidation.orderHash,
                orderParameters.zoneHash,
                orderParameters.orderType,
                orderParameters.offerer,
                orderParameters.zone
            );

            // Update the order status to reflect the new numerator and denominator.
            // Revert if the order is not valid.
            _updateStatus(
                orderValidation.orderHash,
                orderValidation.newNumerator,
                orderValidation.newDenominator,
                true
            );
        } else {
            bytes32 orderHash = _getGeneratedOrder(
                orderValidation.orderToExecute,
                advancedOrder.parameters,
                advancedOrder.extraData,
                true
            );

            orderValidation.orderHash = orderHash;
        }

        // Transfer each item contained in the order.
        _transferEach(
            orderParameters,
            orderValidation.orderToExecute,
            fulfillerConduitKey,
            recipient
        );

        // Declare bytes32 array with this order's hash
        priorOrderHashes = new bytes32[](1);
        priorOrderHashes[0] = orderValidation.orderHash;

        // Ensure restricted orders have valid submitter or pass zone check.
        _assertRestrictedAdvancedOrderValidity(
            advancedOrder,
            orderValidation.orderToExecute,
            priorOrderHashes,
            orderValidation.orderHash,
            orderParameters.zoneHash,
            orderParameters.orderType,
            orderParameters.offerer,
            orderParameters.zone
        );

        // Emit an event signifying that the order has been fulfilled.
        emit OrderFulfilled(
            orderValidation.orderHash,
            orderParameters.offerer,
            orderParameters.zone,
            recipient,
            orderValidation.orderToExecute.spentItems,
            orderValidation.orderToExecute.receivedItems
        );

        return true;
    }

    /**
     * @dev Internal view function to apply a respective fraction to the
     *      amount being transferred on each item of an order.
     *
     * @param orderParameters     The parameters for the fulfilled order.
     * @param numerator           A value indicating the portion of the order
     *                            that should be filled.
     * @param denominator         A value indicating the total order size.
     * @return orderToExecute     Returns the order with items that are being
     *                            transferred. This will be used for the
     *                            OrderFulfilled Event.
     */
    function _applyFractions(
        OrderParameters memory orderParameters,
        uint256 numerator,
        uint256 denominator
    ) internal view returns (OrderToExecute memory orderToExecute) {
        // Derive order duration, time elapsed, and time remaining.
        // Store in memory to avoid stack too deep issues.
        FractionData memory fractionData = FractionData(
            numerator,
            denominator,
            0, // fulfillerConduitKey is not used here.
            orderParameters.startTime,
            orderParameters.endTime
        );

        // Create the array to store the spent items for event.
        orderToExecute.spentItems = (
            new SpentItem[](orderParameters.offer.length)
        );

        // Declare a nested scope to minimize stack depth.
        {
            // Iterate over each offer on the order.
            for (uint256 i = 0; i < orderParameters.offer.length; ++i) {
                // Retrieve the offer item.
                OfferItem memory offerItem = orderParameters.offer[i];

                // Offer items for the native token can not be received outside
                // of a match order function except as part of a contract order.
                if (
                    offerItem.itemType == ItemType.NATIVE &&
                    orderParameters.orderType != OrderType.CONTRACT
                ) {
                    revert InvalidNativeOfferItem();
                }

                // Apply fill fraction to derive offer item amount to transfer.
                uint256 amount = _applyFraction(
                    offerItem.startAmount,
                    offerItem.endAmount,
                    fractionData,
                    false
                );

                // Create Spent Item for the OrderFulfilled event.
                orderToExecute.spentItems[i] = SpentItem(
                    offerItem.itemType,
                    offerItem.token,
                    offerItem.identifierOrCriteria,
                    amount
                );
            }
        }

        // Create the array to store the received items for event.
        orderToExecute.receivedItems = (
            new ReceivedItem[](orderParameters.consideration.length)
        );

        // Declare a nested scope to minimize stack depth.
        {
            // Iterate over each consideration on the order.
            for (uint256 i = 0; i < orderParameters.consideration.length; ++i) {
                // Retrieve the consideration item.
                ConsiderationItem memory considerationItem = (
                    orderParameters.consideration[i]
                );

                // Apply fraction & derive considerationItem amount to transfer.
                uint256 amount = _applyFraction(
                    considerationItem.startAmount,
                    considerationItem.endAmount,
                    fractionData,
                    true
                );

                // Create Received Item from Offer item & add to structs array.
                orderToExecute.receivedItems[i] = ReceivedItem(
                    considerationItem.itemType,
                    considerationItem.token,
                    considerationItem.identifierOrCriteria,
                    amount,
                    considerationItem.recipient
                );
            }
        }

        // Return the order to execute.
        return orderToExecute;
    }

    /**
     * @dev Internal function to transfer each item contained in a given single
     *      order fulfillment.
     *
     * @param orderParameters     The parameters for the fulfilled order.
     * @param orderToExecute      The items that are being transferred.
     * @param fulfillerConduitKey A bytes32 value indicating what conduit, if
     *                            any, to source the fulfiller's token approvals
     *                            from. The zero hash signifies that no conduit
     *                            should be used (and direct approvals set on
     *                            Consideration).
     * @param recipient           The intended recipient for all received items.
     */
    function _transferEach(
        OrderParameters memory orderParameters,
        OrderToExecute memory orderToExecute,
        bytes32 fulfillerConduitKey,
        address recipient
    ) internal {
        // Create the accumulator struct.
        AccumulatorStruct memory accumulatorStruct;

        // Get the offerer of the order.
        address offerer = orderParameters.offerer;

        // Get the conduitKey of the order
        bytes32 conduitKey = orderParameters.conduitKey;

        // Declare a nested scope to minimize stack depth.
        {
            // Iterate over each spent item on the order.
            for (uint256 i = 0; i < orderToExecute.spentItems.length; ++i) {
                // Retrieve the spent item.
                SpentItem memory spentItem = orderToExecute.spentItems[i];

                // Create Received Item from Spent Item for transfer.
                ReceivedItem memory receivedItem = ReceivedItem(
                    spentItem.itemType,
                    spentItem.token,
                    spentItem.identifier,
                    spentItem.amount,
                    payable(recipient)
                );

                // Transfer the item from the offerer to the recipient.
                _transfer(receivedItem, offerer, conduitKey, accumulatorStruct);
            }
        }

        // Declare a nested scope to minimize stack depth.
        {
            // Iterate over each received item on the order.
            for (uint256 i = 0; i < orderToExecute.receivedItems.length; ++i) {
                // Retrieve the received item.
                ReceivedItem memory receivedItem = (
                    orderToExecute.receivedItems[i]
                );

                if (receivedItem.itemType == ItemType.NATIVE) {
                    // Ensure that sufficient native tokens are still available.
                    if (receivedItem.amount > address(this).balance) {
                        revert InsufficientNativeTokensSupplied();
                    }
                }

                // Transfer item from caller to recipient specified by the item.
                _transfer(
                    receivedItem,
                    msg.sender,
                    fulfillerConduitKey,
                    accumulatorStruct
                );
            }
        }

        // Trigger any remaining accumulated transfers via call to the conduit.
        _triggerIfArmed(accumulatorStruct);

        // If any native tokens remain after applying fulfillments...
        if (address(this).balance != 0) {
            // return them to the caller.
            _transferNativeTokens(payable(msg.sender), address(this).balance);
        }
    }

    /**
     * @dev Internal pure function to convert an order to an advanced order with
     *      numerator and denominator of 1 and empty extraData.
     *
     * @param order The order to convert.
     *
     * @return advancedOrder The new advanced order.
     */
    function _convertOrderToAdvanced(
        Order calldata order
    ) internal pure returns (AdvancedOrder memory advancedOrder) {
        // Convert to partial order (1/1 or full fill) and return new value.
        advancedOrder = AdvancedOrder(
            order.parameters,
            1,
            1,
            order.signature,
            ""
        );
    }

    /**
     * @dev Internal pure function to convert an array of orders to an array of
     *      advanced orders with numerator and denominator of 1.
     *
     * @param orders The orders to convert.
     *
     * @return advancedOrders The new array of partial orders.
     */
    function _convertOrdersToAdvanced(
        Order[] calldata orders
    ) internal pure returns (AdvancedOrder[] memory advancedOrders) {
        // Read the number of orders from calldata and place on the stack.
        uint256 totalOrders = orders.length;

        // Allocate new empty array for each partial order in memory.
        advancedOrders = new AdvancedOrder[](totalOrders);

        // Iterate over the given orders.
        for (uint256 i = 0; i < totalOrders; ++i) {
            // Convert to partial order (1/1 or full fill) and update array.
            advancedOrders[i] = _convertOrderToAdvanced(orders[i]);
        }

        // Return the array of advanced orders.
        return advancedOrders;
    }
}

File 10 of 43 : ConduitStructs.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import { ConduitItemType } from "./ConduitEnums.sol";

/**
 * @dev A ConduitTransfer is a struct that contains the information needed for a
 *      conduit to transfer an item from one address to another.
 */
struct ConduitTransfer {
    ConduitItemType itemType;
    address token;
    address from;
    address to;
    uint256 identifier;
    uint256 amount;
}

/**
 * @dev A ConduitBatch1155Transfer is a struct that contains the information
 *      needed for a conduit to transfer a batch of ERC-1155 tokens from one
 *      address to another.
 */
struct ConduitBatch1155Transfer {
    address token;
    address from;
    address to;
    uint256[] ids;
    uint256[] amounts;
}

File 11 of 43 : SeaportInterface.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import {
    AdvancedOrder,
    BasicOrderParameters,
    CriteriaResolver,
    Execution,
    Fulfillment,
    FulfillmentComponent,
    Order,
    OrderComponents
} from "../lib/ConsiderationStructs.sol";

/**
 * @title SeaportInterface
 * @author 0age
 * @custom:version 1.6
 * @notice Seaport is a generalized native token/ERC20/ERC721/ERC1155
 *         marketplace. It minimizes external calls to the greatest extent
 *         possible and provides lightweight methods for common routes as well
 *         as more flexible methods for composing advanced orders.
 *
 * @dev SeaportInterface contains all external function interfaces for Seaport.
 */
interface SeaportInterface {
    /**
     * @notice Fulfill an order offering an ERC721 token by supplying Ether (or
     *         the native token for the given chain) as consideration for the
     *         order. An arbitrary number of "additional recipients" may also be
     *         supplied which will each receive native tokens from the fulfiller
     *         as consideration.
     *
     * @param parameters Additional information on the fulfilled order. Note
     *                   that the offerer must first approve this contract (or
     *                   their preferred conduit if indicated by the order) for
     *                   their offered ERC721 token to be transferred.
     *
     * @return fulfilled A boolean indicating whether the order has been
     *                   successfully fulfilled.
     */
    function fulfillBasicOrder(
        BasicOrderParameters calldata parameters
    ) external payable returns (bool fulfilled);

    /**
     * @notice Fulfill an order with an arbitrary number of items for offer and
     *         consideration. Note that this function does not support
     *         criteria-based orders or partial filling of orders (though
     *         filling the remainder of a partially-filled order is supported).
     *
     * @param order               The order to fulfill. Note that both the
     *                            offerer and the fulfiller must first approve
     *                            this contract (or the corresponding conduit if
     *                            indicated) to transfer any relevant tokens on
     *                            their behalf and that contracts must implement
     *                            `onERC1155Received` to receive ERC1155 tokens
     *                            as consideration.
     * @param fulfillerConduitKey A bytes32 value indicating what conduit, if
     *                            any, to source the fulfiller's token approvals
     *                            from. The zero hash signifies that no conduit
     *                            should be used, with direct approvals set on
     *                            Seaport.
     *
     * @return fulfilled A boolean indicating whether the order has been
     *                   successfully fulfilled.
     */
    function fulfillOrder(
        Order calldata order,
        bytes32 fulfillerConduitKey
    ) external payable returns (bool fulfilled);

    /**
     * @notice Fill an order, fully or partially, with an arbitrary number of
     *         items for offer and consideration alongside criteria resolvers
     *         containing specific token identifiers and associated proofs.
     *
     * @param advancedOrder       The order to fulfill along with the fraction
     *                            of the order to attempt to fill. Note that
     *                            both the offerer and the fulfiller must first
     *                            approve this contract (or their preferred
     *                            conduit if indicated by the order) to transfer
     *                            any relevant tokens on their behalf and that
     *                            contracts must implement `onERC1155Received`
     *                            to receive ERC1155 tokens as consideration.
     *                            Also note that all offer and consideration
     *                            components must have no remainder after
     *                            multiplication of the respective amount with
     *                            the supplied fraction for the partial fill to
     *                            be considered valid.
     * @param criteriaResolvers   An array where each element contains a
     *                            reference to a specific offer or
     *                            consideration, a token identifier, and a proof
     *                            that the supplied token identifier is
     *                            contained in the merkle root held by the item
     *                            in question's criteria element. Note that an
     *                            empty criteria indicates that any
     *                            (transferable) token identifier on the token
     *                            in question is valid and that no associated
     *                            proof needs to be supplied.
     * @param fulfillerConduitKey A bytes32 value indicating what conduit, if
     *                            any, to source the fulfiller's token approvals
     *                            from. The zero hash signifies that no conduit
     *                            should be used, with direct approvals set on
     *                            Seaport.
     * @param recipient           The intended recipient for all received items,
     *                            with `address(0)` indicating that the caller
     *                            should receive the items.
     *
     * @return fulfilled A boolean indicating whether the order has been
     *                   successfully fulfilled.
     */
    function fulfillAdvancedOrder(
        AdvancedOrder calldata advancedOrder,
        CriteriaResolver[] calldata criteriaResolvers,
        bytes32 fulfillerConduitKey,
        address recipient
    ) external payable returns (bool fulfilled);

    /**
     * @notice Attempt to fill a group of orders, each with an arbitrary number
     *         of items for offer and consideration. Any order that is not
     *         currently active, has already been fully filled, or has been
     *         cancelled will be omitted. Remaining offer and consideration
     *         items will then be aggregated where possible as indicated by the
     *         supplied offer and consideration component arrays and aggregated
     *         items will be transferred to the fulfiller or to each intended
     *         recipient, respectively. Note that a failing item transfer or an
     *         issue with order formatting will cause the entire batch to fail.
     *         Note that this function does not support criteria-based orders or
     *         partial filling of orders (though filling the remainder of a
     *         partially-filled order is supported).
     *
     * @param orders                    The orders to fulfill. Note that both
     *                                  the offerer and the fulfiller must first
     *                                  approve this contract (or the
     *                                  corresponding conduit if indicated) to
     *                                  transfer any relevant tokens on their
     *                                  behalf and that contracts must implement
     *                                  `onERC1155Received` to receive ERC1155
     *                                  tokens as consideration.
     * @param offerFulfillments         An array of FulfillmentComponent arrays
     *                                  indicating which offer items to attempt
     *                                  to aggregate when preparing executions.
     * @param considerationFulfillments An array of FulfillmentComponent arrays
     *                                  indicating which consideration items to
     *                                  attempt to aggregate when preparing
     *                                  executions.
     * @param fulfillerConduitKey       A bytes32 value indicating what conduit,
     *                                  if any, to source the fulfiller's token
     *                                  approvals from. The zero hash signifies
     *                                  that no conduit should be used, with
     *                                  direct approvals set on this contract.
     * @param maximumFulfilled          The maximum number of orders to fulfill.
     *
     * @return availableOrders An array of booleans indicating if each order
     *                         with an index corresponding to the index of the
     *                         returned boolean was fulfillable or not.
     * @return executions      An array of elements indicating the sequence of
     *                         transfers performed as part of matching the given
     *                         orders. Note that unspent offer item amounts or
     *                         native tokens will not be reflected as part of
     *                         this array.
     */
    function fulfillAvailableOrders(
        Order[] calldata orders,
        FulfillmentComponent[][] calldata offerFulfillments,
        FulfillmentComponent[][] calldata considerationFulfillments,
        bytes32 fulfillerConduitKey,
        uint256 maximumFulfilled
    )
        external
        payable
        returns (bool[] memory availableOrders, Execution[] memory executions);

    /**
     * @notice Attempt to fill a group of orders, fully or partially, with an
     *         arbitrary number of items for offer and consideration per order
     *         alongside criteria resolvers containing specific token
     *         identifiers and associated proofs. Any order that is not
     *         currently active, has already been fully filled, or has been
     *         cancelled will be omitted. Remaining offer and consideration
     *         items will then be aggregated where possible as indicated by the
     *         supplied offer and consideration component arrays and aggregated
     *         items will be transferred to the fulfiller or to each intended
     *         recipient, respectively. Note that a failing item transfer or an
     *         issue with order formatting will cause the entire batch to fail.
     *
     * @param advancedOrders            The orders to fulfill along with the
     *                                  fraction of those orders to attempt to
     *                                  fill. Note that both the offerer and the
     *                                  fulfiller must first approve this
     *                                  contract (or their preferred conduit if
     *                                  indicated by the order) to transfer any
     *                                  relevant tokens on their behalf and that
     *                                  contracts must implement
     *                                  `onERC1155Received` to enable receipt of
     *                                  ERC1155 tokens as consideration. Also
     *                                  note that all offer and consideration
     *                                  components must have no remainder after
     *                                  multiplication of the respective amount
     *                                  with the supplied fraction for an
     *                                  order's partial fill amount to be
     *                                  considered valid.
     * @param criteriaResolvers         An array where each element contains a
     *                                  reference to a specific offer or
     *                                  consideration, a token identifier, and a
     *                                  proof that the supplied token identifier
     *                                  is contained in the merkle root held by
     *                                  the item in question's criteria element.
     *                                  Note that an empty criteria indicates
     *                                  that any (transferable) token
     *                                  identifier on the token in question is
     *                                  valid and that no associated proof needs
     *                                  to be supplied.
     * @param offerFulfillments         An array of FulfillmentComponent arrays
     *                                  indicating which offer items to attempt
     *                                  to aggregate when preparing executions.
     * @param considerationFulfillments An array of FulfillmentComponent arrays
     *                                  indicating which consideration items to
     *                                  attempt to aggregate when preparing
     *                                  executions.
     * @param fulfillerConduitKey       A bytes32 value indicating what conduit,
     *                                  if any, to source the fulfiller's token
     *                                  approvals from. The zero hash signifies
     *                                  that no conduit should be used, with
     *                                  direct approvals set on this contract.
     * @param recipient                 The intended recipient for all received
     *                                  items, with `address(0)` indicating that
     *                                  the caller should receive the items.
     * @param maximumFulfilled          The maximum number of orders to fulfill.
     *
     * @return availableOrders An array of booleans indicating if each order
     *                         with an index corresponding to the index of the
     *                         returned boolean was fulfillable or not.
     * @return executions      An array of elements indicating the sequence of
     *                         transfers performed as part of matching the given
     *                         orders. Note that unspent offer item amounts or
     *                         native tokens will not be reflected as part of
     *                         this array.
     */
    function fulfillAvailableAdvancedOrders(
        AdvancedOrder[] calldata advancedOrders,
        CriteriaResolver[] calldata criteriaResolvers,
        FulfillmentComponent[][] calldata offerFulfillments,
        FulfillmentComponent[][] calldata considerationFulfillments,
        bytes32 fulfillerConduitKey,
        address recipient,
        uint256 maximumFulfilled
    )
        external
        payable
        returns (bool[] memory availableOrders, Execution[] memory executions);

    /**
     * @notice Match an arbitrary number of orders, each with an arbitrary
     *         number of items for offer and consideration along with a set of
     *         fulfillments allocating offer components to consideration
     *         components. Note that this function does not support
     *         criteria-based or partial filling of orders (though filling the
     *         remainder of a partially-filled order is supported). Any unspent
     *         offer item amounts or native tokens will be transferred to the
     *         caller.
     *
     * @param orders       The orders to match. Note that both the offerer and
     *                     fulfiller on each order must first approve this
     *                     contract (or their conduit if indicated by the order)
     *                     to transfer any relevant tokens on their behalf and
     *                     each consideration recipient must implement
     *                     `onERC1155Received` to enable ERC1155 token receipt.
     * @param fulfillments An array of elements allocating offer components to
     *                     consideration components. Note that each
     *                     consideration component must be fully met for the
     *                     match operation to be valid.
     *
     * @return executions An array of elements indicating the sequence of
     *                    transfers performed as part of matching the given
     *                    orders. Note that unspent offer item amounts or
     *                    native tokens will not be reflected as part of this
     *                    array.
     */
    function matchOrders(
        Order[] calldata orders,
        Fulfillment[] calldata fulfillments
    ) external payable returns (Execution[] memory executions);

    /**
     * @notice Match an arbitrary number of full or partial orders, each with an
     *         arbitrary number of items for offer and consideration, supplying
     *         criteria resolvers containing specific token identifiers and
     *         associated proofs as well as fulfillments allocating offer
     *         components to consideration components. Any unspent offer item
     *         amounts will be transferred to the designated recipient (with the
     *         null address signifying to use the caller) and any unspent native
     *         tokens will be returned to the caller.
     *
     * @param orders            The advanced orders to match. Note that both the
     *                          offerer and fulfiller on each order must first
     *                          approve this contract (or a preferred conduit if
     *                          indicated by the order) to transfer any relevant
     *                          tokens on their behalf and each consideration
     *                          recipient must implement `onERC1155Received` in
     *                          order to receive ERC1155 tokens. Also note that
     *                          the offer and consideration components for each
     *                          order must have no remainder after multiplying
     *                          the respective amount with the supplied fraction
     *                          in order for the group of partial fills to be
     *                          considered valid.
     * @param criteriaResolvers An array where each element contains a reference
     *                          to a specific order as well as that order's
     *                          offer or consideration, a token identifier, and
     *                          a proof that the supplied token identifier is
     *                          contained in the order's merkle root. Note that
     *                          an empty root indicates that any (transferable)
     *                          token identifier is valid and that no associated
     *                          proof needs to be supplied.
     * @param fulfillments      An array of elements allocating offer components
     *                          to consideration components. Note that each
     *                          consideration component must be fully met in
     *                          order for the match operation to be valid.
     * @param recipient         The intended recipient for all unspent offer
     *                          item amounts, or the caller if the null address
     *                          is supplied.
     *
     * @return executions An array of elements indicating the sequence of
     *                    transfers performed as part of matching the given
     *                    orders. Note that unspent offer item amounts or native
     *                    tokens will not be reflected as part of this array.
     */
    function matchAdvancedOrders(
        AdvancedOrder[] calldata orders,
        CriteriaResolver[] calldata criteriaResolvers,
        Fulfillment[] calldata fulfillments,
        address recipient
    ) external payable returns (Execution[] memory executions);

    /**
     * @notice Cancel an arbitrary number of orders. Note that only the offerer
     *         or the zone of a given order may cancel it. Callers should ensure
     *         that the intended order was cancelled by calling `getOrderStatus`
     *         and confirming that `isCancelled` returns `true`.
     *
     * @param orders The orders to cancel.
     *
     * @return cancelled A boolean indicating whether the supplied orders have
     *                   been successfully cancelled.
     */
    function cancel(
        OrderComponents[] calldata orders
    ) external returns (bool cancelled);

    /**
     * @notice Validate an arbitrary number of orders, thereby registering their
     *         signatures as valid and allowing the fulfiller to skip signature
     *         verification on fulfillment. Note that validated orders may still
     *         be unfulfillable due to invalid item amounts or other factors;
     *         callers should determine whether validated orders are fulfillable
     *         by simulating the fulfillment call prior to execution. Also note
     *         that anyone can validate a signed order, but only the offerer can
     *         validate an order without supplying a signature.
     *
     * @param orders The orders to validate.
     *
     * @return validated A boolean indicating whether the supplied orders have
     *                   been successfully validated.
     */
    function validate(
        Order[] calldata orders
    ) external returns (bool validated);

    /**
     * @notice Cancel all orders from a given offerer with a given zone in bulk
     *         by incrementing a counter. Note that only the offerer may
     *         increment the counter.
     *
     * @return newCounter The new counter.
     */
    function incrementCounter() external returns (uint256 newCounter);

    /**
     * @notice Fulfill an order offering an ERC721 token by supplying Ether (or
     *         the native token for the given chain) as consideration for the
     *         order. An arbitrary number of "additional recipients" may also be
     *         supplied which will each receive native tokens from the fulfiller
     *         as consideration. Note that this function costs less gas than
     *         `fulfillBasicOrder` due to the zero bytes in the function
     *         selector (0x00000000) which also results in earlier function
     *         dispatch.
     *
     * @param parameters Additional information on the fulfilled order. Note
     *                   that the offerer must first approve this contract (or
     *                   their preferred conduit if indicated by the order) for
     *                   their offered ERC721 token to be transferred.
     *
     * @return fulfilled A boolean indicating whether the order has been
     *                   successfully fulfilled.
     */
    function fulfillBasicOrder_efficient_6GL6yc(
        BasicOrderParameters calldata parameters
    ) external payable returns (bool fulfilled);

    /**
     * @notice Retrieve the order hash for a given order.
     *
     * @param order The components of the order.
     *
     * @return orderHash The order hash.
     */
    function getOrderHash(
        OrderComponents calldata order
    ) external view returns (bytes32 orderHash);

    /**
     * @notice Retrieve the status of a given order by hash, including whether
     *         the order has been cancelled or validated and the fraction of the
     *         order that has been filled.
     *
     * @param orderHash The order hash in question.
     *
     * @return isValidated A boolean indicating whether the order in question
     *                     has been validated (i.e. previously approved or
     *                     partially filled).
     * @return isCancelled A boolean indicating whether the order in question
     *                     has been cancelled.
     * @return totalFilled The total portion of the order that has been filled
     *                     (i.e. the "numerator").
     * @return totalSize   The total size of the order that is either filled or
     *                     unfilled (i.e. the "denominator").
     */
    function getOrderStatus(
        bytes32 orderHash
    )
        external
        view
        returns (
            bool isValidated,
            bool isCancelled,
            uint256 totalFilled,
            uint256 totalSize
        );

    /**
     * @notice Retrieve the current counter for a given offerer.
     *
     * @param offerer The offerer in question.
     *
     * @return counter The current counter.
     */
    function getCounter(
        address offerer
    ) external view returns (uint256 counter);

    /**
     * @notice Retrieve configuration information for this contract.
     *
     * @return version           The contract version.
     * @return domainSeparator   The domain separator for this contract.
     * @return conduitController The conduit Controller set for this contract.
     */
    function information()
        external
        view
        returns (
            string memory version,
            bytes32 domainSeparator,
            address conduitController
        );

    function getContractOffererNonce(
        address contractOfferer
    ) external view returns (uint256 nonce);

    /**
     * @notice Retrieve the name of this contract.
     *
     * @return contractName The name of this contract.
     */
    function name() external view returns (string memory contractName);
}

File 12 of 43 : ReferenceAmountDeriver.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import {
    AmountDerivationErrors
} from "seaport-types/src/interfaces/AmountDerivationErrors.sol";

import { FractionData } from "./ReferenceConsiderationStructs.sol";

/**
 * @title ReferenceAmountDeriver
 * @author 0age
 * @notice ReferenceAmountDeriver contains view and pure functions related to
 *         deriving item amounts based on partial fill quantity and on linear
 *         interpolation based on current time when the start amount and end
 *         amount differ.
 */
contract ReferenceAmountDeriver is AmountDerivationErrors {
    /**
     * @dev Internal view function to derive the current amount of a given item
     *      based on the current price, the starting price, and the ending
     *      price. If the start and end prices differ, the current price will be
     *      interpolated on a linear basis.
     *
     * @param startAmount The starting amount of the item.
     * @param endAmount   The ending amount of the item.
     * @param startTime   The starting time of the order.
     * @param endTime     The end time of the order.
     * @param roundUp     A boolean indicating whether the resultant amount
     *                    should be rounded up or down.
     *
     * @return The current amount.
     */
    function _locateCurrentAmount(
        uint256 startAmount,
        uint256 endAmount,
        uint256 startTime,
        uint256 endTime,
        bool roundUp
    ) internal view returns (uint256) {
        // Only modify end amount if it doesn't already equal start amount.
        if (startAmount != endAmount) {
            // Leave extra amount to add for rounding at zero (i.e. round down).
            uint256 extraCeiling = 0;

            // Derive the duration for the order and place it on the stack.
            uint256 duration = endTime - startTime;

            // Derive time elapsed since the order started & place on stack.
            uint256 elapsed = block.timestamp - startTime;

            // Derive time remaining until order expires and place on stack.
            uint256 remaining = duration - elapsed;

            // If rounding up, set rounding factor to one less than denominator.
            if (roundUp) {
                extraCeiling = duration - 1;
            }

            // Aggregate new amounts weighted by time with rounding factor.
            uint256 totalBeforeDivision = ((startAmount * remaining) +
                (endAmount * elapsed) +
                extraCeiling);

            // Divide totalBeforeDivision by duration to get the new amount.
            uint256 newAmount = totalBeforeDivision / duration;

            // Return the current amount.
            return newAmount;
        }

        // Return the original amount.
        return endAmount;
    }

    /**
     * @dev Internal pure function to return a fraction of a given value and to
     *      ensure the resultant value does not have any fractional component.
     *
     * @param numerator   A value indicating the portion of the order that
     *                    should be filled.
     * @param denominator A value indicating the total size of the order.
     * @param value       The value for which to compute the fraction.
     *
     * @return newValue The value after applying the fraction.
     */
    function _getFraction(
        uint256 numerator,
        uint256 denominator,
        uint256 value
    ) internal pure returns (uint256 newValue) {
        // Return value early in cases where the fraction resolves to 1.
        if (numerator == denominator) {
            return value;
        }

        // Multiply the numerator by the value and ensure no overflow occurs.
        uint256 valueTimesNumerator = value * numerator;

        // Divide that value by the denominator to get the new value.
        newValue = valueTimesNumerator / denominator;

        // Ensure that division gave a final result with no remainder.
        bool exact = ((newValue * denominator) / numerator) == value;
        if (!exact) {
            revert InexactFraction();
        }
    }

    /**
     * @dev Internal view function to apply a fraction to a consideration
     * or offer item.
     *
     * @param startAmount     The starting amount of the item.
     * @param endAmount       The ending amount of the item.
     * @param fractionData    A struct containing the data used to apply a
     *                        fraction to an order.
     * @param roundUp         A boolean indicating whether the resultant
     *                        amount should be rounded up or down.
     *
     * @return amount The received item to transfer with the final amount.
     */
    function _applyFraction(
        uint256 startAmount,
        uint256 endAmount,
        FractionData memory fractionData,
        bool roundUp
    ) internal view returns (uint256 amount) {
        // If start amount equals end amount, apply fraction to end amount.
        if (startAmount == endAmount) {
            amount = _getFraction(
                fractionData.numerator,
                fractionData.denominator,
                endAmount
            );
        } else {
            // Otherwise, apply fraction to both to interpolated final amount.
            amount = _locateCurrentAmount(
                _getFraction(
                    fractionData.numerator,
                    fractionData.denominator,
                    startAmount
                ),
                _getFraction(
                    fractionData.numerator,
                    fractionData.denominator,
                    endAmount
                ),
                fractionData.startTime,
                fractionData.endTime,
                roundUp
            );
        }
    }
}

File 13 of 43 : FulfillmentApplicationErrors.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import { Side } from "../lib/ConsiderationEnums.sol";

/**
 * @title FulfillmentApplicationErrors
 * @author 0age
 * @notice FulfillmentApplicationErrors contains errors related to fulfillment
 *         application and aggregation.
 */
interface FulfillmentApplicationErrors {
    /**
     * @dev Revert with an error when a fulfillment is provided that does not
     *      declare at least one component as part of a call to fulfill
     *      available orders.
     */
    error MissingFulfillmentComponentOnAggregation(Side side);

    /**
     * @dev Revert with an error when a fulfillment is provided that does not
     *      declare at least one offer component and at least one consideration
     *      component.
     */
    error OfferAndConsiderationRequiredOnFulfillment();

    /**
     * @dev Revert with an error when the initial offer item named by a
     *      fulfillment component does not match the type, token, identifier,
     *      or conduit preference of the initial consideration item.
     *
     * @param fulfillmentIndex The index of the fulfillment component that
     *                         does not match the initial offer item.
     */
    error MismatchedFulfillmentOfferAndConsiderationComponents(
        uint256 fulfillmentIndex
    );

    /**
     * @dev Revert with an error when an order or item index are out of range
     *      or a fulfillment component does not match the type, token,
     *      identifier, or conduit preference of the initial consideration item.
     */
    error InvalidFulfillmentComponentData();
}

File 14 of 43 : ReferenceBasicOrderFulfiller.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import {
    BasicOrderRouteType,
    BasicOrderType,
    ItemType,
    OrderType
} from "seaport-types/src/lib/ConsiderationEnums.sol";

import {
    AdditionalRecipient,
    BasicOrderParameters,
    ConsiderationItem,
    OfferItem,
    ReceivedItem,
    SpentItem
} from "seaport-types/src/lib/ConsiderationStructs.sol";

import {
    AccumulatorStruct,
    BasicFulfillmentHashes,
    FulfillmentItemTypes
} from "./ReferenceConsiderationStructs.sol";

import { ReferenceOrderValidator } from "./ReferenceOrderValidator.sol";

/**
 * @title BasicOrderFulfiller
 * @author 0age
 * @notice BasicOrderFulfiller contains functionality for fulfilling "basic"
 *         orders.
 */
contract ReferenceBasicOrderFulfiller is ReferenceOrderValidator {
    // Map BasicOrderType to BasicOrderRouteType
    mapping(BasicOrderType => BasicOrderRouteType) internal _OrderToRouteType;
    // Map BasicOrderType to OrderType
    mapping(BasicOrderType => OrderType) internal _BasicOrderToOrderType;

    /**
     * @dev Derive and set hashes, reference chainId, and associated domain
     *      separator during deployment.
     *
     * @param conduitController A contract that deploys conduits, or proxies
     *                          that may optionally be used to transfer approved
     *                          ERC20/721/1155 tokens.
     */
    constructor(
        address conduitController
    ) ReferenceOrderValidator(conduitController) {
        createMappings();
    }

    /**
     * @dev Creates a mapping of BasicOrderType Enums to BasicOrderRouteType
     *      Enums and BasicOrderType Enums to OrderType Enums. Note that this
     *      is wildly inefficient, but makes the logic easier to follow when
     *      performing the fulfillment.
     */
    function createMappings() internal {
        // BasicOrderType to BasicOrderRouteType

        // ETH TO ERC 721
        _OrderToRouteType[
            BasicOrderType.ETH_TO_ERC721_FULL_OPEN
        ] = BasicOrderRouteType.ETH_TO_ERC721;
        _OrderToRouteType[
            BasicOrderType.ETH_TO_ERC721_PARTIAL_OPEN
        ] = BasicOrderRouteType.ETH_TO_ERC721;
        _OrderToRouteType[
            BasicOrderType.ETH_TO_ERC721_FULL_RESTRICTED
        ] = BasicOrderRouteType.ETH_TO_ERC721;
        _OrderToRouteType[
            BasicOrderType.ETH_TO_ERC721_PARTIAL_RESTRICTED
        ] = BasicOrderRouteType.ETH_TO_ERC721;

        // ETH TO ERC 1155
        _OrderToRouteType[
            BasicOrderType.ETH_TO_ERC1155_FULL_OPEN
        ] = BasicOrderRouteType.ETH_TO_ERC1155;
        _OrderToRouteType[
            BasicOrderType.ETH_TO_ERC1155_PARTIAL_OPEN
        ] = BasicOrderRouteType.ETH_TO_ERC1155;
        _OrderToRouteType[
            BasicOrderType.ETH_TO_ERC1155_FULL_RESTRICTED
        ] = BasicOrderRouteType.ETH_TO_ERC1155;
        _OrderToRouteType[
            BasicOrderType.ETH_TO_ERC1155_PARTIAL_RESTRICTED
        ] = BasicOrderRouteType.ETH_TO_ERC1155;

        // ERC 20 TO ERC 721
        _OrderToRouteType[
            BasicOrderType.ERC20_TO_ERC721_FULL_OPEN
        ] = BasicOrderRouteType.ERC20_TO_ERC721;
        _OrderToRouteType[
            BasicOrderType.ERC20_TO_ERC721_PARTIAL_OPEN
        ] = BasicOrderRouteType.ERC20_TO_ERC721;
        _OrderToRouteType[
            BasicOrderType.ERC20_TO_ERC721_FULL_RESTRICTED
        ] = BasicOrderRouteType.ERC20_TO_ERC721;
        _OrderToRouteType[
            BasicOrderType.ERC20_TO_ERC721_PARTIAL_RESTRICTED
        ] = BasicOrderRouteType.ERC20_TO_ERC721;

        // ERC 20 TO ERC 1155
        _OrderToRouteType[
            BasicOrderType.ERC20_TO_ERC1155_FULL_OPEN
        ] = BasicOrderRouteType.ERC20_TO_ERC1155;
        _OrderToRouteType[
            BasicOrderType.ERC20_TO_ERC1155_PARTIAL_OPEN
        ] = BasicOrderRouteType.ERC20_TO_ERC1155;
        _OrderToRouteType[
            BasicOrderType.ERC20_TO_ERC1155_FULL_RESTRICTED
        ] = BasicOrderRouteType.ERC20_TO_ERC1155;
        _OrderToRouteType[
            BasicOrderType.ERC20_TO_ERC1155_PARTIAL_RESTRICTED
        ] = BasicOrderRouteType.ERC20_TO_ERC1155;

        // ERC 721 TO ERC 20
        _OrderToRouteType[
            BasicOrderType.ERC721_TO_ERC20_FULL_OPEN
        ] = BasicOrderRouteType.ERC721_TO_ERC20;
        _OrderToRouteType[
            BasicOrderType.ERC721_TO_ERC20_PARTIAL_OPEN
        ] = BasicOrderRouteType.ERC721_TO_ERC20;
        _OrderToRouteType[
            BasicOrderType.ERC721_TO_ERC20_FULL_RESTRICTED
        ] = BasicOrderRouteType.ERC721_TO_ERC20;
        _OrderToRouteType[
            BasicOrderType.ERC721_TO_ERC20_PARTIAL_RESTRICTED
        ] = BasicOrderRouteType.ERC721_TO_ERC20;

        // ERC 1155 TO ERC 20
        _OrderToRouteType[
            BasicOrderType.ERC1155_TO_ERC20_FULL_OPEN
        ] = BasicOrderRouteType.ERC1155_TO_ERC20;
        _OrderToRouteType[
            BasicOrderType.ERC1155_TO_ERC20_PARTIAL_OPEN
        ] = BasicOrderRouteType.ERC1155_TO_ERC20;
        _OrderToRouteType[
            BasicOrderType.ERC1155_TO_ERC20_FULL_RESTRICTED
        ] = BasicOrderRouteType.ERC1155_TO_ERC20;
        _OrderToRouteType[
            BasicOrderType.ERC1155_TO_ERC20_PARTIAL_RESTRICTED
        ] = BasicOrderRouteType.ERC1155_TO_ERC20;

        // Basic OrderType to OrderType

        // FULL OPEN
        _BasicOrderToOrderType[
            BasicOrderType.ETH_TO_ERC721_FULL_OPEN
        ] = OrderType.FULL_OPEN;
        _BasicOrderToOrderType[
            BasicOrderType.ETH_TO_ERC1155_FULL_OPEN
        ] = OrderType.FULL_OPEN;
        _BasicOrderToOrderType[
            BasicOrderType.ERC20_TO_ERC721_FULL_OPEN
        ] = OrderType.FULL_OPEN;
        _BasicOrderToOrderType[
            BasicOrderType.ERC20_TO_ERC1155_FULL_OPEN
        ] = OrderType.FULL_OPEN;
        _BasicOrderToOrderType[
            BasicOrderType.ERC721_TO_ERC20_FULL_OPEN
        ] = OrderType.FULL_OPEN;
        _BasicOrderToOrderType[
            BasicOrderType.ERC1155_TO_ERC20_FULL_OPEN
        ] = OrderType.FULL_OPEN;

        // PARTIAL OPEN
        _BasicOrderToOrderType[
            BasicOrderType.ETH_TO_ERC721_PARTIAL_OPEN
        ] = OrderType.PARTIAL_OPEN;
        _BasicOrderToOrderType[
            BasicOrderType.ETH_TO_ERC1155_PARTIAL_OPEN
        ] = OrderType.PARTIAL_OPEN;
        _BasicOrderToOrderType[
            BasicOrderType.ERC20_TO_ERC721_PARTIAL_OPEN
        ] = OrderType.PARTIAL_OPEN;
        _BasicOrderToOrderType[
            BasicOrderType.ERC20_TO_ERC1155_PARTIAL_OPEN
        ] = OrderType.PARTIAL_OPEN;
        _BasicOrderToOrderType[
            BasicOrderType.ERC721_TO_ERC20_PARTIAL_OPEN
        ] = OrderType.PARTIAL_OPEN;
        _BasicOrderToOrderType[
            BasicOrderType.ERC1155_TO_ERC20_PARTIAL_OPEN
        ] = OrderType.PARTIAL_OPEN;

        // FULL RESTRICTED
        _BasicOrderToOrderType[
            BasicOrderType.ETH_TO_ERC721_FULL_RESTRICTED
        ] = OrderType.FULL_RESTRICTED;
        _BasicOrderToOrderType[
            BasicOrderType.ETH_TO_ERC1155_FULL_RESTRICTED
        ] = OrderType.FULL_RESTRICTED;
        _BasicOrderToOrderType[
            BasicOrderType.ERC20_TO_ERC721_FULL_RESTRICTED
        ] = OrderType.FULL_RESTRICTED;
        _BasicOrderToOrderType[
            BasicOrderType.ERC20_TO_ERC1155_FULL_RESTRICTED
        ] = OrderType.FULL_RESTRICTED;
        _BasicOrderToOrderType[
            BasicOrderType.ERC721_TO_ERC20_FULL_RESTRICTED
        ] = OrderType.FULL_RESTRICTED;
        _BasicOrderToOrderType[
            BasicOrderType.ERC1155_TO_ERC20_FULL_RESTRICTED
        ] = OrderType.FULL_RESTRICTED;

        // PARTIAL RESTRICTED
        _BasicOrderToOrderType[
            BasicOrderType.ETH_TO_ERC721_PARTIAL_RESTRICTED
        ] = OrderType.PARTIAL_RESTRICTED;
        _BasicOrderToOrderType[
            BasicOrderType.ETH_TO_ERC1155_PARTIAL_RESTRICTED
        ] = OrderType.PARTIAL_RESTRICTED;
        _BasicOrderToOrderType[
            BasicOrderType.ERC20_TO_ERC721_PARTIAL_RESTRICTED
        ] = OrderType.PARTIAL_RESTRICTED;
        _BasicOrderToOrderType[
            BasicOrderType.ERC20_TO_ERC1155_PARTIAL_RESTRICTED
        ] = OrderType.PARTIAL_RESTRICTED;
        _BasicOrderToOrderType[
            BasicOrderType.ERC721_TO_ERC20_PARTIAL_RESTRICTED
        ] = OrderType.PARTIAL_RESTRICTED;
        _BasicOrderToOrderType[
            BasicOrderType.ERC1155_TO_ERC20_PARTIAL_RESTRICTED
        ] = OrderType.PARTIAL_RESTRICTED;
    }

    /**
     * @dev Internal function to fulfill an order offering an ERC20, ERC721, or
     *      ERC1155 item by supplying Ether (or other native tokens), ERC20
     *      tokens, an ERC721 item, or an ERC1155 item as consideration. Six
     *      permutations are supported: Native token to ERC721, Native token to
     *      ERC1155, ERC20 to ERC721, ERC20 to ERC1155, ERC721 to ERC20, and
     *      ERC1155 to ERC20 (with native tokens supplied as msg.value). For an
     *      order to be eligible for fulfillment via this method, it must
     *      contain a single offer item (though that item may have a greater
     *      amount if the item is not an ERC721). An arbitrary number of
     *      "additional recipients" may also be supplied which will each receive
     *      native tokens or ERC20 items from the fulfiller as consideration.
     *      Refer to the documentation for a more comprehensive summary of how
     *      to utilize with this method and what orders are compatible with it.
     *
     * @param parameters Additional information on the fulfilled order. Note
     *                   that the offerer and the fulfiller must first approve
     *                   this contract (or their chosen conduit if indicated)
     *                   before any tokens can be transferred. Also note that
     *                   contract recipients of ERC1155 consideration items must
     *                   implement `onERC1155Received` in order to receive those
     *                   items.
     *
     * @return A boolean indicating whether the order has been fulfilled.
     */
    function _validateAndFulfillBasicOrder(
        BasicOrderParameters calldata parameters
    ) internal returns (bool) {
        // Determine the basic order route type from the basic order type.
        BasicOrderRouteType route;
        {
            BasicOrderType basicType = parameters.basicOrderType;
            route = _OrderToRouteType[basicType];
        }

        // Determine the order type from the basic order type.
        OrderType orderType;
        {
            BasicOrderType basicType = parameters.basicOrderType;
            orderType = _BasicOrderToOrderType[basicType];
        }

        // Declare additional recipient item type to derive from the route type.
        ItemType additionalRecipientsItemType;
        if (
            route == BasicOrderRouteType.ETH_TO_ERC721 ||
            route == BasicOrderRouteType.ETH_TO_ERC1155
        ) {
            additionalRecipientsItemType = ItemType.NATIVE;
        } else {
            additionalRecipientsItemType = ItemType.ERC20;
        }

        // Revert if msg.value was not supplied as part of a payable route.
        if (msg.value == 0 && additionalRecipientsItemType == ItemType.NATIVE) {
            revert InvalidMsgValue(msg.value);
        }

        // Revert if msg.value was supplied as part of a non-payable route.
        if (msg.value != 0 && additionalRecipientsItemType == ItemType.ERC20) {
            revert InvalidMsgValue(msg.value);
        }

        // Determine the token that additional recipients should have set.
        address additionalRecipientsToken;
        if (
            route == BasicOrderRouteType.ERC721_TO_ERC20 ||
            route == BasicOrderRouteType.ERC1155_TO_ERC20
        ) {
            additionalRecipientsToken = parameters.offerToken;
        } else {
            additionalRecipientsToken = parameters.considerationToken;
        }

        // Determine the item type for received items.
        ItemType receivedItemType;
        if (
            route == BasicOrderRouteType.ETH_TO_ERC721 ||
            route == BasicOrderRouteType.ETH_TO_ERC1155
        ) {
            receivedItemType = ItemType.NATIVE;
        } else if (
            route == BasicOrderRouteType.ERC20_TO_ERC721 ||
            route == BasicOrderRouteType.ERC20_TO_ERC1155
        ) {
            receivedItemType = ItemType.ERC20;
        } else if (route == BasicOrderRouteType.ERC721_TO_ERC20) {
            receivedItemType = ItemType.ERC721;
        } else {
            receivedItemType = ItemType.ERC1155;
        }

        // Determine the item type for the offered item.
        ItemType offeredItemType;
        if (
            route == BasicOrderRouteType.ERC721_TO_ERC20 ||
            route == BasicOrderRouteType.ERC1155_TO_ERC20
        ) {
            offeredItemType = ItemType.ERC20;
        } else if (
            route == BasicOrderRouteType.ETH_TO_ERC721 ||
            route == BasicOrderRouteType.ERC20_TO_ERC721
        ) {
            offeredItemType = ItemType.ERC721;
        } else {
            offeredItemType = ItemType.ERC1155;
        }

        // Derive & validate order using parameters and update order status.
        bytes32 orderHash = _prepareBasicFulfillment(
            parameters,
            orderType,
            receivedItemType,
            additionalRecipientsItemType,
            additionalRecipientsToken,
            offeredItemType
        );

        // Determine conduitKey argument used by transfer functions.
        bytes32 conduitKey;
        if (
            route == BasicOrderRouteType.ERC721_TO_ERC20 ||
            route == BasicOrderRouteType.ERC1155_TO_ERC20
        ) {
            conduitKey = parameters.fulfillerConduitKey;
        } else {
            conduitKey = parameters.offererConduitKey;
        }

        // Check for dirtied unused parameters.
        if (
            ((route == BasicOrderRouteType.ETH_TO_ERC721 ||
                route == BasicOrderRouteType.ETH_TO_ERC1155) &&
                (uint160(parameters.considerationToken) |
                    parameters.considerationIdentifier) !=
                0) ||
            ((route == BasicOrderRouteType.ERC20_TO_ERC721 ||
                route == BasicOrderRouteType.ERC20_TO_ERC1155) &&
                parameters.considerationIdentifier != 0) ||
            ((route == BasicOrderRouteType.ERC721_TO_ERC20 ||
                route == BasicOrderRouteType.ERC1155_TO_ERC20) &&
                parameters.offerIdentifier != 0)
        ) {
            revert UnusedItemParameters();
        }

        // Declare transfer accumulator that will collect transfers that can be
        // bundled into a single call to their associated conduit.
        AccumulatorStruct memory accumulatorStruct;

        // Transfer tokens based on the route.
        if (route == BasicOrderRouteType.ETH_TO_ERC721) {
            // Transfer ERC721 to caller using offerer's conduit if applicable.
            _transferERC721(
                parameters.offerToken,
                parameters.offerer,
                msg.sender,
                parameters.offerIdentifier,
                parameters.offerAmount,
                conduitKey,
                accumulatorStruct
            );

            // Transfer native to recipients, return excess to caller & wrap up.
            _transferEthAndFinalize(parameters.considerationAmount, parameters);
        } else if (route == BasicOrderRouteType.ETH_TO_ERC1155) {
            // Transfer ERC1155 to caller using offerer's conduit if applicable.
            _transferERC1155(
                parameters.offerToken,
                parameters.offerer,
                msg.sender,
                parameters.offerIdentifier,
                parameters.offerAmount,
                conduitKey,
                accumulatorStruct
            );

            // Transfer native to recipients, return excess to caller & wrap up.
            _transferEthAndFinalize(parameters.considerationAmount, parameters);
        } else if (route == BasicOrderRouteType.ERC20_TO_ERC721) {
            // Transfer ERC721 to caller using offerer's conduit if applicable.
            _transferERC721(
                parameters.offerToken,
                parameters.offerer,
                msg.sender,
                parameters.offerIdentifier,
                parameters.offerAmount,
                conduitKey,
                accumulatorStruct
            );

            // Transfer ERC20 tokens to all recipients and wrap up.
            _transferERC20AndFinalize(
                msg.sender,
                parameters.offerer,
                parameters.considerationToken,
                parameters.considerationAmount,
                parameters,
                false, // Send full amount indicated by all consideration items.
                accumulatorStruct
            );
        } else if (route == BasicOrderRouteType.ERC20_TO_ERC1155) {
            // Transfer ERC1155 to caller using offerer's conduit if applicable.
            _transferERC1155(
                parameters.offerToken,
                parameters.offerer,
                msg.sender,
                parameters.offerIdentifier,
                parameters.offerAmount,
                conduitKey,
                accumulatorStruct
            );

            // Transfer ERC20 tokens to all recipients and wrap up.
            _transferERC20AndFinalize(
                msg.sender,
                parameters.offerer,
                parameters.considerationToken,
                parameters.considerationAmount,
                parameters,
                false, // Send full amount indicated by all consideration items.
                accumulatorStruct
            );
        } else if (route == BasicOrderRouteType.ERC721_TO_ERC20) {
            // Transfer ERC721 to offerer using caller's conduit if applicable.
            _transferERC721(
                parameters.considerationToken,
                msg.sender,
                parameters.offerer,
                parameters.considerationIdentifier,
                parameters.considerationAmount,
                conduitKey,
                accumulatorStruct
            );

            // Transfer ERC20 tokens to all recipients and wrap up.
            _transferERC20AndFinalize(
                parameters.offerer,
                msg.sender,
                parameters.offerToken,
                parameters.offerAmount,
                parameters,
                true, // Reduce amount sent to fulfiller by additional amounts.
                accumulatorStruct
            );
        } else {
            // route == BasicOrderRouteType.ERC1155_TO_ERC20

            // Transfer ERC1155 to offerer using caller's conduit if applicable.
            _transferERC1155(
                parameters.considerationToken,
                msg.sender,
                parameters.offerer,
                parameters.considerationIdentifier,
                parameters.considerationAmount,
                conduitKey,
                accumulatorStruct
            );

            // Transfer ERC20 tokens to all recipients and wrap up.
            _transferERC20AndFinalize(
                parameters.offerer,
                msg.sender,
                parameters.offerToken,
                parameters.offerAmount,
                parameters,
                true, // Reduce amount sent to fulfiller by additional amounts.
                accumulatorStruct
            );
        }

        // Trigger any remaining accumulated transfers via call to the conduit.
        _triggerIfArmed(accumulatorStruct);

        // Determine whether order is restricted and, if so, that it is valid.
        _assertRestrictedBasicOrderValidity(
            orderHash,
            orderType,
            parameters,
            offeredItemType,
            receivedItemType
        );

        return true;
    }

    /**
     * @dev Internal function to calculate the order hash.
     *
     * @param hashes               The array of offerItems and receivedItems
     *                             hashes.
     * @param parameters           The parameters of the basic order.
     * @param fulfillmentItemTypes The fulfillment's item type.
     *
     * @return orderHash           The order hash.
     */
    function _hashOrder(
        BasicFulfillmentHashes memory hashes,
        BasicOrderParameters calldata parameters,
        FulfillmentItemTypes memory fulfillmentItemTypes
    ) internal view returns (bytes32 orderHash) {
        // Read offerer's current counter from storage and place on the stack.
        uint256 counter = _getCounter(parameters.offerer);

        // Hash the contents to get the orderHash
        orderHash = keccak256(
            abi.encode(
                hashes.typeHash,
                parameters.offerer,
                parameters.zone,
                hashes.offerItemsHash,
                hashes.receivedItemsHash,
                fulfillmentItemTypes.orderType,
                parameters.startTime,
                parameters.endTime,
                parameters.zoneHash,
                parameters.salt,
                parameters.offererConduitKey,
                counter
            )
        );
    }

    /**
     * @dev Internal function to prepare fulfillment of a basic order. This
     *      calculates the order hash, emits an OrderFulfilled event, and
     *      asserts basic order validity.
     *
     * @param parameters                   The parameters of the basic order.
     * @param orderType                    The order type.
     * @param receivedItemType             The item type of the initial
     *                                     consideration item on the order.
     * @param additionalRecipientsItemType The item type of any additional
     *                                     consideration item on the order.
     * @param additionalRecipientsToken    The ERC20 token contract address (if
     *                                     applicable) for any additional
     *                                     consideration item on the order.
     * @param offeredItemType              The item type of the offered item on
     *                                     the order.
     *
     * @return orderHash                   The calculated order hash.
     */
    function _prepareBasicFulfillment(
        BasicOrderParameters calldata parameters,
        OrderType orderType,
        ItemType receivedItemType,
        ItemType additionalRecipientsItemType,
        address additionalRecipientsToken,
        ItemType offeredItemType
    ) internal returns (bytes32 orderHash) {
        // Ensure current timestamp falls between order start time and end time.
        _verifyTime(parameters.startTime, parameters.endTime, true);

        // Verify that calldata offsets for all dynamic types were produced by
        // default encoding. This is only required on the optimized contract,
        // but is included here to maintain parity.
        _assertValidBasicOrderParameters();

        // Ensure supplied consideration array length is not less than original.
        _assertConsiderationLengthIsNotLessThanOriginalConsiderationLength(
            parameters.additionalRecipients.length,
            parameters.totalOriginalAdditionalRecipients
        );

        // Memory to store hashes.
        BasicFulfillmentHashes memory hashes;

        // Store ItemType/Token parameters in a struct in memory to avoid stack
        // issues.
        FulfillmentItemTypes memory fulfillmentItemTypes = FulfillmentItemTypes(
            orderType,
            receivedItemType,
            additionalRecipientsItemType,
            additionalRecipientsToken,
            offeredItemType
        );

        // Array of Received Items for use with OrderFulfilled event.
        ReceivedItem[] memory consideration = new ReceivedItem[](
            parameters.additionalRecipients.length + 1
        );

        {
            // Load consideration item typehash from runtime and place on stack.
            hashes.typeHash = _CONSIDERATION_ITEM_TYPEHASH;

            // Create Consideration item.
            ConsiderationItem memory primaryConsiderationItem = (
                ConsiderationItem(
                    fulfillmentItemTypes.receivedItemType,
                    parameters.considerationToken,
                    parameters.considerationIdentifier,
                    parameters.considerationAmount,
                    parameters.considerationAmount,
                    parameters.offerer
                )
            );

            // Array of all consideration item hashes.
            hashes.considerationHashes = new bytes32[](
                parameters.totalOriginalAdditionalRecipients + 1
            );

            // Hash contents.
            hashes.considerationHashes[0] = keccak256(
                abi.encode(
                    hashes.typeHash,
                    primaryConsiderationItem.itemType,
                    primaryConsiderationItem.token,
                    primaryConsiderationItem.identifierOrCriteria,
                    primaryConsiderationItem.startAmount,
                    primaryConsiderationItem.endAmount,
                    primaryConsiderationItem.recipient
                )
            );

            // Declare memory for additionalReceivedItem and
            // additionalRecipientItem.
            ReceivedItem memory additionalReceivedItem;
            ConsiderationItem memory additionalRecipientItem;

            // Create Received item.
            ReceivedItem memory primaryReceivedItem = ReceivedItem(
                fulfillmentItemTypes.receivedItemType,
                primaryConsiderationItem.token,
                primaryConsiderationItem.identifierOrCriteria,
                primaryConsiderationItem.endAmount,
                primaryConsiderationItem.recipient
            );
            // Add the Received item to the
            // OrderFulfilled ReceivedItem[].
            consideration[0] = primaryReceivedItem;

            /**  Loop through all additionalRecipients, to generate
             *    ReceivedItems for OrderFulfilled Event and
             *    ConsiderationItems for hashing.
             */
            for (
                uint256 recipientCount = 0;
                recipientCount < parameters.totalOriginalAdditionalRecipients;
                ++recipientCount
            ) {
                // Get the next additionalRecipient.
                AdditionalRecipient memory additionalRecipient = (
                    parameters.additionalRecipients[recipientCount]
                );

                // Create a Received item for each additional recipients.
                additionalReceivedItem = ReceivedItem(
                    fulfillmentItemTypes.additionalRecipientsItemType,
                    fulfillmentItemTypes.additionalRecipientsToken,
                    0,
                    additionalRecipient.amount,
                    additionalRecipient.recipient
                );
                // Add additional Received items to the
                // OrderFulfilled ReceivedItem[].
                consideration[recipientCount + 1] = additionalReceivedItem;

                // Create a new consideration item for each additional
                // recipient.
                additionalRecipientItem = ConsiderationItem(
                    fulfillmentItemTypes.additionalRecipientsItemType,
                    fulfillmentItemTypes.additionalRecipientsToken,
                    0,
                    additionalRecipient.amount,
                    additionalRecipient.amount,
                    additionalRecipient.recipient
                );

                // Calculate the EIP712 ConsiderationItem hash for
                // each additional recipients.
                hashes.considerationHashes[recipientCount + 1] = keccak256(
                    abi.encode(
                        hashes.typeHash,
                        additionalRecipientItem.itemType,
                        additionalRecipientItem.token,
                        additionalRecipientItem.identifierOrCriteria,
                        additionalRecipientItem.startAmount,
                        additionalRecipientItem.endAmount,
                        additionalRecipientItem.recipient
                    )
                );
            }

            /**
             *  The considerationHashes array now contains
             *  all consideration Item hashes.
             *
             *  The consideration array now contains all received
             *  items excluding tips for OrderFulfilled Event.
             */

            // Get hash of all consideration items.
            hashes.receivedItemsHash = keccak256(
                abi.encodePacked(hashes.considerationHashes)
            );

            // Get remainder of additionalRecipients for tips.
            for (
                uint256 additionalTips = parameters
                    .totalOriginalAdditionalRecipients;
                additionalTips < parameters.additionalRecipients.length;
                ++additionalTips
            ) {
                // Get the next additionalRecipient.
                AdditionalRecipient memory additionalRecipient = (
                    parameters.additionalRecipients[additionalTips]
                );

                // Create the ReceivedItem.
                additionalReceivedItem = ReceivedItem(
                    fulfillmentItemTypes.additionalRecipientsItemType,
                    fulfillmentItemTypes.additionalRecipientsToken,
                    0,
                    additionalRecipient.amount,
                    additionalRecipient.recipient
                );
                // Add additional received items to the
                // OrderFulfilled ReceivedItem[].
                consideration[additionalTips + 1] = additionalReceivedItem;
            }
        }
        // Now let's handle the offer side.

        // Write the offer to the Event SpentItem array.
        SpentItem[] memory offer = new SpentItem[](1);

        {
            // Place offer item typehash on the stack.
            hashes.typeHash = _OFFER_ITEM_TYPEHASH;

            // Create Spent item.
            SpentItem memory offerItem = SpentItem(
                fulfillmentItemTypes.offeredItemType,
                parameters.offerToken,
                parameters.offerIdentifier,
                parameters.offerAmount
            );
            // Add the offer item to the SpentItem array.
            offer[0] = offerItem;

            // Get the hash of the Spent item, treated as an Offer item.
            bytes32[1] memory offerItemHashes = [
                keccak256(
                    abi.encode(
                        hashes.typeHash,
                        offerItem.itemType,
                        offerItem.token,
                        offerItem.identifier,
                        offerItem.amount,
                        // Assembly uses OfferItem instead of SpentItem.
                        offerItem.amount
                    )
                )
            ];

            // Get hash of all Spent items.
            hashes.offerItemsHash = keccak256(
                abi.encodePacked(offerItemHashes)
            );
        }

        {
            // Create the OrderComponent in order to derive
            // the orderHash.

            // Load order typehash from runtime code and place on stack.
            hashes.typeHash = _ORDER_TYPEHASH;

            // Derive the order hash.
            hashes.orderHash = _hashOrder(
                hashes,
                parameters,
                fulfillmentItemTypes
            );

            // Emit an event signifying that the order has been fulfilled.
            emit OrderFulfilled(
                hashes.orderHash,
                parameters.offerer,
                parameters.zone,
                msg.sender,
                offer,
                consideration
            );
        }

        // Determine whether order is restricted and, if so, that it is valid.
        _assertRestrictedBasicOrderAuthorization(
            hashes.orderHash,
            orderType,
            parameters,
            offeredItemType,
            receivedItemType
        );

        // Verify and update the status of the derived order.
        _validateBasicOrderAndUpdateStatus(
            hashes.orderHash,
            parameters.offerer,
            parameters.signature
        );

        // Return the derived order hash.
        return hashes.orderHash;
    }

    /**
     * @dev Internal function to transfer Ether (or other native tokens) to a
     *      given recipient as part of basic order fulfillment. Note that
     *      proxies are not utilized for native tokens as the transferred amount
     *      must be provided as msg.value.
     *
     * @param amount      The amount to transfer.
     * @param parameters  The parameters of the basic order in question.
     */
    function _transferEthAndFinalize(
        uint256 amount,
        BasicOrderParameters calldata parameters
    ) internal {
        // Put native token value supplied by the caller on the stack.
        uint256 nativeTokensRemaining = msg.value;

        // Iterate over each additional recipient.
        for (uint256 i = 0; i < parameters.additionalRecipients.length; ++i) {
            // Retrieve the additional recipient.
            AdditionalRecipient calldata additionalRecipient = (
                parameters.additionalRecipients[i]
            );

            // Read native token amount to transfer to recipient & put on stack.
            uint256 additionalRecipientAmount = additionalRecipient.amount;

            // Ensure that sufficient native tokens are available.
            if (additionalRecipientAmount > nativeTokensRemaining) {
                revert InsufficientNativeTokensSupplied();
            }

            // Transfer native token to the additional recipient.
            _transferNativeTokens(
                additionalRecipient.recipient,
                additionalRecipientAmount
            );

            // Reduce native token value available.
            nativeTokensRemaining -= additionalRecipientAmount;
        }

        // Ensure that sufficient native token is still available.
        if (amount > nativeTokensRemaining) {
            revert InsufficientNativeTokensSupplied();
        }

        // Transfer native token to the offerer.
        _transferNativeTokens(parameters.offerer, amount);

        // If any native token remains after transfers, return it to the caller.
        if (nativeTokensRemaining > amount) {
            // Transfer remaining native token to the caller.
            _transferNativeTokens(
                payable(msg.sender),
                nativeTokensRemaining - amount
            );
        }
    }

    /**
     * @dev Internal function to transfer ERC20 tokens to a given recipient as
     *      part of basic order fulfillment. Note that proxies are not utilized
     *      for ERC20 tokens.
     *
     * @param from                  The originator of the ERC20 token transfer.
     * @param to                    The recipient of the ERC20 token transfer.
     * @param erc20Token            The ERC20 token to transfer.
     * @param amount                The amount of ERC20 tokens to transfer.
     * @param parameters            The parameters of the order.
     * @param fromOfferer           Whether to decrement amount from the
     *                              offered amount.
     * @param accumulatorStruct     A struct containing conduit transfer data
     *                              and its corresponding conduitKey.
     */
    function _transferERC20AndFinalize(
        address from,
        address to,
        address erc20Token,
        uint256 amount,
        BasicOrderParameters calldata parameters,
        bool fromOfferer,
        AccumulatorStruct memory accumulatorStruct
    ) internal {
        // Determine the appropriate conduit to utilize.
        bytes32 conduitKey;
        if (fromOfferer) {
            conduitKey = parameters.offererConduitKey;
        } else {
            conduitKey = parameters.fulfillerConduitKey;
        }

        // Iterate over each additional recipient.
        for (uint256 i = 0; i < parameters.additionalRecipients.length; ++i) {
            // Retrieve the additional recipient.
            AdditionalRecipient calldata additionalRecipient = (
                parameters.additionalRecipients[i]
            );

            // Decrement the amount to transfer to fulfiller if indicated.
            if (fromOfferer) {
                amount -= additionalRecipient.amount;
            }

            // Transfer ERC20 tokens to additional recipient given approval.
            _transferERC20(
                erc20Token,
                from,
                additionalRecipient.recipient,
                additionalRecipient.amount,
                conduitKey,
                accumulatorStruct
            );
        }

        // Transfer ERC20 token amount (from account must have proper approval).
        _transferERC20(
            erc20Token,
            from,
            to,
            amount,
            conduitKey,
            accumulatorStruct
        );
    }
}

File 15 of 43 : TokenTransferrerErrors.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

/**
 * @title TokenTransferrerErrors
 */
interface TokenTransferrerErrors {
    /**
     * @dev Revert with an error when an ERC721 transfer with amount other than
     *      one is attempted.
     *
     * @param amount The amount of the ERC721 tokens to transfer.
     */
    error InvalidERC721TransferAmount(uint256 amount);

    /**
     * @dev Revert with an error when attempting to fulfill an order where an
     *      item has an amount of zero.
     */
    error MissingItemAmount();

    /**
     * @dev Revert with an error when attempting to fulfill an order where an
     *      item has unused parameters. This includes both the token and the
     *      identifier parameters for native transfers as well as the identifier
     *      parameter for ERC20 transfers. Note that the conduit does not
     *      perform this check, leaving it up to the calling channel to enforce
     *      when desired.
     */
    error UnusedItemParameters();

    /**
     * @dev Revert with an error when an ERC20, ERC721, or ERC1155 token
     *      transfer reverts.
     *
     * @param token      The token for which the transfer was attempted.
     * @param from       The source of the attempted transfer.
     * @param to         The recipient of the attempted transfer.
     * @param identifier The identifier for the attempted transfer.
     * @param amount     The amount for the attempted transfer.
     */
    error TokenTransferGenericFailure(
        address token,
        address from,
        address to,
        uint256 identifier,
        uint256 amount
    );

    /**
     * @dev Revert with an error when a batch ERC1155 token transfer reverts.
     *
     * @param token       The token for which the transfer was attempted.
     * @param from        The source of the attempted transfer.
     * @param to          The recipient of the attempted transfer.
     * @param identifiers The identifiers for the attempted transfer.
     * @param amounts     The amounts for the attempted transfer.
     */
    error ERC1155BatchTransferGenericFailure(
        address token,
        address from,
        address to,
        uint256[] identifiers,
        uint256[] amounts
    );

    /**
     * @dev Revert with an error when an ERC20 token transfer returns a falsey
     *      value.
     *
     * @param token      The token for which the ERC20 transfer was attempted.
     * @param from       The source of the attempted ERC20 transfer.
     * @param to         The recipient of the attempted ERC20 transfer.
     * @param amount     The amount for the attempted ERC20 transfer.
     */
    error BadReturnValueFromERC20OnTransfer(
        address token,
        address from,
        address to,
        uint256 amount
    );

    /**
     * @dev Revert with an error when an account being called as an assumed
     *      contract does not have code and returns no data.
     *
     * @param account The account that should contain code.
     */
    error NoContract(address account);

    /**
     * @dev Revert with an error when attempting to execute an 1155 batch
     *      transfer using calldata not produced by default ABI encoding or with
     *      different lengths for ids and amounts arrays.
     */
    error Invalid1155BatchTransferEncoding();
}

File 16 of 43 : ReferenceCriteriaResolution.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import {
    ItemType,
    OrderType,
    Side
} from "seaport-types/src/lib/ConsiderationEnums.sol";

import {
    AdvancedOrder,
    ConsiderationItem,
    CriteriaResolver,
    OfferItem,
    OrderParameters,
    ReceivedItem,
    SpentItem
} from "seaport-types/src/lib/ConsiderationStructs.sol";

import { OrderToExecute } from "./ReferenceConsiderationStructs.sol";

import {
    CriteriaResolutionErrors
} from "seaport-types/src/interfaces/CriteriaResolutionErrors.sol";

/**
 * @title CriteriaResolution
 * @author 0age
 * @notice CriteriaResolution contains a collection of pure functions related to
 *         resolving criteria-based items.
 */
contract ReferenceCriteriaResolution is CriteriaResolutionErrors {
    /**
     * @dev Internal pure function to apply criteria resolvers containing
     *      specific token identifiers and associated proofs to order items.
     *
     * @param ordersToExecute    The orders to apply criteria resolvers to.
     * @param criteriaResolvers  An array where each element contains a
     *                           reference to a specific order as well as that
     *                           order's offer or consideration, a token
     *                           identifier, and a proof that the supplied token
     *                           identifier is contained in the order's merkle
     *                           root. Note that a root of zero indicates that
     *                           any transferable token identifier is valid and
     *                           that no proof needs to be supplied.
     */
    function _applyCriteriaResolvers(
        AdvancedOrder[] memory advancedOrders,
        OrderToExecute[] memory ordersToExecute,
        CriteriaResolver[] memory criteriaResolvers
    ) internal pure {
        // Retrieve length of criteria resolvers array and place on stack.
        uint256 arraySize = criteriaResolvers.length;

        // Iterate over each criteria resolver.
        for (uint256 i = 0; i < arraySize; ++i) {
            // Retrieve the criteria resolver.
            CriteriaResolver memory criteriaResolver = (criteriaResolvers[i]);

            // Read the order index from memory and place it on the stack.
            uint256 orderIndex = criteriaResolver.orderIndex;

            // Ensure that the order index is in range.
            if (orderIndex >= ordersToExecute.length) {
                revert OrderCriteriaResolverOutOfRange(criteriaResolver.side);
            }

            // Skip criteria resolution for order if not fulfilled.
            if (ordersToExecute[orderIndex].numerator == 0) {
                continue;
            }

            // Read component index from memory and place it on the stack.
            uint256 componentIndex = criteriaResolver.index;

            // Declare values for item's type and criteria.
            ItemType itemType;
            uint256 identifierOrCriteria;

            // If the criteria resolver refers to an offer item...
            if (criteriaResolver.side == Side.OFFER) {
                SpentItem[] memory spentItems = ordersToExecute[orderIndex]
                    .spentItems;
                // Ensure that the component index is in range.
                if (componentIndex >= spentItems.length) {
                    revert OfferCriteriaResolverOutOfRange();
                }

                // Retrieve relevant item using component index.
                SpentItem memory offer = (spentItems[componentIndex]);

                // Read item type and criteria from memory & place on stack.
                itemType = offer.itemType;
                identifierOrCriteria = offer.identifier;

                // Optimistically update item type to remove criteria usage.
                if (itemType == ItemType.ERC721_WITH_CRITERIA) {
                    offer.itemType = ItemType.ERC721;
                } else {
                    offer.itemType = ItemType.ERC1155;
                }

                // Optimistically update identifier w/ supplied identifier.
                offer.identifier = criteriaResolver.identifier;
            } else {
                // Otherwise, the resolver refers to a consideration item.

                // Retrieve relevant item using order index.
                ReceivedItem[] memory receivedItems = ordersToExecute[
                    orderIndex
                ].receivedItems;

                // Ensure that the component index is in range.
                if (componentIndex >= receivedItems.length) {
                    revert ConsiderationCriteriaResolverOutOfRange();
                }

                // Retrieve relevant item using component index.
                ReceivedItem memory consideration = (
                    receivedItems[componentIndex]
                );

                // Read item type and criteria from memory & place on stack.
                itemType = consideration.itemType;
                identifierOrCriteria = consideration.identifier;

                // Optimistically update item type to remove criteria usage.
                if (itemType == ItemType.ERC721_WITH_CRITERIA) {
                    consideration.itemType = ItemType.ERC721;
                } else {
                    consideration.itemType = ItemType.ERC1155;
                }

                // Optimistically update identifier w/ supplied identifier.
                consideration.identifier = (criteriaResolver.identifier);
            }

            // Ensure the specified item type indicates criteria usage.
            if (!_isItemWithCriteria(itemType)) {
                revert CriteriaNotEnabledForItem();
            }

            // If criteria is not 0 (i.e. a collection-wide criteria item)...
            if (identifierOrCriteria != uint256(0)) {
                // Verify identifier inclusion in criteria root using proof.
                _verifyProof(
                    criteriaResolver.identifier,
                    identifierOrCriteria,
                    criteriaResolver.criteriaProof
                );
            } else if (criteriaResolver.criteriaProof.length != 0) {
                // Revert if a proof is supplied for a collection-wide item.
                revert InvalidProof();
            }
        }

        // Retrieve length of orders array and place on stack.
        arraySize = ordersToExecute.length;

        // Iterate over each order to execute.
        for (uint256 i = 0; i < arraySize; ++i) {
            // Retrieve the order to execute.
            OrderToExecute memory orderToExecute = ordersToExecute[i];

            // Read offer length from memory and place on stack.
            uint256 totalItems = orderToExecute.spentItems.length;

            // Skip criteria resolution for order if not fulfilled.
            if (orderToExecute.numerator == 0) {
                continue;
            }

            // Iterate over each offer item on the order.
            for (uint256 j = 0; j < totalItems; ++j) {
                // Ensure item type no longer indicates criteria usage.
                if (
                    _isItemWithCriteria(orderToExecute.spentItems[j].itemType)
                ) {
                    if (
                        advancedOrders[i].parameters.orderType !=
                        OrderType.CONTRACT ||
                        orderToExecute.spentItems[j].identifier != 0
                    ) {
                        revert UnresolvedOfferCriteria(i, j);
                    }
                }
            }

            // Read consideration length from memory and place on stack.
            totalItems = (orderToExecute.receivedItems.length);

            // Iterate over each consideration item on the order.
            for (uint256 j = 0; j < totalItems; ++j) {
                // Ensure item type no longer indicates criteria usage.
                if (
                    _isItemWithCriteria(
                        orderToExecute.receivedItems[j].itemType
                    )
                ) {
                    if (
                        advancedOrders[i].parameters.orderType !=
                        OrderType.CONTRACT ||
                        orderToExecute.receivedItems[j].identifier != 0
                    ) {
                        revert UnresolvedConsiderationCriteria(i, j);
                    }
                }
            }
        }
    }

    /**
     * @dev Internal pure function to apply criteria resolvers containing
     *      specific token identifiers and associated proofs to order items.
     *
     * @param advancedOrder      The order to apply criteria resolvers to.
     * @param criteriaResolvers  An array where each element contains a
     *                           reference to a specific order as well as that
     *                           order's offer or consideration, a token
     *                           identifier, and a proof that the supplied token
     *                           identifier is contained in the order's merkle
     *                           root. Note that a root of zero indicates that
     *                           any transferable token identifier is valid and
     *                           that no proof needs to be supplied.
     */
    function _applyCriteriaResolversAdvanced(
        AdvancedOrder memory advancedOrder,
        CriteriaResolver[] memory criteriaResolvers
    ) internal pure {
        // Retrieve length of criteria resolvers array and place on stack.
        uint256 arraySize = criteriaResolvers.length;

        // Retrieve the parameters for the order.
        OrderParameters memory orderParameters = (advancedOrder.parameters);

        // Iterate over each criteria resolver.
        for (uint256 i = 0; i < arraySize; ++i) {
            // Retrieve the criteria resolver.
            CriteriaResolver memory criteriaResolver = (criteriaResolvers[i]);

            // Read the order index from memory and place it on the stack.
            uint256 orderIndex = criteriaResolver.orderIndex;

            if (orderIndex != 0) {
                revert OrderCriteriaResolverOutOfRange(criteriaResolver.side);
            }

            // Read component index from memory and place it on the stack.
            uint256 componentIndex = criteriaResolver.index;

            // Declare values for item's type and criteria.
            ItemType itemType;
            uint256 identifierOrCriteria;

            // If the criteria resolver refers to an offer item...
            if (criteriaResolver.side == Side.OFFER) {
                // Ensure that the component index is in range.
                if (componentIndex >= orderParameters.offer.length) {
                    revert OfferCriteriaResolverOutOfRange();
                }

                // Retrieve relevant item using order and component index.
                OfferItem memory offer = (
                    orderParameters.offer[componentIndex]
                );

                // Read item type and criteria from memory & place on stack.
                itemType = offer.itemType;
                identifierOrCriteria = offer.identifierOrCriteria;

                // Optimistically update item type to remove criteria usage.
                if (itemType == ItemType.ERC721_WITH_CRITERIA) {
                    offer.itemType = ItemType.ERC721;
                } else {
                    offer.itemType = ItemType.ERC1155;
                }

                // Optimistically update identifier w/ supplied identifier.
                offer.identifierOrCriteria = criteriaResolver.identifier;
            } else {
                // Otherwise, the resolver refers to a consideration item.
                // Ensure that the component index is in range.
                if (componentIndex >= orderParameters.consideration.length) {
                    revert ConsiderationCriteriaResolverOutOfRange();
                }

                // Retrieve relevant item using order and component index.
                ConsiderationItem memory consideration = (
                    orderParameters.consideration[componentIndex]
                );

                // Read item type and criteria from memory & place on stack.
                itemType = consideration.itemType;
                identifierOrCriteria = consideration.identifierOrCriteria;

                // Optimistically update item type to remove criteria usage.
                if (itemType == ItemType.ERC721_WITH_CRITERIA) {
                    consideration.itemType = ItemType.ERC721;
                } else {
                    consideration.itemType = ItemType.ERC1155;
                }

                // Optimistically update identifier w/ supplied identifier.
                consideration.identifierOrCriteria = (
                    criteriaResolver.identifier
                );
            }

            // Ensure the specified item type indicates criteria usage.
            if (!_isItemWithCriteria(itemType)) {
                revert CriteriaNotEnabledForItem();
            }

            // If criteria is not 0 (i.e. a collection-wide offer)...
            if (identifierOrCriteria != uint256(0)) {
                // Verify identifier inclusion in criteria root using proof.
                _verifyProof(
                    criteriaResolver.identifier,
                    identifierOrCriteria,
                    criteriaResolver.criteriaProof
                );
            } else if (criteriaResolver.criteriaProof.length != 0) {
                // Revert if a proof is supplied for a collection-wide item.
                revert InvalidProof();
            }
        }

        // Validate Criteria on order has been resolved

        // Read consideration length from memory and place on stack.
        uint256 totalItems = (advancedOrder.parameters.consideration.length);

        // Iterate over each consideration item on the order.
        for (uint256 i = 0; i < totalItems; ++i) {
            // Ensure item type no longer indicates criteria usage.
            if (
                _isItemWithCriteria(
                    advancedOrder.parameters.consideration[i].itemType
                )
            ) {
                if (
                    advancedOrder.parameters.orderType != OrderType.CONTRACT ||
                    advancedOrder
                        .parameters
                        .consideration[i]
                        .identifierOrCriteria !=
                    0
                ) {
                    revert UnresolvedConsiderationCriteria(0, i);
                }
            }
        }

        // Read offer length from memory and place on stack.
        totalItems = advancedOrder.parameters.offer.length;

        // Iterate over each offer item on the order.
        for (uint256 i = 0; i < totalItems; ++i) {
            // Ensure item type no longer indicates criteria usage.
            if (
                _isItemWithCriteria(advancedOrder.parameters.offer[i].itemType)
            ) {
                if (
                    advancedOrder.parameters.orderType != OrderType.CONTRACT ||
                    advancedOrder.parameters.offer[i].identifierOrCriteria != 0
                ) {
                    revert UnresolvedOfferCriteria(0, i);
                }
            }
        }
    }

    /**
     * @dev Internal pure function to check whether a given item type represents
     *      a criteria-based ERC721 or ERC1155 item (e.g. an item that can be
     *      resolved to one of a number of different identifiers at the time of
     *      order fulfillment).
     *
     * @param itemType The item type in question.
     *
     * @return withCriteria A boolean indicating that the item type in question
     *                      represents a criteria-based item.
     */
    function _isItemWithCriteria(
        ItemType itemType
    ) internal pure returns (bool withCriteria) {
        // ERC721WithCriteria is item type 4. ERC1155WithCriteria is item type
        // 5.
        withCriteria = uint256(itemType) > 3;
    }

    /**
     * @dev Internal pure function to ensure that a given element is contained
     *      in a merkle root via a supplied proof.
     *
     * @param leaf  The element for which to prove inclusion.
     * @param root  The merkle root that inclusion will be proved against.
     * @param proof The merkle proof.
     */
    function _verifyProof(
        uint256 leaf,
        uint256 root,
        bytes32[] memory proof
    ) internal pure {
        // Hash the supplied leaf to use as the initial proof element.
        bytes32 computedHash = keccak256(abi.encodePacked(leaf));

        // Iterate over each proof element.
        for (uint256 i = 0; i < proof.length; ++i) {
            // Retrieve the proof element.
            bytes32 proofElement = proof[i];

            // Sort and hash proof elements and update the computed hash.
            if (computedHash <= proofElement) {
                // Hash(current computed hash + current element of proof)
                computedHash = keccak256(
                    abi.encodePacked(computedHash, proofElement)
                );
            } else {
                // Hash(current element of proof + current computed hash)
                computedHash = keccak256(
                    abi.encodePacked(proofElement, computedHash)
                );
            }
        }

        // Ensure that the final derived hash matches the expected root.
        if (computedHash != bytes32(root)) {
            revert InvalidProof();
        }
    }
}

File 17 of 43 : ConduitEnums.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

enum ConduitItemType {
    NATIVE, // unused
    ERC20,
    ERC721,
    ERC1155
}

File 18 of 43 : AmountDerivationErrors.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

/**
 * @title AmountDerivationErrors
 * @author 0age
 * @notice AmountDerivationErrors contains errors related to amount derivation.
 */
interface AmountDerivationErrors {
    /**
     * @dev Revert with an error when attempting to apply a fraction as part of
     *      a partial fill that does not divide the target amount cleanly.
     */
    error InexactFraction();
}

File 19 of 43 : CriteriaResolutionErrors.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import { Side } from "../lib/ConsiderationEnums.sol";

/**
 * @title CriteriaResolutionErrors
 * @author 0age
 * @notice CriteriaResolutionErrors contains all errors related to criteria
 *         resolution.
 */
interface CriteriaResolutionErrors {
    /**
     * @dev Revert with an error when providing a criteria resolver that refers
     *      to an order that has not been supplied.
     *
     * @param side The side of the order that was not supplied.
     */
    error OrderCriteriaResolverOutOfRange(Side side);

    /**
     * @dev Revert with an error if an offer item still has unresolved criteria
     *      after applying all criteria resolvers.
     *
     * @param orderIndex The index of the order that contains the offer item.
     * @param offerIndex The index of the offer item that still has unresolved
     *                   criteria.
     */
    error UnresolvedOfferCriteria(uint256 orderIndex, uint256 offerIndex);

    /**
     * @dev Revert with an error if a consideration item still has unresolved
     *      criteria after applying all criteria resolvers.
     *
     * @param orderIndex         The index of the order that contains the
     *                           consideration item.
     * @param considerationIndex The index of the consideration item that still
     *                           has unresolved criteria.
     */
    error UnresolvedConsiderationCriteria(
        uint256 orderIndex,
        uint256 considerationIndex
    );

    /**
     * @dev Revert with an error when providing a criteria resolver that refers
     *      to an order with an offer item that has not been supplied.
     */
    error OfferCriteriaResolverOutOfRange();

    /**
     * @dev Revert with an error when providing a criteria resolver that refers
     *      to an order with a consideration item that has not been supplied.
     */
    error ConsiderationCriteriaResolverOutOfRange();

    /**
     * @dev Revert with an error when providing a criteria resolver that refers
     *      to an order with an item that does not expect a criteria to be
     *      resolved.
     */
    error CriteriaNotEnabledForItem();

    /**
     * @dev Revert with an error when providing a criteria resolver that
     *      contains an invalid proof with respect to the given item and
     *      chosen identifier.
     */
    error InvalidProof();
}

File 20 of 43 : ReferenceOrderValidator.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import {
    OrderType,
    ItemType
} from "seaport-types/src/lib/ConsiderationEnums.sol";

import {
    AdvancedOrder,
    ConsiderationItem,
    OfferItem,
    Order,
    OrderComponents,
    OrderParameters,
    OrderStatus,
    ReceivedItem,
    SpentItem
} from "seaport-types/src/lib/ConsiderationStructs.sol";

import { ReferenceExecutor } from "./ReferenceExecutor.sol";

import { ReferenceZoneInteraction } from "./ReferenceZoneInteraction.sol";

import {
    ContractOffererInterface
} from "seaport-types/src/interfaces/ContractOffererInterface.sol";

import {
    ReferenceGenerateOrderReturndataDecoder
} from "./ReferenceGenerateOrderReturndataDecoder.sol";

import {
    OrderToExecute,
    OrderValidation
} from "./ReferenceConsiderationStructs.sol";

/**
 * @title OrderValidator
 * @author 0age
 * @notice OrderValidator contains functionality related to validating orders
 *         and updating their status.
 */
contract ReferenceOrderValidator is
    ReferenceExecutor,
    ReferenceZoneInteraction
{
    // Track status of each order (validated, cancelled, and fraction filled).
    mapping(bytes32 => OrderStatus) private _orderStatus;

    // Track nonces for contract offerers.
    mapping(address => uint256) internal _contractNonces;

    /**
     * @dev Derive and set hashes, reference chainId, and associated domain
     *      separator during deployment.
     *
     * @param conduitController A contract that deploys conduits, or proxies
     *                          that may optionally be used to transfer approved
     *                          ERC20/721/1155 tokens.
     */
    constructor(
        address conduitController
    ) ReferenceExecutor(conduitController) {}

    /**
     * @dev Internal function to verify and update the status of a basic order.
     *
     * @param orderHash The hash of the order.
     * @param offerer   The offerer of the order.
     * @param signature A signature from the offerer indicating that the order
     *                  has been approved.
     */
    function _validateBasicOrderAndUpdateStatus(
        bytes32 orderHash,
        address offerer,
        bytes memory signature
    ) internal {
        // Retrieve the order status for the given order hash.
        OrderStatus storage orderStatus = _orderStatus[orderHash];

        // Ensure order is fillable and is not cancelled.
        _verifyOrderStatus(
            orderHash,
            orderStatus,
            true, // Only allow unused orders when fulfilling basic orders.
            true // Signifies to revert if the order is invalid.
        );

        // If the order is not already validated, verify the supplied signature.
        if (!orderStatus.isValidated) {
            _verifySignature(offerer, orderHash, signature);
        }

        // Update order status as fully filled, packing struct values.
        orderStatus.isValidated = true;
        orderStatus.isCancelled = false;
        orderStatus.numerator = 1;
        orderStatus.denominator = 1;
    }

    /**
     * @dev Internal function to validate an order and determine what portion to
     *      fill. The desired fill amount is supplied as a fraction, as is the
     *      returned amount to fill.
     *
     * @param advancedOrder   The order to fulfill as well as the fraction to
     *                        fill. Note that all offer and consideration
     *                        amounts must divide with no remainder in order for
     *                        a partial fill to be valid.
     * @param revertOnInvalid A boolean indicating whether to revert if the
     *                        order is invalid due to the time or order status.
     *
     * @return orderValidation The order validation details, including the fill
     *                         amount.
     */
    function _validateOrder(
        AdvancedOrder memory advancedOrder,
        bool revertOnInvalid
    ) internal view returns (OrderValidation memory orderValidation) {
        // Retrieve the parameters for the order.
        OrderParameters memory orderParameters = advancedOrder.parameters;

        // Ensure current timestamp falls between order start time and end time.
        if (
            !_verifyTime(
                orderParameters.startTime,
                orderParameters.endTime,
                revertOnInvalid
            )
        ) {
            // Assuming an invalid time and no revert, return zeroed out values.
            return
                OrderValidation(
                    bytes32(0),
                    0,
                    0,
                    _convertAdvancedToOrder(orderParameters, 0)
                );
        }

        // Read numerator and denominator from memory and place on the stack.
        uint256 numerator = uint256(advancedOrder.numerator);
        uint256 denominator = uint256(advancedOrder.denominator);

        // If the order is a contract order, return the generated order.
        if (orderParameters.orderType == OrderType.CONTRACT) {
            // Ensure that numerator and denominator are both equal to 1.
            if (numerator != 1 || denominator != 1) {
                revert BadFraction();
            }

            return
                OrderValidation(
                    bytes32(uint256(1)),
                    1,
                    1,
                    _convertAdvancedToOrder(orderParameters, 1)
                );
        }

        // Ensure that the supplied numerator and denominator are valid.  The
        // numerator should not exceed denominator and should not be zero.
        if (numerator > denominator || numerator == 0) {
            revert BadFraction();
        }

        // If attempting partial fill (n < d) check order type & ensure support.
        if (
            numerator < denominator &&
            _doesNotSupportPartialFills(orderParameters.orderType)
        ) {
            // Revert if partial fill was attempted on an unsupported order.
            revert PartialFillsNotEnabledForOrder();
        }

        // Retrieve current counter and use it w/ parameters to get order hash.
        orderValidation.orderHash = (
            _assertConsiderationLengthAndGetOrderHash(orderParameters)
        );

        // Retrieve the order status using the derived order hash.
        OrderStatus storage orderStatus = (
            _orderStatus[orderValidation.orderHash]
        );

        // Ensure order is fillable and is not cancelled.
        if (
            // Allow partially used orders to be filled.
            !_verifyOrderStatus(
                orderValidation.orderHash,
                orderStatus,
                false,
                revertOnInvalid
            )
        ) {
            // Assuming an invalid order status and no revert, return zero fill.
            return
                OrderValidation(
                    orderValidation.orderHash,
                    0,
                    0,
                    _convertAdvancedToOrder(orderParameters, 0)
                );
        }

        // If the order is not already validated, verify the supplied signature.
        if (!orderStatus.isValidated) {
            _verifySignature(
                orderParameters.offerer,
                orderValidation.orderHash,
                advancedOrder.signature
            );
        }

        // Read filled amount as numerator and denominator and put on the stack.
        uint256 filledNumerator = uint256(orderStatus.numerator);
        uint256 filledDenominator = uint256(orderStatus.denominator);

        // If order currently has a non-zero denominator it is partially filled.
        if (filledDenominator != 0) {
            // If denominator of 1 supplied, fill all remaining amount on order.
            if (denominator == 1) {
                // Scale numerator & denominator to match current denominator.
                numerator = filledDenominator;
                denominator = filledDenominator;
            }
            // Otherwise, if supplied denominator differs from current one...
            else if (filledDenominator != denominator) {
                // scale current numerator by the supplied denominator, then...
                filledNumerator *= denominator;

                // the supplied numerator & denominator by current denominator.
                numerator *= filledDenominator;
                denominator *= filledDenominator;
            }

            // Once adjusted, if current+supplied numerator exceeds denominator:
            if (filledNumerator + numerator > denominator) {
                // Reduce current numerator so it + supplied = denominator.
                numerator = denominator - filledNumerator;
            }

            // Increment the filled numerator by the new numerator.
            filledNumerator += numerator;

            // Ensure fractional amounts are below max uint120.
            if (
                filledNumerator > type(uint120).max ||
                denominator > type(uint120).max
            ) {
                // Derive greatest common divisor using euclidean algorithm.
                uint256 scaleDown = _greatestCommonDivisor(
                    numerator,
                    _greatestCommonDivisor(filledNumerator, denominator)
                );

                // Scale all fractional values down by gcd.
                numerator = numerator / scaleDown;
                filledNumerator = filledNumerator / scaleDown;
                denominator = denominator / scaleDown;

                // Perform the overflow check a second time.
                uint256 maxOverhead = type(uint256).max - type(uint120).max;
                ((filledNumerator + maxOverhead) & (denominator + maxOverhead));
            }
        }

        // Return order hash, new numerator and denominator.
        return
            OrderValidation(
                orderValidation.orderHash,
                uint120(numerator),
                uint120(denominator),
                _convertAdvancedToOrder(orderParameters, uint120(numerator))
            );
    }

    /**
     * @dev Internal function to update an order's status.
     *
     * @param orderHash       The hash of the order.
     * @param numerator       The numerator of the fraction to fill.
     * @param denominator     The denominator of the fraction to fill.
     * @param revertOnInvalid Whether to revert on invalid input.
     *
     * @return valid A boolean indicating whether the order is valid.
     */
    function _updateStatus(
        bytes32 orderHash,
        uint256 numerator,
        uint256 denominator,
        bool revertOnInvalid
    ) internal returns (bool valid) {
        if (numerator == 0) {
            return false;
        }

        // Retrieve the order status using the provided order hash.
        OrderStatus storage orderStatus = _orderStatus[orderHash];

        // Read filled amount as numerator and denominator and put on the stack.
        uint256 filledNumerator = uint256(orderStatus.numerator);
        uint256 filledDenominator = uint256(orderStatus.denominator);

        // If order currently has a non-zero denominator it is partially filled.
        if (filledDenominator != 0) {
            // if supplied denominator differs from current one...
            if (filledDenominator != denominator) {
                // scale current numerator by the supplied denominator, then...
                filledNumerator *= denominator;

                // the supplied numerator & denominator by current denominator.
                numerator *= filledDenominator;
                denominator *= filledDenominator;
            }

            // Once adjusted, if current+supplied numerator exceeds
            // denominator...
            if (filledNumerator + numerator > denominator) {
                // Revert or return false, which indicates that the order is
                // invalid.
                if (revertOnInvalid) {
                    revert OrderAlreadyFilled(orderHash);
                } else {
                    return false;
                }
            }

            // Increment the filled numerator by the new numerator.
            filledNumerator += numerator;

            // Ensure fractional amounts are below max uint120.
            if (
                filledNumerator > type(uint120).max ||
                denominator > type(uint120).max
            ) {
                // Derive greatest common divisor using euclidean algorithm.
                uint256 scaleDown = _greatestCommonDivisor(
                    filledNumerator,
                    denominator
                );

                // Scale new filled fractional values down by gcd.
                filledNumerator = filledNumerator / scaleDown;
                denominator = denominator / scaleDown;

                // Perform the overflow check a second time.
                uint256 maxOverhead = type(uint256).max - type(uint120).max;
                ((filledNumerator + maxOverhead) & (denominator + maxOverhead));
            }

            // Update order status and fill amount, packing struct values.
            orderStatus.isValidated = true;
            orderStatus.isCancelled = false;
            orderStatus.numerator = uint120(filledNumerator);
            orderStatus.denominator = uint120(denominator);
        } else {
            // If the order currently has a zero denominator, it is not
            // partially filled. Update the order status and fill amount,
            // packing struct values.
            orderStatus.isValidated = true;
            orderStatus.isCancelled = false;
            orderStatus.numerator = uint120(numerator);
            orderStatus.denominator = uint120(denominator);
        }

        return true;
    }

    function _callGenerateOrder(
        OrderParameters memory orderParameters,
        bytes memory context,
        SpentItem[] memory originalOfferItems,
        SpentItem[] memory originalConsiderationItems
    ) internal returns (bool success, bytes memory returnData) {
        return
            orderParameters.offerer.call(
                abi.encodeWithSelector(
                    ContractOffererInterface.generateOrder.selector,
                    msg.sender,
                    originalOfferItems,
                    originalConsiderationItems,
                    context
                )
            );
    }

    /**
     * @dev Internal function to generate a contract order. When a
     *      collection-wide criteria-based item (criteria = 0) is provided as an
     *      input to a contract order, the contract offerer has full latitude to
     *      choose any identifier it wants mid-flight, which differs from the
     *      usual behavior.  For regular criteria-based orders with
     *      identifierOrCriteria = 0, the fulfiller can pick which identifier to
     *      receive by providing a CriteriaResolver. For contract offers with
     *      identifierOrCriteria = 0, Seaport does not expect a corresponding
     *      CriteriaResolver, and will revert if one is provided.
     *
     * @param orderToExecute  The order to execute.
     * @param orderParameters The parameters for the order.
     * @param context         The context for generating the order.
     * @param revertOnInvalid Whether to revert on invalid input.
     *
     * @return orderHash   The order hash.
     */
    function _getGeneratedOrder(
        OrderToExecute memory orderToExecute,
        OrderParameters memory orderParameters,
        bytes memory context,
        bool revertOnInvalid
    ) internal returns (bytes32 orderHash) {
        // Ensure that consideration array length is equal to the total original
        // consideration items value.
        if (
            orderParameters.consideration.length !=
            orderParameters.totalOriginalConsiderationItems
        ) {
            revert ConsiderationLengthNotEqualToTotalOriginal();
        }

        // Convert offer and consideration to spent and received items.
        SpentItem[] memory originalOfferItems = orderToExecute.spentItems;
        SpentItem[] memory originalConsiderationItems = _convertToSpent(
            orderToExecute.receivedItems
        );

        // Create arrays for returned offer and consideration items.
        SpentItem[] memory offer;
        ReceivedItem[] memory consideration;

        {
            // Do a low-level call to get success status and any return data.
            (bool success, bytes memory returnData) = _callGenerateOrder(
                orderParameters,
                context,
                originalOfferItems,
                originalConsiderationItems
            );

            {
                // Increment contract nonce and use it to derive order hash.
                // Note: nonce will be incremented even for skipped orders, and
                // even if generateOrder's return data doesn't meet constraints.
                uint256 contractNonce = (
                    _contractNonces[orderParameters.offerer]++
                );

                // Derive order hash from contract nonce and offerer address.
                orderHash = bytes32(
                    contractNonce ^
                        (uint256(uint160(orderParameters.offerer)) << 96)
                );
            }

            //  If call succeeds, try to decode offer and consideration items.
            if (success) {
                // Try to decode offer and consideration items from returndata.
                try
                    (new ReferenceGenerateOrderReturndataDecoder()).decode(
                        returnData
                    )
                returns (
                    SpentItem[] memory _offer,
                    ReceivedItem[] memory _consideration
                ) {
                    offer = _offer;
                    consideration = _consideration;
                } catch {
                    // If decoding fails, revert.
                    revert InvalidContractOrder(orderHash);
                }
            } else {
                // If the call fails, revert or return empty.
                (orderHash, orderToExecute) = _revertOrReturnEmpty(
                    revertOnInvalid,
                    orderHash
                );
                return orderHash;
            }
        }

        {
            // Designate lengths.
            uint256 originalOfferLength = orderParameters.offer.length;
            uint256 newOfferLength = offer.length;

            // Explicitly specified offer items cannot be removed.
            if (originalOfferLength > newOfferLength) {
                revert InvalidContractOrder(orderHash);
            }

            // Loop through each new offer and ensure the new amounts are at
            // least as much as the respective original amounts.
            for (uint256 i = 0; i < originalOfferLength; ++i) {
                // Designate original and new offer items.
                SpentItem memory originalOffer = orderToExecute.spentItems[i];
                SpentItem memory newOffer = offer[i];

                // Set returned identifier for criteria-based items with
                // criteria = 0. Note that this reset means that a contract
                // offerer has full latitude to choose any identifier it wants
                // mid-flight, in contrast to the normal behavior, where the
                // fulfiller can pick which identifier to receive by providing a
                // CriteriaResolver.
                if (
                    uint256(originalOffer.itemType) > 3 &&
                    originalOffer.identifier == 0
                ) {
                    originalOffer.itemType = ItemType(
                        uint256(originalOffer.itemType) - 2
                    );
                    originalOffer.identifier = newOffer.identifier;
                }

                // Ensure the original and generated items are compatible.
                if (
                    originalOffer.amount > newOffer.amount ||
                    originalOffer.itemType != newOffer.itemType ||
                    originalOffer.token != newOffer.token ||
                    originalOffer.identifier != newOffer.identifier
                ) {
                    revert InvalidContractOrder(orderHash);
                }
            }

            orderToExecute.spentItems = offer;
            orderToExecute.spentItemOriginalAmounts = new uint256[](
                offer.length
            );

            // Add new offer items if there are more than original.
            for (uint256 i = 0; i < offer.length; ++i) {
                orderToExecute.spentItemOriginalAmounts[i] = offer[i].amount;
            }
        }

        {
            // Designate lengths & memory locations.
            ReceivedItem[] memory originalConsiderationArray = (
                orderToExecute.receivedItems
            );
            uint256 newConsiderationLength = consideration.length;

            // New consideration items cannot be created.
            if (newConsiderationLength > originalConsiderationArray.length) {
                revert InvalidContractOrder(orderHash);
            }

            // Loop through and check consideration.
            for (uint256 i = 0; i < newConsiderationLength; ++i) {
                ReceivedItem memory newConsideration = consideration[i];
                ReceivedItem memory originalConsideration = (
                    originalConsiderationArray[i]
                );

                if (
                    uint256(originalConsideration.itemType) > 3 &&
                    originalConsideration.identifier == 0
                ) {
                    originalConsideration.itemType = ItemType(
                        uint256(originalConsideration.itemType) - 2
                    );
                    originalConsideration.identifier = (
                        newConsideration.identifier
                    );
                }

                // All fields must match the originally supplied fields except
                // for the amount (which may be reduced by the contract offerer)
                // and the recipient if some non-zero address has been provided.
                if (
                    newConsideration.amount > originalConsideration.amount ||
                    originalConsideration.itemType !=
                    newConsideration.itemType ||
                    originalConsideration.token != newConsideration.token ||
                    originalConsideration.identifier !=
                    newConsideration.identifier ||
                    (originalConsideration.recipient != address(0) &&
                        originalConsideration.recipient !=
                        (newConsideration.recipient))
                ) {
                    revert InvalidContractOrder(orderHash);
                }
            }

            orderToExecute.receivedItems = consideration;
            orderToExecute.receivedItemOriginalAmounts = new uint256[](
                consideration.length
            );

            // Iterate over original consideration array and copy to new.
            for (uint256 i = 0; i < consideration.length; ++i) {
                orderToExecute.receivedItemOriginalAmounts[i] = (
                    consideration[i].amount
                );
            }
        }

        // Return the order hash.
        return orderHash;
    }

    /**
     * @dev Internal function to cancel an arbitrary number of orders. Note that
     *      only the offerer or the zone of a given order may cancel it. Callers
     *      should ensure that the intended order was cancelled by calling
     *      `getOrderStatus` and confirming that `isCancelled` returns `true`.
     *      Also note that contract orders are not cancellable.
     *
     * @param orders The orders to cancel.
     *
     * @return A boolean indicating whether the supplied orders were
     *         successfully cancelled.
     */
    function _cancel(
        OrderComponents[] calldata orders
    ) internal returns (bool) {
        // Declare variables outside of the loop.
        OrderStatus storage orderStatus;
        address offerer;
        address zone;

        // Read length of the orders array from memory and place on stack.
        uint256 totalOrders = orders.length;

        // Iterate over each order.
        for (uint256 i = 0; i < totalOrders; ++i) {
            // Retrieve the order.
            OrderComponents calldata order = orders[i];

            offerer = order.offerer;
            zone = order.zone;

            // Ensure caller is either offerer or zone of the order and that the
            // order is not a contract order.
            if (
                order.orderType == OrderType.CONTRACT ||
                (msg.sender != offerer && msg.sender != zone)
            ) {
                revert CannotCancelOrder();
            }

            // Derive order hash using the order parameters and the counter.
            bytes32 orderHash = _deriveOrderHash(
                OrderParameters(
                    offerer,
                    zone,
                    order.offer,
                    order.consideration,
                    order.orderType,
                    order.startTime,
                    order.endTime,
                    order.zoneHash,
                    order.salt,
                    order.conduitKey,
                    order.consideration.length
                ),
                order.counter
            );

            // Retrieve the order status using the derived order hash.
            orderStatus = _orderStatus[orderHash];

            // Update the order status as not valid and cancelled.
            orderStatus.isValidated = false;
            orderStatus.isCancelled = true;

            // Emit an event signifying that the order has been cancelled.
            emit OrderCancelled(orderHash, offerer, zone);
        }

        return true;
    }

    /**
     * @dev Internal function to validate an arbitrary number of orders, thereby
     *      registering them as valid and allowing the fulfiller to skip
     *      verification. Note that anyone can validate a signed order but only
     *      the offerer can validate an order without supplying a signature.
     *
     * @param orders The orders to validate.
     *
     * @return A boolean indicating whether the supplied orders were
     *         successfully validated.
     */
    function _validate(Order[] calldata orders) internal returns (bool) {
        // Declare variables outside of the loop.
        OrderStatus storage orderStatus;
        bytes32 orderHash;
        address offerer;

        // Read length of the orders array from memory and place on stack.
        uint256 totalOrders = orders.length;

        // Iterate over each order.
        for (uint256 i = 0; i < totalOrders; ++i) {
            // Retrieve the order.
            Order calldata order = orders[i];

            // Retrieve the order parameters.
            OrderParameters calldata orderParameters = order.parameters;

            // Skip contract orders.
            if (orderParameters.orderType == OrderType.CONTRACT) {
                continue;
            }

            // Move offerer from memory to the stack.
            offerer = orderParameters.offerer;

            // Get current counter and use it w/ params to derive order hash.
            orderHash = _assertConsiderationLengthAndGetOrderHash(
                orderParameters
            );

            // Retrieve the order status using the derived order hash.
            orderStatus = _orderStatus[orderHash];

            // Ensure order is fillable and retrieve the filled amount.
            _verifyOrderStatus(
                orderHash,
                orderStatus,
                false, // Signifies that partially filled orders are valid.
                true // Signifies to revert if the order is invalid.
            );

            // If the order has not already been validated...
            if (!orderStatus.isValidated) {
                // Ensure that consideration array length is equal to the total
                // original consideration items value.
                if (
                    orderParameters.consideration.length !=
                    orderParameters.totalOriginalConsiderationItems
                ) {
                    revert ConsiderationLengthNotEqualToTotalOriginal();
                }

                // Verify the supplied signature.
                _verifySignature(offerer, orderHash, order.signature);

                // Update order status to mark the order as valid.
                orderStatus.isValidated = true;

                // Emit an event signifying the order has been validated.
                emit OrderValidated(orderHash, orderParameters);
            }
        }

        return true;
    }

    /**
     * @dev Internal view function to retrieve the status of a given order by
     *      hash, including whether the order has been cancelled or validated
     *      and the fraction of the order that has been filled.
     *
     * @param orderHash The order hash in question.
     *
     * @return isValidated A boolean indicating whether the order in question
     *                     has been validated (i.e. previously approved or
     *                     partially filled).
     * @return isCancelled A boolean indicating whether the order in question
     *                     has been cancelled.
     * @return totalFilled The total portion of the order that has been filled
     *                     (i.e. the "numerator").
     * @return totalSize   The total size of the order that is either filled or
     *                     unfilled (i.e. the "denominator").
     */
    function _getOrderStatus(
        bytes32 orderHash
    )
        internal
        view
        returns (
            bool isValidated,
            bool isCancelled,
            uint256 totalFilled,
            uint256 totalSize
        )
    {
        // Retrieve the order status using the order hash.
        OrderStatus storage orderStatus = _orderStatus[orderHash];

        // Return the fields on the order status.
        return (
            orderStatus.isValidated,
            orderStatus.isCancelled,
            orderStatus.numerator,
            orderStatus.denominator
        );
    }

    /**
     * @dev Internal pure function to either revert or return an empty tuple
     *      depending on the value of `revertOnInvalid`.
     *
     * @param revertOnInvalid   Whether to revert on invalid input.
     * @param contractOrderHash The contract order hash.
     *
     * @return orderHash   The order hash.
     */
    function _revertOrReturnEmpty(
        bool revertOnInvalid,
        bytes32 contractOrderHash
    )
        internal
        pure
        returns (bytes32 orderHash, OrderToExecute memory emptyOrder)
    {
        // If invalid input should not revert...
        if (!revertOnInvalid) {
            // Return no contract order hash and zero values for the numerator
            // and denominator.
            return (bytes32(0), emptyOrder);
        }

        // Otherwise, revert.
        revert InvalidContractOrder(contractOrderHash);
    }

    /**
     * @dev Internal pure function to convert received items to spent items.
     *
     * @param consideration  The consideration items to convert.
     *
     * @return receivedItems The converted received items.
     */
    function _convertToSpent(
        ReceivedItem[] memory consideration
    ) internal pure returns (SpentItem[] memory receivedItems) {
        // Create an array of received items equal to the consideration length.
        receivedItems = new SpentItem[](consideration.length);

        // Iterate over each received item on the order.
        for (uint256 i = 0; i < consideration.length; ++i) {
            // Retrieve the consideration item.
            ReceivedItem memory considerationItem = (consideration[i]);

            // Create spent item for event based on the consideration item.
            SpentItem memory receivedItem = SpentItem(
                considerationItem.itemType,
                considerationItem.token,
                considerationItem.identifier,
                considerationItem.amount
            );

            // Add to array of received items.
            receivedItems[i] = receivedItem;
        }
    }

    /**
     * @dev Internal function to derive the greatest common divisor of two
     *      values using the classical euclidian algorithm.
     *
     * @param a The first value.
     * @param b The second value.
     *
     * @return greatestCommonDivisor The greatest common divisor.
     */
    function _greatestCommonDivisor(
        uint256 a,
        uint256 b
    ) internal pure returns (uint256 greatestCommonDivisor) {
        while (b > 0) {
            uint256 c = b;
            b = a % c;
            a = c;
        }

        greatestCommonDivisor = a;
    }

    /**
     * @dev Internal pure function to check whether a given order type indicates
     *      that partial fills are not supported (e.g. only "full fills" are
     *      allowed for the order in question).
     *
     * @param orderType The order type in question.
     *
     * @return isFullOrder A boolean indicating whether the order type only
     *                     supports full fills.
     */
    function _doesNotSupportPartialFills(
        OrderType orderType
    ) internal pure returns (bool isFullOrder) {
        // The "full" order types are even, while "partial" order types are odd.
        isFullOrder = uint256(orderType) & 1 == 0;
    }

    /**
     * @dev Internal pure function to convert an advanced order to an order
     *      to execute.
     *
     * @param orderParameters The order to convert.
     *
     * @return orderToExecute The new order to execute.
     */
    function _convertAdvancedToOrder(
        OrderParameters memory orderParameters,
        uint120 numerator
    ) internal pure returns (OrderToExecute memory orderToExecute) {
        // Retrieve the advanced orders offers.
        OfferItem[] memory offer = orderParameters.offer;

        // Create an array of spent items equal to the offer length.
        SpentItem[] memory spentItems = new SpentItem[](offer.length);
        uint256[] memory spentItemOriginalAmounts = new uint256[](offer.length);

        // Iterate over each offer item on the order.
        for (uint256 i = 0; i < offer.length; ++i) {
            // Retrieve the offer item.
            OfferItem memory offerItem = offer[i];

            // Create spent item for event based on the offer item.
            SpentItem memory spentItem = SpentItem(
                offerItem.itemType,
                offerItem.token,
                offerItem.identifierOrCriteria,
                offerItem.startAmount
            );

            // Add to array of spent items.
            spentItems[i] = spentItem;
            spentItemOriginalAmounts[i] = offerItem.startAmount;
        }

        // Retrieve the consideration array from the advanced order.
        ConsiderationItem[] memory consideration = orderParameters
            .consideration;

        // Create an array of received items equal to the consideration length.
        ReceivedItem[] memory receivedItems = new ReceivedItem[](
            consideration.length
        );
        // Create an array of uint256 values equal in length to the
        // consideration length containing the amounts of each item.
        uint256[] memory receivedItemOriginalAmounts = new uint256[](
            consideration.length
        );

        // Iterate over each consideration item on the order.
        for (uint256 i = 0; i < consideration.length; ++i) {
            // Retrieve the consideration item.
            ConsiderationItem memory considerationItem = (consideration[i]);

            // Create received item for event based on the consideration item.
            ReceivedItem memory receivedItem = ReceivedItem(
                considerationItem.itemType,
                considerationItem.token,
                considerationItem.identifierOrCriteria,
                considerationItem.startAmount,
                considerationItem.recipient
            );

            // Add to array of received items.
            receivedItems[i] = receivedItem;

            // Add to array of received item amounts.
            receivedItemOriginalAmounts[i] = considerationItem.startAmount;
        }

        // Create the order to execute from the advanced order data.
        orderToExecute = OrderToExecute(
            orderParameters.offerer,
            spentItems,
            receivedItems,
            orderParameters.conduitKey,
            numerator,
            spentItemOriginalAmounts,
            receivedItemOriginalAmounts
        );

        // Return the order.
        return orderToExecute;
    }

    /**
     * @dev Internal pure function to convert an array of advanced orders to
     *      an array of orders to execute.
     *
     * @param advancedOrders The advanced orders to convert.
     *
     * @return ordersToExecute The new array of orders.
     */
    function _convertAdvancedToOrdersToExecute(
        AdvancedOrder[] memory advancedOrders
    ) internal pure returns (OrderToExecute[] memory ordersToExecute) {
        // Read the number of orders from memory and place on the stack.
        uint256 totalOrders = advancedOrders.length;

        // Allocate new empty array for each advanced order in memory.
        ordersToExecute = new OrderToExecute[](totalOrders);

        // Iterate over the given orders.
        for (uint256 i = 0; i < totalOrders; ++i) {
            // Convert and update array.
            ordersToExecute[i] = _convertAdvancedToOrder(
                advancedOrders[i].parameters,
                advancedOrders[i].numerator
            );
        }

        // Return the array of orders to execute
        return ordersToExecute;
    }
}

File 21 of 43 : ContractOffererInterface.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import {
    ReceivedItem,
    Schema,
    SpentItem
} from "../lib/ConsiderationStructs.sol";
import { IERC165 } from "../interfaces/IERC165.sol";

/**
 * @title ContractOffererInterface
 * @notice Contains the minimum interfaces needed to interact with a contract
 *         offerer.
 */
interface ContractOffererInterface is IERC165 {
    /**
     * @dev Generates an order with the specified minimum and maximum spent
     *      items, and optional context (supplied as extraData).
     *
     * @param fulfiller       The address of the fulfiller.
     * @param minimumReceived The minimum items that the caller is willing to
     *                        receive.
     * @param maximumSpent    The maximum items the caller is willing to spend.
     * @param context         Additional context of the order.
     *
     * @return offer         A tuple containing the offer items.
     * @return consideration A tuple containing the consideration items.
     */
    function generateOrder(
        address fulfiller,
        SpentItem[] calldata minimumReceived,
        SpentItem[] calldata maximumSpent,
        bytes calldata context // encoded based on the schemaID
    )
        external
        returns (SpentItem[] memory offer, ReceivedItem[] memory consideration);

    /**
     * @dev Ratifies an order with the specified offer, consideration, and
     *      optional context (supplied as extraData).
     *
     * @param offer         The offer items.
     * @param consideration The consideration items.
     * @param context       Additional context of the order.
     * @param orderHashes   The hashes to ratify.
     * @param contractNonce The nonce of the contract.
     *
     * @return ratifyOrderMagicValue The magic value returned by the contract
     *                               offerer.
     */
    function ratifyOrder(
        SpentItem[] calldata offer,
        ReceivedItem[] calldata consideration,
        bytes calldata context, // encoded based on the schemaID
        bytes32[] calldata orderHashes,
        uint256 contractNonce
    ) external returns (bytes4 ratifyOrderMagicValue);

    /**
     * @dev View function to preview an order generated in response to a minimum
     *      set of received items, maximum set of spent items, and context
     *      (supplied as extraData).
     *
     * @param caller          The address of the caller (e.g. Seaport).
     * @param fulfiller       The address of the fulfiller (e.g. the account
     *                        calling Seaport).
     * @param minimumReceived The minimum items that the caller is willing to
     *                        receive.
     * @param maximumSpent    The maximum items the caller is willing to spend.
     * @param context         Additional context of the order.
     *
     * @return offer         A tuple containing the offer items.
     * @return consideration A tuple containing the consideration items.
     */
    function previewOrder(
        address caller,
        address fulfiller,
        SpentItem[] calldata minimumReceived,
        SpentItem[] calldata maximumSpent,
        bytes calldata context // encoded based on the schemaID
    )
        external
        view
        returns (SpentItem[] memory offer, ReceivedItem[] memory consideration);

    /**
     * @dev Gets the metadata for this contract offerer.
     *
     * @return name    The name of the contract offerer.
     * @return schemas The schemas supported by the contract offerer.
     */
    function getSeaportMetadata()
        external
        view
        returns (string memory name, Schema[] memory schemas); // map to SIP IDs

    function supportsInterface(
        bytes4 interfaceId
    ) external view override returns (bool);

    // Additional functions and/or events based on implemented schemaIDs
}

File 22 of 43 : ReferenceExecutor.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import {
    ConduitItemType
} from "seaport-types/src/conduit/lib/ConduitEnums.sol";

import {
    ConduitInterface
} from "seaport-types/src/interfaces/ConduitInterface.sol";

import {
    ConduitTransfer
} from "seaport-types/src/conduit/lib/ConduitStructs.sol";

import { ItemType } from "seaport-types/src/lib/ConsiderationEnums.sol";

import { ReceivedItem } from "seaport-types/src/lib/ConsiderationStructs.sol";

import { ReferenceVerifiers } from "./ReferenceVerifiers.sol";

import { ReferenceTokenTransferrer } from "./ReferenceTokenTransferrer.sol";

import { AccumulatorStruct } from "./ReferenceConsiderationStructs.sol";

/**
 * @title Executor
 * @author 0age
 * @notice Executor contains functions related to processing executions (i.e.
 *         transferring items, either directly or via conduits).
 */
contract ReferenceExecutor is ReferenceVerifiers, ReferenceTokenTransferrer {
    /**
     * @dev Derive and set hashes, reference chainId, and associated domain
     *      separator during deployment.
     *
     * @param conduitController A contract that deploys conduits, or proxies
     *                          that may optionally be used to transfer approved
     *                          ERC20/721/1155 tokens.
     */
    constructor(
        address conduitController
    ) ReferenceVerifiers(conduitController) {}

    /**
     * @dev Internal function to transfer a given item.
     *
     * @param item                  The item to transfer including an amount
     *                              and recipient.
     * @param offerer               The account offering the item, i.e. the
     *                              from address.
     * @param conduitKey            A bytes32 value indicating what
     *                              corresponding conduit, if any, to source
     *                              token approvals from. The zero hash
     *                              signifies that no conduit should be used
     *                              (and direct approvals set on Consideration)
     * @param accumulatorStruct     A struct containing conduit transfer data
     *                              and its corresponding conduitKey.
     */
    function _transfer(
        ReceivedItem memory item,
        address offerer,
        bytes32 conduitKey,
        AccumulatorStruct memory accumulatorStruct
    ) internal {
        // If the item type indicates Ether or a native token...
        if (item.itemType == ItemType.NATIVE) {
            // Ensure neither the token nor the identifier parameters are set.
            if ((uint160(item.token) | item.identifier) != 0) {
                revert UnusedItemParameters();
            }

            // Transfer the native tokens to the recipient.
            _transferNativeTokens(item.recipient, item.amount);
        } else if (item.itemType == ItemType.ERC20) {
            // Ensure that no identifier is supplied.
            if (item.identifier != 0) {
                revert UnusedItemParameters();
            }

            // Transfer ERC20 tokens from the offerer to the recipient.
            _transferERC20(
                item.token,
                offerer,
                item.recipient,
                item.amount,
                conduitKey,
                accumulatorStruct
            );
        } else if (item.itemType == ItemType.ERC721) {
            // Transfer ERC721 token from the offerer to the recipient.
            _transferERC721(
                item.token,
                offerer,
                item.recipient,
                item.identifier,
                item.amount,
                conduitKey,
                accumulatorStruct
            );
        } else {
            // Transfer ERC1155 token from the offerer to the recipient.
            _transferERC1155(
                item.token,
                offerer,
                item.recipient,
                item.identifier,
                item.amount,
                conduitKey,
                accumulatorStruct
            );
        }
    }

    /**
     * @dev Internal function to transfer Ether or other native tokens to a
     *      given recipient. Note that this reference implementation deviates
     *      from the primary contract, which "bubbles up" revert data when
     *      present (the reference contract always throws a generic error).
     *
     * @param to     The recipient of the transfer.
     * @param amount The amount to transfer.
     */
    function _transferNativeTokens(
        address payable to,
        uint256 amount
    ) internal {
        // Ensure that the supplied amount is non-zero.
        _assertNonZeroAmount(amount);

        // Declare a variable indicating whether the call was successful or not.
        (bool success, ) = to.call{ value: amount }("");

        // If the call fails...
        if (!success) {
            // Revert with a generic error message.
            revert NativeTokenTransferGenericFailure(to, amount);
        }
    }

    /**
     * @dev Internal function to transfer ERC20 tokens from a given originator
     *      to a given recipient using a given conduit if applicable. Sufficient
     *      approvals must be set on this contract, the conduit.
     *
     * @param token                 The ERC20 token to transfer.
     * @param from                  The originator of the transfer.
     * @param to                    The recipient of the transfer.
     * @param amount                The amount to transfer.
     * @param conduitKey            A bytes32 value indicating what
     *                              corresponding conduit, if any, to source
     *                              token approvals from. The zero hash
     *                              signifies that no conduit should be used
     *                              (and direct approvals set on Consideration)
     * @param accumulatorStruct     A struct containing conduit transfer data
     *                              and its corresponding conduitKey.
     */
    function _transferERC20(
        address token,
        address from,
        address to,
        uint256 amount,
        bytes32 conduitKey,
        AccumulatorStruct memory accumulatorStruct
    ) internal {
        // Ensure that the supplied amount is non-zero.
        _assertNonZeroAmount(amount);

        // Trigger accumulated transfers if the conduits differ.
        _triggerIfArmedAndNotAccumulatable(accumulatorStruct, conduitKey);

        // If no conduit has been specified...
        if (conduitKey == bytes32(0)) {
            // Perform the token transfer directly.
            _performERC20Transfer(token, from, to, amount);
        } else {
            // Insert the call to the conduit into the accumulator.
            _insert(
                conduitKey,
                accumulatorStruct,
                ConduitItemType.ERC20,
                token,
                from,
                to,
                uint256(0),
                amount
            );
        }
    }

    /**
     * @dev Internal function to transfer a single ERC721 token from a given
     *      originator to a given recipient. Sufficient approvals must be set,
     *      either on the respective conduit or on this contract itself.
     *
     * @param token                 The ERC721 token to transfer.
     * @param from                  The originator of the transfer.
     * @param to                    The recipient of the transfer.
     * @param identifier            The tokenId to transfer.
     * @param amount                The "amount" (this value must be equal
     *                              to one).
     * @param conduitKey            A bytes32 value indicating what
     *                              corresponding conduit, if any, to source
     *                              token approvals from. The zero hash
     *                              signifies that no conduit should be used
     *                              (and direct approvals set on Consideration)
     * @param accumulatorStruct     A struct containing conduit transfer data
     *                              and its corresponding conduitKey.
     */
    function _transferERC721(
        address token,
        address from,
        address to,
        uint256 identifier,
        uint256 amount,
        bytes32 conduitKey,
        AccumulatorStruct memory accumulatorStruct
    ) internal {
        // Trigger accumulated transfers if the conduits differ.
        _triggerIfArmedAndNotAccumulatable(accumulatorStruct, conduitKey);

        // If no conduit has been specified...
        if (conduitKey == bytes32(0)) {
            // Ensure that exactly one 721 item is being transferred.
            if (amount != 1) {
                revert InvalidERC721TransferAmount(amount);
            }

            // Perform transfer via the token contract directly.
            _performERC721Transfer(token, from, to, identifier);
        } else {
            // Insert the call to the conduit into the accumulator.
            _insert(
                conduitKey,
                accumulatorStruct,
                ConduitItemType.ERC721,
                token,
                from,
                to,
                identifier,
                amount
            );
        }
    }

    /**
     * @dev Internal function to transfer ERC1155 tokens from a given originator
     *      to a given recipient. Sufficient approvals must be set, either on
     *      the respective conduit or on this contract itself.
     *
     * @param token                 The ERC1155 token to transfer.
     * @param from                  The originator of the transfer.
     * @param to                    The recipient of the transfer.
     * @param identifier            The tokenId to transfer.
     * @param amount                The amount to transfer.
     * @param conduitKey            A bytes32 value indicating what
     *                              corresponding conduit, if any, to source
     *                              token approvals from. The zero hash
     *                              signifies that no conduit should be used
     *                              (and direct approvals set on Consideration)
     * @param accumulatorStruct     A struct containing conduit transfer data
     *                              and its corresponding conduitKey.
     */
    function _transferERC1155(
        address token,
        address from,
        address to,
        uint256 identifier,
        uint256 amount,
        bytes32 conduitKey,
        AccumulatorStruct memory accumulatorStruct
    ) internal {
        // Ensure that the supplied amount is non-zero.
        _assertNonZeroAmount(amount);

        // Trigger accumulated transfers if the conduits differ.
        _triggerIfArmedAndNotAccumulatable(accumulatorStruct, conduitKey);

        // If no conduit has been specified...
        if (conduitKey == bytes32(0)) {
            // Perform transfer via the token contract directly.
            _performERC1155Transfer(token, from, to, identifier, amount);
        } else {
            // Insert the call to the conduit into the accumulator.
            _insert(
                conduitKey,
                accumulatorStruct,
                ConduitItemType.ERC1155,
                token,
                from,
                to,
                identifier,
                amount
            );
        }
    }

    /**
     * @dev Internal function to trigger a call to the conduit currently held by
     *      the accumulator if the accumulator contains item transfers (i.e. it
     *      is "armed") and the supplied conduit key does not match the key held
     *      by the accumulator.
     *
     * @param accumulatorStruct A struct containing conduit transfer data
     *                          and its corresponding conduitKey.
     * @param conduitKey        A bytes32 value indicating what corresponding
     *                          conduit, if any, to source token approvals
     *                          from. The zero hash signifies that no conduit
     *                          should be used (and direct approvals set on
     *                          Consideration)
     */
    function _triggerIfArmedAndNotAccumulatable(
        AccumulatorStruct memory accumulatorStruct,
        bytes32 conduitKey
    ) internal {
        // Perform conduit call if the set key does not match the supplied key.
        if (accumulatorStruct.conduitKey != conduitKey) {
            _triggerIfArmed(accumulatorStruct);
        }
    }

    /**
     * @dev Internal function to trigger a call to the conduit currently held by
     *      the accumulator if the accumulator contains item transfers (i.e. it
     *      is "armed").
     *
     * @param accumulatorStruct A struct containing conduit transfer data
     *                          and its corresponding conduitKey.
     */
    function _triggerIfArmed(
        AccumulatorStruct memory accumulatorStruct
    ) internal {
        // Exit if the accumulator is not "armed".
        if (accumulatorStruct.transfers.length == 0) {
            return;
        }

        // Perform conduit call.
        _trigger(accumulatorStruct);
    }

    /**
     * @dev Internal function to trigger a call to the conduit corresponding to
     *      a given conduit key, supplying all accumulated item transfers. The
     *      accumulator will be "disarmed" and reset in the process.
     *
     * @param accumulatorStruct A struct containing conduit transfer data
     *                          and its corresponding conduitKey.
     */
    function _trigger(AccumulatorStruct memory accumulatorStruct) internal {
        // Call the conduit with all the accumulated transfers.
        ConduitInterface(_getConduit(accumulatorStruct.conduitKey)).execute(
            accumulatorStruct.transfers
        );

        // Reset accumulator length to signal that it is now "disarmed".
        delete accumulatorStruct.transfers;
    }

    /**
     * @dev Internal pure function to place an item transfer into an accumulator
     *      that collects a series of transfers to execute against a given
     *      conduit in a single call.
     *
     * @param conduitKey        A bytes32 value indicating what
     *                          corresponding conduit, if any, to source
     *                          token approvals from. The zero hash
     *                          signifies that no conduit should be used
     *                          (and direct approvals set on Consideration)
     * @param accumulatorStruct A struct containing conduit transfer data
     *                          and its corresponding conduitKey.
     * @param itemType          The type of the item to transfer.
     * @param token             The token to transfer.
     * @param from              The originator of the transfer.
     * @param to                The recipient of the transfer.
     * @param identifier        The tokenId to transfer.
     * @param amount            The amount to transfer.
     */
    function _insert(
        bytes32 conduitKey,
        AccumulatorStruct memory accumulatorStruct,
        ConduitItemType itemType,
        address token,
        address from,
        address to,
        uint256 identifier,
        uint256 amount
    ) internal pure {
        /**
         *   The following is highly inefficient, but written this way to
         *   simply demonstrate what is performed by the optimized contract.
         */

        // Get the current length of the accumulator's transfers.
        uint256 currentTransferLength = accumulatorStruct.transfers.length;

        // Create a new array to "insert" the new transfer.
        ConduitTransfer[] memory newTransfers = (
            new ConduitTransfer[](currentTransferLength + 1)
        );

        // Fill new array with old transfers.
        for (uint256 i = 0; i < currentTransferLength; ++i) {
            // Get the old transfer.
            ConduitTransfer memory oldTransfer = accumulatorStruct.transfers[i];

            // Add the old transfer into the new array.
            newTransfers[i] = ConduitTransfer(
                oldTransfer.itemType,
                oldTransfer.token,
                oldTransfer.from,
                oldTransfer.to,
                oldTransfer.identifier,
                oldTransfer.amount
            );
        }

        // Insert new transfer into array.
        newTransfers[currentTransferLength] = ConduitTransfer(
            itemType,
            token,
            from,
            to,
            identifier,
            amount
        );

        // Set accumulator struct transfers to new transfers.
        accumulatorStruct.transfers = newTransfers;

        // Set the conduitkey of the current transfers.
        accumulatorStruct.conduitKey = conduitKey;
    }

    /**
     * @dev Internal function get the conduit derived by the provided
     *      conduit key.
     *
     * @param conduitKey A bytes32 value indicating what corresponding conduit,
     *                   if any, to source token approvals from. This value is
     *                   the "salt" parameter supplied by the deployer (i.e. the
     *                   conduit controller) when deploying the given conduit.
     *
     * @return conduit   The address of the conduit associated with the given
     *                   conduit key.
     */
    function _getConduit(
        bytes32 conduitKey
    ) internal view returns (address conduit) {
        // Derive the address of the conduit using the conduit key.
        conduit = _deriveConduit(conduitKey);

        // If the conduit does not have runtime code (i.e. is not deployed)...
        if (conduit.code.length == 0) {
            // Revert with an error indicating an invalid conduit.
            revert InvalidConduit(conduitKey, conduit);
        }
    }
}

File 23 of 43 : ReferenceZoneInteraction.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import { ZoneInterface } from "seaport-types/src/interfaces/ZoneInterface.sol";

import {
    ContractOffererInterface
} from "seaport-types/src/interfaces/ContractOffererInterface.sol";

import {
    ItemType,
    OrderType
} from "seaport-types/src/lib/ConsiderationEnums.sol";

import {
    AdditionalRecipient,
    AdvancedOrder,
    BasicOrderParameters,
    ReceivedItem,
    SpentItem,
    ZoneParameters
} from "seaport-types/src/lib/ConsiderationStructs.sol";

import { OrderToExecute } from "./ReferenceConsiderationStructs.sol";

import {
    ZoneInteractionErrors
} from "seaport-types/src/interfaces/ZoneInteractionErrors.sol";

/**
 * @title ZoneInteraction
 * @author 0age
 * @notice ZoneInteraction contains logic related to interacting with zones.
 */
contract ReferenceZoneInteraction is ZoneInteractionErrors {
    function _assertRestrictedBasicOrderAuthorization(
        bytes32 orderHash,
        OrderType orderType,
        BasicOrderParameters calldata basicOrderParameters,
        ItemType offeredItemType,
        ItemType receivedItemType
    ) internal {
        // Create a new array for the hash.
        bytes32[] memory orderHashes = new bytes32[](0);

        // Convert the order params and types to spent and received items.
        (
            SpentItem[] memory offer,
            ReceivedItem[] memory consideration
        ) = _convertToSpentAndReceivedItems(
                basicOrderParameters,
                offeredItemType,
                receivedItemType
            );

        // Order types 2-3 require zone or offerer be caller or zone to approve.
        // Note that in cases where fulfiller == zone, the restricted order
        // validation will be skipped.
        if (
            (orderType == OrderType.FULL_RESTRICTED ||
                orderType == OrderType.PARTIAL_RESTRICTED) &&
            msg.sender != basicOrderParameters.zone
        ) {
            // Validate the order with the zone.
            if (
                ZoneInterface(basicOrderParameters.zone).authorizeOrder(
                    ZoneParameters({
                        orderHash: orderHash,
                        fulfiller: msg.sender,
                        offerer: basicOrderParameters.offerer,
                        offer: offer,
                        consideration: consideration,
                        extraData: "",
                        orderHashes: orderHashes,
                        startTime: basicOrderParameters.startTime,
                        endTime: basicOrderParameters.endTime,
                        zoneHash: basicOrderParameters.zoneHash
                    })
                ) != ZoneInterface.authorizeOrder.selector
            ) {
                revert InvalidRestrictedOrder(orderHash);
            }
        }
    }

    /**
     * @dev Internal view function to determine if an order has a restricted
     *      order type and, if so, to ensure that either the offerer or the zone
     *      are the fulfiller or that a staticcall to `isValidOrder` on the zone
     *      returns a magic value indicating that the order is currently valid.
     *
     * @param orderHash             The hash of the order.
     * @param basicOrderParameters  The original basic order parameters.
     * @param offeredItemType       The type of the order.
     * @param receivedItemType      The offerer in question.
     */
    function _assertRestrictedBasicOrderValidity(
        bytes32 orderHash,
        OrderType orderType,
        BasicOrderParameters calldata basicOrderParameters,
        ItemType offeredItemType,
        ItemType receivedItemType
    ) internal {
        // Create a new array for the hash.
        bytes32[] memory orderHashes = new bytes32[](1);
        orderHashes[0] = orderHash;

        // Convert the order params and types to spent and received items.
        (
            SpentItem[] memory offer,
            ReceivedItem[] memory consideration
        ) = _convertToSpentAndReceivedItems(
                basicOrderParameters,
                offeredItemType,
                receivedItemType
            );

        // Order types 2-3 require zone or offerer be caller or zone to approve.
        // Note that in cases where fulfiller == zone, the restricted order
        // validation will be skipped.
        if (
            (orderType == OrderType.FULL_RESTRICTED ||
                orderType == OrderType.PARTIAL_RESTRICTED) &&
            msg.sender != basicOrderParameters.zone
        ) {
            // Validate the order with the zone.
            if (
                ZoneInterface(basicOrderParameters.zone).validateOrder(
                    ZoneParameters({
                        orderHash: orderHash,
                        fulfiller: msg.sender,
                        offerer: basicOrderParameters.offerer,
                        offer: offer,
                        consideration: consideration,
                        extraData: "",
                        orderHashes: orderHashes,
                        startTime: basicOrderParameters.startTime,
                        endTime: basicOrderParameters.endTime,
                        zoneHash: basicOrderParameters.zoneHash
                    })
                ) != ZoneInterface.validateOrder.selector
            ) {
                revert InvalidRestrictedOrder(orderHash);
            }
        }
    }

    /**
     * @dev Internal function to check if a restricted advanced order is
     *      authorized by its zone or offerer, in cases where the caller is not
     *      the zone or offerer.
     *
     * @param advancedOrder        The advanced order in question.
     * @param orderToExecute       The order to execute.
     * @param orderHashes          The order hashes of each order supplied
     *                             alongside the current order as part of a
                                   "match" or "fulfill available" variety of
                                   order fulfillment.
     * @param orderHash            The hash of the order to execute.
     * @param revertOnUnauthorized A boolean indicating whether the function
     *                             should revert if the order is invalid.
     *
     * @return authorized          A boolean indicating whether the order is
     *                             authorized by the zone or offerer.
     * @return checked             A boolean indicating whether the order has
     *                             been checked for authorization.
     */
    function _checkRestrictedAdvancedOrderAuthorization(
        AdvancedOrder memory advancedOrder,
        OrderToExecute memory orderToExecute,
        bytes32[] memory orderHashes,
        bytes32 orderHash,
        bool revertOnUnauthorized
    ) internal returns (bool authorized, bool checked) {
        // Order types 2-3 require zone or offerer be caller or zone to approve.
        if (
            (advancedOrder.parameters.orderType == OrderType.FULL_RESTRICTED ||
                advancedOrder.parameters.orderType ==
                OrderType.PARTIAL_RESTRICTED) &&
            msg.sender != advancedOrder.parameters.zone
        ) {
            // Authorize the order.
            try
                ZoneInterface(advancedOrder.parameters.zone).authorizeOrder(
                    ZoneParameters({
                        orderHash: orderHash,
                        fulfiller: msg.sender,
                        offerer: advancedOrder.parameters.offerer,
                        offer: orderToExecute.spentItems,
                        consideration: orderToExecute.receivedItems,
                        extraData: advancedOrder.extraData,
                        orderHashes: orderHashes,
                        startTime: advancedOrder.parameters.startTime,
                        endTime: advancedOrder.parameters.endTime,
                        zoneHash: advancedOrder.parameters.zoneHash
                    })
                )
            returns (bytes4 selector) {
                if (selector != ZoneInterface.authorizeOrder.selector) {
                    revert InvalidRestrictedOrder(orderHash);
                }

                return (true, true);
            } catch {
                if (revertOnUnauthorized) {
                    revert InvalidRestrictedOrder(orderHash);
                }

                return (false, false);
            }
        } else {
            return (true, false);
        }
    }

    /**
     * @dev Internal function to validate that a restricted advanced order is
     *      authorized by its zone or offerer, in cases where the caller is not
     *      the zone or offerer.
     *
     * @param advancedOrder        The advanced order in question.
     * @param orderToExecute       The order to execute.
     * @param orderHashes          The order hashes of each order supplied
     *                             alongside the current order as part of a
                                   "match" or "fulfill available" variety of
                                   order fulfillment.
     * @param orderHash            The hash of the order to execute.
     * @param zoneHash             The hash to provide upon calling the zone.
     * @param orderType            The type of the order.
     * @param offerer              The offerer in question.
     * @param zone                 The zone in question.
     */
    function _assertRestrictedAdvancedOrderAuthorization(
        AdvancedOrder memory advancedOrder,
        OrderToExecute memory orderToExecute,
        bytes32[] memory orderHashes,
        bytes32 orderHash,
        bytes32 zoneHash,
        OrderType orderType,
        address offerer,
        address zone
    ) internal {
        // Order types 2-3 require zone or offerer be caller or zone to approve.
        if (
            (orderType == OrderType.FULL_RESTRICTED ||
                orderType == OrderType.PARTIAL_RESTRICTED) && msg.sender != zone
        ) {
            // Authorize the order.
            if (
                ZoneInterface(zone).authorizeOrder(
                    ZoneParameters({
                        orderHash: orderHash,
                        fulfiller: msg.sender,
                        offerer: offerer,
                        offer: orderToExecute.spentItems,
                        consideration: orderToExecute.receivedItems,
                        extraData: advancedOrder.extraData,
                        orderHashes: orderHashes,
                        startTime: advancedOrder.parameters.startTime,
                        endTime: advancedOrder.parameters.endTime,
                        zoneHash: zoneHash
                    })
                ) != ZoneInterface.authorizeOrder.selector
            ) {
                revert InvalidRestrictedOrder(orderHash);
            }
        }
    }

    /**
     * @dev Internal view function to determine if a proxy should be utilized
     *      for a given order and to ensure that the submitter is allowed by the
     *      order type.
     *
     * @param advancedOrder  The order in question.
     * @param orderHashes    The order hashes of each order supplied alongside
     *                       the current order as part of a "match" or "fulfill
     *                       available" variety of order fulfillment.
     * @param orderHash      The hash of the order.
     * @param zoneHash       The hash to provide upon calling the zone.
     * @param orderType      The type of the order.
     * @param offerer        The offerer in question.
     * @param zone           The zone in question.
     */
    function _assertRestrictedAdvancedOrderValidity(
        AdvancedOrder memory advancedOrder,
        OrderToExecute memory orderToExecute,
        bytes32[] memory orderHashes,
        bytes32 orderHash,
        bytes32 zoneHash,
        OrderType orderType,
        address offerer,
        address zone
    ) internal {
        // Order types 2-3 require zone or offerer be caller or zone to approve.
        if (
            (orderType == OrderType.FULL_RESTRICTED ||
                orderType == OrderType.PARTIAL_RESTRICTED) && msg.sender != zone
        ) {
            // Validate the order.
            if (
                ZoneInterface(zone).validateOrder(
                    ZoneParameters({
                        orderHash: orderHash,
                        fulfiller: msg.sender,
                        offerer: offerer,
                        offer: orderToExecute.spentItems,
                        consideration: orderToExecute.receivedItems,
                        extraData: advancedOrder.extraData,
                        orderHashes: orderHashes,
                        startTime: advancedOrder.parameters.startTime,
                        endTime: advancedOrder.parameters.endTime,
                        zoneHash: zoneHash
                    })
                ) != ZoneInterface.validateOrder.selector
            ) {
                revert InvalidRestrictedOrder(orderHash);
            }
        } else if (orderType == OrderType.CONTRACT) {
            // Ratify the contract order.
            if (
                ContractOffererInterface(offerer).ratifyOrder(
                    orderToExecute.spentItems,
                    orderToExecute.receivedItems,
                    advancedOrder.extraData,
                    orderHashes,
                    uint256(orderHash) ^ (uint256(uint160(offerer)) << 96)
                ) != ContractOffererInterface.ratifyOrder.selector
            ) {
                revert InvalidContractOrder(orderHash);
            }
        }
    }

    /**
     * @dev Converts the offer and consideration parameters from a
     *      BasicOrderParameters object into an array of SpentItem and
     *      ReceivedItem objects.
     *
     * @param parameters            The BasicOrderParameters object containing
     *                              the offer and consideration parameters to be
     *                              converted.
     * @param offerItemType         The item type of the offer.
     * @param considerationItemType The item type of the consideration.
     *
     * @return spentItems           The converted offer parameters as an array
     *                              of SpentItem objects.
     * @return receivedItems        The converted consideration parameters as an
     *                              array of ReceivedItem objects.
     */
    function _convertToSpentAndReceivedItems(
        BasicOrderParameters calldata parameters,
        ItemType offerItemType,
        ItemType considerationItemType
    ) internal pure returns (SpentItem[] memory, ReceivedItem[] memory) {
        // Create the spent item.
        SpentItem[] memory spentItems = new SpentItem[](1);
        spentItems[0] = SpentItem({
            itemType: offerItemType,
            token: parameters.offerToken,
            amount: parameters.offerAmount,
            identifier: parameters.offerIdentifier
        });

        // Create the received item.
        ReceivedItem[] memory receivedItems = new ReceivedItem[](
            1 + parameters.additionalRecipients.length
        );
        address token = parameters.considerationToken;
        uint256 amount = parameters.considerationAmount;
        uint256 identifier = parameters.considerationIdentifier;
        receivedItems[0] = ReceivedItem({
            itemType: considerationItemType,
            token: token,
            amount: amount,
            identifier: identifier,
            recipient: parameters.offerer
        });

        // Iterate through the additional recipients and create the received
        // items.
        for (uint256 i = 0; i < parameters.additionalRecipients.length; i++) {
            AdditionalRecipient calldata additionalRecipient = parameters
                .additionalRecipients[i];
            amount = additionalRecipient.amount;
            receivedItems[i + 1] = ReceivedItem({
                itemType: offerItemType == ItemType.ERC20
                    ? ItemType.ERC20
                    : considerationItemType,
                token: offerItemType == ItemType.ERC20
                    ? parameters.offerToken
                    : token,
                amount: amount,
                identifier: offerItemType == ItemType.ERC20 ? 0 : identifier,
                recipient: additionalRecipient.recipient
            });
        }

        // Return the spent and received items.
        return (spentItems, receivedItems);
    }
}

File 24 of 43 : ReferenceGenerateOrderReturndataDecoder.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import {
    ReceivedItem,
    SpentItem
} from "seaport-types/src/lib/ConsiderationStructs.sol";

contract ReferenceGenerateOrderReturndataDecoder {
    function decode(
        bytes calldata returnedBytes
    ) external pure returns (SpentItem[] memory, ReceivedItem[] memory) {
        return abi.decode(returnedBytes, (SpentItem[], ReceivedItem[]));
    }
}

File 25 of 43 : IERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

pragma solidity ^0.8.7;

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

File 26 of 43 : ConduitInterface.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import {
    ConduitBatch1155Transfer,
    ConduitTransfer
} from "../conduit/lib/ConduitStructs.sol";

/**
 * @title ConduitInterface
 * @author 0age
 * @notice ConduitInterface contains all external function interfaces, events,
 *         and errors for conduit contracts.
 */
interface ConduitInterface {
    /**
     * @dev Revert with an error when attempting to execute transfers using a
     *      caller that does not have an open channel.
     */
    error ChannelClosed(address channel);

    /**
     * @dev Revert with an error when attempting to update a channel to the
     *      current status of that channel.
     */
    error ChannelStatusAlreadySet(address channel, bool isOpen);

    /**
     * @dev Revert with an error when attempting to execute a transfer for an
     *      item that does not have an ERC20/721/1155 item type.
     */
    error InvalidItemType();

    /**
     * @dev Revert with an error when attempting to update the status of a
     *      channel from a caller that is not the conduit controller.
     */
    error InvalidController();

    /**
     * @dev Emit an event whenever a channel is opened or closed.
     *
     * @param channel The channel that has been updated.
     * @param open    A boolean indicating whether the conduit is open or not.
     */
    event ChannelUpdated(address indexed channel, bool open);

    /**
     * @notice Execute a sequence of ERC20/721/1155 transfers. Only a caller
     *         with an open channel can call this function.
     *
     * @param transfers The ERC20/721/1155 transfers to perform.
     *
     * @return magicValue A magic value indicating that the transfers were
     *                    performed successfully.
     */
    function execute(
        ConduitTransfer[] calldata transfers
    ) external returns (bytes4 magicValue);

    /**
     * @notice Execute a sequence of batch 1155 transfers. Only a caller with an
     *         open channel can call this function.
     *
     * @param batch1155Transfers The 1155 batch transfers to perform.
     *
     * @return magicValue A magic value indicating that the transfers were
     *                    performed successfully.
     */
    function executeBatch1155(
        ConduitBatch1155Transfer[] calldata batch1155Transfers
    ) external returns (bytes4 magicValue);

    /**
     * @notice Execute a sequence of transfers, both single and batch 1155. Only
     *         a caller with an open channel can call this function.
     *
     * @param standardTransfers  The ERC20/721/1155 transfers to perform.
     * @param batch1155Transfers The 1155 batch transfers to perform.
     *
     * @return magicValue A magic value indicating that the transfers were
     *                    performed successfully.
     */
    function executeWithBatch1155(
        ConduitTransfer[] calldata standardTransfers,
        ConduitBatch1155Transfer[] calldata batch1155Transfers
    ) external returns (bytes4 magicValue);

    /**
     * @notice Open or close a given channel. Only callable by the controller.
     *
     * @param channel The channel to open or close.
     * @param isOpen  The status of the channel (either open or closed).
     */
    function updateChannel(address channel, bool isOpen) external;
}

File 27 of 43 : ZoneInterface.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import { ZoneParameters, Schema } from "../lib/ConsiderationStructs.sol";

import { IERC165 } from "./IERC165.sol";

/**
 * @title  ZoneInterface
 * @notice Contains functions exposed by a zone.
 */
interface ZoneInterface is IERC165 {
    /**
     * @dev Authorizes an order before any token fulfillments from any order
     *      have been executed by Seaport.
     *
     * @param zoneParameters The context about the order fulfillment and any
     *                       supplied extraData.
     *
     * @return authorizedOrderMagicValue The magic value that indicates a valid
     *                              order.
     */
    function authorizeOrder(
        ZoneParameters calldata zoneParameters
    ) external returns (bytes4 authorizedOrderMagicValue);

    /**
     * @dev Validates an order after all token fulfillments for all orders have
     *      been executed by Seaport.
     *
     * @param zoneParameters The context about the order fulfillment and any
     *                       supplied extraData.
     *
     * @return validOrderMagicValue The magic value that indicates a valid
     *                              order.
     */
    function validateOrder(
        ZoneParameters calldata zoneParameters
    ) external returns (bytes4 validOrderMagicValue);

    /**
     * @dev Returns the metadata for this zone.
     *
     * @return name The name of the zone.
     * @return schemas The schemas that the zone implements.
     */
    function getSeaportMetadata()
        external
        view
        returns (string memory name, Schema[] memory schemas); // map to SIP IDs

    /**
     * @dev Returns a boolean indicating if a given interface is supported in
     *      accordance with ERC-165.
     *
     * @param interfaceId the ERC-165 interface ID.
     *
     * @return a boolean indicating whether the interface is supported.
     */
    function supportsInterface(
        bytes4 interfaceId
    ) external view override returns (bool);
}

File 28 of 43 : ZoneInteractionErrors.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

/**
 * @title ZoneInteractionErrors
 * @author 0age
 * @notice ZoneInteractionErrors contains errors related to zone interaction.
 */
interface ZoneInteractionErrors {
    /**
     * @dev Revert with an error when attempting to fill an order that specifies
     *      a restricted submitter as its order type when not submitted by
     *      either the offerer or the order's zone or approved as valid by the
     *      zone in question via a call to `isValidOrder`.
     *
     * @param orderHash The order hash for the invalid restricted order.
     */
    error InvalidRestrictedOrder(bytes32 orderHash);

    /**
     * @dev Revert with an error when attempting to fill a contract order that
     *      fails to generate an order successfully, that does not adhere to the
     *      requirements for minimum spent or maximum received supplied by the
     *      fulfiller, or that fails the post-execution `ratifyOrder` check..
     *
     * @param orderHash The order hash for the invalid contract order.
     */
    error InvalidContractOrder(bytes32 orderHash);
}

File 29 of 43 : ReferenceVerifiers.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import { OrderStatus } from "seaport-types/src/lib/ConsiderationStructs.sol";

import { ReferenceAssertions } from "./ReferenceAssertions.sol";

import {
    ReferenceSignatureVerification
} from "./ReferenceSignatureVerification.sol";

/**
 * @title Verifiers
 * @author 0age
 * @notice Verifiers contains functions for performing verifications.
 */
contract ReferenceVerifiers is
    ReferenceAssertions,
    ReferenceSignatureVerification
{
    /**
     * @dev Derive and set hashes, reference chainId, and associated domain
     *      separator during deployment.
     *
     * @param conduitController A contract that deploys conduits, or proxies
     *                          that may optionally be used to transfer approved
     *                          ERC20/721/1155 tokens.
     */
    constructor(
        address conduitController
    ) ReferenceAssertions(conduitController) {}

    /**
     * @dev Internal view function to ensure that the current time falls within
     *      an order's valid timespan.
     *
     * @param startTime       The time at which the order becomes active.
     * @param endTime         The time at which the order becomes inactive.
     * @param revertOnInvalid A boolean indicating whether to revert if the
     *                        order is not active.
     *
     * @return valid A boolean indicating whether the order is active.
     */
    function _verifyTime(
        uint256 startTime,
        uint256 endTime,
        bool revertOnInvalid
    ) internal view returns (bool valid) {
        // Revert if order's timespan hasn't started yet or has already ended.
        if (startTime > block.timestamp || endTime <= block.timestamp) {
            // Only revert if revertOnInvalid has been supplied as true.
            if (revertOnInvalid) {
                revert InvalidTime(startTime, endTime);
            }

            // Return false as the order is invalid.
            return false;
        }

        // Return true as the order time is valid.
        valid = true;
    }

    /**
     * @dev Internal view function to verify the signature of an order. An
     *      ERC-1271 fallback will be attempted if either the signature length
     *      is not 64 or 65 bytes or if the recovered signer does not match the
     *      supplied offerer. Note that in cases where a 64 or 65 byte signature
     *      is supplied, only standard ECDSA signatures that recover to a
     *      non-zero address are supported.
     *
     * @param offerer   The offerer for the order.
     * @param orderHash The order hash.
     * @param signature A signature from the offerer indicating that the order
     *                  has been approved.
     */
    function _verifySignature(
        address offerer,
        bytes32 orderHash,
        bytes memory signature
    ) internal view {
        // Skip signature verification if the offerer is the caller.
        if (offerer == msg.sender) {
            return;
        }

        bytes32 domainSeparator = _domainSeparator();

        // Derive original EIP-712 digest using domain separator and order hash.
        bytes32 originalDigest = _deriveEIP712Digest(
            domainSeparator,
            orderHash
        );

        bytes32 digest;
        bytes memory extractedSignature;
        if (_isValidBulkOrderSize(signature)) {
            // Rederive order hash and digest using bulk order proof.
            (orderHash, extractedSignature) = _computeBulkOrderProof(
                signature,
                orderHash
            );
            digest = _deriveEIP712Digest(domainSeparator, orderHash);
        } else {
            digest = originalDigest;
            extractedSignature = signature;
        }

        // Ensure that the signature for the digest is valid for the offerer.
        _assertValidSignature(
            offerer,
            digest,
            originalDigest,
            signature,
            extractedSignature
        );
    }

    /**
     * @dev Determines whether the specified bulk order size is valid.
     *
     * @param signature The signature of the bulk order to check.
     *
     * @return validLength True if bulk order size is valid, false otherwise.
     */
    function _isValidBulkOrderSize(
        bytes memory signature
    ) internal pure returns (bool validLength) {
        validLength =
            signature.length < 837 &&
            signature.length > 98 &&
            ((signature.length - 67) % 32) < 2;
    }

    /**
     * @dev Computes the bulk order hash for the specified proof and leaf. Note
     *      that if an index that exceeds the number of orders in the bulk order
     *      payload will instead "wrap around" and refer to an earlier index.
     *
     * @param proofAndSignature The proof and signature of the bulk order.
     * @param leaf              The leaf of the bulk order tree.
     *
     * @return bulkOrderHash The bulk order hash.
     * @return signature     The signature of the bulk order.
     */
    function _computeBulkOrderProof(
        bytes memory proofAndSignature,
        bytes32 leaf
    ) internal view returns (bytes32 bulkOrderHash, bytes memory signature) {
        bytes32 root = leaf;

        // proofAndSignature with odd length is a compact signature (64 bytes).
        uint256 length = proofAndSignature.length % 2 == 0 ? 65 : 64;

        // Create a new array of bytes equal to the length of the signature.
        signature = new bytes(length);

        // Iterate over each byte in the signature.
        for (uint256 i = 0; i < length; ++i) {
            // Assign the byte from the proofAndSignature to the signature.
            signature[i] = proofAndSignature[i];
        }

        // Compute the key by extracting the next three bytes from the
        // proofAndSignature.
        uint256 key = (((uint256(uint8(proofAndSignature[length])) << 16) |
            ((uint256(uint8(proofAndSignature[length + 1]))) << 8)) |
            (uint256(uint8(proofAndSignature[length + 2]))));

        uint256 height = (proofAndSignature.length - length) / 32;

        // Create an array of bytes32 to hold the proof elements.
        bytes32[] memory proofElements = new bytes32[](height);

        // Iterate over each proof element.
        for (uint256 elementIndex = 0; elementIndex < height; ++elementIndex) {
            // Compute the starting index for the current proof element.
            uint256 start = (length + 3) + (elementIndex * 32);

            // Create a new array of bytes to hold the current proof element.
            bytes memory buffer = new bytes(32);

            // Iterate over each byte in the proof element.
            for (uint256 i = 0; i < 32; ++i) {
                // Assign the byte from the proofAndSignature to the buffer.
                buffer[i] = proofAndSignature[start + i];
            }

            // Decode the current proof element from the buffer and assign it to
            // the proofElements array.
            proofElements[elementIndex] = abi.decode(buffer, (bytes32));
        }

        // Iterate over each proof element.
        for (uint256 i = 0; i < proofElements.length; ++i) {
            // Retrieve the proof element.
            bytes32 proofElement = proofElements[i];

            // Check if the current bit of the key is set.
            if ((key >> i) % 2 == 0) {
                // If the current bit is not set, then concatenate the root and
                // the proof element, and compute the keccak256 hash of the
                // concatenation to assign it to the root.
                root = keccak256(abi.encodePacked(root, proofElement));
            } else {
                // If the current bit is set, then concatenate the proof element
                // and the root, and compute the keccak256 hash of the
                // concatenation to assign it to the root.
                root = keccak256(abi.encodePacked(proofElement, root));
            }
        }

        // Compute the bulk order hash and return it.
        bulkOrderHash = keccak256(
            abi.encodePacked(_bulkOrderTypehashes[height], root)
        );

        // Return the signature.
        return (bulkOrderHash, signature);
    }

    /**
     * @dev Internal view function to validate that a given order is fillable
     *      and not cancelled based on the order status.
     *
     * @param orderHash       The order hash.
     * @param orderStatus     The status of the order, including whether it has
     *                        been cancelled and the fraction filled.
     * @param onlyAllowUnused A boolean flag indicating whether partial fills
     *                        are supported by the calling function.
     * @param revertOnInvalid A boolean indicating whether to revert if the
     *                        order has been cancelled or filled beyond the
     *                        allowable amount.
     *
     * @return valid A boolean indicating whether the order is valid.
     */
    function _verifyOrderStatus(
        bytes32 orderHash,
        OrderStatus storage orderStatus,
        bool onlyAllowUnused,
        bool revertOnInvalid
    ) internal view returns (bool valid) {
        // Ensure that the order has not been cancelled.
        if (orderStatus.isCancelled) {
            // Only revert if revertOnInvalid has been supplied as true.
            if (revertOnInvalid) {
                revert OrderIsCancelled(orderHash);
            }

            // Return false as the order status is invalid.
            return false;
        }

        // Read order status numerator from storage and place on stack.
        uint256 orderStatusNumerator = orderStatus.numerator;

        // If the order is not entirely unused...
        if (orderStatusNumerator != 0) {
            // ensure the order has not been partially filled when not allowed.
            if (onlyAllowUnused) {
                // Always revert on partial fills when onlyAllowUnused is true.
                revert OrderPartiallyFilled(orderHash);
                // Otherwise, ensure that order has not been entirely filled.
            } else if (orderStatusNumerator >= orderStatus.denominator) {
                // Only revert if revertOnInvalid has been supplied as true.
                if (revertOnInvalid) {
                    revert OrderAlreadyFilled(orderHash);
                }

                // Return false as the order status is invalid.
                return false;
            }
        }

        // Return true as the order status is valid.
        valid = true;
    }
}

File 30 of 43 : ReferenceTokenTransferrer.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import {
    ERC20Interface,
    ERC721Interface,
    ERC1155Interface
} from "seaport-types/src/interfaces/AbridgedTokenInterfaces.sol";

import {
    TokenTransferrerErrors
} from "seaport-types/src/interfaces/TokenTransferrerErrors.sol";

contract ReferenceTokenTransferrer is TokenTransferrerErrors {
    /**
     * @dev Internal function to transfer ERC20 tokens from a given originator
     *      to a given recipient. Sufficient approvals must be set on the
     *      contract performing the transfer.
     *
     * @param token      The ERC20 token to transfer.
     * @param from       The originator of the transfer.
     * @param to         The recipient of the transfer.
     * @param amount     The amount to transfer.
     */
    function _performERC20Transfer(
        address token,
        address from,
        address to,
        uint256 amount
    ) internal {
        // If the provided token is not a contract, revert.
        if (token.code.length == 0) {
            revert NoContract(token);
        }

        // Attempt to transfer the tokens.
        (bool ok, bytes memory data) = token.call(
            abi.encodeWithSelector(
                ERC20Interface.transferFrom.selector,
                from,
                to,
                amount
            )
        );

        // NOTE: revert reasons are not "bubbled up" at the moment
        if (!ok) {
            revert TokenTransferGenericFailure(token, from, to, 0, amount);
        }

        // If the token does not return a boolean, revert.
        if (data.length != 0 && data.length >= 32) {
            if (!abi.decode(data, (bool))) {
                revert BadReturnValueFromERC20OnTransfer(
                    token,
                    from,
                    to,
                    amount
                );
            }
        }
    }

    /**
     * @dev Internal function to transfer an ERC721 token from a given
     *      originator to a given recipient. Sufficient approvals must be set on
     *      the contract performing the transfer.
     *
     * @param token      The ERC721 token to transfer.
     * @param from       The originator of the transfer.
     * @param to         The recipient of the transfer.
     * @param identifier The tokenId to transfer.
     */
    function _performERC721Transfer(
        address token,
        address from,
        address to,
        uint256 identifier
    ) internal {
        // If the provided token is not a contract, revert.
        if (token.code.length == 0) {
            revert NoContract(token);
        }

        ERC721Interface(token).transferFrom(from, to, identifier);
    }

    /**
     * @dev Internal function to transfer ERC1155 tokens from a given
     *      originator to a given recipient. Sufficient approvals must be set on
     *      the contract performing the transfer and contract recipients must
     *      implement onReceived to indicate that they are willing to accept the
     *      transfer.
     *
     * @param token      The ERC1155 token to transfer.
     * @param from       The originator of the transfer.
     * @param to         The recipient of the transfer.
     * @param identifier The id to transfer.
     * @param amount     The amount to transfer.
     */
    function _performERC1155Transfer(
        address token,
        address from,
        address to,
        uint256 identifier,
        uint256 amount
    ) internal {
        // If the provided token is not a contract, revert.
        if (token.code.length == 0) {
            revert NoContract(token);
        }

        ERC1155Interface(token).safeTransferFrom(
            from,
            to,
            identifier,
            amount,
            ""
        );
    }

    /**
     * @dev Internal function to transfer ERC1155 tokens from a given
     *      originator to a given recipient. Sufficient approvals must be set on
     *      the contract performing the transfer and contract recipients must
     *      implement onReceived to indicate that they are willing to accept the
     *      transfer.
     *
     * @param token       The ERC1155 token to transfer in batch.
     * @param from        The originator of the transfer batch.
     * @param to          The recipient of the transfer batch.
     * @param identifiers The ids to transfer.
     * @param amounts     The amounts to transfer.
     */
    function _performERC1155BatchTransfer(
        address token,
        address from,
        address to,
        uint256[] memory identifiers,
        uint256[] memory amounts
    ) internal {
        // If the provided token is not a contract, revert.
        if (token.code.length == 0) {
            revert NoContract(token);
        }

        ERC1155Interface(token).safeBatchTransferFrom(
            from,
            to,
            identifiers,
            amounts,
            ""
        );
    }
}

File 31 of 43 : ReferenceAssertions.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import {
    OrderParameters
} from "seaport-types/src/lib/ConsiderationStructs.sol";

import { ReferenceGettersAndDerivers } from "./ReferenceGettersAndDerivers.sol";

import {
    TokenTransferrerErrors
} from "seaport-types/src/interfaces/TokenTransferrerErrors.sol";

import { ReferenceCounterManager } from "./ReferenceCounterManager.sol";

/**
 * @title Assertions
 * @author 0age
 * @notice Assertions contains logic for making various assertions that do not
 *         fit neatly within a dedicated semantic scope.
 */
contract ReferenceAssertions is
    ReferenceGettersAndDerivers,
    ReferenceCounterManager,
    TokenTransferrerErrors
{
    /**
     * @dev Derive and set hashes, reference chainId, and associated domain
     *      separator during deployment.
     *
     * @param conduitController A contract that deploys conduits, or proxies
     *                          that may optionally be used to transfer approved
     *                          ERC20/721/1155 tokens.
     */
    constructor(
        address conduitController
    ) ReferenceGettersAndDerivers(conduitController) {}

    /**
     * @dev Internal view function to ensure that the supplied consideration
     *      array length on a given set of order parameters is not less than the
     *      original consideration array length for that order and to retrieve
     *      the current counter for a given order's offerer and zone and use it
     *      to  derive the order hash.
     *
     * @param orderParameters The parameters of the order to hash.
     *
     * @return orderHash The order hash.
     */
    function _assertConsiderationLengthAndGetOrderHash(
        OrderParameters memory orderParameters
    ) internal view returns (bytes32 orderHash) {
        // Ensure supplied consideration array length is not less than original.
        _assertConsiderationLengthIsNotLessThanOriginalConsiderationLength(
            orderParameters.consideration.length,
            orderParameters.totalOriginalConsiderationItems
        );

        // Derive and return order hash using current counter for the offerer.
        orderHash = _deriveOrderHash(
            orderParameters,
            _getCounter(orderParameters.offerer)
        );
    }

    /**
     * @dev Internal pure function to ensure that the supplied consideration
     *      array length for an order to be fulfilled is not less than the
     *      original consideration array length for that order.
     *
     * @param suppliedConsiderationItemTotal The number of consideration items
     *                                       supplied when fulfilling the order.
     * @param originalConsiderationItemTotal The number of consideration items
     *                                       supplied on initial order creation.
     */
    function _assertConsiderationLengthIsNotLessThanOriginalConsiderationLength(
        uint256 suppliedConsiderationItemTotal,
        uint256 originalConsiderationItemTotal
    ) internal pure {
        // Ensure supplied consideration array length is not less than original.
        if (suppliedConsiderationItemTotal < originalConsiderationItemTotal) {
            revert MissingOriginalConsiderationItems();
        }
    }

    /**
     * @dev Internal pure function to ensure that a given item amount in not
     *      zero.
     *
     * @param amount The amount to check.
     */
    function _assertNonZeroAmount(uint256 amount) internal pure {
        if (amount == 0) {
            revert MissingItemAmount();
        }
    }

    /**
     * @dev Internal pure function to validate calldata offsets for dynamic
     *      types in BasicOrderParameters and other parameters. This ensures
     *      that functions using the calldata object normally will be using the
     *      same data as the assembly functions and that values that are bound
     *      to a given range are within that range. Note that no parameters are
     *      supplied as all basic order functions use the same calldata
     *      encoding.
     */
    function _assertValidBasicOrderParameters() internal pure {
        /*
         * Checks:
         * 1. Order parameters struct offset == 0x20
         * 2. Additional recipients arr offset == 0x200
         * 3. Signature offset == 0x240 + (recipients.length * 0x40)
         * 4. BasicOrderType between 0 and 23 (i.e. < 24)
         */
        // Declare a boolean designating basic order parameter offset validity.
        bool validOffsets = (abi.decode(msg.data[4:36], (uint256)) == 32 &&
            abi.decode(msg.data[548:580], (uint256)) == 576 &&
            abi.decode(msg.data[580:612], (uint256)) ==
            608 + 64 * abi.decode(msg.data[612:644], (uint256))) &&
            abi.decode(msg.data[292:324], (uint256)) < 24;

        // Revert with an error if basic order parameter offsets are invalid.
        if (!validOffsets) {
            revert InvalidBasicOrderParameterEncoding();
        }
    }
}

File 32 of 43 : ReferenceSignatureVerification.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import {
    EIP1271Interface
} from "seaport-types/src/interfaces/EIP1271Interface.sol";

import {
    SignatureVerificationErrors
} from "seaport-types/src/interfaces/SignatureVerificationErrors.sol";

import {
    EIP2098_allButHighestBitMask
} from "seaport-types/src/lib/ConsiderationConstants.sol";

/**
 * @title SignatureVerification
 * @author 0age
 * @notice SignatureVerification contains logic for verifying signatures.
 */
contract ReferenceSignatureVerification is SignatureVerificationErrors {
    /**
     * @dev Internal view function to verify the signature of an order. An
     *      ERC-1271 fallback will be attempted if either the signature length
     *      is not 64 or 65 bytes or if the recovered signer does not match the
     *      supplied signer. Note that in cases where a 64 or 65 byte signature
     *      is supplied, only standard ECDSA signatures that recover to a
     *      non-zero address are supported.
     *
     * @param signer            The signer for the order.
     * @param digest            The digest to verify signature against.
     * @param originalDigest    The original digest to verify signature against.
     * @param originalSignature The original signature.
     * @param signature         A signature from the signer indicating that the
     *                          order has been approved.
     */
    function _assertValidSignature(
        address signer,
        bytes32 digest,
        bytes32 originalDigest,
        bytes memory originalSignature,
        bytes memory signature
    ) internal view {
        // Declare r, s, and v signature parameters.
        bytes32 r;
        bytes32 s;
        uint8 v;

        if (signer.code.length > 0) {
            // If signer is a contract, try verification via EIP-1271.
            _assertValidEIP1271Signature(
                signer,
                originalDigest,
                originalSignature
            );

            // Return early if the ERC-1271 signature check succeeded.
            return;
        } else if (signature.length == 64) {
            // If signature contains 64 bytes, parse as EIP-2098 sig. (r+s&v)
            // Declare temporary vs that will be decomposed into s and v.
            bytes32 vs;

            // Decode signature into r, vs.
            (r, vs) = abi.decode(signature, (bytes32, bytes32));

            // Decompose vs into s and v.
            s = vs & EIP2098_allButHighestBitMask;

            // If the highest bit is set, v = 28, otherwise v = 27.
            v = uint8(uint256(vs >> 255)) + 27;
        } else if (signature.length == 65) {
            (r, s) = abi.decode(signature, (bytes32, bytes32));
            v = uint8(signature[64]);

            // Ensure v value is properly formatted.
            if (v != 27 && v != 28) {
                revert BadSignatureV(v);
            }
        } else {
            revert InvalidSignature();
        }

        // Attempt to recover signer using the digest and signature parameters.
        address recoveredSigner = ecrecover(digest, v, r, s);

        // Disallow invalid signers.
        if (recoveredSigner == address(0) || recoveredSigner != signer) {
            revert InvalidSigner();
            // Should a signer be recovered, but it doesn't match the signer...
        }
    }

    /**
     * @dev Internal view function to verify the signature of an order using
     *      ERC-1271 (i.e. contract signatures via `isValidSignature`).
     *
     * @param signer    The signer for the order.
     * @param digest    The signature digest, derived from the domain separator
     *                  and the order hash.
     * @param signature A signature (or other data) used to validate the digest.
     */
    function _assertValidEIP1271Signature(
        address signer,
        bytes32 digest,
        bytes memory signature
    ) internal view {
        if (
            EIP1271Interface(signer).isValidSignature(digest, signature) !=
            EIP1271Interface.isValidSignature.selector
        ) {
            revert BadContractSignature();
        }
    }
}

File 33 of 43 : AbridgedTokenInterfaces.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

/**
 * @title ERC20Interface
 * @notice Contains the minimum interfaces needed to interact with ERC20s.
 */
interface ERC20Interface {
    /**
     * @dev Allows an operator to transfer tokens on behalf of an owner.
     *
     * @param from  The address of the owner.
     * @param to    The address of the recipient.
     * @param value The amount of tokens to transfer.
     *
     * @return success True if the transfer was successful.
     */
    function transferFrom(
        address from,
        address to,
        uint256 value
    ) external returns (bool success);

    /**
     * @dev Allows an operator to approve a spender to transfer tokens on behalf
     *      of a user.
     *
     * @param spender The address of the spender.
     * @param value   The amount of tokens to approve.
     *
     * @return success True if the approval was successful.
     */
    function approve(
        address spender,
        uint256 value
    ) external returns (bool success);

    /**
     * @dev Returns the balance of a user.
     *
     * @param account The address of the user.
     *
     * @return balance The balance of the user.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Returns the amount which spender is still allowed to withdraw
     *      from owner.
     *
     * @param owner   The address of the owner.
     * @param spender The address of the spender.
     *
     * @return remaining The amount of tokens that the spender is allowed to
     *                   transfer on behalf of the owner.
     */
    function allowance(
        address owner,
        address spender
    ) external view returns (uint256 remaining);
}

/**
 * @title ERC721Interface
 * @notice Contains the minimum interfaces needed to interact with ERC721s.
 */
interface ERC721Interface {
    /**
     * @dev Allows an operator to transfer tokens on behalf of an owner.
     *
     * @param from    The address of the owner.
     * @param to      The address of the recipient.
     * @param tokenId The ID of the token to transfer.
     */
    function transferFrom(address from, address to, uint256 tokenId) external;

    /**
     * @dev Allows an owner to approve an operator to transfer all tokens on a
     *      contract on behalf of the owner.
     *
     * @param to       The address of the operator.
     * @param approved Whether the operator is approved.
     */
    function setApprovalForAll(address to, bool approved) external;

    /**
     * @dev Returns the account approved for tokenId token
     *
     * @param tokenId The tokenId to query the approval of.
     *
     * @return operator The approved account of the tokenId.
     */
    function getApproved(
        uint256 tokenId
    ) external view returns (address operator);

    /**
     * @dev Returns whether an operator is allowed to manage all of
     *      the assets of owner.
     *
     * @param owner    The address of the owner.
     * @param operator The address of the operator.
     *
     * @return approved True if the operator is approved by the owner.
     */
    function isApprovedForAll(
        address owner,
        address operator
    ) external view returns (bool);

    /**
     * @dev Returns the owner of a given token ID.
     *
     * @param tokenId The token ID.
     *
     * @return owner The owner of the token.
     */
    function ownerOf(uint256 tokenId) external view returns (address owner);
}

/**
 * @title ERC1155Interface
 * @notice Contains the minimum interfaces needed to interact with ERC1155s.
 */
interface ERC1155Interface {
    /**
     * @dev Allows an operator to transfer tokens on behalf of an owner.
     *
     * @param from   The address of the owner.
     * @param to     The address of the recipient.
     * @param id     The ID of the token(s) to transfer.
     * @param amount The amount of tokens to transfer.
     * @param data   Additional data.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes calldata data
    ) external;

    /**
     * @dev Allows an operator to transfer tokens on behalf of an owner.
     *
     * @param from    The address of the owner.
     * @param to      The address of the recipient.
     * @param ids     The IDs of the token(s) to transfer.
     * @param amounts The amounts of tokens to transfer.
     * @param data    Additional data.
     */
    function safeBatchTransferFrom(
        address from,
        address to,
        uint256[] calldata ids,
        uint256[] calldata amounts,
        bytes calldata data
    ) external;

    /**
     * @dev Allows an owner to approve an operator to transfer all tokens on a
     *      contract on behalf of the owner.
     *
     * @param to       The address of the operator.
     * @param approved Whether the operator is approved.
     */
    function setApprovalForAll(address to, bool approved) external;

    /**
     * @dev Returns the amount of token type id owned by account.
     *
     * @param account The address of the account.
     * @param id      The id of the token.
     *
     * @return balance The amount of tokens of type id owned by account.
     */
    function balanceOf(
        address account,
        uint256 id
    ) external view returns (uint256);

    /**
     * @dev Returns true if operator is approved to transfer account's tokens.
     *
     * @param account  The address of the account.
     * @param operator The address of the operator.
     *
     * @return approved True if the operator is approved to transfer account's
     *                  tokens.
     */
    function isApprovedForAll(
        address account,
        address operator
    ) external view returns (bool);
}

File 34 of 43 : ReferenceGettersAndDerivers.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import {ConsiderationItem, OfferItem, OrderParameters} from "seaport-types/src/lib/ConsiderationStructs.sol";

import {ReferenceConsiderationBase} from "./ReferenceConsiderationBase.sol";

/**
 * @title GettersAndDerivers
 * @author 0age
 * @notice ConsiderationInternal contains pure and internal view functions
 *         related to getting or deriving various values.
 */
contract ReferenceGettersAndDerivers is ReferenceConsiderationBase {
    /**
     * @dev Derive and set hashes, reference chainId, and associated domain
     *      separator during deployment.
     *
     * @param conduitController A contract that deploys conduits, or proxies
     *                          that may optionally be used to transfer approved
     *                          ERC20/721/1155 tokens.
     */
    constructor(
        address conduitController
    ) ReferenceConsiderationBase(conduitController) {}

    /**
     * @dev Internal view function to derive the EIP-712 hash for an offer item.
     *
     * @param offerItem The offered item to hash.
     *
     * @return The hash.
     */
    function _hashOfferItem(
        OfferItem memory offerItem
    ) internal view returns (bytes32) {
        return
            keccak256(
                abi.encode(
                    _OFFER_ITEM_TYPEHASH,
                    offerItem.itemType,
                    offerItem.token,
                    offerItem.identifierOrCriteria,
                    offerItem.startAmount,
                    offerItem.endAmount
                )
            );
    }

    /**
     * @dev Internal view function to derive the EIP-712 hash for a
     *      consideration item.
     *
     * @param considerationItem The consideration item to hash.
     *
     * @return The hash.
     */
    function _hashConsiderationItem(
        ConsiderationItem memory considerationItem
    ) internal view returns (bytes32) {
        return
            keccak256(
                abi.encode(
                    _CONSIDERATION_ITEM_TYPEHASH,
                    considerationItem.itemType,
                    considerationItem.token,
                    considerationItem.identifierOrCriteria,
                    considerationItem.startAmount,
                    considerationItem.endAmount,
                    considerationItem.recipient
                )
            );
    }

    /**
     * @dev Internal view function to derive the order hash for a given order.
     *      Note that only the original consideration items are included in the
     *      order hash, as additional consideration items may be supplied by the
     *      caller.
     *
     * @param orderParameters The parameters of the order to hash.
     * @param counter           The counter of the order to hash.
     *
     * @return orderHash The hash.
     */
    function _deriveOrderHash(
        OrderParameters memory orderParameters,
        uint256 counter
    ) internal view returns (bytes32 orderHash) {
        // Designate new memory regions for offer and consideration item hashes.
        bytes32[] memory offerHashes = new bytes32[](
            orderParameters.offer.length
        );
        bytes32[] memory considerationHashes = new bytes32[](
            orderParameters.totalOriginalConsiderationItems
        );

        // Iterate over each offer on the order.
        for (uint256 i = 0; i < orderParameters.offer.length; ++i) {
            // Hash the offer and place the result into memory.
            offerHashes[i] = _hashOfferItem(orderParameters.offer[i]);
        }

        // Iterate over each consideration on the order.
        for (
            uint256 i = 0;
            i < orderParameters.totalOriginalConsiderationItems;
            ++i
        ) {
            // Hash the consideration and place the result into memory.
            considerationHashes[i] = _hashConsiderationItem(
                orderParameters.consideration[i]
            );
        }

        // Derive and return the order hash as specified by EIP-712.

        return
            keccak256(
                abi.encode(
                    _ORDER_TYPEHASH,
                    orderParameters.offerer,
                    orderParameters.zone,
                    keccak256(abi.encodePacked(offerHashes)),
                    keccak256(abi.encodePacked(considerationHashes)),
                    orderParameters.orderType,
                    orderParameters.startTime,
                    orderParameters.endTime,
                    orderParameters.zoneHash,
                    orderParameters.salt,
                    orderParameters.conduitKey,
                    counter
                )
            );
    }

    /**
     * @dev Internal pure function to efficiently derive an digest to sign for
     *      an order in accordance with EIP-712.
     *
     * @param domainSeparator The domain separator.
     * @param orderHash       The order hash.
     *
     * @return value The hash.
     */
    function _deriveEIP712Digest(
        bytes32 domainSeparator,
        bytes32 orderHash
    ) internal pure returns (bytes32 value) {
        value = keccak256(
            abi.encodePacked(uint16(0x1901), domainSeparator, orderHash)
        );
    }

    /**
     * @dev Internal view function to derive the address of a given conduit
     *      using a corresponding conduit key.
     *
     * @param conduitKey A bytes32 value indicating what corresponding conduit,
     *                   if any, to source token approvals from. This value is
     *                   the "salt" parameter supplied by the deployer (i.e. the
     *                   conduit controller) when deploying the given conduit.
     *
     * @return conduit The address of the conduit associated with the given
     *                 conduit key.
     */
    function _deriveConduit(
        bytes32 conduitKey
    ) internal view returns (address conduit) {
        // Derive the conduit address
        bytes32 hash = keccak256(
            bytes.concat(
                keccak256("zksyncCreate2"),
                bytes32(uint256(uint160(address(_CONDUIT_CONTROLLER)))),
                conduitKey,
                _CONDUIT_RUNTIME_CODE_HASH,
                keccak256("")
            )
        );

        conduit = address(uint160(uint256(hash)));
    }

    /**
     * @dev Internal view function to get the EIP-712 domain separator. If the
     *      chainId matches the chainId set on deployment, the cached domain
     *      separator will be returned; otherwise, it will be derived from
     *      scratch.
     */
    function _domainSeparator() internal view returns (bytes32) {
        return
            block.chainid == _CHAIN_ID
                ? _DOMAIN_SEPARATOR
                : _deriveDomainSeparator(
                    _EIP_712_DOMAIN_TYPEHASH,
                    _NAME_HASH,
                    _VERSION_HASH
                );
    }

    /**
     * @notice Retrieve configuration information for this contract.
     *
     * @return version           The contract version.
     * @return domainSeparator   The domain separator for this contract.
     * @return conduitController The conduit Controller set for this contract.
     */
    function _information()
        internal
        view
        returns (
            string memory version,
            bytes32 domainSeparator,
            address conduitController
        )
    {
        version = _VERSION;
        domainSeparator = _domainSeparator();
        conduitController = address(_CONDUIT_CONTROLLER);
    }

    /**
     * @notice Retrieve the name of this contract.
     *
     * @return The name of this contract.
     */
    function _name() internal pure returns (string memory) {
        // Return the name of the contract.
        return _NAME;
    }
}

File 35 of 43 : ReferenceCounterManager.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import {
    ConsiderationEventsAndErrors
} from "seaport-types/src/interfaces/ConsiderationEventsAndErrors.sol";

import { ReferenceReentrancyGuard } from "./ReferenceReentrancyGuard.sol";

/**
 * @title CounterManager
 * @author 0age
 * @notice CounterManager contains a storage mapping and related functionality
 *         for retrieving and incrementing a per-offerer counter.
 */
contract ReferenceCounterManager is
    ConsiderationEventsAndErrors,
    ReferenceReentrancyGuard
{
    // Only orders signed using an offerer's current counter are fulfillable.
    mapping(address => uint256) private _counters;

    /**
     * @dev Internal function to cancel all orders from a given offerer in bulk
     *      by incrementing a counter. Note that only the offerer may increment
     *      the counter. Note that the counter is incremented by a large,
     *      quasi-random interval, which makes it infeasible to "activate"
     *      signed orders by incrementing the counter.  This activation
     *      functionality can be achieved instead with restricted orders or
     *      contract orders.
     *
     * @return newCounter The new counter.
     */
    function _incrementCounter() internal returns (uint256 newCounter) {
        // Use second half of the previous block hash as a quasi-random number.
        uint256 quasiRandomNumber = uint256(blockhash(block.number - 1)) >> 128;

        // Retrieve the original counter value.
        uint256 originalCounter = _counters[msg.sender];

        // Increment current counter for the supplied offerer.
        newCounter = quasiRandomNumber + originalCounter;

        // Update the counter with the new value.
        _counters[msg.sender] = newCounter;

        // Emit an event containing the new counter.
        emit CounterIncremented(newCounter, msg.sender);
    }

    /**
     * @dev Internal view function to retrieve the current counter for a given
     *      offerer.
     *
     * @param offerer The offerer in question.
     *
     * @return currentCounter The current counter.
     */
    function _getCounter(
        address offerer
    ) internal view returns (uint256 currentCounter) {
        // Return the counter for the supplied offerer.
        currentCounter = _counters[offerer];
    }
}

File 36 of 43 : SignatureVerificationErrors.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

/**
 * @title SignatureVerificationErrors
 * @author 0age
 * @notice SignatureVerificationErrors contains all errors related to signature
 *         verification.
 */
interface SignatureVerificationErrors {
    /**
     * @dev Revert with an error when a signature that does not contain a v
     *      value of 27 or 28 has been supplied.
     *
     * @param v The invalid v value.
     */
    error BadSignatureV(uint8 v);

    /**
     * @dev Revert with an error when the signer recovered by the supplied
     *      signature does not match the offerer or an allowed EIP-1271 signer
     *      as specified by the offerer in the event they are a contract.
     */
    error InvalidSigner();

    /**
     * @dev Revert with an error when a signer cannot be recovered from the
     *      supplied signature.
     */
    error InvalidSignature();

    /**
     * @dev Revert with an error when an EIP-1271 call to an account fails.
     */
    error BadContractSignature();
}

File 37 of 43 : EIP1271Interface.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

/**
 * @title EIP1271Interface
 * @notice Interface for the EIP-1271 standard signature validation method for
 *         contracts.
 */
interface EIP1271Interface {
    /**
     * @dev Validates a smart contract signature
     *
     * @param digest    bytes32 The digest of the data to be signed.
     * @param signature bytes The signature of the data to be validated.
     *
     * @return bytes4 The magic value, if the signature is valid.
     */
    function isValidSignature(
        bytes32 digest,
        bytes calldata signature
    ) external view returns (bytes4);
}

File 38 of 43 : ConsiderationConstants.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

/*
 * -------------------------- Disambiguation & Other Notes ---------------------
 *    - The term "head" is used as it is in the documentation for ABI encoding,
 *      but only in reference to dynamic types, i.e. it always refers to the
 *      offset or pointer to the body of a dynamic type. In calldata, the head
 *      is always an offset (relative to the parent object), while in memory,
 *      the head is always the pointer to the body. More information found here:
 *      https://docs.soliditylang.org/en/v0.8.17/abi-spec.html#argument-encoding
 *        - Note that the length of an array is separate from and precedes the
 *          head of the array.
 *
 *    - The term "body" is used in place of the term "head" used in the ABI
 *      documentation. It refers to the start of the data for a dynamic type,
 *      e.g. the first word of a struct or the first word of the first element
 *      in an array.
 *
 *    - The term "pointer" is used to describe the absolute position of a value
 *      and never an offset relative to another value.
 *        - The suffix "_ptr" refers to a memory pointer.
 *        - The suffix "_cdPtr" refers to a calldata pointer.
 *
 *    - The term "offset" is used to describe the position of a value relative
 *      to some parent value. For example, OrderParameters_conduit_offset is the
 *      offset to the "conduit" value in the OrderParameters struct relative to
 *      the start of the body.
 *        - Note: Offsets are used to derive pointers.
 *
 *    - Some structs have pointers defined for all of their fields in this file.
 *      Lines which are commented out are fields that are not used in the
 *      codebase but have been left in for readability.
 */

// Declare constants for name, version, and reentrancy sentinel values.

// Name is right padded, so it touches the length which is left padded. This
// enables writing both values at once. Length goes at byte 95 in memory, and
// name fills bytes 96-109, so both values can be written left-padded to 77.
uint256 constant NameLengthPtr = 0x4D;
uint256 constant NameWithLength = 0x0d436F6E73696465726174696F6E;

uint256 constant information_version_offset = 0;
uint256 constant information_version_cd_offset = 0x60;
uint256 constant information_domainSeparator_offset = 0x20;
uint256 constant information_conduitController_offset = 0x40;
uint256 constant information_versionLengthPtr = 0x63;
uint256 constant information_versionWithLength = 0x03312e36; // 1.6
uint256 constant information_length = 0xa0;

// uint256(uint32(bytes4(keccak256("_REENTRANCY_GUARD_SLOT"))))
uint256 constant _REENTRANCY_GUARD_SLOT = 0x929eee14;

/*
 *
 * --------------------------------------------------------------------------+
 * Opcode      | Mnemonic         | Stack               | Memory             |
 * --------------------------------------------------------------------------|
 * 60 0x02     | PUSH1 0x02       | 0x02                |                    |
 * 60 0x1e     | PUSH1 0x1e       | 0x1e 0x02           |                    |
 * 61 0x3d5c   | PUSH2 0x3d5c     | 0x3d5c 0x1e 0x02    |                    |
 * 3d          | RETURNDATASIZE   | 0 0x3d5c 0x1e 0x02  |                    |
 *                                                                           |
 * ::: store deployed bytecode in memory: (3d) RETURNDATASIZE (5c) TLOAD ::: |
 * 52          | MSTORE           | 0x1e 0x02           | [0..0x20): 0x3d5c  |
 * f3          | RETURN           |                     | [0..0x20): 0x3d5c  |
 * --------------------------------------------------------------------------+
 */
uint256 constant _TLOAD_TEST_PAYLOAD = 0x6002_601e_613d5c_3d_52_f3;
uint256 constant _TLOAD_TEST_PAYLOAD_LENGTH = 0x0a;
uint256 constant _TLOAD_TEST_PAYLOAD_OFFSET = 0x16;
uint256 constant _NOT_ENTERED_TSTORE = 0;
uint256 constant _ENTERED_TSTORE = 1;
uint256 constant _ENTERED_AND_ACCEPTING_NATIVE_TOKENS_TSTORE = 2;
uint256 constant _TSTORE_ENABLED_SSTORE = 0;
uint256 constant _NOT_ENTERED_SSTORE = 1;
uint256 constant _ENTERED_SSTORE = 2;
uint256 constant _ENTERED_AND_ACCEPTING_NATIVE_TOKENS_SSTORE = 3;

uint256 constant Offset_fulfillAdvancedOrder_criteriaResolvers = 0x20;
uint256 constant Offset_fulfillAvailableOrders_offerFulfillments = 0x20;
uint256 constant Offset_fulfillAvailableOrders_considerationFulfillments = 0x40;
uint256 constant Offset_fulfillAvailableAdvancedOrders_criteriaResolvers = 0x20;
uint256 constant Offset_fulfillAvailableAdvancedOrders_offerFulfillments = 0x40;
uint256 constant Offset_fulfillAvailableAdvancedOrders_cnsdrationFlflmnts =
    (0x60);

uint256 constant Offset_matchOrders_fulfillments = 0x20;

uint256 constant Offset_matchAdvancedOrders_criteriaResolvers = 0x20;
uint256 constant Offset_matchAdvancedOrders_fulfillments = 0x40;

// Common Offsets
// Offsets for identically positioned fields shared by:
// OfferItem, ConsiderationItem, SpentItem, ReceivedItem

uint256 constant Selector_length = 0x4;

uint256 constant Common_token_offset = 0x20;
uint256 constant Common_identifier_offset = 0x40;
uint256 constant Common_amount_offset = 0x60;
uint256 constant Common_endAmount_offset = 0x80;

uint256 constant SpentItem_size = 0x80;
uint256 constant SpentItem_size_shift = 0x7;

uint256 constant OfferItem_size = 0xa0;
uint256 constant OfferItem_size_with_head_pointer = 0xc0;

uint256 constant ReceivedItem_size_excluding_recipient = 0x80;
uint256 constant ReceivedItem_size = 0xa0;
uint256 constant ReceivedItem_amount_offset = 0x60;
uint256 constant ReceivedItem_recipient_offset = 0x80;

uint256 constant ReceivedItem_CommonParams_size = 0x60;

uint256 constant ConsiderationItem_size = 0xc0;
uint256 constant ConsiderationItem_size_with_head_pointer = 0xe0;

uint256 constant ConsiderationItem_recipient_offset = 0xa0;
// Store the same constant in an abbreviated format for a line length fix.
uint256 constant ConsiderItem_recipient_offset = 0xa0;

uint256 constant Execution_offerer_offset = 0x20;
uint256 constant Execution_conduit_offset = 0x40;

// uint256 constant OrderParameters_offerer_offset = 0x00;
uint256 constant OrderParameters_zone_offset = 0x20;
uint256 constant OrderParameters_offer_head_offset = 0x40;
uint256 constant OrderParameters_consideration_head_offset = 0x60;
// uint256 constant OrderParameters_orderType_offset = 0x80;
uint256 constant OrderParameters_startTime_offset = 0xa0;
uint256 constant OrderParameters_endTime_offset = 0xc0;
uint256 constant OrderParameters_zoneHash_offset = 0xe0;
uint256 constant OrderParameters_salt_offset = 0x100;
uint256 constant OrderParameters_conduit_offset = 0x120;
uint256 constant OrderParameters_counter_offset = 0x140;

uint256 constant Fulfillment_itemIndex_offset = 0x20;

uint256 constant AdvancedOrder_head_size = 0xa0;
uint256 constant AdvancedOrder_numerator_offset = 0x20;
uint256 constant AdvancedOrder_denominator_offset = 0x40;
uint256 constant AdvancedOrder_signature_offset = 0x60;
uint256 constant AdvancedOrder_extraData_offset = 0x80;

uint256 constant OrderStatus_ValidatedAndNotCancelled = 1;
uint256 constant OrderStatus_filledNumerator_offset = 0x10;
uint256 constant OrderStatus_filledDenominator_offset = 0x88;
uint256 constant OrderStatus_ValidatedAndNotCancelledAndFullyFilled = (
    0x0000000000000000000000000000010000000000000000000000000000010001
);

uint256 constant ThirtyOneBytes = 0x1f;
uint256 constant OneWord = 0x20;
uint256 constant TwoWords = 0x40;
uint256 constant ThreeWords = 0x60;
uint256 constant FourWords = 0x80;
uint256 constant FiveWords = 0xa0;

uint256 constant OneWordShift = 0x5;
uint256 constant TwoWordsShift = 0x6;

uint256 constant SixtyThreeBytes = 0x3f;
uint256 constant OnlyFullWordMask = 0xffffffe0;

uint256 constant FreeMemoryPointerSlot = 0x40;
uint256 constant ZeroSlot = 0x60;
uint256 constant DefaultFreeMemoryPointer = 0x80;

uint256 constant Slot0x80 = 0x80;
uint256 constant Slot0xA0 = 0xa0;

uint256 constant BasicOrder_common_params_size = 0xa0;
uint256 constant BasicOrder_considerationHashesArray_ptr = 0x160;
uint256 constant BasicOrder_receivedItemByteMap =
    (0x0000010102030000000000000000000000000000000000000000000000000000);
uint256 constant BasicOrder_offeredItemByteMap =
    (0x0203020301010000000000000000000000000000000000000000000000000000);
uint256 constant BasicOrder_consideration_offset_from_offer = 0xa0;

bytes32 constant OrdersMatchedTopic0 =
    (0x4b9f2d36e1b4c93de62cc077b00b1a91d84b6c31b4a14e012718dcca230689e7);

uint256 constant EIP712_Order_size = 0x180;
uint256 constant EIP712_OfferItem_size = 0xc0;
uint256 constant EIP712_ConsiderationItem_size = 0xe0;
uint256 constant AdditionalRecipient_size = 0x40;
uint256 constant AdditionalRecipient_size_shift = 0x6;

uint256 constant EIP712_DomainSeparator_offset = 0x02;
uint256 constant EIP712_OrderHash_offset = 0x22;
uint256 constant EIP712_DigestPayload_size = 0x42;

uint256 constant EIP712_domainData_nameHash_offset = 0x20;
uint256 constant EIP712_domainData_versionHash_offset = 0x40;
uint256 constant EIP712_domainData_chainId_offset = 0x60;
uint256 constant EIP712_domainData_verifyingContract_offset = 0x80;
uint256 constant EIP712_domainData_size = 0xa0;

// Minimum BulkOrder proof size: 64 bytes for signature + 3 for key + 32 for 1
// sibling. Maximum BulkOrder proof size: 65 bytes for signature + 3 for key +
// 768 for 24 siblings.

uint256 constant BulkOrderProof_minSize = 0x63;
uint256 constant BulkOrderProof_rangeSize = 0x2e2;
uint256 constant BulkOrderProof_lengthAdjustmentBeforeMask = 0x1d;
uint256 constant BulkOrderProof_lengthRangeAfterMask = 0x2;
uint256 constant BulkOrderProof_keyShift = 0xe8;
uint256 constant BulkOrderProof_keySize = 0x3;

uint256 constant BulkOrder_Typehash_Height_One =
    (0x3ca2711d29384747a8f61d60aad3c450405f7aaff5613541dee28df2d6986d32);
uint256 constant BulkOrder_Typehash_Height_Two =
    (0xbf8e29b89f29ed9b529c154a63038ffca562f8d7cd1e2545dda53a1b582dde30);
uint256 constant BulkOrder_Typehash_Height_Three =
    (0x53c6f6856e13104584dd0797ca2b2779202dc2597c6066a42e0d8fe990b0024d);
uint256 constant BulkOrder_Typehash_Height_Four =
    (0xa02eb7ff164c884e5e2c336dc85f81c6a93329d8e9adf214b32729b894de2af1);
uint256 constant BulkOrder_Typehash_Height_Five =
    (0x39c9d33c18e050dda0aeb9a8086fb16fc12d5d64536780e1da7405a800b0b9f6);
uint256 constant BulkOrder_Typehash_Height_Six =
    (0x1c19f71958cdd8f081b4c31f7caf5c010b29d12950be2fa1c95070dc47e30b55);
uint256 constant BulkOrder_Typehash_Height_Seven =
    (0xca74fab2fece9a1d58234a274220ad05ca096a92ef6a1ca1750b9d90c948955c);
uint256 constant BulkOrder_Typehash_Height_Eight =
    (0x7ff98d9d4e55d876c5cfac10b43c04039522f3ddfb0ea9bfe70c68cfb5c7cc14);
uint256 constant BulkOrder_Typehash_Height_Nine =
    (0xbed7be92d41c56f9e59ac7a6272185299b815ddfabc3f25deb51fe55fe2f9e8a);
uint256 constant BulkOrder_Typehash_Height_Ten =
    (0xd1d97d1ef5eaa37a4ee5fbf234e6f6d64eb511eb562221cd7edfbdde0848da05);
uint256 constant BulkOrder_Typehash_Height_Eleven =
    (0x896c3f349c4da741c19b37fec49ed2e44d738e775a21d9c9860a69d67a3dae53);
uint256 constant BulkOrder_Typehash_Height_Twelve =
    (0xbb98d87cc12922b83759626c5f07d72266da9702d19ffad6a514c73a89002f5f);
uint256 constant BulkOrder_Typehash_Height_Thirteen =
    (0xe6ae19322608dd1f8a8d56aab48ed9c28be489b689f4b6c91268563efc85f20e);
uint256 constant BulkOrder_Typehash_Height_Fourteen =
    (0x6b5b04cbae4fcb1a9d78e7b2dfc51a36933d023cf6e347e03d517b472a852590);
uint256 constant BulkOrder_Typehash_Height_Fifteen =
    (0xd1eb68309202b7106b891e109739dbbd334a1817fe5d6202c939e75cf5e35ca9);
uint256 constant BulkOrder_Typehash_Height_Sixteen =
    (0x1da3eed3ecef6ebaa6e5023c057ec2c75150693fd0dac5c90f4a142f9879fde8);
uint256 constant BulkOrder_Typehash_Height_Seventeen =
    (0xeee9a1392aa395c7002308119a58f2582777a75e54e0c1d5d5437bd2e8bf6222);
uint256 constant BulkOrder_Typehash_Height_Eighteen =
    (0xc3939feff011e53ab8c35ca3370aad54c5df1fc2938cd62543174fa6e7d85877);
uint256 constant BulkOrder_Typehash_Height_Nineteen =
    (0x0efca7572ac20f5ae84db0e2940674f7eca0a4726fa1060ffc2d18cef54b203d);
uint256 constant BulkOrder_Typehash_Height_Twenty =
    (0x5a4f867d3d458dabecad65f6201ceeaba0096df2d0c491cc32e6ea4e64350017);
uint256 constant BulkOrder_Typehash_Height_TwentyOne =
    (0x80987079d291feebf21c2230e69add0f283cee0b8be492ca8050b4185a2ff719);
uint256 constant BulkOrder_Typehash_Height_TwentyTwo =
    (0x3bd8cff538aba49a9c374c806d277181e9651624b3e31111bc0624574f8bca1d);
uint256 constant BulkOrder_Typehash_Height_TwentyThree =
    (0x5d6a3f098a0bc373f808c619b1bb4028208721b3c4f8d6bc8a874d659814eb76);
uint256 constant BulkOrder_Typehash_Height_TwentyFour =
    (0x1d51df90cba8de7637ca3e8fe1e3511d1dc2f23487d05dbdecb781860c21ac1c);

uint256 constant receivedItemsHash_ptr = 0x60;

/*
 *  Memory layout in _prepareBasicFulfillmentFromCalldata of
 *  data for OrderFulfilled
 *
 *   event OrderFulfilled(
 *     bytes32 orderHash,
 *     address indexed offerer,
 *     address indexed zone,
 *     address fulfiller,
 *     SpentItem[] offer,
 *       > (itemType, token, id, amount)
 *     ReceivedItem[] consideration
 *       > (itemType, token, id, amount, recipient)
 *   )
 *
 *  - 0x00: orderHash
 *  - 0x20: fulfiller
 *  - 0x40: offer offset (0x80)
 *  - 0x60: consideration offset (0x120)
 *  - 0x80: offer.length (1)
 *  - 0xa0: offerItemType
 *  - 0xc0: offerToken
 *  - 0xe0: offerIdentifier
 *  - 0x100: offerAmount
 *  - 0x120: consideration.length (1 + additionalRecipients.length)
 *  - 0x140: considerationItemType
 *  - 0x160: considerationToken
 *  - 0x180: considerationIdentifier
 *  - 0x1a0: considerationAmount
 *  - 0x1c0: considerationRecipient
 *  - ...
 */

// Minimum length of the OrderFulfilled event data.
// Must be added to the size of the ReceivedItem array for additionalRecipients
// (0xa0 * additionalRecipients.length) to calculate full size of the buffer.
uint256 constant OrderFulfilled_baseSize = 0x1e0;
uint256 constant OrderFulfilled_selector =
    (0x9d9af8e38d66c62e2c12f0225249fd9d721c54b83f48d9352c97c6cacdcb6f31);

// Minimum offset in memory to OrderFulfilled event data.
// Must be added to the size of the EIP712 hash array for additionalRecipients
// (32 * additionalRecipients.length) to calculate the pointer to event data.
uint256 constant OrderFulfilled_baseOffset = 0x180;
uint256 constant OrderFulfilled_consideration_length_baseOffset = 0x2a0;
uint256 constant OrderFulfilled_offer_length_baseOffset = 0x200;

uint256 constant OrderFulfilled_offer_length_offset_relativeTo_baseOffset = (
    0x80
);
uint256 constant OrderFulfilled_offer_itemType_offset_relativeTo_baseOffset = (
    0xa0
);
uint256 constant OrderFulfilled_offer_token_offset_relativeTo_baseOffset = 0xc0;

// Related constants used for restricted order checks on basic orders.
uint256 constant OrderFulfilled_baseDataSize = 0x160;
// uint256 constant ValidateOrder_offerDataOffset = 0x184;
// uint256 constant RatifyOrder_offerDataOffset = 0xc4;

// uint256 constant OrderFulfilled_orderHash_offset = 0x00;
uint256 constant OrderFulfilled_fulfiller_offset = 0x20;
uint256 constant OrderFulfilled_offer_head_offset = 0x40;
uint256 constant OrderFulfilled_offer_body_offset = 0x80;
uint256 constant OrderFulfilled_consideration_head_offset = 0x60;
uint256 constant OrderFulfilled_consideration_body_offset = 0x120;

/*
 * 3 memory slots/words for `authorizeOrder` and `validateOrder` calldata
 * to be used for tails of extra data (length 0) and order hashes (length 1)
 */
uint256 constant OrderFulfilled_post_memory_region_reservedBytes = 0x60;

/*
 * OrderFulfilled_offer_length_baseOffset - 12 * 0x20
 * we back up 12 words from where the `OrderFulfilled`'s data
 * for spent items start to be rewritten for `authorizeOrder`
 * and `validateOrder`. Let the reference pointer be `ptr`
 * pointing to the `OrderFulfilled`'s spent item array's length memory
 * position then we would have:
 *
 * ptr - 0x0180 : zero-padded calldata selector
 * ptr - 0x0160 : ZoneParameter's struct head (0x20)
 * ptr - 0x0140 : order hash
 * ptr - 0x0120 : fulfiller (msg.sender)
 * ptr - 0x0100 : offerer
 * ptr - 0x00e0 : spent items' head
 * ptr - 0x00c0 : received items' head
 * ptr - 0x00a0 : extra data / context head
 * ptr - 0x0080 : order hashes head
 * ptr - 0x0060 : start time
 * ptr - 0x0040 : end time
 * ptr - 0x0020 : zone hash
 * ptr - 0x0000 : offer.length (1)
 * ...
 *
 * Note that the padded calldata selector will be at minimum at the
 * 0x80 memory slot.
 */
uint256 constant authorizeOrder_calldata_baseOffset = (
    OrderFulfilled_offer_length_baseOffset - 0x180
);

// BasicOrderParameters
uint256 constant BasicOrder_parameters_cdPtr = 0x04;
uint256 constant BasicOrder_considerationToken_cdPtr = 0x24;
uint256 constant BasicOrder_considerationIdentifier_cdPtr = 0x44;
uint256 constant BasicOrder_considerationAmount_cdPtr = 0x64;
uint256 constant BasicOrder_offerer_cdPtr = 0x84;
uint256 constant BasicOrder_zone_cdPtr = 0xa4;
uint256 constant BasicOrder_offerToken_cdPtr = 0xc4;
uint256 constant BasicOrder_offerIdentifier_cdPtr = 0xe4;
uint256 constant BasicOrder_offerAmount_cdPtr = 0x104;
uint256 constant BasicOrder_basicOrderParameters_cd_offset = 0x24;
uint256 constant BasicOrder_basicOrderType_cdPtr = 0x124;
uint256 constant BasicOrder_startTime_cdPtr = 0x144;
uint256 constant BasicOrder_endTime_cdPtr = 0x164;
// uint256 constant BasicOrder_zoneHash_cdPtr = 0x184;
// uint256 constant BasicOrder_salt_cdPtr = 0x1a4;
uint256 constant BasicOrder_offererConduit_cdPtr = 0x1c4;
uint256 constant BasicOrder_fulfillerConduit_cdPtr = 0x1e4;
uint256 constant BasicOrder_totalOriginalAdditionalRecipients_cdPtr = 0x204;
uint256 constant BasicOrder_additionalRecipients_head_cdPtr = 0x224;
uint256 constant BasicOrder_signature_cdPtr = 0x244;
uint256 constant BasicOrder_additionalRecipients_length_cdPtr = 0x264;
uint256 constant BasicOrder_addlRecipients_length_cdPtr = 0x264;
uint256 constant BasicOrder_additionalRecipients_data_cdPtr = 0x284;
uint256 constant BasicOrder_parameters_ptr = 0x20;
uint256 constant BasicOrder_basicOrderType_range = 0x18; // 24 values

/*
 *  Memory layout in _prepareBasicFulfillmentFromCalldata of
 *  EIP712 data for ConsiderationItem
 *   - 0x80: ConsiderationItem EIP-712 typehash (constant)
 *   - 0xa0: itemType
 *   - 0xc0: token
 *   - 0xe0: identifier
 *   - 0x100: startAmount
 *   - 0x120: endAmount
 *   - 0x140: recipient
 */
uint256 constant BasicOrder_considerationItem_typeHash_ptr = 0x80; // memoryPtr
uint256 constant BasicOrder_considerationItem_itemType_ptr = 0xa0;
uint256 constant BasicOrder_considerationItem_token_ptr = 0xc0;
uint256 constant BasicOrder_considerationItem_identifier_ptr = 0xe0;
uint256 constant BasicOrder_considerationItem_startAmount_ptr = 0x100;
uint256 constant BasicOrder_considerationItem_endAmount_ptr = 0x120;
// uint256 constant BasicOrder_considerationItem_recipient_ptr = 0x140;

/*
 *  Memory layout in _prepareBasicFulfillmentFromCalldata of
 *  EIP712 data for OfferItem
 *   - 0x80:  OfferItem EIP-712 typehash (constant)
 *   - 0xa0:  itemType
 *   - 0xc0:  token
 *   - 0xe0:  identifier (reused for offeredItemsHash)
 *   - 0x100: startAmount
 *   - 0x120: endAmount
 */
uint256 constant BasicOrder_offerItem_typeHash_ptr = 0x80;
uint256 constant BasicOrder_offerItem_itemType_ptr = 0xa0;
uint256 constant BasicOrder_offerItem_token_ptr = 0xc0;
// uint256 constant BasicOrder_offerItem_identifier_ptr = 0xe0;
// uint256 constant BasicOrder_offerItem_startAmount_ptr = 0x100;
uint256 constant BasicOrder_offerItem_endAmount_ptr = 0x120;

/*
 *  Memory layout in _prepareBasicFulfillmentFromCalldata of
 *  EIP712 data for Order
 *   - 0x80:   Order EIP-712 typehash (constant)
 *   - 0xa0:   orderParameters.offerer
 *   - 0xc0:   orderParameters.zone
 *   - 0xe0:   keccak256(abi.encodePacked(offerHashes))
 *   - 0x100:  keccak256(abi.encodePacked(considerationHashes))
 *   - 0x120:  orderType
 *   - 0x140:  startTime
 *   - 0x160:  endTime
 *   - 0x180:  zoneHash
 *   - 0x1a0:  salt
 *   - 0x1c0:  conduit
 *   - 0x1e0:  _counters[orderParameters.offerer] (from storage)
 */
uint256 constant BasicOrder_order_typeHash_ptr = 0x80;
uint256 constant BasicOrder_order_offerer_ptr = 0xa0;
// uint256 constant BasicOrder_order_zone_ptr = 0xc0;
uint256 constant BasicOrder_order_offerHashes_ptr = 0xe0;
uint256 constant BasicOrder_order_considerationHashes_ptr = 0x100;
uint256 constant BasicOrder_order_orderType_ptr = 0x120;
uint256 constant BasicOrder_order_startTime_ptr = 0x140;
// uint256 constant BasicOrder_order_endTime_ptr = 0x160;
// uint256 constant BasicOrder_order_zoneHash_ptr = 0x180;
// uint256 constant BasicOrder_order_salt_ptr = 0x1a0;
// uint256 constant BasicOrder_order_conduitKey_ptr = 0x1c0;
uint256 constant BasicOrder_order_counter_ptr = 0x1e0;
uint256 constant BasicOrder_additionalRecipients_head_ptr = 0x240;
uint256 constant BasicOrder_signature_ptr = 0x260;
uint256 constant BasicOrder_startTimeThroughZoneHash_size = 0x60;

uint256 constant ContractOrder_orderHash_offerer_shift = 0x60;

uint256 constant Counter_blockhash_shift = 0x80;

// Signature-related
bytes32 constant EIP2098_allButHighestBitMask =
    (0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
bytes32 constant ECDSA_twentySeventhAndTwentyEighthBytesSet =
    (0x0000000000000000000000000000000000000000000000000000000101000000);
uint256 constant ECDSA_MaxLength = 65;
uint256 constant ECDSA_signature_s_offset = 0x40;
uint256 constant ECDSA_signature_v_offset = 0x60;

bytes32 constant EIP1271_isValidSignature_selector =
    (0x1626ba7e00000000000000000000000000000000000000000000000000000000);
uint256 constant EIP1271_isValidSignature_digest_negativeOffset = 0x40;
uint256 constant EIP1271_isValidSignature_selector_negativeOffset = 0x44;
uint256 constant EIP1271_isValidSignature_calldata_baseLength = 0x64;
uint256 constant EIP1271_isValidSignature_signature_head_offset = 0x40;

uint256 constant EIP_712_PREFIX =
    (0x1901000000000000000000000000000000000000000000000000000000000000);

uint256 constant ExtraGasBuffer = 0x20;
uint256 constant CostPerWord = 0x3;
uint256 constant MemoryExpansionCoefficientShift = 0x9;

uint256 constant Create2AddressDerivation_ptr = 0x0b;
uint256 constant Create2AddressDerivation_length = 0x55;

uint256 constant MaskOverByteTwelve =
    (0x0000000000000000000000ff0000000000000000000000000000000000000000);
uint256 constant MaskOverLastTwentyBytes =
    (0x000000000000000000000000ffffffffffffffffffffffffffffffffffffffff);
uint256 constant AddressDirtyUpperBitThreshold =
    (0x0000000000000000000000010000000000000000000000000000000000000000);
uint256 constant MaskOverFirstFourBytes =
    (0xffffffff00000000000000000000000000000000000000000000000000000000);

uint256 constant Conduit_execute_signature =
    (0x4ce34aa200000000000000000000000000000000000000000000000000000000);

uint256 constant MaxUint8 = 0xff;
uint256 constant MaxUint120 = 0xffffffffffffffffffffffffffffff;

uint256 constant Conduit_execute_ConduitTransfer_ptr = 0x20;
uint256 constant Conduit_execute_ConduitTransfer_length = 0x01;
uint256 constant Conduit_execute_ConduitTransfer_offset_ptr = 0x04;
uint256 constant Conduit_execute_ConduitTransfer_length_ptr = 0x24;
uint256 constant Conduit_execute_transferItemType_ptr = 0x44;
uint256 constant Conduit_execute_transferToken_ptr = 0x64;
uint256 constant Conduit_execute_transferFrom_ptr = 0x84;
uint256 constant Conduit_execute_transferTo_ptr = 0xa4;
uint256 constant Conduit_execute_transferIdentifier_ptr = 0xc4;
uint256 constant Conduit_execute_transferAmount_ptr = 0xe4;

uint256 constant OneConduitExecute_size = 0x104;

// Sentinel value to indicate that the conduit accumulator is not armed.
uint256 constant AccumulatorDisarmed = 0x20;
uint256 constant AccumulatorArmed = 0x40;
uint256 constant Accumulator_conduitKey_ptr = 0x20;
uint256 constant Accumulator_selector_ptr = 0x40;
uint256 constant Accumulator_array_offset_ptr = 0x44;
uint256 constant Accumulator_array_length_ptr = 0x64;
uint256 constant Accumulator_itemSizeOffsetDifference = 0x3c;
uint256 constant Accumulator_array_offset = 0x20;

uint256 constant Conduit_transferItem_size = 0xc0;
uint256 constant Conduit_transferItem_token_ptr = 0x20;
uint256 constant Conduit_transferItem_from_ptr = 0x40;
uint256 constant Conduit_transferItem_to_ptr = 0x60;
uint256 constant Conduit_transferItem_identifier_ptr = 0x80;
uint256 constant Conduit_transferItem_amount_ptr = 0xa0;

uint256 constant Ecrecover_precompile = 0x1;
uint256 constant Ecrecover_args_size = 0x80;
uint256 constant Signature_lower_v = 27;

// Bitmask that only gives a non-zero value if masked with a non-match selector.
uint256 constant NonMatchSelector_MagicMask =
    (0x4000000000000000000000000000000000000000000000000000000000);

// First bit indicates that a NATIVE offer items has been used and the 231st bit
// indicates that a non match selector has been called.
uint256 constant NonMatchSelector_InvalidErrorValue =
    (0x4000000000000000000000000000000000000000000000000000000001);

/**
 * @dev Selector and offsets for generateOrder
 *
 * function generateOrder(
 *   address fulfiller,
 *   SpentItem[] calldata minimumReceived,
 *   SpentItem[] calldata maximumSpent,
 *   bytes calldata context
 * )
 */
uint256 constant generateOrder_selector = 0x98919765;
uint256 constant generateOrder_selector_offset = 0x1c;
uint256 constant generateOrder_head_offset = 0x04;
uint256 constant generateOrder_minimumReceived_head_offset = 0x20;
uint256 constant generateOrder_maximumSpent_head_offset = 0x40;
uint256 constant generateOrder_context_head_offset = 0x60;
uint256 constant generateOrder_base_tail_offset = 0x80;
uint256 constant generateOrder_maximum_returned_array_length = 0xffff;

uint256 constant ratifyOrder_selector = 0xf4dd92ce;
uint256 constant ratifyOrder_selector_offset = 0x1c;
uint256 constant ratifyOrder_head_offset = 0x04;
// uint256 constant ratifyOrder_offer_head_offset = 0x00;
uint256 constant ratifyOrder_consideration_head_offset = 0x20;
uint256 constant ratifyOrder_context_head_offset = 0x40;
uint256 constant ratifyOrder_orderHashes_head_offset = 0x60;
uint256 constant ratifyOrder_contractNonce_offset = 0x80;
uint256 constant ratifyOrder_base_tail_offset = 0xa0;

uint256 constant validateOrder_selector = 0x17b1f942;
uint256 constant validateOrder_selector_offset = 0x1c;
uint256 constant validateOrder_head_offset = 0x04;
uint256 constant validateOrder_zoneParameters_offset = 0x20;

uint256 constant authorizeOrder_selector = 0x01e4d72a;
uint256 constant authorizeOrder_selector_offset = 0x1c;
uint256 constant authorizeOrder_head_offset = 0x04;
uint256 constant authorizeOrder_zoneParameters_offset = 0x20;

// uint256 constant ZoneParameters_orderHash_offset = 0x00;
uint256 constant ZoneParameters_fulfiller_offset = 0x20;
uint256 constant ZoneParameters_offerer_offset = 0x40;
uint256 constant ZoneParameters_offer_head_offset = 0x60;
uint256 constant ZoneParameters_consideration_head_offset = 0x80;
uint256 constant ZoneParameters_extraData_head_offset = 0xa0;
uint256 constant ZoneParameters_orderHashes_head_offset = 0xc0;
uint256 constant ZoneParameters_startTime_offset = 0xe0;
uint256 constant ZoneParameters_endTime_offset = 0x100;
uint256 constant ZoneParameters_zoneHash_offset = 0x120;
uint256 constant ZoneParameters_base_tail_offset = 0x140;
uint256 constant ZoneParameters_selectorAndPointer_length = 0x24;
uint256 constant ZoneParameters_basicOrderFixedElements_length = 0x44;

// ConsiderationDecoder Constants
uint256 constant OrderParameters_head_size = 0x0160;
uint256 constant OrderParameters_totalOriginalConsiderationItems_offset = (
    0x0140
);
uint256 constant AdvancedOrderPlusOrderParameters_head_size = 0x0200;

uint256 constant Order_signature_offset = 0x20;
uint256 constant Order_head_size = 0x40;

uint256 constant AdvancedOrder_fixed_segment_0 = 0x40;

uint256 constant CriteriaResolver_head_size = 0xa0;
uint256 constant CriteriaResolver_fixed_segment_0 = 0x80;
uint256 constant CriteriaResolver_criteriaProof_offset = 0x80;

uint256 constant FulfillmentComponent_mem_tail_size = 0x40;
uint256 constant FulfillmentComponent_mem_tail_size_shift = 0x6;
uint256 constant Fulfillment_head_size = 0x40;
uint256 constant Fulfillment_considerationComponents_offset = 0x20;

uint256 constant OrderComponents_OrderParameters_common_head_size = 0x0140;

File 39 of 43 : ReferenceReentrancyGuard.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import {
    ConsiderationEventsAndErrors
} from "seaport-types/src/interfaces/ConsiderationEventsAndErrors.sol";

import {
    ReentrancyErrors
} from "seaport-types/src/interfaces/ReentrancyErrors.sol";

import {
    _ENTERED_AND_ACCEPTING_NATIVE_TOKENS_SSTORE,
    _ENTERED_SSTORE,
    _NOT_ENTERED_SSTORE
} from "seaport-types/src/lib/ConsiderationConstants.sol";

/**
 * @title ReentrancyGuard
 * @author 0age
 * @notice ReentrancyGuard contains a storage variable and related functionality
 *         for protecting against reentrancy.
 */
contract ReferenceReentrancyGuard is
    ConsiderationEventsAndErrors,
    ReentrancyErrors
{
    // Prevent reentrant calls on protected functions.
    uint256 private _reentrancyGuard;

    /**
     * @dev Initialize the reentrancy guard during deployment.
     */
    constructor() {
        // Initialize the reentrancy guard in a cleared state.
        _reentrancyGuard = _NOT_ENTERED_SSTORE;
    }

    /**
     * @dev Modifier to check that the sentinel value for the reentrancy guard
     *      is not currently set by a previous call.
     */
    modifier notEntered() {
        if (_reentrancyGuard != _NOT_ENTERED_SSTORE) {
            revert NoReentrantCalls();
        }

        _;
    }

    /**
     * @dev Modifier to set the reentrancy guard sentinel value for the duration
     *      of the call and check if it is already set by a previous call.
     *
     * @param acceptNativeTokens A boolean indicating whether native tokens may
     *                           be received during execution or not.
     */
    modifier nonReentrant(bool acceptNativeTokens) {
        if (_reentrancyGuard != _NOT_ENTERED_SSTORE) {
            revert NoReentrantCalls();
        }

        if (acceptNativeTokens) {
            _reentrancyGuard = _ENTERED_AND_ACCEPTING_NATIVE_TOKENS_SSTORE;
        } else {
            _reentrancyGuard = _ENTERED_SSTORE;
        }

        _;

        _reentrancyGuard = _NOT_ENTERED_SSTORE;
    }

    /**
     * @dev Internal view function to ensure that the sentinel value indicating
     *      native tokens may be received during execution is currently set.
     */
    function _assertAcceptingNativeTokens() internal view {
        // Ensure that the reentrancy guard is not currently set.
        if (_reentrancyGuard != _ENTERED_AND_ACCEPTING_NATIVE_TOKENS_SSTORE) {
            revert InvalidMsgValue(msg.value);
        }
    }
}

File 40 of 43 : ReferenceConsiderationBase.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import {ConduitControllerInterface} from "seaport-types/src/interfaces/ConduitControllerInterface.sol";

import {ConsiderationEventsAndErrors} from "seaport-types/src/interfaces/ConsiderationEventsAndErrors.sol";

import {ReentrancyErrors} from "seaport-types/src/interfaces/ReentrancyErrors.sol";

/**
 * @title ConsiderationBase
 * @author 0age
 * @notice ConsiderationBase contains all storage, constants, and constructor
 *         logic.
 */
contract ReferenceConsiderationBase is
    ConsiderationEventsAndErrors,
    ReentrancyErrors
{
    // Declare constants for name, version, and reentrancy sentinel values.
    string internal constant _NAME = "Seaport";
    string internal constant _VERSION = "1.6";
    uint256 internal constant _NOT_ENTERED = 1;
    uint256 internal constant _ENTERED = 2;

    // Precompute hashes, original chainId, and domain separator on deployment.
    bytes32 internal immutable _NAME_HASH;
    bytes32 internal immutable _VERSION_HASH;
    bytes32 internal immutable _EIP_712_DOMAIN_TYPEHASH;
    bytes32 internal immutable _OFFER_ITEM_TYPEHASH;
    bytes32 internal immutable _CONSIDERATION_ITEM_TYPEHASH;
    bytes32 internal immutable _ORDER_TYPEHASH;
    bytes32 internal immutable _BULK_ORDER_TYPEHASH;
    uint256 internal immutable _CHAIN_ID;
    bytes32 internal immutable _DOMAIN_SEPARATOR;

    // Allow for interaction with the conduit controller.
    ConduitControllerInterface internal immutable _CONDUIT_CONTROLLER;

    // Cache the conduit code hashes used by the conduit controller.
    bytes32 internal immutable _CONDUIT_CREATION_CODE_HASH;
    bytes32 internal immutable _CONDUIT_RUNTIME_CODE_HASH;

    // Map bulk order tree height to its respective EIP-712 typehash.
    mapping(uint256 => bytes32) internal _bulkOrderTypehashes;

    /**
     * @dev Derive and set hashes, reference chainId, and associated domain
     *      separator during deployment.
     *
     * @param conduitController           A contract that deploys conduits, or
     *                                    proxies that may optionally be used to
     *                                    transfer approved ERC20+721+1155
     *                                    tokens.
     */
    constructor(address conduitController) {
        // Derive name and version hashes alongside required EIP-712 typehashes.
        (
            _NAME_HASH,
            _VERSION_HASH,
            _EIP_712_DOMAIN_TYPEHASH,
            _OFFER_ITEM_TYPEHASH,
            _CONSIDERATION_ITEM_TYPEHASH,
            _ORDER_TYPEHASH,
            _BULK_ORDER_TYPEHASH,
            _DOMAIN_SEPARATOR
        ) = _deriveTypehashes();

        // Store the current chainId and derive the current domain separator.
        _CHAIN_ID = block.chainid;

        // Set supplied conduit controller to an in-memory controller interface.
        ConduitControllerInterface tempController = ConduitControllerInterface(
            conduitController
        );

        // Assign the in-memory interface as an immutable.
        _CONDUIT_CONTROLLER = tempController;

        // Retrieve the conduit creation code hash from the supplied controller.
        (_CONDUIT_CREATION_CODE_HASH, _CONDUIT_RUNTIME_CODE_HASH) = (
            tempController.getConduitCodeHashes()
        );

        _bulkOrderTypehashes[1] = bytes32(
            0x3ca2711d29384747a8f61d60aad3c450405f7aaff5613541dee28df2d6986d32
        );
        _bulkOrderTypehashes[2] = bytes32(
            0xbf8e29b89f29ed9b529c154a63038ffca562f8d7cd1e2545dda53a1b582dde30
        );
        _bulkOrderTypehashes[3] = bytes32(
            0x53c6f6856e13104584dd0797ca2b2779202dc2597c6066a42e0d8fe990b0024d
        );
        _bulkOrderTypehashes[4] = bytes32(
            0xa02eb7ff164c884e5e2c336dc85f81c6a93329d8e9adf214b32729b894de2af1
        );
        _bulkOrderTypehashes[5] = bytes32(
            0x39c9d33c18e050dda0aeb9a8086fb16fc12d5d64536780e1da7405a800b0b9f6
        );
        _bulkOrderTypehashes[6] = bytes32(
            0x1c19f71958cdd8f081b4c31f7caf5c010b29d12950be2fa1c95070dc47e30b55
        );
        _bulkOrderTypehashes[7] = bytes32(
            0xca74fab2fece9a1d58234a274220ad05ca096a92ef6a1ca1750b9d90c948955c
        );
        _bulkOrderTypehashes[8] = bytes32(
            0x7ff98d9d4e55d876c5cfac10b43c04039522f3ddfb0ea9bfe70c68cfb5c7cc14
        );
        _bulkOrderTypehashes[9] = bytes32(
            0xbed7be92d41c56f9e59ac7a6272185299b815ddfabc3f25deb51fe55fe2f9e8a
        );
        _bulkOrderTypehashes[10] = bytes32(
            0xd1d97d1ef5eaa37a4ee5fbf234e6f6d64eb511eb562221cd7edfbdde0848da05
        );
        _bulkOrderTypehashes[11] = bytes32(
            0x896c3f349c4da741c19b37fec49ed2e44d738e775a21d9c9860a69d67a3dae53
        );
        _bulkOrderTypehashes[12] = bytes32(
            0xbb98d87cc12922b83759626c5f07d72266da9702d19ffad6a514c73a89002f5f
        );
        _bulkOrderTypehashes[13] = bytes32(
            0xe6ae19322608dd1f8a8d56aab48ed9c28be489b689f4b6c91268563efc85f20e
        );
        _bulkOrderTypehashes[14] = bytes32(
            0x6b5b04cbae4fcb1a9d78e7b2dfc51a36933d023cf6e347e03d517b472a852590
        );
        _bulkOrderTypehashes[15] = bytes32(
            0xd1eb68309202b7106b891e109739dbbd334a1817fe5d6202c939e75cf5e35ca9
        );
        _bulkOrderTypehashes[16] = bytes32(
            0x1da3eed3ecef6ebaa6e5023c057ec2c75150693fd0dac5c90f4a142f9879fde8
        );
        _bulkOrderTypehashes[17] = bytes32(
            0xeee9a1392aa395c7002308119a58f2582777a75e54e0c1d5d5437bd2e8bf6222
        );
        _bulkOrderTypehashes[18] = bytes32(
            0xc3939feff011e53ab8c35ca3370aad54c5df1fc2938cd62543174fa6e7d85877
        );
        _bulkOrderTypehashes[19] = bytes32(
            0x0efca7572ac20f5ae84db0e2940674f7eca0a4726fa1060ffc2d18cef54b203d
        );
        _bulkOrderTypehashes[20] = bytes32(
            0x5a4f867d3d458dabecad65f6201ceeaba0096df2d0c491cc32e6ea4e64350017
        );
        _bulkOrderTypehashes[21] = bytes32(
            0x80987079d291feebf21c2230e69add0f283cee0b8be492ca8050b4185a2ff719
        );
        _bulkOrderTypehashes[22] = bytes32(
            0x3bd8cff538aba49a9c374c806d277181e9651624b3e31111bc0624574f8bca1d
        );
        _bulkOrderTypehashes[23] = bytes32(
            0x5d6a3f098a0bc373f808c619b1bb4028208721b3c4f8d6bc8a874d659814eb76
        );
        _bulkOrderTypehashes[24] = bytes32(
            0x1d51df90cba8de7637ca3e8fe1e3511d1dc2f23487d05dbdecb781860c21ac1c
        );
    }

    /**
     * @dev Internal view function to derive the initial EIP-712 domain
     *      separator.
     *
     * @param _eip712DomainTypeHash      The primary EIP-712 domain typehash.
     * @param _nameHash                  The hash of the name of the contract.
     * @param _versionHash               The hash of the version string of the
     *                                   contract.
     *
     * @return domainSeparator           The derived domain separator.
     */
    function _deriveInitialDomainSeparator(
        bytes32 _eip712DomainTypeHash,
        bytes32 _nameHash,
        bytes32 _versionHash
    ) internal view virtual returns (bytes32 domainSeparator) {
        return
            _deriveDomainSeparator(
                _eip712DomainTypeHash,
                _nameHash,
                _versionHash
            );
    }

    /**
     * @dev Internal view function to derive the EIP-712 domain separator.
     *
     * @return The derived domain separator.
     */
    function _deriveDomainSeparator(
        bytes32 _eip712DomainTypeHash,
        bytes32 _nameHash,
        bytes32 _versionHash
    ) internal view virtual returns (bytes32) {
        return
            keccak256(
                abi.encode(
                    _eip712DomainTypeHash,
                    _nameHash,
                    _versionHash,
                    block.chainid,
                    address(this)
                )
            );
    }

    /**
     * @dev Internal pure function to derive required EIP-712 typehashes and
     *      other hashes during contract creation.
     *
     * @return nameHash                  The hash of the name of the contract.
     * @return versionHash               The hash of the version string of the
     *                                   contract.
     * @return eip712DomainTypehash      The primary EIP-712 domain typehash.
     * @return offerItemTypehash         The EIP-712 typehash for OfferItem
     *                                   types.
     * @return considerationItemTypehash The EIP-712 typehash for
     *                                   ConsiderationItem types.
     * @return orderTypehash             The EIP-712 typehash for Order types.
     * @return bulkOrderTypeHash
     * @return domainSeparator           The domain separator.
     */
    function _deriveTypehashes()
        internal
        view
        returns (
            bytes32 nameHash,
            bytes32 versionHash,
            bytes32 eip712DomainTypehash,
            bytes32 offerItemTypehash,
            bytes32 considerationItemTypehash,
            bytes32 orderTypehash,
            bytes32 bulkOrderTypeHash,
            bytes32 domainSeparator
        )
    {
        // Derive hash of the name of the contract.
        nameHash = keccak256(bytes(_NAME));

        // Derive hash of the version string of the contract.
        versionHash = keccak256(bytes(_VERSION));

        // Construct the OfferItem type string.
        bytes memory offerItemTypeString = abi.encodePacked(
            "OfferItem(",
            "uint8 itemType,",
            "address token,",
            "uint256 identifierOrCriteria,",
            "uint256 startAmount,",
            "uint256 endAmount",
            ")"
        );

        // Construct the ConsiderationItem type string.
        bytes memory considerationItemTypeString = abi.encodePacked(
            "ConsiderationItem(",
            "uint8 itemType,",
            "address token,",
            "uint256 identifierOrCriteria,",
            "uint256 startAmount,",
            "uint256 endAmount,",
            "address recipient",
            ")"
        );

        // Construct the OrderComponents type string, not including the above.
        bytes memory orderComponentsPartialTypeString = abi.encodePacked(
            "OrderComponents(",
            "address offerer,",
            "address zone,",
            "OfferItem[] offer,",
            "ConsiderationItem[] consideration,",
            "uint8 orderType,",
            "uint256 startTime,",
            "uint256 endTime,",
            "bytes32 zoneHash,",
            "uint256 salt,",
            "bytes32 conduitKey,",
            "uint256 counter",
            ")"
        );

        // Construct the primary EIP-712 domain type string.
        eip712DomainTypehash = keccak256(
            abi.encodePacked(
                "EIP712Domain(",
                "string name,",
                "string version,",
                "uint256 chainId,",
                "address verifyingContract",
                ")"
            )
        );

        // Derive the OfferItem type hash using the corresponding type string.
        offerItemTypehash = keccak256(offerItemTypeString);

        // Derive ConsiderationItem type hash using corresponding type string.
        considerationItemTypehash = keccak256(considerationItemTypeString);

        // Derive OrderItem type hash via combination of relevant type strings.
        orderTypehash = keccak256(
            abi.encodePacked(
                orderComponentsPartialTypeString,
                considerationItemTypeString,
                offerItemTypeString
            )
        );

        // Encode the type string for the BulkOrder struct.
        bytes memory bulkOrderPartialTypeString = abi.encodePacked(
            "BulkOrder(OrderComponents[2][2][2][2][2][2][2] tree)"
        );

        // Generate the keccak256 hash of the concatenated type strings for the
        // BulkOrder, considerationItem, offerItem, and orderComponents.
        bulkOrderTypeHash = keccak256(
            abi.encodePacked(
                bulkOrderPartialTypeString,
                considerationItemTypeString,
                offerItemTypeString,
                orderComponentsPartialTypeString
            )
        );

        // Derive the initial domain separator using the domain typehash, the
        // name hash, and the version hash.
        domainSeparator = _deriveInitialDomainSeparator(
            eip712DomainTypehash,
            nameHash,
            versionHash
        );
    }
}

File 41 of 43 : ReentrancyErrors.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

/**
 * @title ReentrancyErrors
 * @author 0age
 * @notice ReentrancyErrors contains errors related to reentrancy.
 */
interface ReentrancyErrors {
    /**
     * @dev Revert with an error when a caller attempts to reenter a protected
     *      function.
     */
    error NoReentrantCalls();

    /**
     * @dev Revert with an error when attempting to activate the TSTORE opcode
     *      when it is already active.
     */
    error TStoreAlreadyActivated();

    /**
     * @dev Revert with an error when attempting to activate the TSTORE opcode
     *      in an EVM environment that does not support it.
     */
    error TStoreNotSupported();

    /**
     * @dev Revert with an error when deployment of the contract for testing
     *      TSTORE support fails.
     */
    error TloadTestContractDeploymentFailed();
}

File 42 of 43 : ConsiderationEventsAndErrors.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import {
    OrderParameters,
    ReceivedItem,
    SpentItem
} from "../lib/ConsiderationStructs.sol";

/**
 * @title ConsiderationEventsAndErrors
 * @author 0age
 * @notice ConsiderationEventsAndErrors contains all events and errors.
 */
interface ConsiderationEventsAndErrors {
    /**
     * @dev Emit an event whenever an order is successfully fulfilled.
     *
     * @param orderHash     The hash of the fulfilled order.
     * @param offerer       The offerer of the fulfilled order.
     * @param zone          The zone of the fulfilled order.
     * @param recipient     The recipient of each spent item on the fulfilled
     *                      order, or the null address if there is no specific
     *                      fulfiller (i.e. the order is part of a group of
     *                      orders). Defaults to the caller unless explicitly
     *                      specified otherwise by the fulfiller.
     * @param offer         The offer items spent as part of the order.
     * @param consideration The consideration items received as part of the
     *                      order along with the recipients of each item.
     */
    event OrderFulfilled(
        bytes32 orderHash,
        address indexed offerer,
        address indexed zone,
        address recipient,
        SpentItem[] offer,
        ReceivedItem[] consideration
    );

    /**
     * @dev Emit an event whenever an order is successfully cancelled.
     *
     * @param orderHash The hash of the cancelled order.
     * @param offerer   The offerer of the cancelled order.
     * @param zone      The zone of the cancelled order.
     */
    event OrderCancelled(
        bytes32 orderHash,
        address indexed offerer,
        address indexed zone
    );

    /**
     * @dev Emit an event whenever an order is explicitly validated. Note that
     *      this event will not be emitted on partial fills even though they do
     *      validate the order as part of partial fulfillment.
     *
     * @param orderHash        The hash of the validated order.
     * @param orderParameters  The parameters of the validated order.
     */
    event OrderValidated(bytes32 orderHash, OrderParameters orderParameters);

    /**
     * @dev Emit an event whenever one or more orders are matched using either
     *      matchOrders or matchAdvancedOrders.
     *
     * @param orderHashes The order hashes of the matched orders.
     */
    event OrdersMatched(bytes32[] orderHashes);

    /**
     * @dev Emit an event whenever a counter for a given offerer is incremented.
     *
     * @param newCounter The new counter for the offerer.
     * @param offerer    The offerer in question.
     */
    event CounterIncremented(uint256 newCounter, address indexed offerer);

    /**
     * @dev Revert with an error when attempting to fill an order that has
     *      already been fully filled.
     *
     * @param orderHash The order hash on which a fill was attempted.
     */
    error OrderAlreadyFilled(bytes32 orderHash);

    /**
     * @dev Revert with an error when attempting to fill an order outside the
     *      specified start time and end time.
     *
     * @param startTime The time at which the order becomes active.
     * @param endTime   The time at which the order becomes inactive.
     */
    error InvalidTime(uint256 startTime, uint256 endTime);

    /**
     * @dev Revert with an error when attempting to fill an order referencing an
     *      invalid conduit (i.e. one that has not been deployed).
     */
    error InvalidConduit(bytes32 conduitKey, address conduit);

    /**
     * @dev Revert with an error when an order is supplied for fulfillment with
     *      a consideration array that is shorter than the original array.
     */
    error MissingOriginalConsiderationItems();

    /**
     * @dev Revert with an error when an order is validated and the length of
     *      the consideration array is not equal to the supplied total original
     *      consideration items value. This error is also thrown when contract
     *      orders supply a total original consideration items value that does
     *      not match the supplied consideration array length.
     */
    error ConsiderationLengthNotEqualToTotalOriginal();

    /**
     * @dev Revert with an error when a call to a conduit fails with revert data
     *      that is too expensive to return.
     */
    error InvalidCallToConduit(address conduit);

    /**
     * @dev Revert with an error if a consideration amount has not been fully
     *      zeroed out after applying all fulfillments.
     *
     * @param orderIndex         The index of the order with the consideration
     *                           item with a shortfall.
     * @param considerationIndex The index of the consideration item on the
     *                           order.
     * @param shortfallAmount    The unfulfilled consideration amount.
     */
    error ConsiderationNotMet(
        uint256 orderIndex,
        uint256 considerationIndex,
        uint256 shortfallAmount
    );

    /**
     * @dev Revert with an error when insufficient native tokens are supplied as
     *      part of msg.value when fulfilling orders.
     */
    error InsufficientNativeTokensSupplied();

    /**
     * @dev Revert with an error when a native token transfer reverts.
     */
    error NativeTokenTransferGenericFailure(address account, uint256 amount);

    /**
     * @dev Revert with an error when a partial fill is attempted on an order
     *      that does not specify partial fill support in its order type.
     */
    error PartialFillsNotEnabledForOrder();

    /**
     * @dev Revert with an error when attempting to fill an order that has been
     *      cancelled.
     *
     * @param orderHash The hash of the cancelled order.
     */
    error OrderIsCancelled(bytes32 orderHash);

    /**
     * @dev Revert with an error when attempting to fill a basic order that has
     *      been partially filled.
     *
     * @param orderHash The hash of the partially used order.
     */
    error OrderPartiallyFilled(bytes32 orderHash);

    /**
     * @dev Revert with an error when attempting to cancel an order as a caller
     *      other than the indicated offerer or zone or when attempting to
     *      cancel a contract order.
     */
    error CannotCancelOrder();

    /**
     * @dev Revert with an error when supplying a fraction with a value of zero
     *      for the numerator or denominator, or one where the numerator exceeds
     *      the denominator.
     */
    error BadFraction();

    /**
     * @dev Revert with an error when a caller attempts to supply callvalue to a
     *      non-payable basic order route or does not supply any callvalue to a
     *      payable basic order route.
     */
    error InvalidMsgValue(uint256 value);

    /**
     * @dev Revert with an error when attempting to fill a basic order using
     *      calldata not produced by default ABI encoding.
     */
    error InvalidBasicOrderParameterEncoding();

    /**
     * @dev Revert with an error when attempting to fulfill any number of
     *      available orders when none are fulfillable.
     */
    error NoSpecifiedOrdersAvailable();

    /**
     * @dev Revert with an error when attempting to fulfill an order with an
     *      offer for a native token outside of matching orders.
     */
    error InvalidNativeOfferItem();
}

File 43 of 43 : ConduitControllerInterface.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

/**
 * @title ConduitControllerInterface
 * @author 0age
 * @notice ConduitControllerInterface contains all external function interfaces,
 *         structs, events, and errors for the conduit controller.
 */
interface ConduitControllerInterface {
    /**
     * @dev Track the conduit key, current owner, new potential owner, and open
     *      channels for each deployed conduit.
     */
    struct ConduitProperties {
        bytes32 key;
        address owner;
        address potentialOwner;
        address[] channels;
        mapping(address => uint256) channelIndexesPlusOne;
    }

    /**
     * @dev Emit an event whenever a new conduit is created.
     *
     * @param conduit    The newly created conduit.
     * @param conduitKey The conduit key used to create the new conduit.
     */
    event NewConduit(address conduit, bytes32 conduitKey);

    /**
     * @dev Emit an event whenever conduit ownership is transferred.
     *
     * @param conduit       The conduit for which ownership has been
     *                      transferred.
     * @param previousOwner The previous owner of the conduit.
     * @param newOwner      The new owner of the conduit.
     */
    event OwnershipTransferred(
        address indexed conduit,
        address indexed previousOwner,
        address indexed newOwner
    );

    /**
     * @dev Emit an event whenever a conduit owner registers a new potential
     *      owner for that conduit.
     *
     * @param newPotentialOwner The new potential owner of the conduit.
     */
    event PotentialOwnerUpdated(address indexed newPotentialOwner);

    /**
     * @dev Revert with an error when attempting to create a new conduit using a
     *      conduit key where the first twenty bytes of the key do not match the
     *      address of the caller.
     */
    error InvalidCreator();

    /**
     * @dev Revert with an error when attempting to create a new conduit when no
     *      initial owner address is supplied.
     */
    error InvalidInitialOwner();

    /**
     * @dev Revert with an error when attempting to set a new potential owner
     *      that is already set.
     */
    error NewPotentialOwnerAlreadySet(
        address conduit,
        address newPotentialOwner
    );

    /**
     * @dev Revert with an error when attempting to cancel ownership transfer
     *      when no new potential owner is currently set.
     */
    error NoPotentialOwnerCurrentlySet(address conduit);

    /**
     * @dev Revert with an error when attempting to interact with a conduit that
     *      does not yet exist.
     */
    error NoConduit();

    /**
     * @dev Revert with an error when attempting to create a conduit that
     *      already exists.
     */
    error ConduitAlreadyExists(address conduit);

    /**
     * @dev Revert with an error when attempting to update channels or transfer
     *      ownership of a conduit when the caller is not the owner of the
     *      conduit in question.
     */
    error CallerIsNotOwner(address conduit);

    /**
     * @dev Revert with an error when attempting to register a new potential
     *      owner and supplying the null address.
     */
    error NewPotentialOwnerIsZeroAddress(address conduit);

    /**
     * @dev Revert with an error when attempting to claim ownership of a conduit
     *      with a caller that is not the current potential owner for the
     *      conduit in question.
     */
    error CallerIsNotNewPotentialOwner(address conduit);

    /**
     * @dev Revert with an error when attempting to retrieve a channel using an
     *      index that is out of range.
     */
    error ChannelOutOfRange(address conduit);

    /**
     * @notice Deploy a new conduit using a supplied conduit key and assigning
     *         an initial owner for the deployed conduit. Note that the first
     *         twenty bytes of the supplied conduit key must match the caller
     *         and that a new conduit cannot be created if one has already been
     *         deployed using the same conduit key.
     *
     * @param conduitKey   The conduit key used to deploy the conduit. Note that
     *                     the first twenty bytes of the conduit key must match
     *                     the caller of this contract.
     * @param initialOwner The initial owner to set for the new conduit.
     *
     * @return conduit The address of the newly deployed conduit.
     */
    function createConduit(
        bytes32 conduitKey,
        address initialOwner
    ) external returns (address conduit);

    /**
     * @notice Open or close a channel on a given conduit, thereby allowing the
     *         specified account to execute transfers against that conduit.
     *         Extreme care must be taken when updating channels, as malicious
     *         or vulnerable channels can transfer any ERC20, ERC721 and ERC1155
     *         tokens where the token holder has granted the conduit approval.
     *         Only the owner of the conduit in question may call this function.
     *
     * @param conduit The conduit for which to open or close the channel.
     * @param channel The channel to open or close on the conduit.
     * @param isOpen  A boolean indicating whether to open or close the channel.
     */
    function updateChannel(
        address conduit,
        address channel,
        bool isOpen
    ) external;

    /**
     * @notice Initiate conduit ownership transfer by assigning a new potential
     *         owner for the given conduit. Once set, the new potential owner
     *         may call `acceptOwnership` to claim ownership of the conduit.
     *         Only the owner of the conduit in question may call this function.
     *
     * @param conduit The conduit for which to initiate ownership transfer.
     * @param newPotentialOwner The new potential owner of the conduit.
     */
    function transferOwnership(
        address conduit,
        address newPotentialOwner
    ) external;

    /**
     * @notice Clear the currently set potential owner, if any, from a conduit.
     *         Only the owner of the conduit in question may call this function.
     *
     * @param conduit The conduit for which to cancel ownership transfer.
     */
    function cancelOwnershipTransfer(address conduit) external;

    /**
     * @notice Accept ownership of a supplied conduit. Only accounts that the
     *         current owner has set as the new potential owner may call this
     *         function.
     *
     * @param conduit The conduit for which to accept ownership.
     */
    function acceptOwnership(address conduit) external;

    /**
     * @notice Retrieve the current owner of a deployed conduit.
     *
     * @param conduit The conduit for which to retrieve the associated owner.
     *
     * @return owner The owner of the supplied conduit.
     */
    function ownerOf(address conduit) external view returns (address owner);

    /**
     * @notice Retrieve the conduit key for a deployed conduit via reverse
     *         lookup.
     *
     * @param conduit The conduit for which to retrieve the associated conduit
     *                key.
     *
     * @return conduitKey The conduit key used to deploy the supplied conduit.
     */
    function getKey(address conduit) external view returns (bytes32 conduitKey);

    /**
     * @notice Derive the conduit associated with a given conduit key and
     *         determine whether that conduit exists (i.e. whether it has been
     *         deployed).
     *
     * @param conduitKey The conduit key used to derive the conduit.
     *
     * @return conduit The derived address of the conduit.
     * @return exists  A boolean indicating whether the derived conduit has been
     *                 deployed or not.
     */
    function getConduit(
        bytes32 conduitKey
    ) external view returns (address conduit, bool exists);

    /**
     * @notice Retrieve the potential owner, if any, for a given conduit. The
     *         current owner may set a new potential owner via
     *         `transferOwnership` and that owner may then accept ownership of
     *         the conduit in question via `acceptOwnership`.
     *
     * @param conduit The conduit for which to retrieve the potential owner.
     *
     * @return potentialOwner The potential owner, if any, for the conduit.
     */
    function getPotentialOwner(
        address conduit
    ) external view returns (address potentialOwner);

    /**
     * @notice Retrieve the status (either open or closed) of a given channel on
     *         a conduit.
     *
     * @param conduit The conduit for which to retrieve the channel status.
     * @param channel The channel for which to retrieve the status.
     *
     * @return isOpen The status of the channel on the given conduit.
     */
    function getChannelStatus(
        address conduit,
        address channel
    ) external view returns (bool isOpen);

    /**
     * @notice Retrieve the total number of open channels for a given conduit.
     *
     * @param conduit The conduit for which to retrieve the total channel count.
     *
     * @return totalChannels The total number of open channels for the conduit.
     */
    function getTotalChannels(
        address conduit
    ) external view returns (uint256 totalChannels);

    /**
     * @notice Retrieve an open channel at a specific index for a given conduit.
     *         Note that the index of a channel can change as a result of other
     *         channels being closed on the conduit.
     *
     * @param conduit      The conduit for which to retrieve the open channel.
     * @param channelIndex The index of the channel in question.
     *
     * @return channel The open channel, if any, at the specified channel index.
     */
    function getChannel(
        address conduit,
        uint256 channelIndex
    ) external view returns (address channel);

    /**
     * @notice Retrieve all open channels for a given conduit. Note that calling
     *         this function for a conduit with many channels will revert with
     *         an out-of-gas error.
     *
     * @param conduit The conduit for which to retrieve open channels.
     *
     * @return channels An array of open channels on the given conduit.
     */
    function getChannels(
        address conduit
    ) external view returns (address[] memory channels);

    /**
     * @dev Retrieve the conduit creation code and runtime code hashes.
     */
    function getConduitCodeHashes()
        external
        view
        returns (bytes32 creationCodeHash, bytes32 runtimeCodeHash);
}

Settings
{
  "viaIR": true,
  "evmVersion": "cancun",
  "optimizer": {
    "enabled": true,
    "mode": "3"
  },
  "outputSelection": {
    "*": {
      "*": [
        "abi"
      ]
    }
  },
  "detectMissingLibraries": false,
  "forceEVMLA": false,
  "enableEraVMExtensions": true,
  "libraries": {
    "contracts/usdc/util/SignatureChecker.sol": {
      "SignatureChecker": "0xbBB5d95A805b48E24f369127ECcDDF81e87f1A0F"
    }
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"conduitController","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"BadContractSignature","type":"error"},{"inputs":[],"name":"BadFraction","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"BadReturnValueFromERC20OnTransfer","type":"error"},{"inputs":[{"internalType":"uint8","name":"v","type":"uint8"}],"name":"BadSignatureV","type":"error"},{"inputs":[],"name":"CannotCancelOrder","type":"error"},{"inputs":[],"name":"ConsiderationCriteriaResolverOutOfRange","type":"error"},{"inputs":[],"name":"ConsiderationLengthNotEqualToTotalOriginal","type":"error"},{"inputs":[{"internalType":"uint256","name":"orderIndex","type":"uint256"},{"internalType":"uint256","name":"considerationIndex","type":"uint256"},{"internalType":"uint256","name":"shortfallAmount","type":"uint256"}],"name":"ConsiderationNotMet","type":"error"},{"inputs":[],"name":"CriteriaNotEnabledForItem","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256[]","name":"identifiers","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"name":"ERC1155BatchTransferGenericFailure","type":"error"},{"inputs":[],"name":"InexactFraction","type":"error"},{"inputs":[],"name":"InsufficientNativeTokensSupplied","type":"error"},{"inputs":[],"name":"Invalid1155BatchTransferEncoding","type":"error"},{"inputs":[],"name":"InvalidBasicOrderParameterEncoding","type":"error"},{"inputs":[{"internalType":"address","name":"conduit","type":"address"}],"name":"InvalidCallToConduit","type":"error"},{"inputs":[{"internalType":"bytes32","name":"conduitKey","type":"bytes32"},{"internalType":"address","name":"conduit","type":"address"}],"name":"InvalidConduit","type":"error"},{"inputs":[{"internalType":"bytes32","name":"orderHash","type":"bytes32"}],"name":"InvalidContractOrder","type":"error"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"InvalidERC721TransferAmount","type":"error"},{"inputs":[],"name":"InvalidFulfillmentComponentData","type":"error"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"InvalidMsgValue","type":"error"},{"inputs":[],"name":"InvalidNativeOfferItem","type":"error"},{"inputs":[],"name":"InvalidProof","type":"error"},{"inputs":[{"internalType":"bytes32","name":"orderHash","type":"bytes32"}],"name":"InvalidRestrictedOrder","type":"error"},{"inputs":[],"name":"InvalidSignature","type":"error"},{"inputs":[],"name":"InvalidSigner","type":"error"},{"inputs":[{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"endTime","type":"uint256"}],"name":"InvalidTime","type":"error"},{"inputs":[{"internalType":"uint256","name":"fulfillmentIndex","type":"uint256"}],"name":"MismatchedFulfillmentOfferAndConsiderationComponents","type":"error"},{"inputs":[{"internalType":"enum Side","name":"side","type":"uint8"}],"name":"MissingFulfillmentComponentOnAggregation","type":"error"},{"inputs":[],"name":"MissingItemAmount","type":"error"},{"inputs":[],"name":"MissingOriginalConsiderationItems","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"NativeTokenTransferGenericFailure","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"NoContract","type":"error"},{"inputs":[],"name":"NoReentrantCalls","type":"error"},{"inputs":[],"name":"NoSpecifiedOrdersAvailable","type":"error"},{"inputs":[],"name":"OfferAndConsiderationRequiredOnFulfillment","type":"error"},{"inputs":[],"name":"OfferCriteriaResolverOutOfRange","type":"error"},{"inputs":[{"internalType":"bytes32","name":"orderHash","type":"bytes32"}],"name":"OrderAlreadyFilled","type":"error"},{"inputs":[{"internalType":"enum Side","name":"side","type":"uint8"}],"name":"OrderCriteriaResolverOutOfRange","type":"error"},{"inputs":[{"internalType":"bytes32","name":"orderHash","type":"bytes32"}],"name":"OrderIsCancelled","type":"error"},{"inputs":[{"internalType":"bytes32","name":"orderHash","type":"bytes32"}],"name":"OrderPartiallyFilled","type":"error"},{"inputs":[],"name":"PartialFillsNotEnabledForOrder","type":"error"},{"inputs":[],"name":"TStoreAlreadyActivated","type":"error"},{"inputs":[],"name":"TStoreNotSupported","type":"error"},{"inputs":[],"name":"TloadTestContractDeploymentFailed","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"identifier","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TokenTransferGenericFailure","type":"error"},{"inputs":[{"internalType":"uint256","name":"orderIndex","type":"uint256"},{"internalType":"uint256","name":"considerationIndex","type":"uint256"}],"name":"UnresolvedConsiderationCriteria","type":"error"},{"inputs":[{"internalType":"uint256","name":"orderIndex","type":"uint256"},{"internalType":"uint256","name":"offerIndex","type":"uint256"}],"name":"UnresolvedOfferCriteria","type":"error"},{"inputs":[],"name":"UnusedItemParameters","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newCounter","type":"uint256"},{"indexed":true,"internalType":"address","name":"offerer","type":"address"}],"name":"CounterIncremented","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"orderHash","type":"bytes32"},{"indexed":true,"internalType":"address","name":"offerer","type":"address"},{"indexed":true,"internalType":"address","name":"zone","type":"address"}],"name":"OrderCancelled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"orderHash","type":"bytes32"},{"indexed":true,"internalType":"address","name":"offerer","type":"address"},{"indexed":true,"internalType":"address","name":"zone","type":"address"},{"indexed":false,"internalType":"address","name":"recipient","type":"address"},{"components":[{"internalType":"enum ItemType","name":"itemType","type":"uint8"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"identifier","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"indexed":false,"internalType":"struct SpentItem[]","name":"offer","type":"tuple[]"},{"components":[{"internalType":"enum ItemType","name":"itemType","type":"uint8"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"identifier","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address payable","name":"recipient","type":"address"}],"indexed":false,"internalType":"struct ReceivedItem[]","name":"consideration","type":"tuple[]"}],"name":"OrderFulfilled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"orderHash","type":"bytes32"},{"components":[{"internalType":"address","name":"offerer","type":"address"},{"internalType":"address","name":"zone","type":"address"},{"components":[{"internalType":"enum ItemType","name":"itemType","type":"uint8"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"identifierOrCriteria","type":"uint256"},{"internalType":"uint256","name":"startAmount","type":"uint256"},{"internalType":"uint256","name":"endAmount","type":"uint256"}],"internalType":"struct OfferItem[]","name":"offer","type":"tuple[]"},{"components":[{"internalType":"enum ItemType","name":"itemType","type":"uint8"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"identifierOrCriteria","type":"uint256"},{"internalType":"uint256","name":"startAmount","type":"uint256"},{"internalType":"uint256","name":"endAmount","type":"uint256"},{"internalType":"address payable","name":"recipient","type":"address"}],"internalType":"struct ConsiderationItem[]","name":"consideration","type":"tuple[]"},{"internalType":"enum OrderType","name":"orderType","type":"uint8"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"endTime","type":"uint256"},{"internalType":"bytes32","name":"zoneHash","type":"bytes32"},{"internalType":"uint256","name":"salt","type":"uint256"},{"internalType":"bytes32","name":"conduitKey","type":"bytes32"},{"internalType":"uint256","name":"totalOriginalConsiderationItems","type":"uint256"}],"indexed":false,"internalType":"struct OrderParameters","name":"orderParameters","type":"tuple"}],"name":"OrderValidated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32[]","name":"orderHashes","type":"bytes32[]"}],"name":"OrdersMatched","type":"event"},{"inputs":[{"components":[{"internalType":"address","name":"offerer","type":"address"},{"internalType":"address","name":"zone","type":"address"},{"components":[{"internalType":"enum ItemType","name":"itemType","type":"uint8"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"identifierOrCriteria","type":"uint256"},{"internalType":"uint256","name":"startAmount","type":"uint256"},{"internalType":"uint256","name":"endAmount","type":"uint256"}],"internalType":"struct OfferItem[]","name":"offer","type":"tuple[]"},{"components":[{"internalType":"enum ItemType","name":"itemType","type":"uint8"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"identifierOrCriteria","type":"uint256"},{"internalType":"uint256","name":"startAmount","type":"uint256"},{"internalType":"uint256","name":"endAmount","type":"uint256"},{"internalType":"address payable","name":"recipient","type":"address"}],"internalType":"struct ConsiderationItem[]","name":"consideration","type":"tuple[]"},{"internalType":"enum OrderType","name":"orderType","type":"uint8"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"endTime","type":"uint256"},{"internalType":"bytes32","name":"zoneHash","type":"bytes32"},{"internalType":"uint256","name":"salt","type":"uint256"},{"internalType":"bytes32","name":"conduitKey","type":"bytes32"},{"internalType":"uint256","name":"counter","type":"uint256"}],"internalType":"struct OrderComponents[]","name":"orders","type":"tuple[]"}],"name":"cancel","outputs":[{"internalType":"bool","name":"cancelled","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"address","name":"offerer","type":"address"},{"internalType":"address","name":"zone","type":"address"},{"components":[{"internalType":"enum ItemType","name":"itemType","type":"uint8"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"identifierOrCriteria","type":"uint256"},{"internalType":"uint256","name":"startAmount","type":"uint256"},{"internalType":"uint256","name":"endAmount","type":"uint256"}],"internalType":"struct OfferItem[]","name":"offer","type":"tuple[]"},{"components":[{"internalType":"enum ItemType","name":"itemType","type":"uint8"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"identifierOrCriteria","type":"uint256"},{"internalType":"uint256","name":"startAmount","type":"uint256"},{"internalType":"uint256","name":"endAmount","type":"uint256"},{"internalType":"address payable","name":"recipient","type":"address"}],"internalType":"struct ConsiderationItem[]","name":"consideration","type":"tuple[]"},{"internalType":"enum OrderType","name":"orderType","type":"uint8"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"endTime","type":"uint256"},{"internalType":"bytes32","name":"zoneHash","type":"bytes32"},{"internalType":"uint256","name":"salt","type":"uint256"},{"internalType":"bytes32","name":"conduitKey","type":"bytes32"},{"internalType":"uint256","name":"totalOriginalConsiderationItems","type":"uint256"}],"internalType":"struct OrderParameters","name":"parameters","type":"tuple"},{"internalType":"uint120","name":"numerator","type":"uint120"},{"internalType":"uint120","name":"denominator","type":"uint120"},{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"bytes","name":"extraData","type":"bytes"}],"internalType":"struct AdvancedOrder","name":"advancedOrder","type":"tuple"},{"components":[{"internalType":"uint256","name":"orderIndex","type":"uint256"},{"internalType":"enum Side","name":"side","type":"uint8"},{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"uint256","name":"identifier","type":"uint256"},{"internalType":"bytes32[]","name":"criteriaProof","type":"bytes32[]"}],"internalType":"struct CriteriaResolver[]","name":"criteriaResolvers","type":"tuple[]"},{"internalType":"bytes32","name":"fulfillerConduitKey","type":"bytes32"},{"internalType":"address","name":"recipient","type":"address"}],"name":"fulfillAdvancedOrder","outputs":[{"internalType":"bool","name":"fulfilled","type":"bool"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"address","name":"offerer","type":"address"},{"internalType":"address","name":"zone","type":"address"},{"components":[{"internalType":"enum ItemType","name":"itemType","type":"uint8"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"identifierOrCriteria","type":"uint256"},{"internalType":"uint256","name":"startAmount","type":"uint256"},{"internalType":"uint256","name":"endAmount","type":"uint256"}],"internalType":"struct OfferItem[]","name":"offer","type":"tuple[]"},{"components":[{"internalType":"enum ItemType","name":"itemType","type":"uint8"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"identifierOrCriteria","type":"uint256"},{"internalType":"uint256","name":"startAmount","type":"uint256"},{"internalType":"uint256","name":"endAmount","type":"uint256"},{"internalType":"address payable","name":"recipient","type":"address"}],"internalType":"struct ConsiderationItem[]","name":"consideration","type":"tuple[]"},{"internalType":"enum OrderType","name":"orderType","type":"uint8"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"endTime","type":"uint256"},{"internalType":"bytes32","name":"zoneHash","type":"bytes32"},{"internalType":"uint256","name":"salt","type":"uint256"},{"internalType":"bytes32","name":"conduitKey","type":"bytes32"},{"internalType":"uint256","name":"totalOriginalConsiderationItems","type":"uint256"}],"internalType":"struct OrderParameters","name":"parameters","type":"tuple"},{"internalType":"uint120","name":"numerator","type":"uint120"},{"internalType":"uint120","name":"denominator","type":"uint120"},{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"bytes","name":"extraData","type":"bytes"}],"internalType":"struct AdvancedOrder[]","name":"advancedOrders","type":"tuple[]"},{"components":[{"internalType":"uint256","name":"orderIndex","type":"uint256"},{"internalType":"enum Side","name":"side","type":"uint8"},{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"uint256","name":"identifier","type":"uint256"},{"internalType":"bytes32[]","name":"criteriaProof","type":"bytes32[]"}],"internalType":"struct CriteriaResolver[]","name":"criteriaResolvers","type":"tuple[]"},{"components":[{"internalType":"uint256","name":"orderIndex","type":"uint256"},{"internalType":"uint256","name":"itemIndex","type":"uint256"}],"internalType":"struct FulfillmentComponent[][]","name":"offerFulfillments","type":"tuple[][]"},{"components":[{"internalType":"uint256","name":"orderIndex","type":"uint256"},{"internalType":"uint256","name":"itemIndex","type":"uint256"}],"internalType":"struct FulfillmentComponent[][]","name":"considerationFulfillments","type":"tuple[][]"},{"internalType":"bytes32","name":"fulfillerConduitKey","type":"bytes32"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"maximumFulfilled","type":"uint256"}],"name":"fulfillAvailableAdvancedOrders","outputs":[{"internalType":"bool[]","name":"availableOrders","type":"bool[]"},{"components":[{"components":[{"internalType":"enum ItemType","name":"itemType","type":"uint8"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"identifier","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address payable","name":"recipient","type":"address"}],"internalType":"struct ReceivedItem","name":"item","type":"tuple"},{"internalType":"address","name":"offerer","type":"address"},{"internalType":"bytes32","name":"conduitKey","type":"bytes32"}],"internalType":"struct Execution[]","name":"executions","type":"tuple[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"address","name":"offerer","type":"address"},{"internalType":"address","name":"zone","type":"address"},{"components":[{"internalType":"enum ItemType","name":"itemType","type":"uint8"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"identifierOrCriteria","type":"uint256"},{"internalType":"uint256","name":"startAmount","type":"uint256"},{"internalType":"uint256","name":"endAmount","type":"uint256"}],"internalType":"struct OfferItem[]","name":"offer","type":"tuple[]"},{"components":[{"internalType":"enum ItemType","name":"itemType","type":"uint8"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"identifierOrCriteria","type":"uint256"},{"internalType":"uint256","name":"startAmount","type":"uint256"},{"internalType":"uint256","name":"endAmount","type":"uint256"},{"internalType":"address payable","name":"recipient","type":"address"}],"internalType":"struct ConsiderationItem[]","name":"consideration","type":"tuple[]"},{"internalType":"enum OrderType","name":"orderType","type":"uint8"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"endTime","type":"uint256"},{"internalType":"bytes32","name":"zoneHash","type":"bytes32"},{"internalType":"uint256","name":"salt","type":"uint256"},{"internalType":"bytes32","name":"conduitKey","type":"bytes32"},{"internalType":"uint256","name":"totalOriginalConsiderationItems","type":"uint256"}],"internalType":"struct OrderParameters","name":"parameters","type":"tuple"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct Order[]","name":"orders","type":"tuple[]"},{"components":[{"internalType":"uint256","name":"orderIndex","type":"uint256"},{"internalType":"uint256","name":"itemIndex","type":"uint256"}],"internalType":"struct FulfillmentComponent[][]","name":"offerFulfillments","type":"tuple[][]"},{"components":[{"internalType":"uint256","name":"orderIndex","type":"uint256"},{"internalType":"uint256","name":"itemIndex","type":"uint256"}],"internalType":"struct FulfillmentComponent[][]","name":"considerationFulfillments","type":"tuple[][]"},{"internalType":"bytes32","name":"fulfillerConduitKey","type":"bytes32"},{"internalType":"uint256","name":"maximumFulfilled","type":"uint256"}],"name":"fulfillAvailableOrders","outputs":[{"internalType":"bool[]","name":"availableOrders","type":"bool[]"},{"components":[{"components":[{"internalType":"enum ItemType","name":"itemType","type":"uint8"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"identifier","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address payable","name":"recipient","type":"address"}],"internalType":"struct ReceivedItem","name":"item","type":"tuple"},{"internalType":"address","name":"offerer","type":"address"},{"internalType":"bytes32","name":"conduitKey","type":"bytes32"}],"internalType":"struct Execution[]","name":"executions","type":"tuple[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"considerationToken","type":"address"},{"internalType":"uint256","name":"considerationIdentifier","type":"uint256"},{"internalType":"uint256","name":"considerationAmount","type":"uint256"},{"internalType":"address payable","name":"offerer","type":"address"},{"internalType":"address","name":"zone","type":"address"},{"internalType":"address","name":"offerToken","type":"address"},{"internalType":"uint256","name":"offerIdentifier","type":"uint256"},{"internalType":"uint256","name":"offerAmount","type":"uint256"},{"internalType":"enum BasicOrderType","name":"basicOrderType","type":"uint8"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"endTime","type":"uint256"},{"internalType":"bytes32","name":"zoneHash","type":"bytes32"},{"internalType":"uint256","name":"salt","type":"uint256"},{"internalType":"bytes32","name":"offererConduitKey","type":"bytes32"},{"internalType":"bytes32","name":"fulfillerConduitKey","type":"bytes32"},{"internalType":"uint256","name":"totalOriginalAdditionalRecipients","type":"uint256"},{"components":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address payable","name":"recipient","type":"address"}],"internalType":"struct AdditionalRecipient[]","name":"additionalRecipients","type":"tuple[]"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct BasicOrderParameters","name":"parameters","type":"tuple"}],"name":"fulfillBasicOrder","outputs":[{"internalType":"bool","name":"fulfilled","type":"bool"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"considerationToken","type":"address"},{"internalType":"uint256","name":"considerationIdentifier","type":"uint256"},{"internalType":"uint256","name":"considerationAmount","type":"uint256"},{"internalType":"address payable","name":"offerer","type":"address"},{"internalType":"address","name":"zone","type":"address"},{"internalType":"address","name":"offerToken","type":"address"},{"internalType":"uint256","name":"offerIdentifier","type":"uint256"},{"internalType":"uint256","name":"offerAmount","type":"uint256"},{"internalType":"enum BasicOrderType","name":"basicOrderType","type":"uint8"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"endTime","type":"uint256"},{"internalType":"bytes32","name":"zoneHash","type":"bytes32"},{"internalType":"uint256","name":"salt","type":"uint256"},{"internalType":"bytes32","name":"offererConduitKey","type":"bytes32"},{"internalType":"bytes32","name":"fulfillerConduitKey","type":"bytes32"},{"internalType":"uint256","name":"totalOriginalAdditionalRecipients","type":"uint256"},{"components":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address payable","name":"recipient","type":"address"}],"internalType":"struct AdditionalRecipient[]","name":"additionalRecipients","type":"tuple[]"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct BasicOrderParameters","name":"parameters","type":"tuple"}],"name":"fulfillBasicOrder_efficient_6GL6yc","outputs":[{"internalType":"bool","name":"fulfilled","type":"bool"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"address","name":"offerer","type":"address"},{"internalType":"address","name":"zone","type":"address"},{"components":[{"internalType":"enum ItemType","name":"itemType","type":"uint8"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"identifierOrCriteria","type":"uint256"},{"internalType":"uint256","name":"startAmount","type":"uint256"},{"internalType":"uint256","name":"endAmount","type":"uint256"}],"internalType":"struct OfferItem[]","name":"offer","type":"tuple[]"},{"components":[{"internalType":"enum ItemType","name":"itemType","type":"uint8"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"identifierOrCriteria","type":"uint256"},{"internalType":"uint256","name":"startAmount","type":"uint256"},{"internalType":"uint256","name":"endAmount","type":"uint256"},{"internalType":"address payable","name":"recipient","type":"address"}],"internalType":"struct ConsiderationItem[]","name":"consideration","type":"tuple[]"},{"internalType":"enum OrderType","name":"orderType","type":"uint8"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"endTime","type":"uint256"},{"internalType":"bytes32","name":"zoneHash","type":"bytes32"},{"internalType":"uint256","name":"salt","type":"uint256"},{"internalType":"bytes32","name":"conduitKey","type":"bytes32"},{"internalType":"uint256","name":"totalOriginalConsiderationItems","type":"uint256"}],"internalType":"struct OrderParameters","name":"parameters","type":"tuple"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct Order","name":"order","type":"tuple"},{"internalType":"bytes32","name":"fulfillerConduitKey","type":"bytes32"}],"name":"fulfillOrder","outputs":[{"internalType":"bool","name":"fulfilled","type":"bool"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"contractOfferer","type":"address"}],"name":"getContractOffererNonce","outputs":[{"internalType":"uint256","name":"nonce","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"offerer","type":"address"}],"name":"getCounter","outputs":[{"internalType":"uint256","name":"counter","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"offerer","type":"address"},{"internalType":"address","name":"zone","type":"address"},{"components":[{"internalType":"enum ItemType","name":"itemType","type":"uint8"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"identifierOrCriteria","type":"uint256"},{"internalType":"uint256","name":"startAmount","type":"uint256"},{"internalType":"uint256","name":"endAmount","type":"uint256"}],"internalType":"struct OfferItem[]","name":"offer","type":"tuple[]"},{"components":[{"internalType":"enum ItemType","name":"itemType","type":"uint8"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"identifierOrCriteria","type":"uint256"},{"internalType":"uint256","name":"startAmount","type":"uint256"},{"internalType":"uint256","name":"endAmount","type":"uint256"},{"internalType":"address payable","name":"recipient","type":"address"}],"internalType":"struct ConsiderationItem[]","name":"consideration","type":"tuple[]"},{"internalType":"enum OrderType","name":"orderType","type":"uint8"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"endTime","type":"uint256"},{"internalType":"bytes32","name":"zoneHash","type":"bytes32"},{"internalType":"uint256","name":"salt","type":"uint256"},{"internalType":"bytes32","name":"conduitKey","type":"bytes32"},{"internalType":"uint256","name":"counter","type":"uint256"}],"internalType":"struct OrderComponents","name":"order","type":"tuple"}],"name":"getOrderHash","outputs":[{"internalType":"bytes32","name":"orderHash","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"orderHash","type":"bytes32"}],"name":"getOrderStatus","outputs":[{"internalType":"bool","name":"isValidated","type":"bool"},{"internalType":"bool","name":"isCancelled","type":"bool"},{"internalType":"uint256","name":"totalFilled","type":"uint256"},{"internalType":"uint256","name":"totalSize","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"incrementCounter","outputs":[{"internalType":"uint256","name":"newCounter","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"information","outputs":[{"internalType":"string","name":"version","type":"string"},{"internalType":"bytes32","name":"domainSeparator","type":"bytes32"},{"internalType":"address","name":"conduitController","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"address","name":"offerer","type":"address"},{"internalType":"address","name":"zone","type":"address"},{"components":[{"internalType":"enum ItemType","name":"itemType","type":"uint8"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"identifierOrCriteria","type":"uint256"},{"internalType":"uint256","name":"startAmount","type":"uint256"},{"internalType":"uint256","name":"endAmount","type":"uint256"}],"internalType":"struct OfferItem[]","name":"offer","type":"tuple[]"},{"components":[{"internalType":"enum ItemType","name":"itemType","type":"uint8"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"identifierOrCriteria","type":"uint256"},{"internalType":"uint256","name":"startAmount","type":"uint256"},{"internalType":"uint256","name":"endAmount","type":"uint256"},{"internalType":"address payable","name":"recipient","type":"address"}],"internalType":"struct ConsiderationItem[]","name":"consideration","type":"tuple[]"},{"internalType":"enum OrderType","name":"orderType","type":"uint8"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"endTime","type":"uint256"},{"internalType":"bytes32","name":"zoneHash","type":"bytes32"},{"internalType":"uint256","name":"salt","type":"uint256"},{"internalType":"bytes32","name":"conduitKey","type":"bytes32"},{"internalType":"uint256","name":"totalOriginalConsiderationItems","type":"uint256"}],"internalType":"struct OrderParameters","name":"parameters","type":"tuple"},{"internalType":"uint120","name":"numerator","type":"uint120"},{"internalType":"uint120","name":"denominator","type":"uint120"},{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"bytes","name":"extraData","type":"bytes"}],"internalType":"struct AdvancedOrder[]","name":"advancedOrders","type":"tuple[]"},{"components":[{"internalType":"uint256","name":"orderIndex","type":"uint256"},{"internalType":"enum Side","name":"side","type":"uint8"},{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"uint256","name":"identifier","type":"uint256"},{"internalType":"bytes32[]","name":"criteriaProof","type":"bytes32[]"}],"internalType":"struct CriteriaResolver[]","name":"criteriaResolvers","type":"tuple[]"},{"components":[{"components":[{"internalType":"uint256","name":"orderIndex","type":"uint256"},{"internalType":"uint256","name":"itemIndex","type":"uint256"}],"internalType":"struct FulfillmentComponent[]","name":"offerComponents","type":"tuple[]"},{"components":[{"internalType":"uint256","name":"orderIndex","type":"uint256"},{"internalType":"uint256","name":"itemIndex","type":"uint256"}],"internalType":"struct FulfillmentComponent[]","name":"considerationComponents","type":"tuple[]"}],"internalType":"struct Fulfillment[]","name":"fulfillments","type":"tuple[]"},{"internalType":"address","name":"recipient","type":"address"}],"name":"matchAdvancedOrders","outputs":[{"components":[{"components":[{"internalType":"enum ItemType","name":"itemType","type":"uint8"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"identifier","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address payable","name":"recipient","type":"address"}],"internalType":"struct ReceivedItem","name":"item","type":"tuple"},{"internalType":"address","name":"offerer","type":"address"},{"internalType":"bytes32","name":"conduitKey","type":"bytes32"}],"internalType":"struct Execution[]","name":"executions","type":"tuple[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"address","name":"offerer","type":"address"},{"internalType":"address","name":"zone","type":"address"},{"components":[{"internalType":"enum ItemType","name":"itemType","type":"uint8"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"identifierOrCriteria","type":"uint256"},{"internalType":"uint256","name":"startAmount","type":"uint256"},{"internalType":"uint256","name":"endAmount","type":"uint256"}],"internalType":"struct OfferItem[]","name":"offer","type":"tuple[]"},{"components":[{"internalType":"enum ItemType","name":"itemType","type":"uint8"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"identifierOrCriteria","type":"uint256"},{"internalType":"uint256","name":"startAmount","type":"uint256"},{"internalType":"uint256","name":"endAmount","type":"uint256"},{"internalType":"address payable","name":"recipient","type":"address"}],"internalType":"struct ConsiderationItem[]","name":"consideration","type":"tuple[]"},{"internalType":"enum OrderType","name":"orderType","type":"uint8"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"endTime","type":"uint256"},{"internalType":"bytes32","name":"zoneHash","type":"bytes32"},{"internalType":"uint256","name":"salt","type":"uint256"},{"internalType":"bytes32","name":"conduitKey","type":"bytes32"},{"internalType":"uint256","name":"totalOriginalConsiderationItems","type":"uint256"}],"internalType":"struct OrderParameters","name":"parameters","type":"tuple"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct Order[]","name":"orders","type":"tuple[]"},{"components":[{"components":[{"internalType":"uint256","name":"orderIndex","type":"uint256"},{"internalType":"uint256","name":"itemIndex","type":"uint256"}],"internalType":"struct FulfillmentComponent[]","name":"offerComponents","type":"tuple[]"},{"components":[{"internalType":"uint256","name":"orderIndex","type":"uint256"},{"internalType":"uint256","name":"itemIndex","type":"uint256"}],"internalType":"struct FulfillmentComponent[]","name":"considerationComponents","type":"tuple[]"}],"internalType":"struct Fulfillment[]","name":"fulfillments","type":"tuple[]"}],"name":"matchOrders","outputs":[{"components":[{"components":[{"internalType":"enum ItemType","name":"itemType","type":"uint8"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"identifier","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address payable","name":"recipient","type":"address"}],"internalType":"struct ReceivedItem","name":"item","type":"tuple"},{"internalType":"address","name":"offerer","type":"address"},{"internalType":"bytes32","name":"conduitKey","type":"bytes32"}],"internalType":"struct Execution[]","name":"executions","type":"tuple[]"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"contractName","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"address","name":"offerer","type":"address"},{"internalType":"address","name":"zone","type":"address"},{"components":[{"internalType":"enum ItemType","name":"itemType","type":"uint8"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"identifierOrCriteria","type":"uint256"},{"internalType":"uint256","name":"startAmount","type":"uint256"},{"internalType":"uint256","name":"endAmount","type":"uint256"}],"internalType":"struct OfferItem[]","name":"offer","type":"tuple[]"},{"components":[{"internalType":"enum ItemType","name":"itemType","type":"uint8"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"identifierOrCriteria","type":"uint256"},{"internalType":"uint256","name":"startAmount","type":"uint256"},{"internalType":"uint256","name":"endAmount","type":"uint256"},{"internalType":"address payable","name":"recipient","type":"address"}],"internalType":"struct ConsiderationItem[]","name":"consideration","type":"tuple[]"},{"internalType":"enum OrderType","name":"orderType","type":"uint8"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"endTime","type":"uint256"},{"internalType":"bytes32","name":"zoneHash","type":"bytes32"},{"internalType":"uint256","name":"salt","type":"uint256"},{"internalType":"bytes32","name":"conduitKey","type":"bytes32"},{"internalType":"uint256","name":"totalOriginalConsiderationItems","type":"uint256"}],"internalType":"struct OrderParameters","name":"parameters","type":"tuple"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct Order[]","name":"orders","type":"tuple[]"}],"name":"validate","outputs":[{"internalType":"bool","name":"validated","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

3cda3351000000000000000000000000000000000000000000000000000000000000000001001c8f194205e3aab04a245337783bca19841c1a5a66f32ed88f3411870d1c000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000200000000000000000000000001972ddfa941670a9f5fa2a0094f4490347b99d7b

Deployed Bytecode

0x000400000000000200220000000000020000000003010019000000600330027000001ba4043001970003000000410355000200000001035500001ba40030019d0000000100200190000000400000c13d0000022002000039000000400020043f000000040040008c000001130000413d000000000301043b000000e00330027000001bf60030009c0000011b0000a13d00001bf70030009c0000013d0000a13d00001bf80030009c000002140000a13d00001bf90030009c000003570000613d00001bfa0030009c0000034c0000613d00001bfb0030009c00000ca20000c13d000000240040008c00000ca20000413d0000000003000416000000000003004b00000ca20000c13d0000000403100370000000000303043b000200000003001d00001bce0030009c00000ca20000213d00000002030000290000002303300039000000000043004b00000ca20000813d00000002030000290000000403300039000000000131034f000000000101043b000100000001001d00001bce0010009c00000ca20000213d0000000201000029000c00240010003d000000010100002900000005011002100000000c01100029000000000041004b00000ca20000213d0000000103000039000000000103041a000000010010008c000004f00000c13d000000010000006b000006a80000c13d0000000000320435000003520000013d0000020003000039000000400030043f0000000002000416000000000002004b00000ca20000c13d0000001f0240003900001ba5022001970000020002200039000000400020043f0000001f0540018f00001ba6064001980000020002600039000000520000613d000000000701034f000000007807043c0000000003830436000000000023004b0000004e0000c13d000000000005004b0000005f0000613d000000000161034f0000000303500210000000000502043300000000053501cf000000000535022f000000000101043b0000010003300089000000000131022f00000000013101cf000000000151019f0000000000120435000000200040008c00000ca20000413d000002000300043d00001ba70030009c00000ca20000213d000000400100043d00001ba80010009c0000010d0000213d0000004002100039000000400020043f0000000702000039000000000121043600001ba902000041000000000021043500001ba40010009c00001ba4010080410000004001100210000000000200041400001ba40020009c00001ba402008041000000c002200210000000000121019f00001baa011001c70000801002000039001900000003001d6e8b6e860000040f000000010020019000000ca20000613d000000000201043b000000400100043d00001ba80010009c0000010d0000213d001800000002001d0000004002100039000000400020043f0000000302000039000000000121043600001bab02000041000000000021043500001ba40010009c00001ba4010080410000004001100210000000000200041400001ba40020009c00001ba402008041000000c002200210000000000121019f00001bac011001c700008010020000396e8b6e860000040f000000010020019000000ca20000613d000000000701043b000000400900043d000000200890003900001bad0100004100000000001804350000002a0290003900001bae010000410000000000120435000000390390003900001baf020000410000000000230435000000470390003900001bb0040000410000000000430435000000640390003900001bb1050000410000000000530435000000780390003900001bb2060000410000000000630435000000890690003900001bb30300004100000000003604350000006a06000039000000000069043500001bb40090009c0000010d0000213d000000a00b9000390000004000b0043f000000c00a90003900001bb50600004100000000006a0435000000d2069000390000000000160435000000e1019000390000000000210435000000ef0190003900000000004104350000010c019000390000000000510435000001200190003900001bb6020000410000000000210435000001320190003900001bb702000041000000000021043500000143019000390000000000310435000000840100003900000000001b043500001bb80090009c0000010d0000213d0000016006900039000000400060043f000001df0190003900001bb9020000410000000000210435000001e10190003900001bba020000410000000000210435000001f10190003900001bbb020000410000000000210435000002030190003900001bbc020000410000000000210435000002130190003900001bbd020000410000000000210435000001800590003900001bbe010000410000000000150435000001900190003900001bbf020000410000000000210435000002240190003900001bc0020000410000000000210435000001a00190003900001bc1020000410000000000210435000002310190003900001bc2020000410000000000210435000001ad0190003900001bc3020000410000000000210435000002440190003900001bc4020000410000000000210435000001bf0190003900001bc5020000410000000000210435000002530190003900001bb3020000410000000000210435000000d401000039000000000016043500001bc60090009c0000010d0000213d000002800190003900001bc70300004100000000003104350000028d0390003900001bc8040000410000000000430435000002990390003900001bc9040000410000000000430435000002a80390003900001bca040000410000000000430435000002b80390003900001bcb040000410000000000430435000002d103900039000000000023043500000260029000390000005203000039000000000032043500001bcc0090009c000005440000a13d00001c1401000041000000000010043f0000004101000039000000040010043f00001c150100004100006e8d00010430000000000004004b00000ca20000c13d0000000101000039000000000101041a000000030010008c000001370000c13d000000000100001900006e8c0001042e00001c030030009c0000017f0000213d00001c090030009c0000027a0000213d000000000003004b0000034c0000613d00001c0c0030009c00000ca20000c13d0000000001000416000000000001004b00000ca20000c13d0000026001000039000000400010043f0000000701000039000002200010043f00001ba901000041000002400010043f0000002001000039000002600010043f000002200100003900000280020000396e8b0fc00000040f000002600110008a00001ba40010009c00001ba401008041000000600110021000001c2a011001c700006e8c0001042e00001bf401000041000002200010043f0000000001000416000002240010043f00001bf50100004100006e8d0001043000001bfe0030009c000002990000213d00001c010030009c000003850000613d00001c020030009c00000ca20000c13d000000440040008c00000ca20000413d0000000402100370000000000302043b00001bce0030009c00000ca20000213d000000000534004900001c0f0050009c00000ca20000213d000000440050008c00000ca20000413d0000000402300039000000000421034f000000000404043b000001630550008a00001c0d0640019700001c0d07500197000000000876013f000000000076004b000000000600001900001c0d06004041000000000054004b000000000500001900001c0d0500804100001c0d0080009c000000000605c019000000000006004b00000ca20000c13d00000000034300190000008403300039000000000131034f000000000101043b000000040010008c00000ca20000213d0000000104000039000000000304041a000000010030008c000004f00000c13d000000040010008c00000002010000390000000301006039000000000014041b00000000010200196e8b33fb0000040f001900000001001d000000400100043d001800000001001d6e8b0fdd0000040f0000001802000029000000000002043500000024010000390000000201100367000000000301043b000000000400041100000019010000296e8b359c0000040f0000000102000039000000000022041b000000400100043d0000053e0000013d00001c040030009c000002fe0000213d00001c070030009c000003980000613d00001c080030009c00000ca20000c13d000000e40040008c00000ca20000413d0000000401100370000000000101043b00001bce0010009c00000ca20000213d000000040110003900000000020400196e8b12300000040f001900000001001d00000002010003670000002402100370000000000402043b00001bce0040009c00000ca20000213d0000002305400039000000000200003100001c0d0320019700001c0d06500197000000000736013f000000000036004b000000000600001900001c0d06004041000000000025004b000000000500001900001c0d0500804100001c0d0070009c000000000605c019000000000006004b00000ca20000c13d0000000405400039000000000551034f000000000505043b001800000005001d00001bce0050009c00000ca20000213d001700240040003d000000180400002900000005044002100000001704400029000000000024004b00000ca20000213d0000004404100370000000000404043b00001bce0040009c00000ca20000213d0000002305400039000000000025004b000000000600001900001c0d0600804100001c0d05500197000000000735013f000000000035004b000000000500001900001c0d0500404100001c0d0070009c000000000506c019000000000005004b00000ca20000c13d0000000405400039000000000551034f000000000505043b001600000005001d00001bce0050009c00000ca20000213d001500240040003d000000160400002900000005044002100000001504400029000000000024004b00000ca20000213d0000006404100370000000000404043b00001bce0040009c00000ca20000213d0000002305400039000000000025004b000000000600001900001c0d0600804100001c0d05500197000000000735013f000000000035004b000000000300001900001c0d0300404100001c0d0070009c000000000306c019000000000003004b00000ca20000c13d0000000403400039000000000331034f000000000303043b001400000003001d00001bce0030009c00000ca20000213d001300240040003d000000140300002900000005033002100000001303300029000000000023004b00000ca20000213d000000a401100370000000000101043b001200000001001d00001ba70010009c00000ca20000213d0000000101000039000000000101041a000000010010008c00000cb00000c13d000000120100002900101ba70010019b00000003010000390000000102000039000000000012041b00000019010000296e8b274d0000040f001100000001001d000000100000006b000001fe0000c13d0000000001000411001200000001001d00000002010003670000008402100370000000000202043b001000000002001d000000c401100370000000000101043b000f00000001001d0000000003000031000000170100002900000018020000296e8b24b30000040f0000000003010019000000190100002900000011020000290000001504000029000000160500002900000013060000290000001407000029000000100800002900000012090000290000000f0a000029000002f30000013d00001bfc0030009c0000044a0000613d00001bfd0030009c00000ca20000c13d000000840040008c00000ca20000413d0000000401100370000000000101043b00001bce0010009c00000ca20000213d000000040110003900000000020400196e8b12300000040f001900000001001d00000002040003670000002401400370000000000101043b00001bce0010009c00000ca20000213d0000002302100039000000000300003100001c0d0530019700001c0d06200197000000000756013f000000000056004b000000000600001900001c0d06004041000000000032004b000000000200001900001c0d0200804100001c0d0070009c000000000602c019000000000006004b00000ca20000c13d0000000402100039000000000224034f000000000202043b00001bce0020009c00000ca20000213d000000240110003900000005062002100000000006160019000000000036004b00000ca20000213d0000004406400370000000000606043b00001bce0060009c00000ca20000213d0000002307600039000000000037004b000000000800001900001c0d0800804100001c0d07700197000000000957013f000000000057004b000000000500001900001c0d0500404100001c0d0090009c000000000508c019000000000005004b00000ca20000c13d0000000405600039000000000554034f000000000505043b001800000005001d00001bce0050009c00000ca20000213d001700240060003d000000180500002900000005055002100000001705500029000000000035004b00000ca20000213d0000006404400370000000000404043b001600000004001d00001ba70040009c00000ca20000213d0000000104000039000000000404041a000000010040008c00000cb00000c13d00000003040000390000000105000039000000000045041b000000160000006b0000026d0000c13d0000000004000411001600000004001d6e8b24b30000040f000000000201001900000019010000290000001703000029000000180400002900000016050000296e8b2ecb0000040f0000000102000039000000000022041b000000400300043d001900000003001d0000002002000039000003400000013d00001c0a0030009c000004550000613d00001c0b0030009c00000ca20000c13d0000000001000416000000000001004b00000ca20000c13d0000000101000039000000000101041a000000010010008c000004f00000c13d00001c25010000410000000000100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001bd3011001c70000800b020000396e8b6e860000040f0000000100200190000009e00000613d000000000101043b000000000001004b000004f40000c13d00001c1401000041000000000010043f0000001101000039000000040010043f00001c150100004100006e8d0001043000001bff0030009c000004720000613d00001c000030009c00000ca20000c13d000000a40040008c00000ca20000413d0000000402100370000000000302043b00001bce0030009c00000ca20000213d0000002302300039000000000042004b00000ca20000813d0000000402300039000000000221034f000000000202043b00001bce0020009c00000ca20000213d000000240330003900000005052002100000000005350019000000000045004b00000ca20000213d0000002405100370000000000505043b00001bce0050009c00000ca20000213d0000002306500039000000000046004b00000ca20000813d0000000406500039000000000661034f000000000606043b001900000006001d00001bce0060009c00000ca20000213d001800240050003d000000190500002900000005055002100000001805500029000000000045004b00000ca20000213d0000004405100370000000000505043b00001bce0050009c00000ca20000213d0000002306500039000000000046004b00000ca20000813d0000000406500039000000000161034f000000000101043b001700000001001d00001bce0010009c00000ca20000213d001600240050003d000000170100002900000005011002100000001601100029000000000041004b00000ca20000213d00000001010000390000000004010019000000000101041a000000010010008c000004f00000c13d0000000301000039000000000014041b00000000010300196e8b2cb90000040f001500000001001d6e8b274d0000040f001400000001001d000000400100043d001300000001001d6e8b0fdd0000040f0000001303000029000000000003043500000002010003670000006402100370000000000802043b0000008401100370000000000a01043b00000000090004110000001501000029000000140200002900000018040000290000001905000029000000160600002900000017070000296e8b28d50000040f0000000103000039000000000033041b00000000030100190000000004020019000000400100043d001900000001001d000000000203001900000000030400196e8b14400000040f000003420000013d00001c050030009c000004cc0000613d00001c060030009c00000ca20000c13d000000440040008c00000ca20000413d0000000402100370000000000302043b00001bce0030009c00000ca20000213d0000002302300039000000000042004b00000ca20000813d0000000402300039000000000221034f000000000202043b00001bce0020009c00000ca20000213d000000240330003900000005052002100000000005350019000000000045004b00000ca20000213d0000002405100370000000000505043b00001bce0050009c00000ca20000213d0000002306500039000000000046004b00000ca20000813d0000000406500039000000000161034f000000000101043b001900000001001d00001bce0010009c00000ca20000213d001800240050003d000000190100002900000005011002100000001801100029000000000041004b00000ca20000213d0000000104000039000000000104041a000000010010008c000004f00000c13d0000000301000039000000000014041b00000000010300196e8b2cb90000040f001700000001001d000000400100043d001600000001001d6e8b0fdd0000040f0000001602000029000000000002043500000000050004110000001701000029000000180300002900000019040000296e8b2ecb0000040f0000000102000039000000000022041b0000002002000039000000400300043d001900000003001d00000000022304366e8b14100000040f0000001902000029000000000121004900001ba40010009c00001ba401008041000000600110021000001ba40020009c00001ba4020080410000004002200210000000000121019f00006e8c0001042e00000000010400196e8b0fae0000040f6e8b14830000040f0000000101000039000000400200043d000000000012043500001ba40020009c00001ba402008041000000400120021000001c1c011001c700006e8c0001042e0000000001000416000000000001004b00000ca20000c13d0000026001000039000000400010043f0000000301000039000002200010043f00001bab01000041000002400010043f6e8b5fb70000040f0000006002000039000000400300043d001900000003001d0000000002230436001800000002001d001700000001001d000002200100003900000060023000396e8b0fc00000040f0000001802000029000000170300002900000000003204350000000002000412001b00000002001d001a01200000003d001800000001001d0000800501000039000000440300003900000000040004150000001b0440008a000000050440021000001c10020000416e8b6e630000040f00001ba701100197000000190300002900000040023000390000000000120435000000180130006900001ba40010009c00001ba401008041000000600110021000001ba40030009c00001ba4030080410000004002300210000000000121019f00006e8c0001042e000000240040008c00000ca20000413d0000000002000416000000000002004b00000ca20000c13d0000000401100370000000000101043b00001ba70010009c00000ca20000213d000000000010043f0000000401000039000000200010043f000000400200003900000000010000196e8b6e4e0000040f000000000101041a000002200010043f00001c1d0100004100006e8c0001042e000000240040008c00000ca20000413d0000000002000416000000000002004b00000ca20000c13d0000000402100370000000000202043b00001bce0020009c00000ca20000213d000000000324004900001c0f0030009c00000ca20000213d000001640030008c00000ca20000413d0000000403200039000000000531034f000000000505043b001900000005001d00001ba70050009c00000ca20000213d0000002005300039000000000651034f000000000606043b001800000006001d00001ba70060009c00000ca20000213d00000000063400490000002007500039000000000571034f000000000805043b0000001f0560008a00001c0d0650019700001c0d09800197000000000a69013f000000000069004b000000000900001900001c0d09004041000000000058004b000000000b00001900001c0d0b00804100001c0d00a0009c00000000090bc019000000000009004b00000ca20000c13d0000000008380019000000000981034f000000000909043b001700000009001d00001bce0090009c00000ca20000213d000000a00900008a00000017099000b90000000009490019000000200c80003900001c0d0890019700001c0d0ac00197000000000b8a013f00000000008a004b000000000800001900001c0d0800404100160000000c001d00000000009c004b000000000900001900001c0d0900204100001c0d00b0009c000000000809c019000000000008004b00000ca20000c13d0000002007700039000000000871034f000000000808043b00001c0d09800197000000000a69013f000000000069004b000000000600001900001c0d06004041000000000058004b000000000500001900001c0d0500804100001c0d00a0009c000000000605c019000000000006004b00000ca20000c13d0000000005380019000000000651034f000000000606043b001500000006001d00001bce0060009c00000ca20000213d000000c00600008a00000015066000b90000000004460019000000200950003900001c0d0540019700001c0d06900197000000000856013f000000000056004b000000000500001900001c0d05004041001400000009001d000000000049004b000000000400001900001c0d0400204100001c0d0080009c000000000504c019000000000005004b00000ca20000c13d001200200070003d0000001201100360000000000101043b001100000001001d000000040010008c00000ca20000213d000000640220003900000000010300196e8b24880000040f001000000001001d000000400100043d001300000001001d6e8b0fd20000040f0000001303000029000000200130003900000018020000290000000000210435000000190100002900000000001304350000000003000031000000160100002900000017020000296e8b0fe80000040f0000001302000029000000400220003900000000001204350000000003000031000000140100002900000015020000296e8b10330000040f000000130500002900000080025000390000001103000029000000000032043500000060025000390000000000120435000000120400002900000020014000390000000201100367000000000101043b000000a003500039000000000013043500000040014000390000000201100367000000000101043b000000c003500039000000000013043500000060014000390000000201100367000000000101043b000000e003500039000000000013043500000080014000390000000201100367000000000101043b00000100035000390000000000130435000000a0014000390000000201100367000000000101043b000001200350003900000000001304350000014003500039000000000105001900000010050000290000000000530435000000c0034000390000000202300367000000000202043b6e8b25460000040f000003500000013d000000240040008c00000ca20000413d0000000002000416000000000002004b00000ca20000c13d0000000401100370000000000101043b00001ba70010009c00000ca20000213d6e8b25340000040f000003500000013d000000240040008c00000ca20000413d0000000002000416000000000002004b00000ca20000c13d0000000401100370000000000101043b000000000010043f0000000301000039000000200010043f000000400200003900000000010000196e8b6e4e0000040f000000000101041a000000ff001001900000000002000039000000010200c039000002200020043f0000ff00001001900000000002000039000000010200c039000002400020043f000000100210027000001c1f02200197000002600020043f0000008801100270000002800010043f00001c290100004100006e8c0001042e000000840040008c00000ca20000413d0000000402100370000000000302043b00001bce0030009c00000ca20000213d000000000534004900001c0f0050009c00000ca20000213d000000a40050008c00000ca20000413d0000002402100370000000000202043b00001bce0020009c00000ca20000213d0000002306200039000000000046004b00000ca20000813d0000000406200039000000000661034f000000000606043b001900000006001d00001bce0060009c00000ca20000213d001800240020003d000000190200002900000005022002100000001802200029000000000042004b00000ca20000213d0000006402100370000000000202043b001700000002001d00001ba70020009c00000ca20000213d0000000402300039000000000621034f000000000606043b000001630550008a00001c0d0760019700001c0d08500197000000000987013f000000000087004b000000000700001900001c0d07004041000000000056004b000000000500001900001c0d0500804100001c0d0090009c000000000705c019000000000007004b00000ca20000c13d00000000036300190000008403300039000000000131034f000000000101043b000000040010008c00000ca20000213d0000000103000039000000000303041a000000010030008c000004f00000c13d000000040010008c000000020100003900000003010060390000000103000039000000000013041b000000170000006b000004b90000c13d0000000001000411001700000001001d000000000102001900000000020400196e8b10850000040f00000044020000390000000202200367000000000202043b001600000002001d001500000001001d0000000003000031000000180100002900000019020000296e8b24b30000040f00000000020100190000001501000029000000160300002900000017040000296e8b359c0000040f00000001020000390000017c0000013d000000240040008c00000ca20000413d0000000002000416000000000002004b00000ca20000c13d0000000402100370000000000202043b001400000002001d00001bce0020009c00000ca20000213d00000014020000290000002302200039000000000042004b00000ca20000813d00000014020000290000000402200039000000000121034f000000000101043b001300000001001d00001bce0010009c00000ca20000213d0000001401000029000000240e100039000000130100002900000005011002100000000001e10019000000000041004b00000ca20000213d0000000102000039000000000102041a000000010010008c000004f00000c13d000000130000006b000009e10000c13d00000220010000390000053e0000013d00001c2301000041000002200010043f00001c240100004100006e8d00010430001900000001001d0000000001000411000000000010043f0000000201000039000000200010043f000000000100041400001ba40010009c00001ba401008041000000c00110021000001c17011001c700008010020000396e8b6e860000040f000000010020019000000ca20000613d0000001902000029000000010220008a000000000101043b000000000101041a001900000001001d00001c260100004100000000001004430000000400200443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c27011001c70000800b020000396e8b6e860000040f0000000100200190000009e00000613d000000000101043b0000008001100270001800000001001d000000190010002a000002930000413d0000000001000411000000000010043f0000000201000039000000200010043f000000000100041400001ba40010009c00001ba401008041000000c00110021000001c17011001c700008010020000396e8b6e860000040f000000010020019000000ca20000613d00000018030000290000001902300029000000000101043b000000000021041b000000400100043d001900000002001d000000000021043500001ba40010009c00001ba4010080410000004001100210000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001c19011001c70000800d02000039000000020300003900001c280400004100000000050004116e8b6e810000040f000000010020019000000ca20000613d000000400100043d0000001902000029000000000021043500001ba40010009c00001ba401008041000000400110021000001c1c011001c700006e8c0001042e00140000000b001d001300000006001d001100000005001d00150000000a001d001600000008001d001000000007001d001700000009001d000002e003900039001200000003001d000000400030043f00001ba40010009c00001ba4010080410000004001100210000000000202043300001ba40020009c00001ba4020080410000006002200210000000000112019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f000000010020019000000ca20000613d000000160200002900001ba40020009c00001ba40200804100000040022002100000001703000029000000000303043300001ba40030009c00001ba4030080410000006003300210000000000223019f000000000101043b000f00000001001d000000000100041400001ba40010009c00001ba401008041000000c001100210000000000121019f00001bcd011001c700008010020000396e8b6e860000040f000000010020019000000ca20000613d000000150200002900001ba40020009c00001ba40200804100000040022002100000001403000029000000000303043300001ba40030009c00001ba4030080410000006003300210000000000223019f000000000101043b000e00000001001d000000000100041400001ba40010009c00001ba401008041000000c001100210000000000121019f00001bcd011001c700008010020000396e8b6e860000040f000000010020019000000ca20000613d00000017020000290000030002200039000000000101043b000d00000001001d00000013010000290000000001010433000000000001004b00000011060000290000059d0000613d000000000300001900000000042300190000000005630019000000000505043300000000005404350000002003300039000000000013004b000005960000413d0000000001210019000000000001043500000014030000290000000003030433000000000003004b0000001507000029000005ac0000613d000000000400001900000000051400190000000006740019000000000606043300000000006504350000002004400039000000000034004b000005a50000413d0000000001130019000000000001043500000017030000290000000003030433000000000003004b0000001607000029000005bb0000613d000000000400001900000000051400190000000006740019000000000606043300000000006504350000002004400039000000000034004b000005b40000413d00000000011300190000000000010435000000130110006a000001a00310008a00000012040000290000000000340435000001610110008a00001c2b031001970000000001430019000000000031004b0000000003000039000000010300403900001bce0010009c0000010d0000213d00000001003001900000010d0000c13d000000400010043f00001ba40020009c00001ba40200804100000040012002100000001202000029000000000202043300001ba40020009c00001ba4020080410000006002200210000000000112019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f000000010020019000000ca20000613d000000000101043b001200000001001d000000400300043d000000400130003900001bcf020000410000000000210435000000200430003900001bd00100004100000000001404350000003401000039000000000013043500001bd10030009c0000010d0000213d0000006001300039000000400010043f00000080023000390000000005030433000000000005004b000005fa0000613d000000000600001900000000072600190000000008460019000000000808043300000000008704350000002006600039000000000056004b000005f30000413d0000000004250019000000000004043500000014050000290000000005050433000000000005004b0000001509000029000006090000613d000000000600001900000000074600190000000008960019000000000808043300000000008704350000002006600039000000000056004b000006020000413d0000000004450019000000000004043500000017050000290000000005050433000000000005004b0000001609000029000006180000613d000000000600001900000000074600190000000008960019000000000808043300000000008704350000002006600039000000000056004b000006110000413d0000000004450019000000000004043500000013050000290000000005050433000000000005004b0000001109000029000006270000613d000000000600001900000000074600190000000008960019000000000808043300000000008704350000002006600039000000000056004b000006200000413d000000000445001900000000000404350000000003340049000000800430008a0000000000410435000000410330008a00001c2b043001970000000003140019000000000043004b0000000004000039000000010400403900001bce0030009c0000010d0000213d00000001004001900000010d0000c13d000000400030043f00001ba40020009c00001ba4020080410000004002200210000000000101043300001ba40010009c00001ba4010080410000006001100210000000000121019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f000000010020019000000ca20000613d000000000101043b001500000001001d000000400300043d000000600130003900000010020000290000000000210435000000400130003900000018020000290000000000210435001700000003001d00000020023000390000000f01000029001600000002001d000000000012043500001bd2010000410000000000100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001bd3011001c70000800b020000396e8b6e860000040f0000000100200190000009e00000613d000000000301043b0000001704000029000000a001400039000000000200041000000000002104350000008001400039001400000003001d0000000000310435000000a001000039000000000014043500001bd40040009c0000010d0000213d0000001702000029000000c001200039000000400010043f000000160100002900001ba40010009c00001ba4010080410000004001100210000000000202043300001ba40020009c00001ba4020080410000006002200210000000000112019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f0000001903000029000000010020019000000ca20000613d00001ba702300197000000000101043b000001800010043f002201400000003d0000001501000029000001400010043f0000001201000029000001200010043f0000000d01000029000001000010043f0000000e01000029000000e00010043f0000000f01000029000000c00010043f0000001001000029000000a00010043f0000001801000029000000800010043f002101600000003d0000001401000029000001600010043f000001a00020043f00001bd501000041000000400300043d001900000003001d0000000001130436001800000001001d0000000001000414000000040020008c00000ccf0000c13d0000000103000031000000400030008c0000004004000039000000000403401900000cfa0000013d0000000002000019000b00000002001d00000005012002100000000c021000290000000201000367000000000221034f000000000302043b0000000002000031000000020420006a000001830440008a00001c0d0540019700001c0d06300197000000000756013f000000000056004b000000000500001900001c0d05004041000000000043004b000000000400001900001c0d0400804100001c0d0070009c000000000504c019000000000005004b00000ca20000c13d0000000c03300029000000000431034f000000000404043b000e00000004001d00001ba70040009c00000ca20000213d0000002004300039000000000541034f000000000505043b000d00000005001d00001ba70050009c00000ca20000213d0000006005400039000000000451034f000000000404043b000000050040008c00000ca20000813d000000040040008c00000cbb0000613d00000000060004110000000e0060006c000006d70000613d0000000d0060006c00000cbb0000c13d0000000006320049000000400950008a000000000591034f000000000705043b0000001f0560008a00001c0d0650019700001c0d08700197000000000a68013f000000000068004b000000000800001900001c0d08004041000000000057004b000000000b00001900001c0d0b00804100001c0d00a0009c00000000080bc019000000000008004b00000ca20000c13d0000000007370019000000000871034f000000000808043b00001bce0080009c00000ca20000213d00001c2c0a8000d1000000000a2a0019000000200770003900001c0d0ba0019700001c0d0c700197000000000dbc013f0000000000bc004b000000000b00001900001c0d0b0040410000000000a7004b000000000a00001900001c0d0a00204100001c0d00d0009c000000000b0ac01900000000000b004b00000ca20000c13d0000002009900039000000000991034f000000000909043b00001c0d0a900197000000000b6a013f00000000006a004b000000000600001900001c0d06004041000000000059004b000000000500001900001c0d0500804100001c0d00b0009c000000000605c019000000000006004b00000ca20000c13d0000000006390019000000000561034f000000000505043b00001bce0050009c00000ca20000213d00001c2d095000d10000000009290019000000200660003900001c0d0a90019700001c0d0b600197000000000cab013f0000000000ab004b000000000a00001900001c0d0a004041000000000096004b000000000900001900001c0d0900204100001c0d00c0009c000000000a09c01900000000000a004b00000ca20000c13d000000400900043d000f00000009001d00001bb80090009c0000010d0000213d0000000f0a0000290000016009a00039000000400090043f0000000e09000029000000000a9a04360000000d09000029000a0000000a001d00000000009a043500000005098002100000003f0990003900001c0e0a900197000000400900043d000000000aa9001900000000009a004b000000000b000039000000010b00403900001bce00a0009c0000010d0000213d0000000100b001900000010d0000c13d0000004000a0043f0000000000890435000000a0088000c90000000008780019000000000028004b00000ca20000213d000000000078004b0000076c0000a13d000000000a090019000000000b72004900001c0f00b0009c00000ca20000213d000000a000b0008c00000ca20000413d000000400b00043d00001bb400b0009c0000010d0000213d000000a00cb000390000004000c0043f000000000c71034f000000000c0c043b0000000500c0008c00000ca20000213d000000000dcb0436000000200c700039000000000ec1034f000000000e0e043b00001ba700e0009c00000ca20000213d000000200aa000390000000000ed0435000000200dc00039000000000dd1034f000000000d0d043b000000400eb000390000000000de0435000000400dc00039000000000dd1034f000000000d0d043b000000600eb000390000000000de0435000000600cc00039000000000cc1034f000000000c0c043b000000800db000390000000000cd04350000000000ba0435000000a007700039000000000087004b000007430000413d0000000f070000290000004007700039001600000007001d000000000097043500000005075002100000003f0770003900001c0e08700197000000400700043d0000000008870019000000000078004b0000000009000039000000010900403900001bce0080009c0000010d0000213d00000001009001900000010d0000c13d000000400080043f0000000000570435000000c0085000c90000000008680019000000000028004b00000ca20000213d000000000068004b000007b50000a13d0000000009070019000000000a62004900001c0f00a0009c00000ca20000213d000000c000a0008c00000ca20000413d000000400a00043d00001bd400a0009c0000010d0000213d000000c00ba000390000004000b0043f000000000b61034f000000000b0b043b0000000500b0008c00000ca20000213d000000000cba0436000000200b600039000000000db1034f000000000d0d043b00001ba700d0009c00000ca20000213d0000000000dc0435000000200cb00039000000000cc1034f000000000c0c043b000000400da000390000000000cd0435000000400cb00039000000000cc1034f000000000c0c043b000000600da000390000000000cd0435000000600cb00039000000000cc1034f000000000c0c043b000000800da000390000000000cd0435000000800bb00039000000000bb1034f000000000b0b043b00001ba700b0009c00000ca20000213d0000002009900039000000a00ca000390000000000bc04350000000000a90435000000c006600039000000000086004b000007850000413d0000000f060000290000006006600039001000000006001d0000000000760435000000040040008c00000caa0000213d0000000f070000290000008006700039000900000006001d0000000000460435000000a004300039000000000441034f000000000404043b000000a006700039000800000006001d0000000000460435000000c004300039000000000441034f000000000404043b000000c006700039000700000006001d0000000000460435000000e004300039000000000441034f000000000404043b000000e006700039000600000006001d00000000004604350000012004300039000000000441034f0000010006300039000000000661034f0000014003300039000000000331034f000000000606043b0000010008700039000500000008001d0000000000680435000000000404043b0000014006700039001500000006001d00000000005604350000012005700039000400000005001d0000000000450435000000000303043b000300000003001d00000016030000290000000003030433000000000403043300001bce0040009c0000010d0000213d00000005034002100000003f0530003900001c0e05500197000000400700043d0000000005570019000000000075004b0000000006000039000000010600403900001bce0050009c0000010d0000213d00000001006001900000010d0000c13d000000400050043f0000000004470436001300000004001d000000000121034f000000000003004b000008020000613d00000013050000290000000002350019000000000401034f000000004604043c0000000005650436000000000025004b000007fe0000c13d0000001f003001900000001502000029000000000302043300001bce0030009c0000010d0000213d00000005023002100000003f0420003900001c0e04400197000000400600043d0000000004460019000000000064004b0000000005000039000000010500403900001bce0040009c0000010d0000213d00000001005001900000010d0000c13d000000400040043f0000000003360436001200000003001d000000000002004b0000081e0000613d00000012040000290000000003240019000000001501043c0000000004540436000000000034004b0000081a0000c13d001900000007001d001400000006001d0000001f0020019000001c100100004100000000001004430000000001000412000000040010044300000060010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f0000000100200190000009e00000613d000000000101043b001100000001001d000000160100002900000000010104330000000002010433000000000002004b0000087e0000613d000000000400001900000005054002100000000001510019000000200110003900000000010104330000000032010434000000050020008c00000caa0000213d001700000005001d001800000004001d0000000003030433000000400410003900000000040404330000006005100039000000000505043300000080011000390000000006010433000000400100043d000000c0071000390000000000670435000000a0061000390000000000560435000000800510003900000000004504350000004004100039000000000024043500001ba70230019700000060031000390000000000230435000000200210003900000011030000290000000000320435000000c003000039000000000031043500001c120010009c0000010d0000213d000000e003100039000000400030043f00001ba40020009c00001ba4020080410000004002200210000000000101043300001ba40010009c00001ba4010080410000006001100210000000000121019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f000000010020019000000ca20000613d000000190200002900000000020204330000001804000029000000000042004b00000ca40000a13d00000017030000290000001302300029000000000101043b00000000001204350000000104400039000000160100002900000000010104330000000002010433000000000024004b000008380000413d00001c100100004100000000001004430000000001000412000000040010044300000080010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f0000000100200190000009e00000613d000000000101043b001600000001001d00000015010000290000000001010433000000000001004b0000001907000029000008e50000613d0000000004000019000000100100002900000000010104330000000002010433000000000042004b00000ca40000a13d00000005054002100000000001150019000000200110003900000000010104330000000032010434000000050020008c00000caa0000213d001700000005001d001800000004001d0000000003030433000000a0041000390000000004040433000000400510003900000000050504330000006006100039000000000606043300000080011000390000000007010433000000400100043d000000c0081000390000000000780435000000a0071000390000000000670435000000800610003900000000005604350000004005100039000000000025043500001ba702400197000000e004100039000000000024043500001ba70230019700000060031000390000000000230435000000200210003900000016030000290000000000320435000000e003000039000000000031043500001c130010009c0000010d0000213d0000010003100039000000400030043f00001ba40020009c00001ba4020080410000004002200210000000000101043300001ba40010009c00001ba4010080410000006001100210000000000121019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f000000010020019000000ca20000613d000000140200002900000000020204330000001804000029000000000042004b000000190700002900000ca40000a13d00000017030000290000001202300029000000000101043b0000000000120435000000010440003900000015010000290000000001010433000000000014004b000008950000413d000000400100043d00000020021000390000000a030000290000000003030433001900000003001d0000000f030000290000000003030433001800000003001d0000000003070433000000000003004b0000000004020019000008f90000613d000000000500001900000000040200190000002007700039000000000607043300000000046404360000000105500039000000000035004b000008f30000413d0000000003140049000000200430008a00000000004104350000001f0330003900001c2b043001970000000003140019000000000043004b0000000004000039000000010400403900001bce0030009c0000010d0000213d00000001004001900000010d0000c13d000000400030043f00001ba40020009c00001ba4020080410000004002200210000000000101043300001ba40010009c00001ba4010080410000006001100210000000000121019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f000000010020019000000ca20000613d000000400200043d0000002003200039000000000101043b001700000001001d00000014070000290000000001070433000000000001004b00000000040300190000092a0000613d000000000500001900000000040300190000002007700039000000000607043300000000046404360000000105500039000000000015004b000009240000413d0000000001240049000000200410008a00000000004204350000001f0110003900001c2b041001970000000001240019000000000041004b0000000004000039000000010400403900001bce0010009c0000010d0000213d00000001004001900000010d0000c13d000000400010043f00001ba40030009c00001ba4030080410000004001300210000000000202043300001ba40020009c00001ba4020080410000006002200210000000000112019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f000000010020019000000ca20000613d000000000101043b001600000001001d00000009010000290000000001010433001500000001001d000000040010008c00000caa0000213d00000004010000290000000001010433000f00000001001d00000005010000290000000001010433001000000001001d00000006010000290000000001010433001100000001001d00000007010000290000000001010433001200000001001d00000008010000290000000001010433001300000001001d000000400100043d001400000001001d00001c1001000041000000000010044300000000010004120000000400100443000000a0010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f0000000100200190000009e00000613d000000190200002900001ba702200197000000180300002900001ba703300197000000000401043b000000140600002900000180016000390000000305000029000000000051043500000160016000390000000f050000290000000000510435000001400160003900000010050000290000000000510435000001200160003900000011050000290000000000510435000001000160003900000012050000290000000000510435000000e00160003900000013050000290000000000510435000000c00160003900000015050000290000000000510435000000a001600039000000160500002900000000005104350000008001600039000000170500002900000000005104350000006001600039000000000021043500000040016000390000000000310435000000200160003900000000004104350000018002000039000000000026043500001c160060009c0000010d0000213d000001a002600039000000400020043f00001ba40010009c00001ba4010080410000004001100210000000000206043300001ba40020009c00001ba4020080410000006002200210000000000112019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f000000010020019000000ca20000613d000000000101043b001900000001001d000000000010043f0000000301000039000000200010043f000000000100041400001ba40010009c00001ba401008041000000c00110021000001c17011001c700008010020000396e8b6e860000040f000000010020019000000ca20000613d000000000101043b000000000201041a00001c180220019700000100022001bf000000000021041b000000400100043d0000001902000029000000000021043500001ba40010009c00001ba4010080410000004001100210000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f0000000e0200002900001ba7052001970000000d0200002900001ba70620019700001c19011001c70000800d02000039000000030300003900001c1a040000416e8b6e810000040f000000010020019000000ca20000613d0000000b020000290000000102200039000000010020006c000006a90000413d000000400200043d00000001030000390000003e0000013d000000000001042f000000000f000019000f0000000e001d000009e90000013d000000ff00a0019000000b280000613d000000010ff000390000001300f0006c00000cb80000813d0000000501f002100000000001e100190000000202000367000000000112034f000000000101043b0000000003000031000000140430006a000000630440008a00001c0d0540019700001c0d06100197000000000756013f000000000056004b000000000500001900001c0d05004041000000000041004b000000000400001900001c0d0400804100001c0d0070009c000000000504c019000000000005004b00000ca20000c13d0018000000e1001d0000001801200360000000000101043b000000180430006a0000015f0440008a00001c0d0540019700001c0d06100197000000000756013f000000000056004b000000000500001900001c0d05004041000000000041004b000000000400001900001c0d0400804100001c0d0070009c000000000504c019000000000005004b00000ca20000c13d0000001801100029001900000001001d0000008001100039000000000112034f000000000401043b000000040040008c00000ca20000213d000009e60000613d000000190130006a0000001905200360000000000505043b001700000005001d00001c0f0010009c00000ca20000213d000001600010008c00000ca20000413d000000170100002900001ba70010009c00000ca20000213d000000400100043d00001bb80010009c0000010d0000213d0000016005100039000000400050043f000000170500002900000000055104360000001906000029001600200060003d0000001606200360000000000606043b00001ba70060009c00000ca20000213d00000000006504350000001605000029001200200050003d0000001205200360000000000505043b00001bce0050009c00000ca20000213d00000019075000290000001f05700039000000000035004b000000000600001900001c0d0600804100001c0d0850019700001c0d05300197000000000958013f000000000058004b000000000800001900001c0d0800404100001c0d0090009c000000000806c019000000000008004b00000ca20000c13d000000000672034f000000000806043b00001bce0080009c0000010d0000213d00000005068002100000003f0660003900001c0e09600197000000400600043d0000000009960019000000000069004b000000000a000039000000010a00403900001bce0090009c0000010d0000213d0000000100a001900000010d0000c13d0000002007700039000000400090043f0000000000860435000000a0088000c90000000008780019000000000038004b00000ca20000213d000000000078004b00000a890000a13d0000000009060019000000000a73004900001c0f00a0009c00000ca20000213d000000a000a0008c00000ca20000413d000000400a00043d00001bb400a0009c0000010d0000213d000000a00ba000390000004000b0043f000000000b72034f000000000b0b043b0000000500b0008c00000ca20000213d000000000cba0436000000200b700039000000000db2034f000000000d0d043b00001ba700d0009c00000ca20000213d00000020099000390000000000dc0435000000200cb00039000000000cc2034f000000000c0c043b000000400da000390000000000cd0435000000400cb00039000000000cc2034f000000000c0c043b000000600da000390000000000cd0435000000600bb00039000000000bb2034f000000000b0b043b000000800ca000390000000000bc04350000000000a90435000000a007700039000000000087004b00000a600000413d0000004007100039000000000067043500000019060000290000006006600039000000000662034f000000000606043b00001bce0060009c00000ca20000213d00000019066000290000001f07600039000000000037004b000000000800001900001c0d0800804100001c0d07700197000000000957013f000000000057004b000000000500001900001c0d0500404100001c0d0090009c000000000508c019000000000005004b00000ca20000c13d000000000562034f000000000705043b00001bce0070009c0000010d0000213d00000005057002100000003f0550003900001c0e08500197000000400500043d0000000008850019000000000058004b0000000009000039000000010900403900001bce0080009c0000010d0000213d00000001009001900000010d0000c13d0000002006600039000000400080043f0000000000750435000000c0077000c90000000007670019000000000037004b00000ca20000213d000000000067004b00000ae90000a13d0000000008050019000000000963004900001c0f0090009c00000ca20000213d000000c00090008c00000ca20000413d000000400900043d00001bd40090009c0000010d0000213d000000c00a9000390000004000a0043f000000000a62034f000000000a0a043b0000000500a0008c00000ca20000213d000000000ba90436000000200a600039000000000ca2034f000000000c0c043b00001ba700c0009c00000ca20000213d0000000000cb0435000000200ba00039000000000bb2034f000000000b0b043b000000400c9000390000000000bc0435000000400ba00039000000000bb2034f000000000b0b043b000000600c9000390000000000bc0435000000600ba00039000000000bb2034f000000000b0b043b000000800c9000390000000000bc0435000000800aa00039000000000aa2034f000000000a0a043b00001ba700a0009c00000ca20000213d0000002008800039000000a00b9000390000000000ab04350000000000980435000000c006600039000000000076004b00000ab90000413d00000080031000390000000000430435000000600310003900000000005304350000001905000029000000a003500039000000000332034f000000000303043b000000a0041000390000000000340435000000c003500039000000000332034f000000000303043b000000c0041000390000000000340435000000e003500039000000000332034f000000000303043b000000e00410003900000000003404350000010003500039000000000332034f000000000303043b000001000410003900000000003404350000012003500039000000000332034f000000000303043b00000120041000390000000000340435001101400050003d0000001102200360000000000202043b0000014003100039000000000023043500150000000f001d6e8b5a830000040f001000000001001d000000000010043f0000000301000039000000200010043f000000000100041400001ba40010009c00001ba401008041000000c00110021000001c17011001c700008010020000396e8b6e860000040f000000150f0000290000000f0e000029000000010020019000000ca20000613d000000000901043b000000000a09041a0000ff0000a0019000000cbe0000c13d0000001001a0027000001c1f01100198000009e40000613d0000008802a00270000000000021004b000009e40000413d00000cc10000013d0000001101000029000000e00210008a0000000201000367000000000221034f000000000302043b0000000002000031000000190420006a0000001f0440008a00001c0d0540019700001c0d06300197000000000756013f000000000056004b000000000500001900001c0d05004041000000000043004b000000000400001900001c0d0400804100001c0d0070009c000000000504c019000000000005004b00000ca20000c13d0000001904300029000000000341034f000000000303043b00001bce0030009c00000ca20000213d00001c2d053000d100000000052500190000002004400039000000000054004b000000000600001900001c0d0600204100001c0d0550019700001c0d04400197000000000754013f000000000054004b000000000400001900001c0d0400404100001c0d0070009c000000000406c019000000000004004b00000ca20000c13d0000001104100360000000000404043b000000000043004b00000ccc0000c13d000000180300002900000000043200490000002003300039000000000331034f000000000303043b0000001f0440008a00001c0d0540019700001c0d06300197000000000756013f000000000056004b000000000500001900001c0d05004041000000000043004b000000000400001900001c0d0400804100001c0d0070009c000000000504c019000000000005004b00000ca20000c13d0000001803300029000000000431034f000000000404043b00001bce0040009c00000ca20000213d0000000005420049000000200630003900001c0d0350019700001c0d07600197000000000837013f000000000037004b000000000300001900001c0d03004041000000000056004b000000000500001900001c0d0500204100001c0d0080009c000000000305c019000000000003004b00000ca20000c13d0000001f0340003900001c2b033001970000003f0330003900001c2b05300197000000400300043d0000000005530019000000000035004b0000000007000039000000010700403900001bce0050009c0000010d0000213d00000001007001900000010d0000c13d000000400050043f00000000054304360000000007640019000000000027004b00000ca20000213d001800000009001d000000000261034f00001c2b06400198000000000165001900000b9a0000613d000000000702034f0000000008050019000000007907043c0000000008980436000000000018004b00000b960000c13d00110000000a001d0000001f0740019000000ba80000613d000000000262034f0000000306700210000000000701043300000000076701cf000000000767022f000000000202043b0000010006600089000000000262022f00000000026201cf000000000272019f000000000021043500000000014500190000000000010435000000170100002900000010020000296e8b5c900000040f000001000100008a000000110110017f00000001011001bf0000001802000029000000000012041b000000400100043d0000002002100039000000400300003900000000003204350000001002000029000000000021043500000002020003670000001903200360000000000303043b00001ba70030009c00000ca20000213d000000400410003900000000003404350000001603200360000000000303043b00001ba70030009c00000ca20000213d0000006004100039000000000034043500000012042003600000000003000031000000190530006a0000001f0550008a000000000404043b00001c0d0740019700001c0d06500197000000000867013f000000000067004b000000000700001900001c0d07004041000000000054004b000000000900001900001c0d0900804100001c0d0080009c000000000709c019000000000007004b00000ca20000c13d0000001907400029000000000472034f000000000404043b00001bce0040009c00000ca20000213d00001c2c084000d10000000009380019000000200870003900001c0d0790019700001c0d0a800197000000000b7a013f00000000007a004b000000000700001900001c0d07004041000000000098004b000000000900001900001c0d0900204100001c0d00b0009c000000000709c019000000000007004b00000ca20000c13d000000800710003900000160090000390000000000970435000001a0071000390000000000470435000001c007100039000000000004004b00000c140000613d0000000009000019000000000a82034f000000000a0a043b0000000500a0008c00000ca20000213d000000000ba70436000000200a800039000000000ca2034f000000000c0c043b00001ba700c0009c00000ca20000213d0000000000cb0435000000200ba00039000000000bb2034f000000000b0b043b000000400c7000390000000000bc0435000000400ba00039000000000bb2034f000000000b0b043b000000600c7000390000000000bc0435000000600aa00039000000000aa2034f000000000a0a043b000000800b7000390000000000ab0435000000a008800039000000a0077000390000000109900039000000000049004b00000bf50000413d00000012040000290000002004400039000000000842034f000000000808043b00001c0d09800197000000000a69013f000000000069004b000000000600001900001c0d06002041000000000058004b000000000500001900001c0d0500404100001c0d00a0009c000000000605c019000000000006004b00000ca20000613d0000001906800029000000000562034f000000000505043b00001bce0050009c00000ca20000213d000000200660003900001c2d085000d10000000003380019000000000036004b000000000800001900001c0d0800204100001c0d0330019700001c0d09600197000000000a39013f000000000039004b000000000300001900001c0d0300404100001c0d00a0009c000000000308c019000000000003004b00000ca20000c13d0000000003170049000000400330008a000000a00810003900000000003804350000000003570436000000000005004b00000c670000613d0000000007000019000000000862034f000000000808043b000000050080008c00000ca20000213d00000000098304360000002008600039000000000a82034f000000000a0a043b00001ba700a0009c00000ca20000213d0000000000a904350000002009800039000000000992034f000000000909043b000000400a30003900000000009a04350000004009800039000000000992034f000000000909043b000000600a30003900000000009a04350000006009800039000000000992034f000000000909043b000000800a30003900000000009a04350000008008800039000000000882034f000000000808043b00001ba70080009c00000ca20000213d000000a0093000390000000000890435000000c006600039000000c0033000390000000107700039000000000057004b00000c410000413d0000002004400039000000000542034f000000000505043b000000050050008c00000caa0000813d000000c00610003900000000005604350000002005400039000000000552034f000000000505043b000000e00610003900000000005604350000004005400039000000000552034f000000000505043b000001000610003900000000005604350000006005400039000000000552034f000000000505043b000001200610003900000000005604350000008005400039000000000552034f000000000505043b00000140061000390000000000560435000000a005400039000000000552034f000000000505043b00000160061000390000000000560435000000c004400039000000000242034f000000000202043b00000180041000390000000000240435000000000213004900001ba40020009c00001ba402008041000000600220021000001ba40010009c00001ba4010080410000004001100210000000000112019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c70000800d02000039000000010300003900001c22040000416e8b6e810000040f00000001002001900000000f0e000029000000150f000029000009e60000c13d000000000100001900006e8d0001043000001c1401000041000000000010043f0000003201000039000000040010043f00001c150100004100006e8d0001043000001c1401000041000000000010043f0000002101000039000000040010043f00001c150100004100006e8d00010430000000400100043d00001c2302000041000000000021043500001ba40010009c00001ba401008041000000400110021000001bd6011001c700006e8d00010430000000400100043d00000001020000390000053e0000013d000000400100043d00001c1b0200004100000cb20000013d000000400100043d00001c1e0200004100000cc30000013d000000400100043d00001c2002000041000000000021043500000004021000390000001003000029000000000032043500001ba40010009c00001ba401008041000000400110021000001c15011001c700006e8d00010430000000400100043d00001c210200004100000cb20000013d000000190300002900001ba40030009c00001ba403008041000000400330021000001ba40010009c00001ba401008041000000c001100210000000000131019f00001bd6011001c76e8b6e860000040f0000000003010019000000600330027000001ba403300197000000400030008c000000400400003900000000040340190000001f0640018f0000006007400190000000190570002900000ce90000613d000000000801034f0000001909000029000000008a08043c0000000009a90436000000000059004b00000ce50000c13d000000000006004b00000cf60000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f0000000000650435000100000003001f0003000000010355000000010020019000000f900000613d0000001f01400039000000e00210018f0000001901200029000000000021004b0000000002000039000000010200403900001bce0010009c0000010d0000213d00000001002001900000010d0000c13d000000400010043f000000400030008c00000ca20000413d0000001901000029000000000101043300000018020000290000000002020433002001e00000003d000001e00020043f001f01c00000003d000001c00010043f001e00010000003d000000200000043f00001bd70100004100001bd802000041000000000012041b001d00020000003d00001bd90100004100001bda02000041000000000012041b00001bdb0100004100001bdc02000041000000000012041b0000000401000039000000000010043f000000400200003900000000010000196e8b6e4e0000040f00001bdd02000041000000000021041b001c00050000003d0000000501000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f00001bde02000041000000000021041b0000000601000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f00001bdf02000041000000000021041b0000000701000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f00001be002000041000000000021041b0000000801000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f00001be102000041000000000021041b0000000901000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f00001be202000041000000000021041b0000000a01000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f00001be302000041000000000021041b0000000b01000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f00001be402000041000000000021041b0000000c01000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f00001be502000041000000000021041b0000000d01000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f00001be602000041000000000021041b0000000e01000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f00001be702000041000000000021041b0000000f01000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f00001be802000041000000000021041b0000001001000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f00001be902000041000000000021041b0000001101000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f00001bea02000041000000000021041b0000001201000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f00001beb02000041000000000021041b0000001301000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f00001bec02000041000000000021041b0000001401000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f00001bed02000041000000000021041b0000001501000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f00001bee02000041000000000021041b0000001601000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f00001bef02000041000000000021041b0000001701000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f00001bf002000041000000000021041b0000001801000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f00001bf102000041000000000021041b0000000101000039000000000011041b000000000000043f0000000501000039000000200010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e02200197000000000021041b0000000101000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e02200197000000000021041b0000000201000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e02200197000000000021041b0000000301000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e02200197000000000021041b0000000401000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000001022001bf000000000021041b0000000501000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000001022001bf000000000021041b0000000601000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000001022001bf000000000021041b0000000701000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000001022001bf000000000021041b0000000801000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000002022001bf000000000021041b0000000901000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000002022001bf000000000021041b0000000a01000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000002022001bf000000000021041b0000000b01000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000002022001bf000000000021041b0000000c01000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000003022001bf000000000021041b0000000d01000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000003022001bf000000000021041b0000000e01000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000003022001bf000000000021041b0000000f01000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000003022001bf000000000021041b0000001001000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000004022001bf000000000021041b0000001101000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000004022001bf000000000021041b0000001201000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000004022001bf000000000021041b0000001301000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000004022001bf000000000021041b0000001401000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000005022001bf000000000021041b0000001501000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000005022001bf000000000021041b0000001601000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000005022001bf000000000021041b0000001701000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000005022001bf000000000021041b0000000601000039000000200010043f00001bf201000041000000000201041a00001c2e02200197000000000021041b0000000401000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e02200197000000000021041b0000000801000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e02200197000000000021041b0000000c01000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e02200197000000000021041b0000001001000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e02200197000000000021041b0000001401000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e02200197000000000021041b0000001e01000029001900000001001d000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000019022001af000000000021041b0000001c01000029000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000019022001af000000000021041b0000000901000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000019022001af000000000021041b0000000d01000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000019022001af000000000021041b0000001101000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000019022001af000000000021041b0000001501000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000019022001af000000000021041b0000001d01000029001900000001001d000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000019022001af000000000021041b0000000601000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000019022001af000000000021041b0000000a01000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000019022001af000000000021041b0000000e01000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000019022001af000000000021041b0000001201000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000019022001af000000000021041b0000001601000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000019022001af000000000021041b0000000301000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000003022001bf000000000021041b0000000701000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000003022001bf000000000021041b0000000b01000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000003022001bf000000000021041b0000000f01000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000003022001bf000000000021041b0000001301000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000003022001bf000000000021041b0000001701000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000003022001bf000000000021041b000000800100043d000001400000044300000160001004430000002001000039000000a00200043d0000018000100443000001a000200443000000c00200043d0000004003000039000001c000300443000001e0002004430000006002000039000000e00300043d000002000020044300000220003004430000008002000039000001000300043d00000240002004430000026000300443000001200200043d000000a0030000390000028000300443000002a00020044300000022020000290000000002020433000000c003000039000002c000300443000002e00020044300000021020000290000000002020433000000e003000039000003000030044300000320002004430000010002000039000001800300043d000003400020044300000360003004430000012002000039000001a00300043d0000038000200443000003a0003004430000001f0200002900000000020204330000014003000039000003c000300443000003e0002004430000002002000029000000000202043300000160030000390000040000300443000004200020044300000100001004430000000c01000039000001200010044300001bf30100004100006e8c0001042e0000001f0530018f00001ba606300198000000400200043d000000000462001900000f9b0000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b00000f970000c13d000000000005004b00000fa80000613d000000000161034f0000000305500210000000000604043300000000065601cf000000000656022f000000000101043b0000010005500089000000000151022f00000000015101cf000000000161019f0000000000140435000000600130021000001ba40020009c00001ba4020080410000004002200210000000000112019f00006e8d0001043000001c0f0010009c00000fbe0000213d000000230010008c00000fbe0000a13d00000004020000390000000202200367000000000202043b00001bce0020009c00000fbe0000213d000000000121004900001c0f0010009c00000fbe0000213d000002440010008c00000fbe0000413d0000000401200039000000000001042d000000000100001900006e8d0001043000000000430104340000000001320436000000000003004b00000fcc0000613d000000000200001900000000052100190000000006240019000000000606043300000000006504350000002002200039000000000032004b00000fc50000413d000000000231001900000000000204350000001f0230003900001c2b022001970000000001210019000000000001042d00001c2f0010009c00000fd70000813d0000016001100039000000400010043f000000000001042d00001c1401000041000000000010043f0000004101000039000000040010043f00001c150100004100006e8d0001043000001c300010009c00000fe20000813d0000002001100039000000400010043f000000000001042d00001c1401000041000000000010043f0000004101000039000000040010043f00001c150100004100006e8d0001043000001c310020009c0000102d0000813d00000005042002100000003f0440003900001c0e05400197000000400400043d0000000005540019000000000045004b0000000006000039000000010600403900001bce0050009c0000102d0000213d00000001006001900000102d0000c13d000000400050043f0000000000240435000000a0022000c90000000002120019000000000032004b0000102b0000213d000000000012004b000010290000a13d00000002050003670000000006040019000000000713004900001c0f0070009c0000102b0000213d000000a00070008c0000102b0000413d000000400700043d00001bb40070009c0000102d0000213d000000a008700039000000400080043f000000000815034f000000000808043b000000050080008c0000102b0000213d00000000098704360000002008100039000000000a85034f000000000a0a043b00001ba700a0009c0000102b0000213d00000020066000390000000000a904350000002009800039000000000995034f000000000909043b000000400a70003900000000009a04350000004009800039000000000995034f000000000909043b000000600a70003900000000009a04350000006008800039000000000885034f000000000808043b000000800970003900000000008904350000000000760435000000a001100039000000000021004b000010000000413d0000000001040019000000000001042d000000000100001900006e8d0001043000001c1401000041000000000010043f0000004101000039000000040010043f00001c150100004100006e8d0001043000001c310020009c0000107f0000813d00000005042002100000003f0440003900001c0e05400197000000400400043d0000000005540019000000000045004b0000000006000039000000010600403900001bce0050009c0000107f0000213d00000001006001900000107f0000c13d000000400050043f0000000000240435000000c0022000c90000000002120019000000000032004b0000107d0000213d000000000012004b0000107b0000a13d00000002050003670000000006040019000000000713004900001c0f0070009c0000107d0000213d000000c00070008c0000107d0000413d000000400700043d00001bd40070009c0000107f0000213d000000c008700039000000400080043f000000000815034f000000000808043b000000050080008c0000107d0000213d00000000098704360000002008100039000000000a85034f000000000a0a043b00001ba700a0009c0000107d0000213d0000000000a904350000002009800039000000000995034f000000000909043b000000400a70003900000000009a04350000004009800039000000000995034f000000000909043b000000600a70003900000000009a04350000006009800039000000000995034f000000000909043b000000800a70003900000000009a04350000008008800039000000000885034f000000000808043b00001ba70080009c0000107d0000213d0000002006600039000000a00970003900000000008904350000000000760435000000c001100039000000000021004b0000104b0000413d0000000001040019000000000001042d000000000100001900006e8d0001043000001c1401000041000000000010043f0000004101000039000000040010043f00001c150100004100006e8d000104300001000000000002000000000f0100190000000001f2004900001c0f0010009c000012280000213d0000009f0010008c000012280000a13d000000400100043d00001c320010009c0000122a0000813d000000a006100039000000400060043f00000002040003670000000003f4034f000000000303043b00001bce0030009c000012280000213d0000000007f30019000000000372004900001c0f0030009c000012280000213d000001600030008c000012280000413d00001c330010009c0000122a0000213d0000020003100039000000400030043f000000000374034f000000000303043b00001ba70030009c000012280000213d00000000003604350000002003700039000000000534034f000000000505043b00001ba70050009c000012280000213d000000c00810003900000000005804350000002003300039000000000334034f000000000303043b00001bce0030009c000012280000213d00000000097300190000001f03900039000000000023004b000000000800001900001c0d0800804100001c0d0330019700001c0d05200197000000000a53013f000000000053004b000000000300001900001c0d0300404100001c0d00a0009c000000000308c019000000000003004b000012280000c13d000000000394034f000000000a03043b00001bce00a0009c0000122a0000213d0000000503a002100000003f0330003900001c0e03300197000000400800043d000000000b38001900000000008b004b0000000003000039000000010300403900001bce00b0009c0000122a0000213d00000001003001900000122a0000c13d00000020099000390000004000b0043f0000000000a80435000000a003a000c9000000000a93001900000000002a004b000012280000213d00000000009a004b000011030000a13d000000000b080019000000000392004900001c0f0030009c000012280000213d000000a00030008c000012280000413d000000400c00043d00001bb400c0009c0000122a0000213d000000a003c00039000000400030043f000000000394034f000000000303043b000000050030008c000012280000213d00000000033c0436000000200d900039000000000ed4034f000000000e0e043b00001ba700e0009c000012280000213d000000200bb000390000000000e304350000002003d00039000000000334034f000000000303043b000000400ec0003900000000003e04350000004003d00039000000000334034f000000000303043b000000600ec0003900000000003e04350000006003d00039000000000334034f000000000303043b000000800dc0003900000000003d04350000000000cb0435000000a0099000390000000000a9004b000010da0000413d000000e00310003900000000008304350000006003700039000000000334034f000000000303043b00001bce0030009c000012280000213d00000000097300190000001f03900039000000000023004b000000000800001900001c0d0800804100001c0d03300197000000000a53013f000000000053004b000000000300001900001c0d0300404100001c0d00a0009c000000000308c019000000000003004b000012280000c13d000000000394034f000000000a03043b00001bce00a0009c0000122a0000213d0000000503a002100000003f0330003900001c0e03300197000000400800043d000000000b38001900000000008b004b0000000003000039000000010300403900001bce00b0009c0000122a0000213d00000001003001900000122a0000c13d00000020099000390000004000b0043f0000000000a80435000000c003a000c9000000000a93001900000000002a004b000012280000213d00000000009a004b000011620000a13d000000000b080019000000000392004900001c0f0030009c000012280000213d000000c00030008c000012280000413d000000400c00043d00001bd400c0009c0000122a0000213d000000c003c00039000000400030043f000000000394034f000000000303043b000000050030008c000012280000213d00000000033c0436000000200d900039000000000ed4034f000000000e0e043b00001ba700e0009c000012280000213d0000000000e304350000002003d00039000000000334034f000000000303043b000000400ec0003900000000003e04350000004003d00039000000000334034f000000000303043b000000600ec0003900000000003e04350000006003d00039000000000334034f000000000303043b000000800ec0003900000000003e04350000008003d00039000000000334034f000000000303043b00001ba70030009c000012280000213d000000200bb00039000000a00dc0003900000000003d04350000000000cb0435000000c0099000390000000000a9004b000011320000413d000001000310003900000000008304350000008007700039000000000374034f000000000303043b000000040030008c000012280000213d000001200810003900000000003804350000002003700039000000000334034f000000000303043b000001400810003900000000003804350000004003700039000000000334034f000000000303043b000001600810003900000000003804350000006003700039000000000334034f000000000303043b000001800810003900000000003804350000008003700039000000000334034f000000000303043b000001a0081000390000000000380435000000a003700039000000000334034f000000000303043b000001c0081000390000000000380435000000c003700039000000000334034f000000000703043b0000000003610436000001e00610003900000000007604350000002006f00039000000000764034f000000000707043b00001c1f0070009c000012280000213d00000000007304350000002003600039000000000634034f000000000606043b00001c1f0060009c000012280000213d000000400710003900000000006704350000002007300039000000000374034f000000000303043b00001bce0030009c000012280000213d000000000af300190000001f03a00039000000000023004b000000000600001900001c0d0600804100001c0d03300197000000000853013f000000000053004b000000000300001900001c0d0300404100001c0d0080009c000000000306c019000000000003004b000012280000c13d0000000003a4034f000000000803043b00001bce0080009c0000122a0000213d0000001f0380003900001c2b033001970000003f0330003900001c2b03300197000000400900043d000000000b39001900000000009b004b0000000003000039000000010300403900001bce00b0009c0000122a0000213d00000001003001900000122a0000c13d000000200aa000390000004000b0043f0000000003890436000000000ba8001900000000002b004b000012280000213d000100000005001d00000000060f0019000000000ca4034f00001c2b0d8001980000001f0e80018f000000000bd30019000011ce0000613d000000000f0c034f000000000a03001900000000f50f043c000000000a5a04360000000000ba004b000011ca0000c13d00000000000e004b000011db0000613d0000000005dc034f000000030ae00210000000000c0b0433000000000cac01cf000000000cac022f000000000505043b000001000aa000890000000005a5022f0000000005a501cf0000000005c5019f00000000005b043500000000038300190000000000030435000000600310003900000000009304350000002003700039000000000334034f000000000303043b00001bce0030009c0000000105000029000012280000213d00000000076300190000001f03700039000000000023004b0000000006050019000000000500001900001c0d0500804100001c0d03300197000000000863013f000000000063004b000000000300001900001c0d0300404100001c0d0080009c000000000305c019000000000003004b000012280000c13d000000000374034f000000000303043b00001bce0030009c0000122a0000213d0000001f0530003900001c2b055001970000003f0550003900001c2b08500197000000400500043d0000000008850019000000000058004b0000000009000039000000010900403900001bce0080009c0000122a0000213d00000001009001900000122a0000c13d0000002009700039000000400080043f00000000073504360000000008930019000000000028004b000012280000213d000000000494034f00001c2b063001980000001f0830018f0000000002670019000012160000613d000000000904034f000000000a070019000000009b09043c000000000aba043600000000002a004b000012120000c13d000000000008004b000012230000613d000000000464034f0000000306800210000000000802043300000000086801cf000000000868022f000000000404043b0000010006600089000000000464022f00000000046401cf000000000484019f00000000004204350000000002370019000000000002043500000080021000390000000000520435000000000001042d000000000100001900006e8d0001043000001c1401000041000000000010043f0000004101000039000000040010043f00001c150100004100006e8d000104300006000000000002000300000001001d0000001f01100039000000000021004b000000000300001900001c0d0300404100061c0d0020019b00001c0d01100197000000060410014f000000060010006c000000000100001900001c0d0100204100001c0d0040009c000000000103c019000000000001004b000014080000613d00000002050003670000000301500360000000000101043b00001c310010009c0000140a0000813d00000005031002100000003f0430003900001c0e04400197000000400700043d0000000006470019000100000007001d000000000076004b0000000004000039000000010400403900001bce0060009c0000140a0000213d00000001004001900000140a0000c13d000000400060043f0000000104000029000000000014043500000003010000290000002006100039000200000036001d000000020020006b000014080000213d000000020060006c000014060000813d0000000104000029000012680000013d00000004040000290000002004400039000000000117001900000000000104350000008001a0003900000000003104350000000000a404350000002006600039000000020060006c000014060000813d000400000004001d000000000165034f000000000101043b00001bce0010009c000014080000213d0000000301100029000500000001001d000000200b1000390000000001b2004900001c0f0010009c000014080000213d000000a00010008c000014080000413d000000400a00043d00001bb400a0009c0000140a0000213d0000000001b5034f000000a00da000390000004000d0043f000000000101043b00001bce0010009c000014080000213d000000000eb100190000000001e2004900001c0f0010009c000014080000213d000001600010008c000014080000413d00001c3300a0009c0000140a0000213d0000020001a00039000000400010043f0000000001e5034f000000000101043b00001ba70010009c000014080000213d00000000001d04350000002001e00039000000000315034f000000000303043b00001ba70030009c000014080000213d000000c004a0003900000000003404350000002001100039000000000115034f000000000101043b00001bce0010009c000014080000213d0000000001e100190000001f03100039000000000023004b000000000400001900001c0d0400804100001c0d03300197000000060730014f000000060030006c000000000300001900001c0d0300404100001c0d0070009c000000000304c019000000000003004b000014080000c13d000000000315034f000000000703043b00001bce0070009c0000140a0000213d00000005037002100000003f0330003900001c0e03300197000000400f00043d00000000083f00190000000000f8004b0000000003000039000000010300403900001bce0080009c0000140a0000213d00000001003001900000140a0000c13d0000002003100039000000400080043f00000000007f0435000000a0017000c90000000007310019000000000027004b000014080000213d000000000037004b000012ea0000a13d00000000010f0019000000000432004900001c0f0040009c000014080000213d000000a00040008c000014080000413d000000400800043d00001bb40080009c0000140a0000213d000000a004800039000000400040043f000000000435034f000000000404043b000000050040008c000014080000213d00000000044804360000002009300039000000000c95034f000000000c0c043b00001ba700c0009c000014080000213d00000020011000390000000000c404350000002004900039000000000445034f000000000404043b000000400c80003900000000004c04350000004004900039000000000445034f000000000404043b000000600c80003900000000004c04350000006004900039000000000445034f000000000404043b000000800980003900000000004904350000000000810435000000a003300039000000000073004b000012c10000413d000000e001a000390000000000f104350000006001e00039000000000115034f000000000101043b00001bce0010009c000014080000213d0000000003e100190000001f01300039000000000021004b000000000400001900001c0d0400804100001c0d01100197000000060710014f000000060010006c000000000100001900001c0d0100404100001c0d0070009c000000000104c019000000000001004b000014080000c13d000000000135034f000000000701043b00001bce0070009c0000140a0000213d00000005017002100000003f0110003900001c0e04100197000000400100043d0000000008410019000000000018004b0000000004000039000000010400403900001bce0080009c0000140a0000213d00000001004001900000140a0000c13d0000002003300039000000400080043f0000000000710435000000c0047000c90000000007340019000000000027004b000014080000213d000000000037004b000013490000a13d000000000f010019000000000432004900001c0f0040009c000014080000213d000000c00040008c000014080000413d000000400800043d00001bd40080009c0000140a0000213d000000c004800039000000400040043f000000000435034f000000000404043b000000050040008c000014080000213d00000000044804360000002009300039000000000c95034f000000000c0c043b00001ba700c0009c000014080000213d0000000000c404350000002004900039000000000445034f000000000404043b000000400c80003900000000004c04350000004004900039000000000445034f000000000404043b000000600c80003900000000004c04350000006004900039000000000445034f000000000404043b000000800c80003900000000004c04350000008004900039000000000445034f000000000404043b00001ba70040009c000014080000213d000000200ff00039000000a009800039000000000049043500000000008f0435000000c003300039000000000073004b000013190000413d0000010003a0003900000000001304350000008001e00039000000000315034f000000000303043b000000040030008c000014080000213d0000012004a0003900000000003404350000002003100039000000000335034f000000000303043b0000014004a0003900000000003404350000004003100039000000000335034f000000000303043b0000016004a0003900000000003404350000006003100039000000000335034f000000000303043b0000018004a0003900000000003404350000008003100039000000000335034f000000000303043b000001a004a000390000000000340435000000a003100039000000000335034f000000000303043b000001c004a000390000000000340435000000c001100039000000000115034f000000000301043b0000000001da0436000001e004a00039000000000034043500000005030000290000004003300039000000000435034f000000000404043b00001c1f0040009c000014080000213d00000000004104350000002001300039000000000315034f000000000303043b00001c1f0030009c000014080000213d0000004004a000390000000000340435000000200c1000390000000001c5034f000000000101043b00001bce0010009c000014080000213d0000000007b100190000001f01700039000000000021004b000000000300001900001c0d0300804100001c0d01100197000000060410014f000000060010006c000000000100001900001c0d0100404100001c0d0040009c000000000103c019000000000001004b000014080000c13d000000000175034f000000000101043b00001bce0010009c0000140a0000213d0000001f0310003900001c2b033001970000003f0330003900001c2b04300197000000400300043d0000000008430019000000000038004b0000000004000039000000010400403900001bce0080009c0000140a0000213d00000001004001900000140a0000c13d0000002004700039000000400080043f00000000071304360000000008410019000000000028004b000014080000213d000000000d45034f00001c2b091001980000000008970019000013b30000613d000000000e0d034f000000000f07001900000000e40e043c000000000f4f043600000000008f004b000013af0000c13d0000001f04100190000013c00000613d00000000099d034f0000000304400210000000000d080433000000000d4d01cf000000000d4d022f000000000909043b0000010004400089000000000949022f00000000044901cf0000000004d4019f0000000000480435000000000117001900000000000104350000006001a0003900000000003104350000002001c00039000000000115034f000000000101043b00001bce0010009c000014080000213d0000000007b100190000001f01700039000000000021004b000000000300001900001c0d0300804100001c0d01100197000000060410014f000000060010006c000000000100001900001c0d0100404100001c0d0040009c000000000103c019000000000001004b000014080000c13d000000000175034f000000000101043b00001bce0010009c0000140a0000213d0000001f0310003900001c2b033001970000003f0330003900001c2b04300197000000400300043d0000000008430019000000000038004b0000000004000039000000010400403900001bce0080009c0000140a0000213d00000001004001900000140a0000c13d0000002004700039000000400080043f00000000071304360000000008410019000000000028004b000014080000213d000000000b45034f00001c2b091001980000000008970019000013f80000613d000000000c0b034f000000000d07001900000000c40c043c000000000d4d043600000000008d004b000013f40000c13d0000001f041001900000125e0000613d00000000099b034f0000000304400210000000000b080433000000000b4b01cf000000000b4b022f000000000909043b0000010004400089000000000949022f00000000044901cf0000000004b4019f00000000004804350000125e0000013d0000000101000029000000000001042d000000000100001900006e8d0001043000001c1401000041000000000010043f0000004101000039000000040010043f00001c150100004100006e8d00010430000000000301001900000000040304330000000001420436000000000004004b000014390000613d00000000020000190000002003300039000000000503043300000000670504340000000089070434000000060090008c0000143a0000813d0000000009910436000000000808043300001ba7088001970000000000890435000000400870003900000000080804330000004009100039000000000089043500000060087000390000000008080433000000600910003900000000008904350000008007700039000000000707043300001ba70770019700000080081000390000000000780435000000000606043300001ba706600197000000a007100039000000000067043500000040055000390000000005050433000000c0061000390000000000560435000000e0011000390000000102200039000000000042004b000014160000413d000000000001042d00001c1401000041000000000010043f0000002101000039000000040010043f00001c150100004100006e8d00010430000000400400003900000000044104360000000006020433000000400510003900000000006504350000006005100039000000000006004b000014520000613d000000000700001900000020022000390000000008020433000000000008004b0000000008000039000000010800c03900000000058504360000000107700039000000000067004b000014490000413d0000000001150049000000000014043500000000020304330000000001250436000000000002004b0000147c0000613d00000000040000190000002003300039000000000503043300000000670504340000000089070434000000060090008c0000147d0000813d0000000009910436000000000808043300001ba7088001970000000000890435000000400870003900000000080804330000004009100039000000000089043500000060087000390000000008080433000000600910003900000000008904350000008007700039000000000707043300001ba70770019700000080081000390000000000780435000000000606043300001ba706600197000000a007100039000000000067043500000040055000390000000005050433000000c0061000390000000000560435000000e0011000390000000104400039000000000024004b000014590000413d000000000001042d00001c1401000041000000000010043f0000002101000039000000040010043f00001c150100004100006e8d00010430003200000000000200000000030100190000000102000039000000000102041a000000010010008c000023ea0000c13d0000000201000039001a00000002001d000e00000001001d000000000012041b0000010001300039001c00000001001d0000000201100367000000000101043b000000180010008c00001d0f0000813d000000000010043f0000000501000039000000200010043f000000000100041400001ba40010009c00001ba401008041000000c00110021000001c17011001c70000801002000039001e00000003001d6e8b6e860000040f000000010020019000001d0f0000613d000000000101043b000000000101041a001b00000001001d003200ff001001930000000601000039000000200010043f000000000100041400001ba40010009c00001ba401008041000000c00110021000001c17011001c700008010020000396e8b6e860000040f0000001b050000290000001e04000029000000010020019000001d0f0000613d000000ff0250018f000000000101043b000000000101041a000a00000001001d003100ff00100193000000060020008c000024820000813d000000000002004b002f00000000003d002f00010000c03d003000000000003d003000010000603d000000010020008c000000000300003900000001030020390000000001000416001d00000001001d000000000001004b000014cc0000613d000000020020008c000014ce0000413d000000400100043d00001bf402000041000000000021043500000004021000390000000003000416000024030000013d000000010020008c0000242b0000a13d001800000003001d000000040020008c002d00000000003d002d00010000c03d002e00000000003d002e00010000603d0000000201000367000000fe0350018f000000040030008c000014da0000c13d0000001c04000029000000600440008a000000000141034f000000000101043b001600000001001d00001ba70010009c00001d0f0000213d000000020020008c0000000001000019000014fd0000413d000000020030008c000014f00000c13d00000000030004150000002a0330008a0000000503300210002c00010000003d000000040020008c0000000101000039000e00010000003d000014f60000613d000000050020008c000015030000c13d000e00000001001d000014f60000013d000000040020008c000014fc0000c13d0000000003000415000000290330008a0000000503300210002c00020000003d000100000003001d0000000501300270000000010100003f000200010000003d000b00010000003d000015120000013d0000000301000039002c00000001001d00000000030004150000002b0330008a0000000503300210000000050020008c000014ee0000613d00000002025001bf000000ff0220018f000000020020008c000100000003001d00000005023002700000150c0000c13d000000020200003f00000002020000390000150e0000013d000000030200003f0000000302000039000b00000002001d001a00000001001d000e00000001001d000200000000001d00001c34010000410000000000100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001bd3011001c70000800b020000396e8b6e860000040f0000000100200190000023e00000613d0000001c0400002900000020034000390000000202000367000000000332034f0000004004400039000000000542034f000000000505043b000000000303043b000000000101043b000000000013004b000023ed0000213d000000000015004b000023ed0000a13d0000000003000031000000240030008c0000001e0900002900001d0f0000413d0000000401200370000000000101043b000000200010008c000023e70000c13d000002440030008c00001d0f0000413d0000022401200370000000000101043b000002400010008c000023e70000c13d000002840030008c00001d0f0000413d0000026401200370000000000101043b00001c370010009c000023e10000813d000000060110021000000260011000390000024405200370000000000505043b000000000015004b000023e70000c13d0000012401200370000000000101043b000000180010008c000023e70000813d000000c004400039000000000142034f000000000101043b00000000059300490000001f0550008a00001c0d0650019700001c0d07100197000000000867013f000000000067004b000000000600001900001c0d06004041000000000051004b000000000500001900001c0d0500804100001c0d0080009c000000000605c019000000000006004b00001d0f0000c13d0000000005910019000000000152034f000000000101043b00001bce0010009c00001d0f0000213d000000060610021000000000036300490000002005500039000000000035004b000000000600001900001c0d0600204100001c0d0330019700001c0d05500197000000000735013f000000000035004b000000000300001900001c0d0300404100001c0d0070009c000000000306c019000000000003004b00001d0f0000c13d000000200340008a000000000232034f000000400300043d000000000202043b000000000021004b000023f40000413d001900000003001d00001c380030009c000024250000813d0000001903000029000000e002300039000000400020043f00000060043000390000006002000039001700000004001d0000000000240435000000c0023000390000000000020435000000a00230003900000000000204350000008002300039000800000002001d00000000000204350000004002300039000700000002001d00000000000204350000000002030436001100000002001d0000000000020435000000400200043d000f00000002001d00001bb40020009c000024250000213d0000000a02000029000000ff0320018f0000000f02000029000000a002200039000000400020043f000900000003001d000000040030008c000024820000213d00000009020000290000000f03000029000000000523043600000080043000390000000b02000029000300000004001d00000000002404350000006006300039000000160200002900000000002604350000004007300039000000180200002900000000002704350000000e02000029001c00000005001d000000000025043500001c390010009c000024250000213d000000010210003900000005012002100000003f0310003900001c0e03300197000000400500043d0000000003350019000000000053004b0000000004000039000000010400403900001bce0030009c000024250000213d0000000100400190000024250000c13d001302000090003d001801e00090003d000000400030043f00000000082504360000000002000019000000400300043d00001bb40030009c000024250000213d000000a004300039000000400040043f000000800430003900000000000404350000006004300039000000000004043500000040043000390000000000040435000000200430003900000000000404350000000000030435000000000428001900000000003404350000002002200039000000000012004b000015bc0000413d000c00000008001d001400000007001d001500000006001d001600000005001d00001c100100004100000000001004430000000001000412000000040010044300000080010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f0000000100200190000023e00000613d000000000101043b000000190200002900000000001204350000001c010000290000000003010433000000050030008c0000001e04000029000024820000213d0000000202000367000000000142034f000000000501043b00001ba70050009c00001d0f0000213d001200600040003d0000001201200360000000000401043b00001ba70040009c00001d0f0000213d000000400100043d00001bd40010009c000024250000213d000000c006100039000000400060043f000000200a10003900000000005a043500000000003104350000001206000029000d0040006000920000000d03200360000000000303043b000000400b10003900000000003b043500100020006000920000001003200360000000000503043b000000a00c10003900000000004c04350000006003100039000000800d10003900000000005d043500000000005304350000018004600039000000000442034f000000000404043b000000010540003a000023e10000613d00001c390040009c000024250000213d00000005065002100000003f0460003900001c0e07400197000000400400043d0000000007740019000000000047004b0000000008000039000000010800403900001bce0070009c000024250000213d0000000100800190000024250000c13d000000400070043f00000000075404360000001f0560018f000000000006004b000016290000613d00000000066700190000000002200368000000002802043c0000000007870436000000000067004b000016250000c13d000000000005004b000000170200002900000000004204350000000002010433000000050020008c000024820000213d0000001901000029000000000401043300000000050a043300000000060c043300000000070b0433000000000303043300000000080d0433000000400100043d000000c0091000390000000000890435000000a0081000390000000000380435000000800310003900000000007304350000004003100039000000000023043500001ba702600197000000e003100039000000000023043500001ba7025001970000006003100039000000000023043500000020021000390000000000420435000000e003000039000000000031043500001c130010009c000024250000213d00040000000d001d00050000000c001d00060000000b001d001b0000000a001d0000010003100039000000400030043f00001ba40020009c00001ba4020080410000004002200210000000000101043300001ba40010009c00001ba4010080410000006001100210000000000121019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f0000000c0c000029000000140b000029000000150a00002900000016090000290000001e08000029000000010020019000001d0f0000613d000000170200002900000000020204330000000023020434000000000003004b0000233e0000613d000000000101043b0000000000120435000000400100043d00001bb40010009c0000001b03000029000000060400002900000005060000290000000405000029000024250000213d000000a002100039000000400020043f000000800210003900000000000204350000006002100039000000000002043500000040021000390000000000020435000000200210003900000000000204350000000000010435000000400100043d00001bd40010009c000024250000213d000000c002100039000000400020043f000000a00210003900000000000204350000008002100039000000000002043500000060021000390000000000020435000000400210003900000000000204350000002002100039000000000002043500000000000104350000001c010000290000000002010433000000050020008c000024820000213d000000400100043d00001bb40010009c000024250000213d0000000003030433000000000404043300000000050504330000000006060433000000a007100039000000400070043f00001ba70660019700000080071000390000000000670435000000600610003900000000005604350000004005100039000000000045043500001ba7033001970000002004100039000000000034043500000000002104350000000002090433000000000002004b0000233e0000613d00000000001c043500000002010003670000001802100360000000000202043b000000000002004b000017640000613d000000000c0000190000001302100360000000000302043b000000000200003100000000048200490000001f0440008a00001c0d0540019700001c0d06300197000000000756013f000000000056004b000000000500001900001c0d05004041000000000043004b000000000400001900001c0d0400804100001c0d0070009c000000000504c019000000000005004b00001d0f0000c13d0000000004830019000000000341034f000000000303043b00001bce0030009c00001d0f0000213d00000006053002100000000005520049000000200440003900001c0d0650019700001c0d07400197000000000867013f000000000067004b000000000600001900001c0d06004041000000000054004b000000000500001900001c0d0500204100001c0d0080009c000000000605c019000000000006004b00001d0f0000c13d00000000003c004b0000233e0000813d0000000603c002100000000005340019000000000252004900001c0f0020009c00001d0f0000213d000000400020008c00001d0f0000413d000000400200043d00001ba80020009c000024250000213d0000004003200039000000400030043f000000000351034f000000000403043b00000000034204360000002005500039000000000151034f000000000501043b00001ba70050009c00001d0f0000213d000000000053043500000000060b0433000000050060008c000024820000213d000000400100043d00001bb40010009c000024250000213d00000000070a0433000000a008100039000000400080043f000000800810003900000000005804350000006005100039000000000045043500001ba70470019700000020051000390000000000450435000000000061043500000040041000390000000000040435000000010cc0003900000000040904330000000000c4004b0000233e0000a13d0000000504c0021000000020054000390000000004950019000000000014043500000000010904330000000000c1004b0000233e0000a13d00000000010b0433000000050010008c000024820000213d001c00000005001d000000400400043d00001bd40040009c000024250000213d00000000050a043300000000060204330000000002030433000000c003400039000000400030043f00001ba703200197000000a0024000390000000000320435000000800240003900000000006204350000006002400039000000000062043500001ba7055001970000002002400039000000000052043500000000001404350000004002400039000000000002043500000019020000290000000004020433000000400200043d000000e0072000390000000000370435000000c0032000390000000000630435000000a00320003900000000006304350000006003200039000000000053043500000040032000390000000000130435000000e001000039000000000112043600000000004104350000008003200039000000000003043500001c130020009c000024250000213d0000010003200039000000400030043f00001ba40010009c00001ba4010080410000004001100210000000000202043300001ba40020009c00001ba4020080410000006002200210000000000112019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c70000801002000039001b0000000c001d6e8b6e860000040f0000001b0c000029000000140b000029000000150a00002900000016090000290000001e08000029000000010020019000001d0f0000613d0000001702000029000000000202043300000000030204330000000000c3004b0000001c030000290000233e0000a13d0000000002230019000000000101043b000000000012043500000002010003670000001802100360000000000202043b00000000002c004b000016b30000413d000000400100043d0000002002100039000000170300002900000000030304330000000004030433000000000004004b0000000005020019000017740000613d000000000600001900000000050200190000002003300039000000000703043300000000057504360000000106600039000000000046004b0000176e0000413d0000000003150049000000200430008a00000000004104350000001f0330003900001c2b043001970000000003140019000000000043004b0000000004000039000000010400403900001bce0030009c000024250000213d0000000100400190000024250000c13d000000400030043f00001ba40020009c00001ba4020080410000004002200210000000000101043300001ba40010009c00001ba4010080410000006001100210000000000121019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f0000000c0f000029000000140e000029000000150d000029000000160c0000290000001e08000029000000010020019000001d0f0000613d000000000101043b00000008020000290000000000120435000000180100002900000020021000390000000201000367000000000221034f000000000302043b000000000200003100000000048200490000001f0440008a00001c0d0540019700001c0d06300197000000000756013f000000000056004b000000000500001900001c0d05004041000000000043004b000000000400001900001c0d0400804100001c0d0070009c000000000504c019000000000005004b00001d0f0000c13d0000000004830019000000000341034f000000000303043b00001bce0030009c00001d0f0000213d000000200440003900000006053002100000000005520049000000000054004b000000000600001900001c0d0600204100001c0d0550019700001c0d07400197000000000857013f000000000057004b000000000500001900001c0d0500404100001c0d0080009c000000000506c019000000000005004b00001d0f0000c13d0000001805100360000000000505043b000000000035004b000017fd0000813d00000006065002100000000007640019000000000672004900001c0f0060009c00001d0f0000213d000000400060008c00001d0f0000413d000000400800043d00001ba80080009c000024250000213d0000004006800039000000400060043f000000000671034f000000000606043b00000000096804360000002007700039000000000771034f000000000807043b00001ba70080009c00001d0f0000213d000000000089043500000000090e0433000000050090008c000024820000213d000000400700043d00001bb40070009c000024250000213d000000000a0d0433000000a00b7000390000004000b0043f000000800b70003900000000008b04350000006008700039000000000068043500001ba706a0019700000020087000390000000000680435000000000097043500000040067000390000000000060435000000010550003900000000060c0433000000000056004b0000233e0000a13d000000050650021000000000066f0019000000000076043500000000060c0433000000000056004b000017c80000213d0000233e0000013d000000400200043d00001ba80020009c000024250000213d0000004001200039000000400010043f00000001010000390000000003120436000000400100043d00001c3a0010009c000024250000213d001c00000002001d0000008002100039000000400020043f0000006002100039000000000002043500000040021000390000000000020435000000200210003900000000000204350000000000010435001b00000003001d000000000013043500001c100100004100000000001004430000000001000412000000040010044300000060010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f0000000100200190000023e00000613d000000000101043b0000001902000029000000000012043500000003010000290000000004010433000000050040008c000024820000213d0000001801000029000001400510008a0000000201000367000000000251034f000000000602043b00001ba70060009c0000001b0800002900001d0f0000213d000000400200043d00001c3a0020009c0000001c07000029000024250000213d0000008003200039000000400030043f0000002003200039000000000063043500000000004204350000002004500039000000000441034f000000000604043b00000040042000390000000000640435001800400050003d0000001801100360000000000101043b000000600520003900000000001504350000000001070433000000000001004b0000233e0000613d0000000000280435000000400800043d00001c3b0080009c000024250000213d0000002001800039000000400010043f0000000002020433000000050020008c000024820000213d00000019060000290000000006060433000000000303043300000000040404330000000005050433000000e0078000390000000000570435000000c0078000390000000000570435000000a00580003900000000004504350000006004800039000000000024043500001ba7023001970000008003800039000000000023043500000040028000390000000000620435000000c003000039000000000031043500001c130080009c000024250000213d001b00000008001d0000010003800039000000400030043f00001ba40020009c00001ba4020080410000004002200210000000000101043300001ba40010009c00001ba4010080410000006001100210000000000121019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f000000010020019000001d0f0000613d000000000301043b0000001b0100002900000000003104350000002002000039000000400100043d0000000002210436000000000032043500001ba80010009c000024250000213d0000004003100039000000400030043f00001ba40020009c00001ba4020080410000004002200210000000000101043300001ba40010009c00001ba4010080410000006001100210000000000121019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f000000010020019000001d0f0000613d000000000101043b0000000702000029000000000012043500001c1001000041000000000010044300000000010004120000000400100443000000a0010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f0000000100200190000023e00000613d000000000101043b000000190200002900000000001204350000001801000029000000800310008a0000000201300367000000000101043b00001ba70010009c00001d0f0000213d000000000010043f0000000201000039000000200010043f000000000100041400001ba40010009c00001ba401008041000000c00110021000001c17011001c70000801002000039001b00000003001d6e8b6e860000040f0000001b07000029000000010020019000001d0f0000613d0000000202000367000000000372034f00000019040000290000000006040433000000000101043b000000000101041a000000000503043b00001ba70050009c00001d0f0000213d0000002004700039000000000342034f000000000703043b00001ba70070009c00001d0f0000213d0000000f030000290000000008030433000000040080008c000024820000213d000000070300002900000000090304330000000803000029000000000a030433000000400300043d000000c00b30003900000000008b0435000000a0083000390000000000a8043500000080083000390000000000980435000000600830003900000000007804350000004007300039000000000057043500000020053000390000000000650435000000a006400039000000000662034f000000000606043b000000e0073000390000000000670435000000c006400039000000000662034f000000000606043b00000100073000390000000000670435000000e006400039000000000662034f000000000606043b000001200730003900000000006704350000010006400039000000000662034f000000000606043b00000140073000390000000000670435001b01200040003d0000001b02200360000000000202043b00000180043000390000000000140435000001600130003900000000002104350000018001000039000000000013043500001c160030009c000024250000213d000001a001300039000000400010043f00001ba40050009c00001ba4050080410000004001500210000000000203043300001ba40020009c00001ba4020080410000006002200210000000000112019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f000000160a000029000000010020019000001d0f0000613d000000000201043b000000110100002900000000002104350000001b01000029000001400310008a0000000201000367000000000431034f000000000504043b00001ba70050009c00001d0f0000213d000000200c3000390000000001c1034f000000000601043b00001ba70060009c00001d0f0000213d000000400100043d0000004003100039000000800400003900000000004304350000000002210436000000000300041100001ba703300197000c00000003001d00000000003204350000001c0b00002900000000030b043300000080021000390000000000320435000000a002100039000000000003004b0000194d0000613d0000000004000019000000200bb0003900000000070b04330000000089070434000000050090008c000024820000213d0000000009920436000000000808043300001ba70880019700000000008904350000004008700039000000000808043300000040092000390000000000890435000000600770003900000000070704330000006008200039000000000078043500000080022000390000000104400039000000000034004b000019380000413d00000000031200490000006004100039000000000034043500000000030a04330000000002320436000000000003004b0000196f0000613d0000000004000019000000200aa0003900000000070a04330000000089070434000000050090008c000024820000213d0000000009920436000000000808043300001ba7088001970000000000890435000000400870003900000000080804330000004009200039000000000089043500000060087000390000000008080433000000600920003900000000008904350000008007700039000000000707043300001ba70770019700000080082000390000000000780435000000a0022000390000000104400039000000000034004b000019550000413d000000000212004900001ba40020009c00001ba402008041000000600220021000001ba40010009c00001ba4010080410000004001100210000000000112019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000121019f00001bcd011001c70000800d02000039000000030300003900001c3c04000041001c0000000c001d6e8b6e810000040f0000001c060000290000001e0f000029000000010020019000001d0f0000613d000000400300043d00001c3b0030009c000024250000213d00000011010000290000000001010433001b00000001001d0000002001300039000000400010043f0000000000030435000000400400043d00001ba80040009c000024250000213d0000004001400039000000400010043f00000001010000390000000005140436000000400100043d00001c3a0010009c000024250000213d0000008002100039000000400020043f0000006002100039000000000002043500000040021000390000000000020435000000200210003900000000000204350000000000010435000000000015043500000020076000390000000201000367000000000271034f000000000202043b00001ba70020009c00001d0f0000213d000000400600043d00001c3a0060009c000024250000213d0000008008600039000000400080043f000000200860003900000000002804350000000b0800002900000000008604350000002008700039000000000881034f000000000808043b000000400960003900000000008904350000004007700039000000000871034f000000000808043b000000600960003900000000008904350000000008040433000000000008004b0000233e0000613d00000000006504350000012005700039000000000551034f00000000060000310000000007f600490000001f0770008a000000000505043b00001c0d0850019700001c0d09700197000000000a98013f000000000098004b000000000800001900001c0d08004041000000000075004b000000000700001900001c0d0700804100001c0d00a0009c000000000807c019000000000008004b00001d0f0000c13d0000000007f50019000000000571034f000000000505043b00001bce0050009c00001d0f0000213d00000006085002100000000006860049000000200770003900001c0d0860019700001c0d09700197000000000a89013f000000000089004b000000000800001900001c0d08004041000000000067004b000000000600001900001c0d0600204100001c0d00a0009c000000000806c019000000000008004b00001d0f0000c13d00001c390050009c000024250000213d000000010850003900000005098002100000003f0690003900001c0e0a600197000000400600043d000000000aa6001900000000006a004b000000000b000039000000010b00403900001bce00a0009c000024250000213d0000000100b00190000024250000c13d001600a000f0003d001800c000f0003d001901a000f0003d0000004000a0043f0000000008860436000000000a000019000000400b00043d00001bb400b0009c000024250000213d000000a00cb000390000004000c0043f000000800cb0003900000000000c0435000000600cb0003900000000000c0435000000400cb0003900000000000c0435000000200cb0003900000000000c043500000000000b0435000000000c8a00190000000000bc0435000000200aa0003900000000009a004b000019fd0000413d0000000009f1034f000000000a09043b00001ba700a0009c00001d0f0000213d0000001209100360000000000909043b001c00000009001d00001ba70090009c00001d0f0000213d000000400b00043d00001bb400b0009c000024250000213d000000a009b00039000000400090043f0000002009b000390000000000a904350000000e0900002900000000009b04350000000d09100360000000000909043b000000400cb0003900000000009c0435000000100c100360000000000c0c043b000000800db000390000001c0e0000290000000000ed0435000000600db000390000000000cd0435000000000c06043300000000000c004b0000233e0000613d0000000000b80435000000020000006b00000000020a6019000000000900c01900001ba702200197000000000a00001900000000005a004b00001a5b0000813d000000060ba00210000000000c7b0019000000200bc00039000000000bb1034f000000000d0b043b00001ba700d0009c00001d0f0000213d000000400b00043d00001bb400b0009c000024250000213d000000a00eb000390000004000e0043f000000400eb0003900000000009e0435000000200eb0003900000000002e04350000001a0e0000290000000000eb0435000000000cc1034f000000000c0c043b000000800eb000390000000000de0435000000600db000390000000000cd0435000000010aa00039000000000c0604330000000000ac004b0000233e0000a13d000000050ca00210000000000c8c00190000000000bc0435000000000b0604330000000000ab004b00001a360000213d0000233e0000013d0000000902000029000000020020008c002700000000003d002700010000603d002600000000003d002600010000c03d002800000000003d0000000a02000029000000fe0220018f000000020020008c00000010020000290000004002200039000f00000002001d00001b720000c13d000000000221034f000000000202043b00001ba70020009c00001d0f0000213d0000000005000411000000000025004b00001b720000613d000000400900043d00001c3d0090009c000024250000213d0000014005900039000000400050043f00000080079000390000000000670435000000600890003900000000004804350000001c0400002900001ba704400197000000400a90003900000000004a04350000001b04000029000000000b490436000000000400041100000000004b0435000000400400043d00001c3b0040009c000024250000213d0000002005400039000000400050043f0000000000040435000000c0059000390000000000350435000000a00690003900000000004604350000000f0d000029000000a003d00039000000000331034f000000000403043b000000e0039000390000000000430435000000c004d00039000000000441034f000000000c04043b00000100049000390000000000c40435000000e00cd000390000000001c1034f000000000c01043b00000120019000390000000000c1043500001c3e0c000041000000400e00043d0000000000ce0435000000040ce00039000000200d0000390000000000dc04350000000009090433000000240ce0003900000000009c043500000000090b043300001ba709900197000000440be0003900000000009b043500000000090a043300001ba709900197000000640ae0003900000000009a043500000000090804330000014008000039000000840ae0003900000000008a04350000016408e00039000000000a0904330000000000a80435001c0000000e001d0000018408e0003900000000000a004b00001acd0000613d000000000b0000190000002009900039000000000c09043300000000de0c04340000000500e0008c000024820000213d000000000ee80436000000000d0d043300001ba70dd001970000000000de0435000000400dc00039000000000d0d0433000000400e8000390000000000de0435000000600cc00039000000000c0c0433000000600d8000390000000000cd04350000008008800039000000010bb000390000000000ab004b00001ab80000413d0000001c0b0000290000000009b80049000000240a90008a0000000009070433000000a407b000390000000000a70435000000000a0904330000000007a8043600000000000a004b00001af20000613d00000000080000190000002009900039000000000b09043300000000cd0b04340000000500d0008c000024820000213d000000000dd70436000000000c0c043300001ba70cc001970000000000cd0435000000400cb00039000000000c0c0433000000400d7000390000000000cd0435000000600cb00039000000000c0c0433000000600d7000390000000000cd0435000000800bb00039000000000b0b043300001ba70bb00197000000800c7000390000000000bc0435000000a00770003900000001088000390000000000a8004b00001ad80000413d0000001c0c0000290000000008c70049000000240880008a0000000006060433000000c409c00039000000000089043500000000980604340000000006870436000000000008004b00001b040000613d0000000007000019000000000a670019000000000b790019000000000b0b04330000000000ba04350000002007700039000000000087004b00001afd0000413d000000000786001900000000000704350000001f0780003900001c2b0770019700000000087600190000000006c80049000000240760008a0000000006050433000000e405c00039000000000075043500000000070604330000000005780436000000000007004b00001b190000613d00000000080000190000002006600039000000000906043300000000059504360000000108800039000000000078004b00001b130000413d00000000030304330000010406c00039000000000036043500000000030404330000012404c0003900000000003404350000014403c00039000000000101043300000000001304350000000001000414000000040020008c00001b2a0000c13d0000000103000031000000200030008c0000002004000039000000000403401900001b5b0000013d0000000003c5004900001ba40030009c00001ba403008041000000600330021000001ba400c0009c00001ba40400004100000000040c40190000004004400210000000000334019f00001ba40010009c00001ba401008041000000c001100210000000000131019f6e8b6e810000040f0000001c0c0000290000000003010019000000600330027000001ba403300197000000200030008c000000200400003900000000040340190000001f0640018f000000200740019000000000057c001900001b490000613d000000000801034f00000000090c0019000000008a08043c0000000009a90436000000000059004b00001b450000c13d000000000006004b00001b560000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f0000000000650435000100000003001f000300000001035500000001002001900000001e0f000029000024620000613d0000001f01400039000000600210018f0000000001c20019000000000021004b0000000002000039000000010200403900001bce0010009c000024250000213d0000000100200190000024250000c13d000000400010043f000000200030008c00001d0f0000413d00000000020c043300001c3f0020019800001d0f0000c13d00001c400220019700001c3e0020009c000024540000c13d00000002010003670000001202100360000000000202043b001c00000002001d0000001c0200002900001ba70020009c00001d0f0000213d00000011020000290000000002020433001b00000002001d001a022000f0003d0000001a02100360000000000202043b00000000030000310000000004f300490000001f0440008a00001c0d0540019700001c0d06200197000000000756013f000000000056004b000000000500001900001c0d05004041000000000042004b000000000400001900001c0d0400804100001c0d0070009c000000000504c019000000000005004b00001d0f0000c13d0000000004f20019000000000241034f000000000202043b00001bce0020009c00001d0f0000213d0000000006230049000000200540003900001c0d0460019700001c0d07500197000000000847013f000000000047004b000000000400001900001c0d04004041000000000065004b000000000600001900001c0d0600204100001c0d0080009c000000000406c019000000000004004b00001d0f0000c13d0000001f0420003900001c2b044001970000003f0440003900001c2b04400197000000400700043d0000000004470019000000000074004b0000000006000039000000010600403900001bce0040009c000024250000213d0000000100600190000024250000c13d000000400040043f001700000007001d00000000042704360000000006520019000000000036004b00001d0f0000213d000000000351034f00001c2b052001980000001f0620018f000000000154001900001bbd0000613d000000000703034f0000000008040019000000007907043c0000000008980436000000000018004b00001bb90000c13d000000000006004b00001bca0000613d000000000353034f0000000305600210000000000601043300000000065601cf000000000656022f000000000303043b0000010005500089000000000353022f00000000035301cf000000000363019f0000000000310435000000000124001900000000000104350000001b01000029000000000010043f0000000301000039000000200010043f000000000100041400001ba40010009c00001ba401008041000000c00110021000001c17011001c700008010020000396e8b6e860000040f00000001002001900000001e0b00002900001d0f0000613d000000000201043b000000000102041a0000ff0000100190000023fb0000c13d00001c4200100198000023fe0000c13d000000ff0010019000001be90000c13d0000001c01000029001c00000002001d0000001b0200002900000017030000296e8b5c900000040f0000001c020000290000001e0b00002900001c4401000041000000000012041b00000011010000290000000001010433001300000001001d002500000001001d0000003201000029000000050010008c000024820000213d000000000500003900000001050060390000002d0000002a0000002e020000290000000005026019000000010010008c000000000700003900000001070060390000002f0000002a00000030030000290000000007036019000001c00cb00039000000000005004b00000000060c001900000019060060290000000204000367000000000664034f000000000606043b000000000007004b00001c1c0000613d0000000007b4034f000000000707043b00001ba70070009c00001d0f0000213d0000002008b00039000000000884034f000000000808043b000000000878019f0000000007000415000000230770008a0000000507700210000000000008004b002300000000003d002300010000c03d00001c440000c13d000000020010008c00001c220000c13d0000000008000415000000220880008a0000000508800210002200010000003d00001c2a0000013d0000000007000415000000240770008a0000000507700210002400000000003d000000020010008c00001c170000613d0000000008000415000000200880008a0000000508800210000000030010008c00000000090000390000000109006039002000000009001d00001c470000c13d0000001a09000029000002000990008a000000000994034f000000000909043b000000000009004b000000000a000039000000010a00c039000000050880027000000000080a001f000000050770027000000000070a001f00210000000a001d0000000007000415000000210770008a0000000507700210000000000009004b00001c440000c13d000000000005004b00001c4f0000613d0000001805400360000000000505043b000000000005004b0000000505700270000000000500003f000000010500c03f00001c510000613d000000400100043d00001c4e02000041000023cc0000013d0000000507700270000000000709001f001f00000009001d00000000070004150000001f0770008a0000000507700210000000000005004b00001c3d0000c13d0000000505700270000000000500003f000000400500043d001900000005001d00001ba80050009c000024250000213d00000019080000290000004005800039000000400050043f00000020078000390000006005000039001500000007001d00000000005704350000000000080435000000000003004b00001d230000613d0000001601400360000000000101043b00001ba70010009c00001d0f0000213d0000001602000029000000400320008a000000000234034f000000000202043b00001ba70020009c00001d0f0000213d0000000005030019001c00000005001d0000006003500039000000000334034f0000008005500039000000000454034f000000000504043b000000000403043b000000000300041100000019070000296e8b48f10000040f0000001e0d00002900001c5109d000990000001c08000029000001a00a80003900000002010003670000000002a1034f000000000302043b0000000002000031000000000492001900001c0d0540019700001c0d06300197000000000756013f000000000056004b000000000500001900001c0d05004041000000000043004b000000000400001900001c0d0400804100001c0d0070009c000000000504c019000000200480008a000000000441034f000000000404043b001400000004001d000000000005004b00001d0f0000c13d000000000b000019001800000009001d00170000000a001d0000000004d30019000000000341034f000000000303043b00001bce0030009c00001d0f0000213d00000006053002100000000005520049000000200240003900001c0d0450019700001c0d06200197000000000746013f000000000046004b000000000400001900001c0d04004041000000000052004b000000000500001900001c0d0500204100001c0d0070009c000000000405c019000000000004004b00001d0f0000c13d00000000003b004b00001d110000813d0000000603b002100000000002230019000000000321034f000000000503043b001d001d00500073000023c70000413d0000002002200039000000000121034f000000000401043b00001ba70040009c00001d0f0000213d000000000005004b000023ca0000613d0000000001000414000000040040008c001c00000005001d001b00000004001d00001cbf0000c13d00000001010000310000000102000039000000000001004b00001cd30000c13d00001cfa0000013d00001ba40010009c00001ba401008041000000c00110021000001bcd011001c7000080090200003900000000030500190000000005000019001a0000000b001d6e8b6e810000040f0000001a0b000029000000170a00002900000018090000290000001e0d000029000000010220018f0003000000010355000000600110027000011ba40010019d00001ba401100197000000000001004b00001cfa0000613d00001bce0010009c000024250000213d0000001f0310003900001c2b033001970000003f0330003900001c2b04300197000000400300043d0000000004430019000000000034004b0000000005000039000000010500403900001bce0040009c000024250000213d0000000100500190000024250000c13d000000400040043f000000000613043600001c2b041001980000000003460019000000030500036700001ced0000613d000000000705034f000000007807043c0000000006860436000000000036004b00001ce90000c13d0000001f0110019000001cfa0000613d000000000445034f0000000301100210000000000503043300000000051501cf000000000515022f000000000404043b0000010001100089000000000414022f00000000011401cf000000000151019f0000000000130435000000000002004b000023d20000613d00000002010003670000000002a1034f000000000302043b0000000002000031000000000492001900001c0d0540019700001c0d06300197000000000756013f000000000056004b000000000500001900001c0d05002041000000000043004b000000000400001900001c0d0400404100001c0d0070009c000000000504c019000000010bb00039000000000005004b00001c910000c13d000000000100001900006e8d0001043000000014030000290000001d0030006b000023c70000413d0000001201100360000000000401043b00001ba70040009c00001d0f0000213d000000140000006b000023ca0000613d0000000001000414000000040040008c001c00000004001d00001da60000c13d00000001020000390000000101000031000000000001004b00001db60000c13d00001dde0000013d000000010010008c00001e2d0000613d000000020010008c00001ede0000613d000000030010008c00001f610000c13d0000001601400360000000000101043b00001ba70010009c00001d0f0000213d0000001602000029000000400320008a000000000234034f000000000202043b00001ba70020009c00001d0f0000213d001c00000003001d0000001c030000290000006003300039000000000334034f0000001c050000290000008005500039000000000454034f000000000504043b000000000403043b00000000030004110000001907000029001d0000000c001d6e8b46c00000040f0000001c030000290000001d090000290000001e080000290000000201000367000000000231034f000000000202043b001700000002001d00001ba70020009c00001d0f0000213d000000000281034f000000200330008a000000000331034f000000000303043b001400000003001d000000000202043b001c00000002001d00001ba70020009c00001d0f0000213d00001c5104800099001800400090003d0000001802100360000000000302043b0000000002000031001a00000004001d000000000442001900001c0d0540019700001c0d06300197000000000756013f000000000056004b000000000500001900001c0d05004041000000000043004b000000000400001900001c0d0400804100001c0d0070009c000000000504c019000000000491034f000000000404043b001b00000004001d000000000005004b00001d0f0000c13d00000000090000190000000004830019000000000341034f000000000303043b00001bce0030009c00001d0f0000213d00000006053002100000000005520049000000200240003900001c0d0450019700001c0d06200197000000000746013f000000000046004b000000000400001900001c0d04004041000000000052004b000000000500001900001c0d0500204100001c0d0070009c000000000405c019000000000004004b00001d0f0000c13d000000000039004b00001f5b0000813d000000060390021000000000022300190000002003200039000000000331034f000000000303043b00001ba70030009c00001d0f0000213d000000000121034f000000000401043b0000001c0100002900000000020004110000001b050000290000001906000029001d00000009001d6e8b604a0000040f0000001d090000290000001e0800002900000002010003670000001802100360000000000302043b00000000020000310000001a0420002900001c0d0540019700001c0d06300197000000000756013f000000000056004b000000000500001900001c0d05002041000000000043004b000000000400001900001c0d0400404100001c0d0070009c000000000504c0190000000109900039000000000005004b00001d6a0000c13d00001d0f0000013d00001ba40010009c00001ba401008041000000c00110021000001bcd011001c70000800902000039000000140300002900000000050000196e8b6e810000040f0000001e0d000029000000010220018f0003000000010355000000600110027000011ba40010019d00001ba401100197000000000001004b00001dde0000613d00001bce0010009c000024250000213d0000001f0310003900001c2b033001970000003f0330003900001c2b04300197000000400300043d0000000004430019000000000034004b0000000005000039000000010500403900001bce0040009c000024250000213d0000000100500190000024250000c13d000000400040043f000000000713043600001c2b041001980000001f0510018f0000000003470019000000030600036700001dd10000613d000000000806034f000000008908043c0000000007970436000000000037004b00001dcd0000c13d000000000005004b00001dde0000613d000000000446034f0000000305500210000000000603043300000000065601cf000000000656022f000000000404043b0000010005500089000000000454022f00000000045401cf000000000464019f0000000000430435000000000002004b000024090000613d00000014030000290000001d0930006b000020b10000a13d00000000020004140000000c04000029000000040040008c00001deb0000c13d0000000102000039000000000001004b00001dfd0000c13d00001e230000013d00001ba40020009c00001ba402008041000000c00120021000001bcd011001c7000080090200003900000000030900190000000005000019001d00000009001d6e8b6e810000040f0000001d090000290000001e0d000029000000010220018f0003000000010355000000600110027000011ba40010019d00001ba401100197000000000001004b00001e230000613d0000001f0310003900001c2b033001970000003f0330003900001c2b04300197000000400300043d0000000004430019000000000034004b0000000005000039000000010500403900001bce0040009c000024250000213d0000000100500190000024250000c13d000000400040043f000000000613043600001c2b031001980000001f0410018f0000000001360019000000030500036700001e160000613d000000000705034f000000007807043c0000000006860436000000000016004b00001e120000c13d000000000004004b00001e230000613d000000000335034f0000000304400210000000000501043300000000054501cf000000000545022f000000000303043b0000010004400089000000000343022f00000000034301cf000000000353019f0000000000310435000000000002004b000020b10000c13d000000400100043d0000002402100039000000000092043500001c4502000041000000000021043500000004021000390000000c03000029000023da0000013d0000001601400360000000000101043b00001ba70010009c00001d0f0000213d0000001602000029000000400320008a000000000234034f000000000202043b00001ba70020009c00001d0f0000213d0000000005030019001c00000005001d0000006003500039000000000334034f0000008005500039000000000454034f000000000504043b000000000403043b000000000300041100000019070000296e8b46c00000040f0000001e0d00002900001c5109d000990000001c08000029000001a00a80003900000002010003670000000002a1034f000000000302043b0000000002000031000000000492001900001c0d0540019700001c0d06300197000000000756013f000000000056004b000000000500001900001c0d05004041000000000043004b000000000400001900001c0d0400804100001c0d0070009c000000000504c019000000200480008a000000000441034f000000000404043b001400000004001d000000000005004b00001d0f0000c13d000000000b000019001800000009001d00170000000a001d0000000004d30019000000000341034f000000000303043b00001bce0030009c00001d0f0000213d00000006053002100000000005520049000000200240003900001c0d0450019700001c0d06200197000000000746013f000000000046004b000000000400001900001c0d04004041000000000052004b000000000500001900001c0d0500204100001c0d0070009c000000000405c019000000000004004b00001d0f0000c13d00000000003b004b00001fdc0000813d0000000603b002100000000002230019000000000321034f000000000503043b001d001d00500073000023c70000413d0000002002200039000000000121034f000000000401043b00001ba70040009c00001d0f0000213d000000000005004b000023ca0000613d0000000001000414000000040040008c001c00000005001d001b00000004001d00001e8d0000c13d00000001010000310000000102000039000000000001004b00001ea10000c13d00001ec80000013d00001ba40010009c00001ba401008041000000c00110021000001bcd011001c7000080090200003900000000030500190000000005000019001a0000000b001d6e8b6e810000040f0000001a0b000029000000170a00002900000018090000290000001e0d000029000000010220018f0003000000010355000000600110027000011ba40010019d00001ba401100197000000000001004b00001ec80000613d00001bce0010009c000024250000213d0000001f0310003900001c2b033001970000003f0330003900001c2b04300197000000400300043d0000000004430019000000000034004b0000000005000039000000010500403900001bce0040009c000024250000213d0000000100500190000024250000c13d000000400040043f000000000613043600001c2b041001980000000003460019000000030500036700001ebb0000613d000000000705034f000000007807043c0000000006860436000000000036004b00001eb70000c13d0000001f0110019000001ec80000613d000000000445034f0000000301100210000000000503043300000000051501cf000000000515022f000000000404043b0000010001100089000000000414022f00000000011401cf000000000151019f0000000000130435000000000002004b000023d20000613d00000002010003670000000002a1034f000000000302043b0000000002000031000000000492001900001c0d0540019700001c0d06300197000000000756013f000000000056004b000000000500001900001c0d05002041000000000043004b000000000400001900001c0d0400404100001c0d0070009c000000000504c019000000010bb00039000000000005004b00001e5f0000c13d00001d0f0000013d0000001601400360000000000101043b00001ba70010009c00001d0f0000213d0000001602000029000000400320008a000000000234034f000000000202043b00001ba70020009c00001d0f0000213d001c00000003001d0000001c030000290000006003300039000000000334034f0000001c050000290000008005500039000000000454034f000000000504043b000000000403043b00000000030004110000001907000029001d0000000c001d6e8b48f10000040f0000001c030000290000001d090000290000001e080000290000000201000367000000000231034f000000000202043b001700000002001d00001ba70020009c00001d0f0000213d000000000281034f000000200330008a000000000331034f000000000303043b001400000003001d000000000202043b001c00000002001d00001ba70020009c00001d0f0000213d00001c5104800099001800400090003d0000001802100360000000000302043b0000000002000031001a00000004001d000000000442001900001c0d0540019700001c0d06300197000000000756013f000000000056004b000000000500001900001c0d05004041000000000043004b000000000400001900001c0d0400804100001c0d0070009c000000000504c019000000000491034f000000000404043b001b00000004001d000000000005004b00001d0f0000c13d00000000090000190000000004830019000000000341034f000000000303043b00001bce0030009c00001d0f0000213d00000006053002100000000005520049000000200240003900001c0d0450019700001c0d06200197000000000746013f000000000046004b000000000400001900001c0d04004041000000000052004b000000000500001900001c0d0500204100001c0d0070009c000000000405c019000000000004004b00001d0f0000c13d000000000039004b00001f5b0000813d000000060390021000000000022300190000002003200039000000000331034f000000000303043b00001ba70030009c00001d0f0000213d000000000121034f000000000401043b0000001c0100002900000000020004110000001b050000290000001906000029001d00000009001d6e8b604a0000040f0000001d090000290000001e0800002900000002010003670000001802100360000000000302043b00000000020000310000001a0420002900001c0d0540019700001c0d06300197000000000756013f000000000056004b000000000500001900001c0d05002041000000000043004b000000000400001900001c0d0400404100001c0d0070009c000000000504c0190000000109900039000000000005004b00001f1f0000c13d00001d0f0000013d0000001c010000290000000002000411000000170300002900000014040000290000001b05000029000020ae0000013d0000000001b4034f000000000101043b000000000002004b000020320000613d00001ba70010009c00001d0f0000213d0000001202400360000000000302043b00001ba70030009c00001d0f0000213d0000000d024003600000001004400360000000000504043b000000000402043b000000000200041100000019070000296e8b48f10000040f0000001e0900002900000002010003670000001202100360000000000202043b001a00000002001d00001ba70020009c00001d0f0000213d00000012020000290000004004200039000000000241034f000000000202043b001800000002001d00001ba70020009c00001d0f0000213d00001c5105900099001b01600040003d0000001b02100360000000000302043b0000000002000031001400000005001d000000000552001900001c0d0650019700001c0d07300197000000000867013f000000000067004b000000000600001900001c0d06004041000000000053004b000000000500001900001c0d0500804100001c0d0080009c000000000605c0190000010004400039000000000441034f000000000404043b001700000004001d000000000006004b00001d0f0000c13d0000001b04000029000001200440008a000000000441034f000000000404043b001d00000004001d00000000080000190000000004930019000000000341034f000000000303043b00001bce0030009c00001d0f0000213d00000006053002100000000005520049000000200240003900001c0d0450019700001c0d06200197000000000746013f000000000046004b000000000400001900001c0d04004041000000000052004b000000000500001900001c0d0500204100001c0d0070009c000000000405c019000000000004004b00001d0f0000c13d000000000038004b000020a90000813d00000006038002100000000002230019000000000321034f000000000403043b001d001d00400073000023e10000413d0000002002200039000000000121034f000000000301043b00001ba70030009c00001d0f0000213d00000018010000290000001a0200002900000017050000290000001906000029001c00000008001d6e8b604a0000040f0000001c080000290000001e0900002900000002010003670000001b02100360000000000302043b0000000002000031000000140420002900001c0d0540019700001c0d06300197000000000756013f000000000056004b000000000500001900001c0d05002041000000000043004b000000000400001900001c0d0400404100001c0d0070009c000000000504c0190000000108800039000000000005004b00001f9e0000c13d00001d0f0000013d00000014030000290000001d0030006b000023c70000413d0000001201100360000000000401043b00001ba70040009c00001d0f0000213d000000140000006b000023ca0000613d0000000001000414000000040040008c001c00000004001d00001fee0000c13d00000001020000390000000101000031000000000001004b00001ffe0000c13d000020260000013d00001ba40010009c00001ba401008041000000c00110021000001bcd011001c70000800902000039000000140300002900000000050000196e8b6e810000040f0000001e0d000029000000010220018f0003000000010355000000600110027000011ba40010019d00001ba401100197000000000001004b000020260000613d00001bce0010009c000024250000213d0000001f0310003900001c2b033001970000003f0330003900001c2b04300197000000400300043d0000000004430019000000000034004b0000000005000039000000010500403900001bce0040009c000024250000213d0000000100500190000024250000c13d000000400040043f000000000713043600001c2b041001980000001f0510018f00000000034700190000000306000367000020190000613d000000000806034f000000008908043c0000000007970436000000000037004b000020150000c13d000000000005004b000020260000613d000000000446034f0000000305500210000000000603043300000000065601cf000000000656022f000000000404043b0000010005500089000000000454022f00000000045401cf000000000464019f0000000000430435000000000002004b000024090000613d00000014030000290000001d0330006b000020b10000a13d00000000020004140000000c04000029000000040040008c001d00000003001d0000238b0000c13d0000000102000039000023980000013d00001ba70010009c00001d0f0000213d0000001202400360000000000302043b00001ba70030009c00001d0f0000213d0000000d024003600000001004400360000000000504043b000000000402043b000000000200041100000019070000296e8b46c00000040f0000001e0900002900000002010003670000001202100360000000000202043b001a00000002001d00001ba70020009c00001d0f0000213d00000012020000290000004004200039000000000241034f000000000202043b001800000002001d00001ba70020009c00001d0f0000213d00001c5105900099001b01600040003d0000001b02100360000000000302043b0000000002000031001400000005001d000000000552001900001c0d0650019700001c0d07300197000000000867013f000000000067004b000000000600001900001c0d06004041000000000053004b000000000500001900001c0d0500804100001c0d0080009c000000000605c0190000010004400039000000000441034f000000000404043b001700000004001d000000000006004b00001d0f0000c13d0000001b04000029000001200440008a000000000441034f000000000404043b001d00000004001d00000000080000190000000004930019000000000341034f000000000303043b00001bce0030009c00001d0f0000213d00000006053002100000000005520049000000200240003900001c0d0450019700001c0d06200197000000000746013f000000000046004b000000000400001900001c0d04004041000000000052004b000000000500001900001c0d0500204100001c0d0070009c000000000405c019000000000004004b00001d0f0000c13d000000000038004b000020a90000813d00000006038002100000000002230019000000000321034f000000000403043b001d001d00400073000023e10000413d0000002002200039000000000121034f000000000301043b00001ba70030009c00001d0f0000213d00000018010000290000001a0200002900000017050000290000001906000029001c00000008001d6e8b604a0000040f0000001c080000290000001e0900002900000002010003670000001b02100360000000000302043b0000000002000031000000140420002900001c0d0540019700001c0d06300197000000000756013f000000000056004b000000000500001900001c0d05002041000000000043004b000000000400001900001c0d0400404100001c0d0070009c000000000504c0190000000108800039000000000005004b0000206b0000c13d00001d0f0000013d00000018010000290000001a0200002900000000030004110000001d04000029000000170500002900000019060000296e8b604a0000040f0000001e0d000029000000150100002900000000010104330000000001010433000000000001004b000021950000613d00000019010000290000000001010433001c00000001001d000000400100043d001d00000001001d000000200210003900001c4801000041001b00000002001d000000000012043500001c100100004100000000001004430000000001000412000000040010044300000120010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f0000000100200190000023e00000613d000000000101043b0000001d0400002900000060024000390000001c030000290000000000320435000000400240003900001ba701100197000000000012043500001c100100004100000000001004430000000001000412000000040010044300000160010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f0000000100200190000023e00000613d000000000101043b0000001d04000029000000a00240003900001c4903000041000000000032043500000080024000390000000000120435000000a001000039000000000014043500001bd40040009c000024250000213d0000001d02000029000000c001200039000000400010043f0000001b0100002900001ba40010009c00001ba4010080410000004001100210000000000202043300001ba40020009c00001ba4020080410000006002200210000000000112019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f000000010020019000001d0f0000613d000000000101043b00001c4a02000041000000000020044300001ba701100197001d00000001001d0000000400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c27011001c700008002020000396e8b6e860000040f0000000100200190000023e00000613d000000400b00043d0000002404b000390000000403b00039000000000101043b000000000001004b000024120000613d0000001501000029000000000201043300001c4b0100004100000000001b043500000020010000390000000000130435000000000302043300000000003404350000004401b00039000000000003004b0000001e0d000029000021470000613d0000000004000019000000200220003900000000050204330000000067050434000000040070008c000024820000813d0000000007710436000000000606043300001ba70660019700000000006704350000004006500039000000000606043300001ba706600197000000400710003900000000006704350000006006500039000000000606043300001ba706600197000000600710003900000000006704350000008006500039000000000606043300000080071000390000000000670435000000a0055000390000000005050433000000a0061000390000000000560435000000c0011000390000000104400039000000000034004b000021280000413d00000000040004140000001d02000029000000040020008c000021500000c13d0000000103000031000000200030008c00000020040000390000000004034019000021820000013d0000000001b1004900001ba40010009c00001ba401008041000000600110021000001ba400b0009c00001ba40300004100000000030b40190000004003300210000000000131019f00001ba40040009c00001ba404008041000000c003400210000000000131019f001d0000000b001d6e8b6e810000040f0000001d0b0000290000000003010019000000600330027000001ba403300197000000200030008c000000200400003900000000040340190000001f0640018f000000200740019000000000057b0019000021700000613d000000000801034f00000000090b0019000000008a08043c0000000009a90436000000000059004b0000216c0000c13d000000000006004b0000217d0000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f0000000000650435000100000003001f000300000001035500000001002001900000001e0d000029000024310000613d0000001f01400039000000600210018f0000000001b20019000000000021004b0000000002000039000000010200403900001bce0010009c000024250000213d0000000100200190000024250000c13d000000400010043f000000200030008c00001d0f0000413d00000000010b043300001c3f0010019800001d0f0000c13d000000600100003900000015020000290000000000120435000000400100043d001c00000001001d00001ba80010009c000024250000213d0000001c020000290000004001200039000000400010043f000000010100003900000000021204360000000201000367000000000600003100000013030000290000000000320435000000400200043d001d00000002001d00001ba80020009c000024250000213d0000000102000029000000050220027000000000050200310000002c020000290000001d040000290000004007400039000000400070043f00000001030000390000000008340436000000400700043d00001c3a0070009c000024250000213d0000008009700039000000400090043f000000600970003900000000000904350000004009700039000000000009043500000020097000390000000000090435000000000007043500000000007804350000001607100360000000000707043b00001ba70070009c00001d0f0000213d000000400900043d00001c3a0090009c000024250000213d000000800a9000390000004000a0043f000000050050008c000024820000213d000000200a90003900000000007a043500000000005904350000001603000029000000200a300039000000000aa1034f000000000a0a043b000000400b9000390000000000ab0435000000400a300039000000000ba1034f000000000b0b043b000000600c9000390000000000bc04350000001d03000029000000000b03043300000000000b004b0000233e0000613d00000000009804350000000009d600490000012008a00039000000000881034f000000000808043b0000001f0990008a00001c0d0a90019700001c0d0b800197000000000cab013f0000000000ab004b000000000a00001900001c0d0a004041000000000098004b000000000900001900001c0d0900804100001c0d00c0009c000000000a09c01900000000000a004b00001d0f0000c13d000000000cd800190000000008c1034f000000000808043b00001bce0080009c00001d0f0000213d000000060980021000000000069600490000002009c0003900001c0d0a60019700001c0d0b900197000000000dab013f0000000000ab004b000000000a00001900001c0d0a004041000000000069004b000000000600001900001c0d0600204100001c0d00d0009c000000000a06c01900000000000a004b00001d0f0000c13d00001c390080009c000024250000213d000000010b800039000000050ab002100000003f06a0003900001c0e0d600197000000400600043d000000000dd6001900000000006d004b000000000e000039000000010e00403900001bce00d0009c000024250000213d0000000100e00190000024250000c13d0000004000d0043f000000000bb60436000000000d000019000000400e00043d00001bb400e0009c000024250000213d000000a00fe000390000004000f0043f000000800fe0003900000000000f0435000000600fe0003900000000000f0435000000400fe0003900000000000f0435000000200fe0003900000000000f043500000000000e0435000000000fbd00190000000000ef04350000001e03000029000000200dd000390000000000ad004b000022130000413d000000000a31034f000000000e0a043b00001ba700e0009c00001d0f0000213d000000120a100360000000000a0a043b00001ba700a0009c00001d0f0000213d000000400f00043d00001bb400f0009c000024250000213d000000a00df000390000004000d0043f000000050020008c000024820000213d000000200df000390000000000ed043500000000002f04350000000d0d100360000000000d0d043b0000004003f000390000000000d304350000001003100360000000000303043b0000008004f000390000000000a404350000006004f0003900000000003404350000000003060433000000000003004b0000233e0000613d0000000000fb0435000000010050008c0000000102006039000000050020008c000023160000a13d000000000008004b0000241d0000c13d000000280000002a000024820000c13d0000003102000029000000030020008c00000000020000390000000102006039000000260000002a0000002702006029000000000002004b000023880000613d0000000f02100360000000000202043b00001ba70020009c00001d0f0000213d0000000003000411000000000023004b000023880000613d000000400900043d00001c3d0090009c000024250000213d0000014003900039000000400030043f0000008007900039000000000067043500000060089000390000001d03000029000000000038043500001ba703a00197000000400a90003900000000003a04350000001303000029000000000b390436000000000300041100000000003b0435000000400400043d00001c3b0040009c000024250000213d0000002003400039000000400030043f0000000000040435000000c0059000390000001c030000290000000000350435000000a00690003900000000004604350000000f0d000029000000a003d00039000000000331034f000000000403043b000000e0039000390000000000430435000000c004d00039000000000441034f000000000c04043b00000100049000390000000000c40435000000e00cd000390000000001c1034f000000000c01043b00000120019000390000000000c1043500001c4d0c000041000000400f00043d0000000000cf0435000000040cf00039000000200d0000390000000000dc04350000000009090433000000240cf0003900000000009c043500000000090b043300001ba709900197000000440bf0003900000000009b043500000000090a043300001ba709900197000000640af0003900000000009a043500000000090804330000014008000039000000840af0003900000000008a04350000016408f00039000000000a0904330000000000a804350000018408f0003900000000000a004b000022bb0000613d000000000b0000190000002009900039000000000c09043300000000de0c04340000000500e0008c000024820000213d000000000ee80436000000000d0d043300001ba70dd001970000000000de0435000000400dc00039000000000d0d0433000000400e8000390000000000de0435000000600cc00039000000000c0c0433000000600d8000390000000000cd04350000008008800039000000010bb000390000000000ab004b000022a60000413d0000000009f80049000000240a90008a0000000009070433000000a407f000390000000000a70435000000000a0904330000000007a8043600000000000a004b000022df0000613d00000000080000190000002009900039000000000b09043300000000cd0b04340000000500d0008c000024820000213d000000000dd70436000000000c0c043300001ba70cc001970000000000cd0435000000400cb00039000000000c0c0433000000400d7000390000000000cd0435000000600cb00039000000000c0c0433000000600d7000390000000000cd0435000000800bb00039000000000b0b043300001ba70bb00197000000800c7000390000000000bc0435000000a00770003900000001088000390000000000a8004b000022c50000413d0000000008f70049000000240880008a0000000006060433000000c409f00039000000000089043500000000980604340000000006870436000000000008004b000022f00000613d0000000007000019000000000a670019000000000b790019000000000b0b04330000000000ba04350000002007700039000000000087004b000022e90000413d000000000786001900000000000704350000001f0780003900001c2b0770019700000000087600190000000006f80049000000240760008a0000000006050433000000e405f00039000000000075043500000000070604330000000005780436000000000007004b000023050000613d00000000080000190000002006600039000000000906043300000000059504360000000108800039000000000078004b000022ff0000413d00000000030304330000010406f00039000000000036043500000000030404330000012404f0003900000000003404350000014403f00039000000000101043300000000001304350000000001000414000000040020008c000023440000c13d0000000103000031000000200030008c00000020040000390000000004034019000023750000013d000000010050008c00000000070ec019000000000d00601900001ba7057001970000000007000019000000000087004b0000224d0000813d0000000603700210000000000e9300190000002003e00039000000000331034f000000000f03043b00001ba700f0009c00001d0f0000213d000000400c00043d00001bb400c0009c000024250000213d000000a003c00039000000400030043f0000004003c000390000000000d304350000002003c00039000000000053043500000000002c04350000000003e1034f000000000303043b0000008004c000390000000000f404350000006004c00039000000000034043500000001077000390000000003060433000000000073004b0000233e0000a13d00000005037002100000000003b300190000000000c304350000000003060433000000000073004b0000231b0000213d00001c1401000041000000000010043f0000003201000039000000040010043f00001c150100004100006e8d000104300000000003f5004900001ba40030009c00001ba403008041000000600330021000001ba400f0009c00001ba40400004100000000040f40190000004004400210000000000343019f00001ba40010009c00001ba401008041000000c001100210000000000131019f001e0000000f001d6e8b6e810000040f0000001e0f0000290000000003010019000000600330027000001ba403300197000000200030008c000000200400003900000000040340190000001f0640018f000000200740019000000000057f0019000023640000613d000000000801034f00000000090f0019000000008a08043c0000000009a90436000000000059004b000023600000c13d000000000006004b000023710000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f0000000000650435000100000003001f00030000000103550000000100200190000024560000613d0000001f01400039000000600210018f0000000001f20019000000000021004b0000000002000039000000010200403900001bce0010009c000024250000213d0000000100200190000024250000c13d000000400010043f000000200030008c00001d0f0000413d00000000020f043300001c3f0020019800001d0f0000c13d00001c400220019700001c4d0020009c0000244f0000c13d0000000101000039000000000011041b000000000001042d00001ba40020009c00001ba402008041000000c00120021000001bcd011001c7000080090200003900000000050000196e8b6e810000040f0000001e0d000029000000010220018f0003000000010355000000600110027000011ba40010019d00001ba401100197000000000001004b000023c00000613d0000001f0310003900001c2b033001970000003f0330003900001c2b04300197000000400300043d0000000004430019000000000034004b0000000005000039000000010500403900001bce0040009c000024250000213d0000000100500190000024250000c13d000000400040043f000000000613043600001c2b031001980000001f0410018f00000000013600190000000305000367000023b30000613d000000000705034f000000007807043c0000000006860436000000000016004b000023af0000c13d000000000004004b000023c00000613d000000000335034f0000000304400210000000000501043300000000054501cf000000000545022f000000000303043b0000010004400089000000000343022f00000000034301cf000000000353019f0000000000310435000000000002004b0000001d03000029000020b10000c13d000000400100043d0000002402100039000000000032043500001e280000013d000000400100043d00001c4702000041000023cc0000013d000000400100043d00001c4602000041000000000021043500001ba40010009c00001ba401008041000000400110021000001bd6011001c700006e8d00010430000000400100043d00000024021000390000001c03000029000000000032043500001c4502000041000000000021043500000004021000390000001b03000029000000000032043500001ba40010009c00001ba401008041000000400110021000001c36011001c700006e8d00010430000000000001042f00001c1401000041000000000010043f0000001101000039000000040010043f00001c150100004100006e8d00010430000000400100043d00001c5002000041000023cc0000013d000000400100043d00001c2302000041000023cc0000013d000000400100043d0000002402100039000000000052043500001c350200004100000000002104350000000402100039000023da0000013d00001c4f01000041000000000013043500001ba40030009c00001ba403008041000000400130021000001bd6011001c700006e8d00010430000000400100043d00001c1e02000041000024000000013d000000400100043d00001c4302000041000000000021043500000004021000390000001b03000029000000000032043500001ba40010009c00001ba401008041000000400110021000001c15011001c700006e8d00010430000000400100043d00000024021000390000001403000029000000000032043500001c4502000041000000000021043500000004021000390000001c03000029000023da0000013d00001c4c0100004100000000001b04350000001c0100002900000000001304350000001d01000029000000000014043500001ba400b0009c00001ba40b0080410000004001b0021000001c36011001c700006e8d000104300000004002c00039000000000121034f000000000101043b00001ba70010009c00001d0f0000213d000000400100043d00001bb40010009c000024800000a13d00001c1401000041000000000010043f0000004101000039000000040010043f00001c150100004100006e8d00010430000000400100043d00001bf402000041000000000021043500000004021000390000000000020435000024040000013d0000001f0530018f00001ba606300198000000400200043d00000000046200190000243c0000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000024380000c13d000000000005004b000024490000613d000000000161034f0000000305500210000000000604043300000000065601cf000000000656022f000000000101043b0000010005500089000000000151022f00000000015101cf000000000161019f0000000000140435000000600130021000001ba40020009c00001ba4020080410000004002200210000000000112019f00006e8d0001043000001c4102000041000000000021043500000004021000390000002503000029000024030000013d00001c4102000041000024000000013d0000001f0530018f00001ba606300198000000400200043d00000000046200190000246d0000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b0000245d0000c13d0000246d0000013d0000001f0530018f00001ba606300198000000400200043d00000000046200190000246d0000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000024690000c13d000000000005004b0000247a0000613d000000000161034f0000000305500210000000000604043300000000065601cf000000000656022f000000000101043b0000010005500089000000000151022f00000000015101cf000000000161019f0000000000140435000000600130021000001ba40020009c00001ba4020080410000004002200210000000000121019f00006e8d00010430000000a001100039000000400010043f00001c1401000041000000000010043f0000002101000039000000040010043f00001c150100004100006e8d000104300000000203000367000000000223034f000000000402043b000000000200003100000000051200490000001f0550008a00001c0d0650019700001c0d07400197000000000867013f000000000067004b000000000600001900001c0d06002041000000000054004b000000000500001900001c0d0500404100001c0d0080009c000000000605c019000000000006004b000024b10000613d0000000004140019000000000143034f000000000101043b00001bce0010009c000024b10000213d00001c2d031000d100000000022300190000002003400039000000000023004b000000000400001900001c0d0400204100001c0d0220019700001c0d03300197000000000523013f000000000023004b000000000200001900001c0d0200404100001c0d0050009c000000000204c019000000000002004b000024b10000c13d000000000001042d000000000100001900006e8d0001043000001c310020009c0000252e0000813d00000005052002100000003f0450003900001c0e06400197000000400400043d0000000006640019000000000046004b0000000007000039000000010700403900001bce0060009c0000252e0000213d00000001007001900000252e0000c13d000000400060043f00000000002404350000000002150019000000000032004b0000252c0000213d000000000012004b0000252a0000a13d000000020500036700000000060400190000000007010019000024d30000013d0000002006600039000000800a80003900000000009a043500000000008604350000002007700039000000000027004b0000252a0000813d000000000875034f000000000808043b00001bce0080009c0000252c0000213d0000000009180019000000000893004900001c0f0080009c0000252c0000213d000000a00080008c0000252c0000413d000000400800043d00001bb40080009c0000252e0000213d000000a00a8000390000004000a0043f000000000a95034f000000000a0a043b000000000ba80436000000200a900039000000000ca5034f000000000c0c043b0000000100c0008c0000252c0000213d0000000000cb0435000000200ba00039000000000bb5034f000000000b0b043b000000400c8000390000000000bc0435000000400ba00039000000000bb5034f000000000b0b043b000000600c8000390000000000bc0435000000600aa00039000000000aa5034f000000000a0a043b00001bce00a0009c0000252c0000213d000000000a9a00190000001f09a00039000000000039004b000000000b00001900001c0d0b00804100001c0d0990019700001c0d0c300197000000000dc9013f0000000000c9004b000000000900001900001c0d0900404100001c0d00d0009c00000000090bc019000000000009004b0000252c0000c13d0000000009a5034f000000000b09043b00001bce00b0009c0000252e0000213d000000050cb002100000003f09c0003900001c0e0d900197000000400900043d000000000dd9001900000000009d004b000000000e000039000000010e00403900001bce00d0009c0000252e0000213d0000000100e001900000252e0000c13d0000004000d0043f0000000000b90435000000200aa00039000000000bca001900000000003b004b0000252c0000213d0000000000ba004b000024cc0000813d000000000c090019000000000da5034f000000000d0d043b000000200cc000390000000000dc0435000000200aa000390000000000ba004b000025220000413d000024cc0000013d0000000001040019000000000001042d000000000100001900006e8d0001043000001c1401000041000000000010043f0000004101000039000000040010043f00001c150100004100006e8d0001043000001ba701100197000000000010043f0000000201000039000000200010043f000000000100041400001ba40010009c00001ba401008041000000c00110021000001c17011001c700008010020000396e8b6e860000040f0000000100200190000025440000613d000000000101043b000000000101041a000000000001042d000000000100001900006e8d00010430000d000000000002000300000002001d000400000001001d0000004001100039000a00000001001d0000000001010433000000000101043300001c310010009c000027240000813d00000005021002100000003f0320003900001c0e03300197000000400700043d0000000003370019000000000073004b0000000004000039000000010400403900001bce0030009c000027240000213d0000000100400190000027240000c13d000000400030043f0000000001170436000700000001001d0000001f0320018f00000000010000310000000201100367000000000002004b0000256a0000613d00000007050000290000000002250019000000000401034f000000004604043c0000000005650436000000000025004b000025660000c13d000000000003004b00000004020000290000014002200039000900000002001d000000000302043300001bce0030009c000027240000213d00000005023002100000003f0420003900001c0e04400197000000400600043d0000000004460019000000000064004b0000000005000039000000010500403900001bce0040009c000027240000213d0000000100500190000027240000c13d000000400040043f0000000003360436000600000003001d0000001f0320018f000000000002004b000025890000613d00000006040000290000000002240019000000001501043c0000000004540436000000000024004b000025850000c13d000d00000007001d000800000006001d000000000003004b00001c100100004100000000001004430000000001000412000000040010044300000060010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f0000000100200190000027320000613d000000000101043b000500000001001d0000000a0100002900000000010104330000000002010433000000000002004b000025e80000613d0000000004000019000b0005004002180000000b01100029000000200110003900000000010104330000000032010434000000060020008c0000272c0000813d000c00000004001d0000000003030433000000400410003900000000040404330000006005100039000000000505043300000080011000390000000006010433000000400100043d000000c0071000390000000000670435000000a0061000390000000000560435000000800510003900000000004504350000004004100039000000000024043500001ba70230019700000060031000390000000000230435000000200210003900000005030000290000000000320435000000c003000039000000000031043500001c120010009c000027240000213d000000e003100039000000400030043f00001ba40020009c00001ba4020080410000004002200210000000000101043300001ba40010009c00001ba4010080410000006001100210000000000121019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f00000001002001900000272a0000613d0000000d0200002900000000020204330000000c04000029000000000042004b0000271e0000a13d0000000b030000290000000702300029000000000101043b000000000012043500000001044000390000000a0100002900000000010104330000000002010433000000000024004b000025a30000413d00001c100100004100000000001004430000000001000412000000040010044300000080010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f0000000100200190000027320000613d000000000101043b000a00000001001d00000009010000290000000001010433000000000001004b0000000d07000029000026500000613d0000000401000029000700600010003d0000000004000019000000070100002900000000010104330000000002010433000000000042004b0000271e0000a13d000b0005004002180000000b01100029000000200110003900000000010104330000000032010434000000050020008c0000272c0000213d000c00000004001d0000000003030433000000a0041000390000000004040433000000400510003900000000050504330000006006100039000000000606043300000080011000390000000007010433000000400100043d000000c0081000390000000000780435000000a0071000390000000000670435000000800610003900000000005604350000004005100039000000000025043500001ba702400197000000e004100039000000000024043500001ba7023001970000006003100039000000000023043500000020021000390000000a030000290000000000320435000000e003000039000000000031043500001c130010009c000027240000213d0000010003100039000000400030043f00001ba40020009c00001ba4020080410000004002200210000000000101043300001ba40010009c00001ba4010080410000006001100210000000000121019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f00000001002001900000272a0000613d000000080200002900000000020204330000000c04000029000000000042004b0000000d070000290000271e0000a13d0000000b030000290000000602300029000000000101043b0000000000120435000000010440003900000009010000290000000001010433000000000014004b000026010000413d000000400100043d000000200210003900000004030000290000000034030434000d00000004001d0000000003030433000c00000003001d0000000003070433000000000003004b0000000004020019000026630000613d000000000500001900000000040200190000002007700039000000000607043300000000046404360000000105500039000000000035004b0000265d0000413d0000000003140049000000200430008a00000000004104350000001f0330003900001c2b043001970000000003140019000000000043004b0000000004000039000000010400403900001bce0030009c000027240000213d0000000100400190000027240000c13d000000400030043f00001ba40020009c00001ba4020080410000004002200210000000000101043300001ba40010009c00001ba4010080410000006001100210000000000121019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f00000001002001900000272a0000613d000000400200043d0000002003200039000000000101043b000b00000001001d00000008070000290000000001070433000000000001004b0000000004030019000026940000613d000000000500001900000000040300190000002007700039000000000607043300000000046404360000000105500039000000000015004b0000268e0000413d0000000001240049000000200410008a00000000004204350000001f0110003900001c2b041001970000000001240019000000000041004b0000000004000039000000010400403900001bce0010009c000027240000213d0000000100400190000027240000c13d000000400010043f00001ba40030009c00001ba4030080410000004001300210000000000202043300001ba40020009c00001ba4020080410000006002200210000000000112019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f00000001002001900000272a0000613d000000000101043b000a00000001001d000000040100002900000080011000390000000001010433000900000001001d000000040010008c0000272c0000213d000000040200002900000120012000390000000001010433000100000001001d00000100012000390000000001010433000200000001001d000000e0012000390000000001010433000500000001001d000000c0012000390000000001010433000600000001001d000000a0012000390000000001010433000700000001001d000000400100043d000800000001001d00001c1001000041000000000010044300000000010004120000000400100443000000a0010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f0000000100200190000027320000613d0000000d0200002900001ba7022001970000000c0300002900001ba703300197000000000401043b0000000806000029000001800160003900000003050000290000000000510435000001600160003900000001050000290000000000510435000001400160003900000002050000290000000000510435000001200160003900000005050000290000000000510435000001000160003900000006050000290000000000510435000000e00160003900000007050000290000000000510435000000c00160003900000009050000290000000000510435000000a0016000390000000a05000029000000000051043500000080016000390000000b0500002900000000005104350000006001600039000000000031043500000040016000390000000000210435000000200160003900000000004104350000018002000039000000000026043500001c160060009c000027240000213d000001a002600039000000400020043f00001ba40010009c00001ba4010080410000004001100210000000000206043300001ba40020009c00001ba4020080410000006002200210000000000112019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f00000001002001900000272a0000613d000000000101043b000000000001042d00001c1401000041000000000010043f0000003201000039000000040010043f00001c150100004100006e8d0001043000001c1401000041000000000010043f0000004101000039000000040010043f00001c150100004100006e8d00010430000000000100001900006e8d0001043000001c1401000041000000000010043f0000002101000039000000040010043f00001c150100004100006e8d00010430000000000001042f000000400100043d00001c380010009c000027470000813d000000e002100039000000400020043f000000c00210003900000060030000390000000000320435000000a0021000390000000000320435000000400210003900000000003204350000002002100039000000000032043500000080021000390000000000020435000000600210003900000000000204350000000000010435000000000001042d00001c1401000041000000000010043f0000004101000039000000040010043f00001c150100004100006e8d00010430000d000000000002000200000001001d0000000021010434000100000002001d000300000001001d00001c310010009c000028c90000813d000000030100002900000005011002100000003f0210003900001c0e02200197000000400300043d0000000002230019000800000003001d000000000032004b0000000003000039000000010300403900001bce0020009c000028c90000213d0000000100300190000028c90000c13d000000400020043f000000030200002900000008030000290000000003230436000700000003001d000000000002004b000028c10000613d00000000020000190000006005000039000000400300043d00001c120030009c000028c90000213d000000e004300039000000400040043f000000c0043000390000000000540435000000a0043000390000000000540435000000400430003900000000005404350000002004300039000000000054043500000080043000390000000000040435000000600430003900000000000404350000000000030435000000070420002900000000003404350000002002200039000000000012004b0000276b0000413d0000000001000031000400020010036b000000000200001900000002010000290000000001010433000a00000002001d000000000021004b000028c30000a13d000000400100043d00001c120010009c000028c90000213d0000000a020000290000000503200210000600000003001d0000000102300029000000000202043300000000240204340000000002020433000500000002001d000000e002100039000000400020043f000000c00210003900000060030000390000000000320435000000a0021000390000000000320435000000400210003900000000003204350000002002100039000000000032043500000080021000390000000000020435000000600210003900000000000204350000000000010435000900000004001d0000004001400039000000000401043300000000e204043400001bce0020009c000028c90000213d00000005012002100000003f0310003900001c0e03300197000000400c00043d00000000033c00190000000000c3004b0000000005000039000000010500403900001bce0030009c000028c90000213d0000000100500190000028c90000c13d000000400030043f00000000032c0436000000000002004b000027cd0000613d0000000002000019000000400500043d00001c3a0050009c000028c90000213d0000008006500039000000400060043f0000006006500039000000000006043500000040065000390000000000060435000000200650003900000000000604350000000000050435000000000623001900000000005604350000002002200039000000000012004b000027bc0000413d000000000104043300001bce0010009c000028c90000213d00000005021002100000003f0520003900001c0e05500197000000400600043d0000000005560019000d00000006001d000000000065004b0000000006000039000000010600403900001bce0050009c000028c90000213d0000000100600190000028c90000c13d000000400050043f0000000d050000290000000001150436000000000002004b000027e90000613d0000000005210019000000040600035f0000000007010019000000006806043c0000000007870436000000000057004b000027e50000c13d0000001f002001900000000002040433000000000002004b000028190000613d0000000005000019000000050250021000000000062e0019000000000a06043300000000b90a0434000000060090008c000028cf0000813d000000400700043d00001c3a0070009c000028c90000213d0000006006a0003900000000080b0433000000400aa00039000000000a0a0433000000000b060433000000800f7000390000004000f0043f000000600f7000390000000000bf0435000000400b7000390000000000ab043500001ba708800197000000200a70003900000000008a0435000000000097043500000000080c0433000000000058004b000028c30000a13d0000000008230019000000000078043500000000070c0433000000000057004b000028c30000a13d0000000d070000290000000007070433000000000057004b000028c30000a13d00000000021200190000000006060433000000000062043500000001055000390000000002040433000000000025004b000027ee0000413d000000090100002900000060011000390000000001010433000c00000001001d0000000012010434000b00000001001d00001bce0020009c000028c90000213d00000005012002100000003f0310003900001c0e03300197000000400e00043d00000000033e00190000000000e3004b0000000005000039000000010500403900001bce0030009c000028c90000213d0000000100500190000028c90000c13d000000400030043f00000000032e0436000000000002004b000028450000613d0000000002000019000000400500043d00001bb40050009c000028c90000213d000000a006500039000000400060043f000000800650003900000000000604350000006006500039000000000006043500000040065000390000000000060435000000200650003900000000000604350000000000050435000000000623001900000000005604350000002002200039000000000012004b000028320000413d0000000c01000029000000000501043300001bce0050009c000028c90000213d00000005025002100000003f0120003900001c0e06100197000000400100043d0000000006610019000000000016004b0000000007000039000000010700403900001bce0060009c000028c90000213d0000000100700190000028c90000c13d000000400060043f0000000007510436000000000002004b000028600000613d0000000005270019000000040600035f0000000008070019000000006906043c0000000008980436000000000058004b0000285c0000c13d0000001f002001900000000c020000290000000002020433000000000002004b000028980000613d000000000500001900000005025002100000000b06200029000000000a06043300000000890a0434000000050090008c000028cf0000213d000000400b00043d00001bb400b0009c000028c90000213d0000006006a000390000000008080433000000400da00039000000000d0d04330000000004060433000000a00aa00039000000000a0a0433000000000f0c0019000000a00cb000390000004000c0043f00001ba70aa00197000000800cb000390000000000ac0435000000000c0f0019000000600ab0003900000000004a04350000004004b000390000000000d4043500001ba7048001970000002008b00039000000000048043500000000009b043500000000040e0433000000000054004b000028c30000a13d00000000042300190000000000b4043500000000040e0433000000000054004b000028c30000a13d0000000004010433000000000054004b000028c30000a13d00000000027200190000000004060433000000000042043500000001055000390000000c020000290000000002020433000000000025004b000028660000413d000000400200043d00001c120020009c000028c90000213d000000050300002900001c1f033001970000000905000029000000000405043300000120055000390000000005050433000000e006200039000000400060043f000000c0062000390000000000160435000000a0012000390000000d060000290000000000610435000000800120003900000000003104350000006001200039000000000051043500000040012000390000000000e1043500000020012000390000000000c1043500001ba7014001970000000000120435000000080100002900000000010104330000000a0010006c000028c30000a13d000000060300002900000007013000290000000000210435000000080100002900000000010104330000000a0010006c000028c30000a13d0000000a020000290000000102200039000000030020006c000027850000413d0000000801000029000000000001042d00001c1401000041000000000010043f0000003201000039000000040010043f00001c150100004100006e8d0001043000001c1401000041000000000010043f0000004101000039000000040010043f00001c150100004100006e8d0001043000001c1401000041000000000010043f0000002101000039000000040010043f00001c150100004100006e8d00010430000f000000000002000400000008001d000700000007001d000e00000006001d000f00000004001d000300000001001d000000800020043f000000a00090043f000000400400043d00001c520040009c00002c720000813d0000006001400039000000400010043f00000020014000390000000000a104350000000000040435000000a00100043d00001ba70110019700000040024000390000000000120435000000800200043d0000000301000029000d00000005001d6e8b4b140000040f0000000d04000029000100000001001d000200000002001d00001bce0040009c00002c720000213d00000005014002100000003f0210003900001c0e02200197000000400900043d0000000002290019000000000092004b0000000003000039000000010300403900001bce0020009c00002c720000213d000000010030019000002c720000c13d0000000003000031000000400020043f000000000a4904360000000f01100029000000000031004b00002c7e0000213d0000000f0010006c000029530000a13d000000020200036700001c0d0430019700000000050900190000000f06000029000029100000013d000000200550003900000000007504350000002006600039000000000016004b000029530000813d000000000762034f000000000707043b00001bce0070009c00002c7e0000213d0000000f087000290000001f07800039000000000037004b000000000b00001900001c0d0b00804100001c0d07700197000000000c47013f000000000047004b000000000700001900001c0d0700404100001c0d00c0009c00000000070bc019000000000007004b00002c7e0000c13d000000000782034f000000000b07043b00001bce00b0009c00002c720000213d0000000507b002100000003f0770003900001c0e0c700197000000400700043d000000000cc7001900000000007c004b000000000d000039000000010d00403900001bce00c0009c00002c720000213d0000000100d0019000002c720000c13d00000020088000390000004000c0043f0000000000b70435000000060bb00210000000000b8b001900000000003b004b00002c7e0000213d00000000008b004b0000290b0000a13d000000000c070019000000000d83004900001c0f00d0009c00002c7e0000213d0000004000d0008c00002c7e0000413d000000400d00043d00001ba800d0009c00002c720000213d000000200cc00039000000400ed000390000004000e0043f000000000e82034f000000000e0e043b000000000eed0436000000200f800039000000000ff2034f000000000f0f043b0000000000fe04350000000000dc043500000040088000390000000000b8004b0000293c0000413d0000290b0000013d000000070100002900001bce0010009c00002c720000213d000000070100002900000005011002100000003f0210003900001c0e02200197000000400400043d0000000002240019000600000004001d000000000042004b0000000004000039000000010400403900001bce0020009c00002c720000213d000000010040019000002c720000c13d000000400020043f000000070200002900000006040000290000000002240436000500000002001d0000000e01100029000000000031004b00002c7e0000213d0000000e06000029000000000061004b000029be0000a13d000000020200036700001c0d043001970000000605000029000029780000013d000000200550003900000000007504350000002006600039000000000016004b000029bb0000813d000000000762034f000000000707043b00001bce0070009c00002c7e0000213d0000000e087000290000001f07800039000000000037004b000000000b00001900001c0d0b00804100001c0d07700197000000000c47013f000000000047004b000000000700001900001c0d0700404100001c0d00c0009c00000000070bc019000000000007004b00002c7e0000c13d000000000782034f000000000b07043b00001bce00b0009c00002c720000213d0000000507b002100000003f0770003900001c0e0c700197000000400700043d000000000cc7001900000000007c004b000000000d000039000000010d00403900001bce00c0009c00002c720000213d0000000100d0019000002c720000c13d00000020088000390000004000c0043f0000000000b70435000000060bb00210000000000b8b001900000000003b004b00002c7e0000213d00000000008b004b000029730000a13d000000000c070019000000000d83004900001c0f00d0009c00002c7e0000213d0000004000d0008c00002c7e0000413d000000400d00043d00001ba800d0009c00002c720000213d000000200cc00039000000400ed000390000004000e0043f000000000e82034f000000000e0e043b000000000eed0436000000200f800039000000000ff2034f000000000f0f043b0000000000fe04350000000000dc043500000040088000390000000000b8004b000029a40000413d000029730000013d00000006010000290000000001010433000700000001001d0000000002090433000800000002001d000000070020002a00002cb30000413d0000000802000029000000070220002900001bce0020009c00002c720000213d00000005012002100000003f0310003900001c0e03300197000000400400043d0000000003340019000b00000004001d000000000043004b0000000004000039000000010400403900001bce0030009c00002c720000213d000000010040019000002c720000c13d000000400030043f0000000b030000290000000003230436000900000003001d000000000002004b000029f50000613d0000000002000019000000400300043d00001bd10030009c00002c720000213d0000006004300039000000400040043f00001c130030009c00002c720000213d0000010005300039000000400050043f00000000000404350000000004430436000000e0053000390000000000050435000000c0053000390000000000050435000000a005300039000000000005043500000080053000390000000000050435000000400530003900000000000504350000000000040435000000090420002900000000003404350000002002200039000000000012004b000029da0000413d000001000000043f000000080000006b000000010c00003900002b100000613d00000000010000190000000002090433000000000012004b00002c780000a13d000000050110021000000000011a00190000000001010433000001200010043f000000400100043d00001bd10010009c00002c720000213d0000006002100039000000400020043f00001c130010009c00002c720000213d0000010003100039000000400030043f00000000000204350000000002210436000000e0031000390000000000030435000000c0031000390000000000030435000000a003100039000000000003043500000080031000390000000000030435000000400110003900000000000104350000000000020435000000400100043d000001200200043d0000000002020433000000000002004b00002ca40000613d00001bd10010009c00002c720000213d0000006002100039000000400020043f00001c130010009c00002c720000213d0000010003100039000000400030043f00000000000204350000000002210436000000e0031000390000000000030435000000c0031000390000000000030435000000a003100039000000000003043500000080031000390000000000030435000000400110003900000000000104350000000000020435000000400600043d00001bd10060009c00002c720000213d0000006001600039000000400010043f00001c130060009c00002c720000213d0000010002600039000000400020043f00000000000104350000000001160436000000e0026000390000000000020435000000c0026000390000000000020435000000a002600039000000000002043500000080026000390000000000020435000000400260003900000000000204350000000000010435000000c00000043f000000400100043d00001c120010009c00002c720000213d000000e002100039000000400020043f000000c00210003900000060030000390000000000320435000000a0021000390000000000320435000000400210003900000000003204350000002002100039000000000032043500000080021000390000000000020435000000600210003900000000000204350000000000010435000000e00000043f000001200500043d0000000001050433000000000001004b00002aff0000613d000000800700043d000000000400001900002a700000013d0000000001050433000000000001004b00000000010000390000000101006039000000e00010043f000000000005043500002c8f0000613d000001200500043d000000800700043d00000001044000390000000001050433000000000014004b00002aff0000813d000000050140021000000000021500190000002002200039000000000202043300000000320204340000000008070433000000000082004b00002c8f0000813d00000005022002100000000002720019000000200220003900000000020204330000008008200039000000000808043300001c1f0080019800002a6c0000613d000000000303043300000020082000390000000008080433000000000b0804330000000000b3004b00002a6c0000813d0000000503300210000000000383001900000020033000390000000003030433000000c00500043d000000000005004b00002abe0000613d0000006001300039000000000501043300000000780604340000006008800039000000000b0804330000000000b5001a00002cb30000413d0000000005b500190000000000580435000000400530003900000000080504330000000005060433000000400b500039000000000b0b043300000000008b004b00002c890000c13d00000000080204330000000007070433000000000778013f00001ba70070019800002c890000c13d0000006002200039000000000202043300000040076000390000000007070433000000000027004b00002c890000c13d0000000025050434000000060050008c00002c9e0000813d0000000037030434000000050070008c00002c9e0000213d000000000075004b00002c890000c13d000000000303043300000000050204330000000002010433000000000002004b00000000070000390000000107006039000000e00070043f000000000353013f00001ba70030019800002c8e0000c13d0000000000010435000000000002004b00002a6a0000c13d00002c8f0000013d000000c000c0043f0000000056030434000000050060008c00002c9e0000213d000000400700043d00001bb40070009c00002c720000213d00000000080504330000004005300039000000000b05043300000060053000390000000003050433000000a00c7000390000004000c0043f000000600c70003900000000003c0435000000010c00003900000040037000390000000000b3043500001ba7038001970000002008700039000000000038043500000000006704350000008003700039000000a00600043d00001ba7066001970000000000630435000000400600043d00001bd10060009c00002c720000213d0000000003020433000000600220003900000000020204330000006008600039000000400080043f0000004008600039000000000028043500001ba702300197000000200360003900000000002304350000000000760435000000000004004b00002a630000613d000001200200043d0000000032020434000000000002004b00002c780000613d000000000042004b00002c780000a13d0000000002030433000000000713001900000000070704330000000000730435000001200300043d0000000007030433000000000047004b00002c780000a13d000000000131001900000020011000390000000000210435000001200100043d0000000001010433000000000041004b00002a630000213d00002c780000013d0000000b010000290000000002010433000001000100043d000000000012004b00002c780000a13d0000000501100210000000090110002900000000006104350000000b010000290000000002010433000001000100043d000000000012004b00002c780000a13d0000000101100039000001000010043f000000080010006c000029fa0000413d000000070000006b00002c690000613d000000000900001900000006010000290000000001010433000000000091004b00002c780000a13d000000400100043d00001bd10010009c00002c720000213d00000005029002100000000502200029000000000b0204330000006002100039000000400020043f00001c130010009c00002c720000213d0000010003100039000000400030043f00000000000204350000000002210436000000e0031000390000000000030435000000c0031000390000000000030435000000a003100039000000000003043500000080031000390000000000030435000000400110003900000000000104350000000000020435000000400100043d00000000320b0434000a00000003001d000000000002004b00002ca90000613d00001bd10010009c00002c720000213d0000006002100039000000400020043f00001c130010009c00002c720000213d0000010003100039000000400030043f00000000000204350000000002210436000000e0031000390000000000030435000000c0031000390000000000030435000000a003100039000000000003043500000080031000390000000000030435000000400110003900000000000104350000000000020435000000400100043d00001bd10010009c00002c720000213d0000006002100039000000400020043f00001c130010009c00002c720000213d0000010003100039000000400030043f00000000000204350000000002210436000000e0031000390000000000030435000000c0031000390000000000030435000000a003100039000000000003043500000080031000390000000000030435000000400110003900000000000104350000000000020435000000400d00043d00001bb400d0009c00002c720000213d000000800e00043d000000a001d00039000000400010043f0000008001d0003900000000000104350000004001d0003900000000000104350000002001d00039000000000001043500000000000d04350000006001d000390000000000010435000000400600043d00001c3a0060009c00002c720000213d0000008002600039000000400020043f0000006002600039000d00000002001d0000000000020435000000400460003900000000000404350000000002060436000e00000002001d0000000000020435000000400200043d00001bb40020009c00002c720000213d000000a003200039000000400030043f000000800320003900000000000304350000006003200039000000000003043500000040032000390000000000030435000000200320003900000000000304350000000000020435000000400200043d00001c120020009c00002c720000213d000000e003200039000000400030043f000000c00320003900000060050000390000000000530435000000a003200039000000000053043500000040032000390000000000530435000000200320003900000000005304350000008003200039000000000003043500000060032000390000000000030435000000000002043500000000020b0433000000000002004b00002c400000613d000000200fe00039000f00000000001d00000000010000190000000a020000290000000e0a000029000c0000000f001d00002bbd0000013d0000000103a0018f00000000003404350000000e0a0000290000000c0f0000290000000003050433000000000003004b000000000300003900000001030060390000000d0700002900000000003704350000000007040433000000000007004b000000010330c1bf000000000034043500000000000504350000000003040433000000000003004b00002c800000c13d000000010110003900000000030b0433000000000031004b00002c3e0000813d0000000503100210000000000723001900000000030704330000000005030433000000000056043500000000030b0433000000000013004b00002c780000a13d00000000030704330000002003300039000000000303043300000000003a043500000000080e0433000000000085004b00000000080000390000000108008039000000000084043500002c800000813d00000000080e0433000000000058004b00002c780000a13d000000050550021000000000055f001900000000050504330000008008500039000000000808043300001c1f0080019800002bb90000613d000000400550003900000000050504330000000008050433000000000083004b00002bb90000813d00000005033002100000000003530019000000200330003900000000030304330000000f0000006b00002c0b0000613d0000006007d00039000000000a070433000000600530003900000000080504330000000000a8001a00002cb30000413d0000000008a8001900000000008704350000008007d00039000000000707043300000080083000390000000008080433000000000778013f00001ba700700198000000000a0c001900002ba70000c13d000000007a0d04340000000500a0008c00002c9e0000213d00000000f8030434000000050080008c00002c9e0000213d00000000008a004b000000000a0c001900002ba70000c13d000000000707043300000000080f0433000000000778013f00001ba700700198000000000a0c001900002ba70000c13d000000400330003900000000030304330000004007d000390000000007070433000000000037004b000000000a000039000000010a00c03900002ba70000013d0000000058030434000000050080008c00002c9e0000213d000000400d00043d00001bb400d0009c00002c720000213d0000000002090019000000000a0504330000004005300039000000000f0504330000008005300039000000000c05043300000060053000390000000003050433000000a009d00039000000400090043f00001ba709c00197000000800cd0003900000000009c04350000006009d0003900000000003904350000004003d000390000000000f3043500001ba703a001970000002009d00039000000000039043500000000008d0435000000000001004b00002c390000613d00000000030b0433000000000013004b000000010c00003900000000090200190000000a020000290000000e0a0000290000000c0f00002900002c780000a13d000000000302043300000000080704330000000000820435000000000037043500000000030b0433000000000013004b00002c780000a13d000f0000000c001d00002bab0000013d000000010c000039000f0000000c001d00000000090200190000000a0200002900002ba90000013d0000006001d0003900002c430000013d0000000002040433000000000002004b00002c800000c13d000000400200043d0000000001010433000000000001004b00002c4f0000613d00001bd10020009c00002c720000213d0000006001200039000000400010043f0000000000d204350000000001000411000000040300002900002c560000013d00001bd10020009c00002c720000213d0000006001200039000000400010043f0000000000d2043500000000010000190000000003000019000000400420003900000000003404350000002003200039000000000013043500000008019000290000000b030000290000000003030433000000000013004b00002c780000a13d0000000503100210000000090330002900000000002304350000000b020000290000000002020433000000000012004b00002c780000a13d0000000109900039000000070090006c00002b130000413d000000800200043d000000a00500043d00000003010000290000000b03000029000000010400002900000002060000296e8b62c60000040f0000000b02000029000000000001042d00001c1401000041000000000010043f0000004101000039000000040010043f00001c150100004100006e8d0001043000001c1401000041000000000010043f0000003201000039000000040010043f00001c150100004100006e8d00010430000000000100001900006e8d00010430000000400200043d00001ba40020009c00001ba4010000410000000001024019000000400110021000001bd6011001c70000000d03000029000000000303043300002c960000013d0000000002010433000000000002004b00000000020000390000000102006039000000e00020043f0000000000010435000000400200043d00001ba40020009c00001ba4010000410000000001024019000000400110021000001bd6011001c7000000e00300043d000000000003004b00002c9b0000c13d00001c5303000041000000000032043500006e8d0001043000001c4603000041000000000032043500006e8d0001043000001c1401000041000000000010043f0000002101000039000000040010043f00001c150100004100006e8d0001043000001c540200004100000000002104350000000402100039000000000002043500002cae0000013d00001c5402000041000000000021043500000004021000390000000103000039000000000032043500001ba40010009c00001ba401008041000000400110021000001c15011001c700006e8d0001043000001c1401000041000000000010043f0000001101000039000000040010043f00001c150100004100006e8d000104300009000000000002000800000001001d000400000002001d00001c310020009c00002ebf0000813d000000040100002900000005011002100000003f0210003900001c0e02200197000000400300043d0000000002230019000300000003001d000000000032004b0000000003000039000000010300403900001bce0020009c00002ebf0000213d000000010030019000002ebf0000c13d000000400020043f000000040200002900000003030000290000000004230436000700000004001d000000000002004b00002ebb0000613d00000000020000190000006006000039000000400300043d00001bb40030009c00002ebf0000213d000000a004300039000000400040043f00001c330030009c00002ebf0000213d0000020005300039000000400050043f000000000004043500000100053000390000000000650435000000e005300039000000000065043500000080053000390000000000650435000000600530003900000000006504350000000004430436000001e0053000390000000000050435000001c0053000390000000000050435000001a005300039000000000005043500000180053000390000000000050435000001600530003900000000000504350000014005300039000000000005043500000120053000390000000000050435000000c0053000390000000000050435000000400530003900000000000504350000000000040435000000070420002900000000003404350000002002200039000000000012004b00002cd50000413d0000000006000031000000080160006a00000002070003670000003f0110008a000200000001001d00011c0d0010019b0000000002000019000600000002001d0000000502200210000500000002001d0000000801200029000000000117034f000000000201043b00001c0d01200197000000010310014f000000010010006c000000000100001900001c0d01002041000000020020006c000000000400001900001c0d0400404100001c0d0030009c000000000104c019000000000001004b00002ebd0000613d000000400100043d00001bb40010009c00002ebf0000213d000000a003100039000000400030043f00001c330010009c00002ebf0000213d00000008022000290000020004100039000000400040043f0000000000030435000001000410003900000060050000390000000000540435000000e004100039000000000054043500000080041000390000000000540435000000600410003900000000005404350000000003310436000001e0041000390000000000040435000001c0041000390000000000040435000001a004100039000000000004043500000180041000390000000000040435000001600410003900000000000404350000014004100039000000000004043500000120041000390000000000040435000000c00410003900000000000404350000004001100039000000000001043500000000000304350000000003260049000000000127034f000000000101043b0000015f0430008a00001c0d0540019700001c0d08100197000000000958013f000000000058004b000000000500001900001c0d05004041000000000041004b000000000400001900001c0d0400804100001c0d0090009c000000000504c019000000000005004b00002ebd0000c13d0000002004200039000000000447034f000000000404043b0000001f0330008a00001c0d0540019700001c0d08300197000000000985013f000000000085004b000000000500001900001c0d05004041000000000034004b000000000300001900001c0d0300804100001c0d0090009c000000000503c019000000000005004b00002ebd0000c13d0000000003240019000000000437034f000000000e04043b00001bce00e0009c00002ebd0000213d0000000004e60049000000200a30003900001c0d0340019700001c0d05a00197000000000835013f000000000035004b000000000300001900001c0d0300404100000000004a004b000000000400001900001c0d0400204100001c0d0080009c000000000304c019000000000003004b00002ebd0000c13d000000400f00043d00001bb400f0009c00002ebf0000213d000000000b2100190000000001b60049000000a002f00039000900000002001d000000400020043f00001c0f0010009c00002ebd0000213d000001600010008c00002ebd0000413d00001c3300f0009c00002ebf0000213d0000020001f00039000000400010043f0000000001b7034f000000000101043b00001ba70010009c00002ebd0000213d000000090200002900000000001204350000002001b00039000000000217034f000000000202043b00001ba70020009c00002ebd0000213d000000c003f0003900000000002304350000002001100039000000000117034f000000000101043b00001bce0010009c00002ebd0000213d0000000001b100190000001f02100039000000000062004b000000000300001900001c0d0300804100001c0d0420019700001c0d02600197000000000524013f000000000024004b000000000400001900001c0d0400404100001c0d0050009c000000000403c019000000000004004b00002ebd0000c13d000000000317034f000000000303043b00001bce0030009c00002ebf0000213d00000005043002100000003f0440003900001c0e04400197000000400900043d0000000004490019000000000094004b0000000005000039000000010500403900001bce0040009c00002ebf0000213d000000010050019000002ebf0000c13d0000002001100039000000400040043f0000000000390435000000a0033000c90000000003130019000000000063004b00002ebd0000213d000000000013004b00002deb0000a13d0000000004090019000000000516004900001c0f0050009c00002ebd0000213d000000a00050008c00002ebd0000413d000000400500043d00001bb40050009c00002ebf0000213d000000a008500039000000400080043f000000000817034f000000000808043b000000050080008c00002ebd0000213d0000000008850436000000200d100039000000000cd7034f000000000c0c043b00001ba700c0009c00002ebd0000213d00000020044000390000000000c804350000002008d00039000000000887034f000000000808043b000000400c50003900000000008c04350000004008d00039000000000887034f000000000808043b000000600c50003900000000008c04350000006008d00039000000000887034f000000000808043b000000800c50003900000000008c04350000000000540435000000a001100039000000000031004b00002dc20000413d000000e001f0003900000000009104350000006001b00039000000000117034f000000000101043b00001bce0010009c00002ebd0000213d0000000001b100190000001f03100039000000000063004b000000000400001900001c0d0400804100001c0d03300197000000000523013f000000000023004b000000000200001900001c0d0200404100001c0d0050009c000000000204c019000000000002004b00002ebd0000c13d000000000217034f000000000302043b00001bce0030009c00002ebf0000213d00000005023002100000003f0220003900001c0e04200197000000400200043d0000000005420019000000000025004b0000000004000039000000010400403900001bce0050009c00002ebf0000213d000000010040019000002ebf0000c13d0000002004100039000000400050043f0000000000320435000000c0013000c90000000001410019000000000061004b00002ebd0000213d000000000041004b00002e4a0000a13d0000000003020019000000000546004900001c0f0050009c00002ebd0000213d000000c00050008c00002ebd0000413d000000400900043d00001bd40090009c00002ebf0000213d000000c005900039000000400050043f000000000547034f000000000505043b000000050050008c00002ebd0000213d00000000085904360000002005400039000000000c57034f000000000c0c043b00001ba700c0009c00002ebd0000213d0000000000c804350000002008500039000000000887034f000000000808043b000000400c90003900000000008c04350000004008500039000000000887034f000000000808043b000000600c90003900000000008c04350000006008500039000000000887034f000000000808043b000000800c90003900000000008c04350000008005500039000000000557034f000000000505043b00001ba70050009c00002ebd0000213d0000002003300039000000a00890003900000000005804350000000000930435000000c004400039000000000014004b00002e1a0000413d0000010001f0003900000000002104350000008001b00039000000000217034f000000000202043b000000040020008c00002ebd0000213d0000012003f0003900000000002304350000002002100039000000000227034f000000000202043b0000014003f0003900000000002304350000004002100039000000000227034f000000000202043b0000016003f0003900000000002304350000006002100039000000000227034f000000000202043b0000018003f0003900000000002304350000008002100039000000000227034f000000000202043b000001a003f000390000000000230435000000a002100039000000000227034f000000000202043b000001c003f000390000000000230435000000c001100039000000000117034f000000000101043b0000004002f00039000000010300003900000000003204350000002002f000390000000000320435000000090200002900000000002f0435000001e002f0003900000000001204350000001f01e0003900001c2b011001970000003f0110003900001c2b02100197000000400100043d0000000002210019000000000012004b0000000003000039000000010300403900001bce0020009c00002ebf0000213d000000010030019000002ebf0000c13d000000400020043f0000000002e104360000000003ae0019000000000063004b00002ebd0000213d0000000004a7034f00001c2b05e00198000000000352001900002e940000613d000000000804034f0000000009020019000000008a08043c0000000009a90436000000000039004b00002e900000c13d0000001f08e0019000002ea10000613d000000000454034f0000000305800210000000000803043300000000085801cf000000000858022f000000000404043b0000010005500089000000000454022f00000000045401cf000000000484019f00000000004304350000000002e2001900000000000204350000006002f000390000000000120435000000400100043d00001c3b0010009c00002ebf0000213d0000002002100039000000400020043f00000000000104350000008002f000390000000000120435000000030300002900000000010304330000000602000029000000000021004b00002ec50000a13d000000050400002900000007014000290000000000f104350000000001030433000000000021004b00002ec50000a13d0000000102200039000000040020006c00002d070000413d0000000001030019000000000001042d000000000100001900006e8d0001043000001c1401000041000000000010043f0000004101000039000000040010043f00001c150100004100006e8d0001043000001c1401000041000000000010043f0000003201000039000000040010043f00001c150100004100006e8d000104300015000000000002000300000005001d000700000004001d000a00000003001d000800000002001d000600000001001d0000000021010434000900000002001d000b00000001001d00001c310010009c000033b90000813d0000000b0100002900000005021002100000003f0120003900001c0e01100197000000400300043d0000000001130019001500000003001d000000000031004b0000000003000039000000010300403900001bce0010009c000033b90000213d0000000100300190000033b90000c13d000000400010043f00000015010000290000000b030000290000000001310436001400000001001d000000000003004b000030430000613d00000000010000190000006005000039000000400300043d00001c120030009c000033b90000213d000000e004300039000000400040043f000000c0043000390000000000540435000000a0043000390000000000540435000000400430003900000000005404350000002004300039000000000054043500000080043000390000000000040435000000600430003900000000000404350000000000030435000000140410002900000000003404350000002001100039000000000021004b00002eed0000413d0000000001000031000c00020010036b000000000200001900000006010000290000000001010433001000000002001d000000000021004b000033b30000a13d000000400100043d00001c120010009c000033b90000213d00000010020000290000000503200210000d00000003001d0000000902300029000000000202043300000000240204340000000002020433000e00000002001d000000e002100039000000400020043f000000c00210003900000060030000390000000000320435000000a0021000390000000000320435000000400210003900000000003204350000002002100039000000000032043500000080021000390000000000020435000000600210003900000000000204350000000000010435000f00000004001d0000004001400039000000000b01043300000000c20b043400001bce0020009c000033b90000213d00000005012002100000003f0310003900001c0e03300197000000400900043d0000000003390019000000000093004b0000000004000039000000010400403900001bce0030009c000033b90000213d0000000100400190000033b90000c13d000000400030043f000000000d290436000000000002004b00002f4f0000613d0000000002000019000000400300043d00001c3a0030009c000033b90000213d0000008004300039000000400040043f000000600430003900000000000404350000004004300039000000000004043500000020043000390000000000040435000000000003043500000000042d001900000000003404350000002002200039000000000012004b00002f3e0000413d00000000020b043300001bce0020009c000033b90000213d00000005012002100000003f0310003900001c0e03300197000000400400043d0000000003340019001300000004001d000000000043004b0000000004000039000000010400403900001bce0030009c000033b90000213d0000000100400190000033b90000c13d000000400030043f00000013030000290000000003230436000000000001004b00002f6b0000613d00000000021300190000000c0400035f0000000005030019000000004604043c0000000005650436000000000025004b00002f670000c13d0000001f0010019000000000010b0433000000000001004b00002f9b0000613d0000000002000019000000050120021000000000041c0019000000000704043300000000e8070434000000060080008c000033bf0000813d000000400600043d00001c3a0060009c000033b90000213d000000600470003900000000050e043300000040077000390000000007070433000000000e040433000000800f6000390000004000f0043f000000600f6000390000000000ef0435000000400e60003900000000007e043500001ba7055001970000002007600039000000000057043500000000008604350000000005090433000000000025004b000033b30000a13d00000000051d001900000000006504350000000005090433000000000025004b000033b30000a13d00000013050000290000000005050433000000000025004b000033b30000a13d000000000131001900000000040404330000000000410435000000010220003900000000010b0433000000000012004b00002f700000413d0000000f0100002900000060011000390000000001010433001200000001001d0000000012010434001100000001001d00001bce0020009c000033b90000213d00000005012002100000003f0310003900001c0e03300197000000400b00043d00000000033b00190000000000b3004b0000000004000039000000010400403900001bce0030009c000033b90000213d0000000100400190000033b90000c13d000000400030043f000000000e2b0436000000000002004b00002fc70000613d0000000002000019000000400300043d00001bb40030009c000033b90000213d000000a004300039000000400040043f00000080043000390000000000040435000000600430003900000000000404350000004004300039000000000004043500000020043000390000000000040435000000000003043500000000042e001900000000003404350000002002200039000000000012004b00002fb40000413d0000001201000029000000000201043300001bce0020009c000033b90000213d00000005012002100000003f0310003900001c0e03300197000000400f00043d00000000033f00190000000000f3004b0000000004000039000000010400403900001bce0030009c000033b90000213d0000000100400190000033b90000c13d000000400030043f00000000032f0436000000000001004b00002fe20000613d00000000021300190000000c0400035f0000000005030019000000004604043c0000000005650436000000000025004b00002fde0000c13d0000001f0010019000000012010000290000000001010433000000000001004b0000301a0000613d00000000020000190000000501200210000000110410002900000000070404330000000056070434000000050060008c000033bf0000213d000000400800043d00001bb40080009c000033b90000213d00000060047000390000000005050433000000400a700039000000000a0a0433000000000d040433000000a0077000390000000007070433000000000c090019000000a009800039000000400090043f00001ba7077001970000008009800039000000000079043500000000090c001900000060078000390000000000d7043500000040078000390000000000a7043500001ba70550019700000020078000390000000000570435000000000068043500000000050b0433000000000025004b000033b30000a13d00000000051e0019000000000085043500000000050b0433000000000025004b000033b30000a13d00000000050f0433000000000025004b000033b30000a13d000000000131001900000000040404330000000000410435000000010220003900000012010000290000000001010433000000000012004b00002fe80000413d000000400100043d00001c120010009c000033b90000213d0000000e0200002900001c1f022001970000000f04000029000000000304043300000120044000390000000004040433000000e005100039000000400050043f000000c0051000390000000000f50435000000a00510003900000013060000290000000000650435000000800510003900000000002504350000006002100039000000000042043500000040021000390000000000b204350000002002100039000000000092043500001ba702300197000000000021043500000015020000290000000002020433000000100020006c000033b30000a13d0000000d030000290000001402300029000000000012043500000015010000290000000001010433000000100010006c000033b30000a13d000000100200002900000001022000390000000b0020006c00002f070000413d000000400400043d00001bd10040009c000033b90000213d000000060100002900000000050104330000006002400039000000400020043f000000030200002900001ba702200197000000400340003900000000002304350000002002400039000000000052043500000001020000390000000000240435000000150200002900000008030000296e8b4b140000040f0000002004000039000000400300043d0000000004430436000200000002001d000000000201043300000000002404350000004007300039000000000002004b000100000001001d000030670000613d000000000400001900000000050100190000002005500039000000000605043300000000076704360000000104400039000000000024004b000030610000413d000000000137004900001ba40010009c00001ba401008041000000600110021000001ba40030009c00001ba4030080410000004002300210000000000121019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000121019f00001bcd011001c70000800d02000039000000010300003900001c55040000416e8b6e810000040f0000000100200190000033c50000613d000000070100002900001bce0010009c000033b90000213d000000070100002900000005011002100000003f0210003900001c0e02200197000000400300043d0000000002230019000b00000003001d000000000032004b0000000003000039000000010300403900001bce0020009c000033b90000213d0000000100300190000033b90000c13d000000400020043f00000007020000290000000b030000290000000003230436000900000003001d000000000002004b000033aa0000613d0000000002000019000000400300043d00001bd10030009c000033b90000213d0000006004300039000000400040043f00001c130030009c000033b90000213d0000010005300039000000400050043f00000000000404350000000004430436000000e0053000390000000000050435000000c0053000390000000000050435000000a005300039000000000005043500000080053000390000000000050435000000400530003900000000000504350000000000040435000000090420002900000000003404350000002002200039000000000012004b000030940000413d000000000c0000310000000a01c0006a00000002040003670000003f0110008a000500000001001d00041c0d0010019b000000000200001900100000000c001d000c000000040353000e00000002001d0000000502200210000800000002001d0000000a01200029000000000114034f000000000101043b00001c0d02100197000000040320014f000000040020006c000000000200001900001c0d02004041000000050010006c000000000500001900001c0d0500804100001c0d0030009c000000000205c019000000000002004b000033c50000c13d0000000a01100029000000000214034f000000000502043b00000000021c00490000001f0320008a00001c0d0630019700001c0d02500197000000000762013f000000000062004b000000000200001900001c0d02004041000000000035004b000000000800001900001c0d0800804100001c0d0070009c000000000208c019000000000002004b000033c50000c13d0000000005150019000000000254034f000000000702043b00001bce0070009c000033c50000213d000000060970021000000000029c0049000000200550003900001c0d0820019700001c0d0a500197000000000b8a013f00000000008a004b000000000800001900001c0d08004041000000000025004b000000000200001900001c0d0200204100001c0d00b0009c000000000802c019000000000008004b000033c50000c13d0000002002100039000000000224034f000000000802043b00001c0d02800197000000000a62013f000000000062004b000000000200001900001c0d02004041000000000038004b000000000300001900001c0d0300804100001c0d00a0009c000000000203c019000000000002004b000033c50000c13d0000000001180019000000000214034f000000000302043b00001bce0030009c000033c50000213d000000060630021000000000026c0049000000200110003900001c0d0820019700001c0d0a100197000000000b8a013f00000000008a004b000000000800001900001c0d08004041000000000021004b000000000200001900001c0d0200204100001c0d00b0009c000000000802c019000000000008004b000033c50000c13d00000005027002100000003f0220003900001c0e02200197000000400a00043d00000000082a001900120000000a001d0000000000a8004b0000000002000039000000010200403900001bce0080009c000033b90000213d0000000100200190000033b90000c13d000000400080043f00000012020000290000000002720436000f00000002001d00000000075900190000000000c7004b000033c50000213d000000000057004b000031420000a13d000000120800002900000000025c004900001c0f0020009c000033c50000213d000000400020008c000033c50000413d000000400900043d00001ba80090009c000033b90000213d00000020088000390000004002900039000000400020043f000000000254034f000000000202043b0000000002290436000000200a500039000000000aa4034f000000000a0a043b0000000000a2043500000000009804350000004005500039000000000075004b0000312c0000413d00000005023002100000003f0220003900001c0e02200197000000400b00043d00000000052b00190000000000b5004b0000000002000039000000010200403900001bce0050009c000033b90000213d0000000100200190000033b90000c13d000000400050043f000000000d3b043600000000031600190000000000c3004b000033c50000213d000000000013004b0000316c0000a13d00000000050b001900000000021c004900001c0f0020009c000033c50000213d000000400020008c000033c50000413d000000400600043d00001ba80060009c000033b90000213d00000020055000390000004002600039000000400020043f000000000214034f000000000202043b00000000022604360000002007100039000000000774034f000000000707043b000000000072043500000000006504350000004001100039000000000031004b000031560000413d000000400a00043d00001bd100a0009c000033b90000213d0000006001a00039000000400010043f00001c1300a0009c000033b90000213d0000010002a00039000000400020043f000000000001043500000000011a0436000000e002a000390000000000020435000000c002a000390000000000020435000000a002a0003900000000000204350000008002a0003900000000000204350000004002a000390000000000020435000000000001043500000012010000290000000001010433000000000001004b000033e70000613d00000000010b0433000000000001004b000033e70000613d000000400100043d001300000001001d00001bb40010009c000033b90000213d0000001302000029000000a001200039000000400010043f0000008001200039000000000001043500000040012000390000000000010435000000200120003900000000000104350000000000020435000000600e20003900000000000e0435000000400500043d00001c3a0050009c000033b90000213d0000008001500039000000400010043f00000060065000390000000000060435000000400150003900000000000104350000000002050436001100000002001d0000000000020435000000400300043d00001bb40030009c000033b90000213d000000a002300039000000400020043f000000800230003900000000000204350000006002300039000000000002043500000040023000390000000000020435000000200230003900000000000204350000000000030435000000400300043d00001c120030009c000033b90000213d000000e002300039000000400020043f000000c00230003900000060070000390000000000720435000000a002300039000000000072043500000040023000390000000000720435000000200230003900000000007204350000008002300039000000000002043500000060023000390000000000020435000000000003043500000000020b0433000000000002004b000032720000613d0000000007000019000000000e000019000000110f000029000d00000006001d000031e30000013d0000000102f0018f0000000000210435000000100c000029000000110f0000290000000002030433000000000002004b0000000002000039000000010200603900000000002604350000000008010433000000000008004b000000010220c1bf000000000021043500000000000304350000000002010433000000000002004b000033c70000c13d000000010ee0003900000000020b043300000000002e004b0000326f0000813d0000000502e002100000000009d2001900000000020904330000000008020433000000000085043500000000020b04330000000000e2004b000033b30000a13d00000000020904330000002002200039000000000302043300000000003f043500000015020000290000000002020433000000000028004b000000000200003900000001020080390000000000210435000033c70000813d00000015020000290000000002020433000000000082004b000033b30000a13d0000000502800210000000140220002900000000080204330000008002800039000000000202043300001c1f00200198000031df0000613d000000400280003900000000080204330000000002080433000000000023004b000031df0000813d0000000502300210000000000282001900000020022000390000000008020433000000000007004b000032360000613d00000013020000290000006009200039000000000c090433000000600380003900000000020304330000000000c2001a000033f50000413d0000000002c20019000000000029043500000013020000290000008002200039000000000202043300000080098000390000000009090433000000000229013f00001ba700200198000000010f000039000031ce0000c13d0000001302000029000000009f0204340000000500f0008c000033bf0000213d00000000c2080434000000050020008c000033bf0000213d00000000002f004b000000010f000039000031ce0000c13d000000000209043300000000090c0433000000000229013f00001ba700200198000031ce0000c13d00000040028000390000000002020433000000130800002900000040088000390000000008080433000000000028004b000000000f000039000000010f00c039000031ce0000013d0000000037080434000000050070008c000033bf0000213d000000400200043d001300000002001d00001bb40020009c000033b90000213d00000000040d0019000000000d0a001900000000020304330000004003800039000000000c0304330000008003800039000000000f030433000000600380003900000000080304330000001306000029000000a00a6000390000004000a0043f00001ba70af00197000000800f6000390000000000af0435000000600a60003900000000008a043500000040086000390000000000c8043500001ba70220019700000020086000390000000000280435000000000076043500000000000e004b000032680000613d00000000020b04330000000000e2004b000000100c000029000000000a0d0019000000000d0400190000000c0400035f0000000d06000029000000110f000029000033b30000a13d00000000020d0433000000000709043300000000007d0435000000000029043500000000020b04330000000000e2004b000033b30000a13d0000000107000039000031d20000013d0000000107000039000000100c000029000000000a0d0019000000000d0400190000000c0400035f0000000d06000029000031d10000013d0000001301000029000000600e100039000032750000013d0000000001010433000000000001004b000033c70000c13d00000000010e0433000000000001004b0000339b0000613d000000400a00043d00001bd100a0009c000033b90000213d0000006001a00039000000400010043f00001c1300a0009c000033b90000213d0000010002a00039000000400020043f000000000001043500000000011a0436000000e002a000390000000000020435000000c002a000390000000000020435000000a002a0003900000000000204350000008002a0003900000000000204350000004002a0003900000000000204350000000000010435000000400100043d00001c120010009c000033b90000213d000000e002100039000000400020043f000000c00210003900000060030000390000000000320435000000a002100039000000000032043500000040021000390000000000320435000000200210003900000000003204350000008002100039000000000002043500000060021000390000000000020435000000000001043500000012010000290000000006010433000000000006004b000033380000613d000000000f0a0019000000000100001900000000050000190000000f0a000029000032b10000013d00000000020504330000000000050435000000000002004b00000001050000390000000f0a000029000032fb0000c13d000033da0000013d00000005021002100000000003a200190000000002030433000000008702043400000015020000290000000002020433000000000027004b000033df0000813d0000000502700210000000140220002900000000070204330000008002700039000000000202043300001c1f00200198000032fd0000613d0000000008080433000000200270003900000000090204330000000002090433000000000028004b000032fd0000813d0000000502800210000000000292001900000020022000390000000006020433000000000005004b000033010000613d00000060036000390000000008030433000000000a0f001900000000920a0434000000600c20003900000000020c0433000000000028001a000033f50000413d000000000228001900000000002c04350000004002600039000000000202043300000000080a0433000000400a800039000000000a0a043300000000002a004b000000000a0f0019000033d60000c13d00000000020704330000000009090433000000000292013f00001ba700200198000033d60000c13d000000600270003900000000020204330000004007a000390000000007070433000000000027004b000033d60000c13d0000000078080434000000050080008c000033bf0000213d0000000062060434000000050020008c000033bf0000213d000000000028004b000033d60000c13d0000000002060433000000000707043300000000060304330000000000030435000000000272013f00001ba700200198000033dd0000c13d000000000006004b0000000f0a000029000033da0000613d000000120200002900000000060204330000000101100039000000000061004b000032b10000413d000033360000013d0000000059060434000000050090008c000033bf0000213d000000400800043d00001bb40080009c000033b90000213d00000000020504330000004005600039000000000a05043300000060056000390000000006050433000000a00c8000390000004000c0043f000000600c80003900000000006c043500000040068000390000000000a6043500001ba70220019700000020068000390000000000260435000000000098043500000080028000390000000000020435000000400f00043d00001bd100f0009c000033b90000213d0000000002070433000000600670003900000000060604330000006007f00039000000400070043f0000004007f00039000000000067043500001ba7022001970000002006f00039000000000026043500000000008f0435000000000001004b000032aa0000613d00000012020000290000000002020433000000000012004b000033b30000a13d0000000f07000029000000000207043300000000060304330000000000670435000000000023043500000012020000290000000002020433000000000012004b000032aa0000213d000033b30000013d000000000a0f0019000033390000013d000000000600001900000000010a04330000000035010434000000050050008c000033bf0000213d00000013020000290000000072020434000000050020008c000033bf0000213d000000000025004b000033ea0000c13d00000000020304330000000003070433000000000223013f00001ba700200198000033ea0000c13d00000013020000290000004002200039000000000202043300000040031000390000000003030433000000000023004b000033ea0000c13d00000000030e043300000060011000390000000005010433000000000153004b000033720000a13d00000000020b0433000000000002004b000000100c000029000033b30000613d00000000020d0433000000003502043400000015020000290000000002020433000000000052004b000033b30000a13d0000000502500210000000140220002900000000020204330000004002200039000000000502043300000000060504330000000002030433000000000026004b000033b30000a13d00000005022002100000000002250019000000200220003900000000020204330000006002200039000000000012043500000000010a04330000006001100039000000000101043300000000001e04350000338d0000013d000000000006004b000000100c000029000033b30000613d0000000f010000290000000001010433000000001601043400000015020000290000000002020433000000000062004b000033b30000a13d0000000502600210000000140220002900000000020204330000002002200039000000000602043300000000020604330000000001010433000000000012004b000033b30000a13d000000000235004900000005011002100000000001160019000000200110003900000000010104330000006001100039000000000021043500000000010e043300000000020a04330000006002200039000000000012043500000000010a043300000060021000390000000002020433000000000002004b0000339b0000613d000000800110003900000013020000290000008002200039000000000202043300001ba70220019700000000002104350000000b0100002900000000010104330000000e0010006c000033b30000a13d000000080200002900000009012000290000000000a104350000000b0100002900000000010104330000000e0010006c000033b30000a13d0000000e020000290000000102200039000000070020006c000030b80000413d000000060100002900000015020000290000000b030000290000000104000029000000030500002900000002060000296e8b62c60000040f0000000b01000029000000000001042d00001c1401000041000000000010043f0000003201000039000000040010043f00001c150100004100006e8d0001043000001c1401000041000000000010043f0000004101000039000000040010043f00001c150100004100006e8d0001043000001c1401000041000000000010043f0000002101000039000000040010043f00001c150100004100006e8d00010430000000000100001900006e8d00010430000000400200043d00001ba40020009c00001ba4010000410000000001024019000000400110021000001bd6011001c70000000003060433000000000003004b000033d30000c13d00001c5303000041000000000032043500006e8d0001043000001c4603000041000000000032043500006e8d0001043000000000010304330000000000030435000000000001004b000033df0000c13d000000400100043d00001c4602000041000033e10000013d000000000006004b000033da0000613d000000400100043d00001c5302000041000000000021043500001ba40010009c00001ba401008041000000400110021000001bd6011001c700006e8d00010430000000400100043d00001c5702000041000033e10000013d000000400100043d00001c5602000041000000000021043500000004021000390000000e03000029000000000032043500001ba40010009c00001ba401008041000000400110021000001c15011001c700006e8d0001043000001c1401000041000000000010043f0000001101000039000000040010043f00001c150100004100006e8d0001043000010000000000020000000002010019000000400100043d00001c320010009c000035960000813d000000a003100039000000400030043f00001c330010009c000035960000213d0000020004100039000000400040043f0000000000030435000001000410003900000060050000390000000000540435000000e004100039000000000054043500000080041000390000000000540435000000600410003900000000005404350000000003310436000001e0041000390000000000040435000001c0041000390000000000040435000001a004100039000000000004043500000180041000390000000000040435000001600410003900000000000404350000014004100039000000000004043500000120041000390000000000040435000000c00410003900000000000404350000004001100039000000000001043500000000000304350000000203000367000000000123034f000000000701043b000000000500003100000000012500490000015f0410008a00001c0d0640019700001c0d08700197000000000968013f000000000068004b000000000600001900001c0d06002041000000000047004b000000000400001900001c0d0400404100001c0d0090009c000000000604c019000000000006004b000035940000613d0000002004200039000000000443034f000000000404043b0000001f0110008a00001c0d0640019700001c0d08100197000000000986013f000000000086004b000000000600001900001c0d06004041000000000014004b000000000100001900001c0d0100804100001c0d0090009c000000000601c019000000000006004b000035940000c13d0000000001240019000000000413034f000000000404043b00001bce0040009c000035940000213d0000000008450049000000200610003900001c0d0180019700001c0d09600197000000000a19013f000000000019004b000000000100001900001c0d01004041000000000086004b000000000800001900001c0d0800204100001c0d00a0009c000000000108c019000000000001004b000035940000c13d000000400100043d00001bb40010009c000035960000213d00000000072700190000000008750049000000a002100039000100000002001d000000400020043f00001c0f0080009c000035940000213d000001600080008c000035940000413d00001c330010009c000035960000213d0000020002100039000000400020043f000000000273034f000000000202043b00001ba70020009c000035940000213d000000010800002900000000002804350000002008700039000000000283034f000000000902043b00001ba70090009c000035940000213d000000c00210003900000000009204350000002002800039000000000223034f000000000202043b00001bce0020009c000035940000213d000000000a7200190000001f02a00039000000000052004b000000000900001900001c0d0900804100001c0d0220019700001c0d08500197000000000b82013f000000000082004b000000000200001900001c0d0200404100001c0d00b0009c000000000209c019000000000002004b000035940000c13d0000000002a3034f000000000b02043b00001bce00b0009c000035960000213d0000000502b002100000003f0220003900001c0e02200197000000400900043d000000000c29001900000000009c004b0000000002000039000000010200403900001bce00c0009c000035960000213d0000000100200190000035960000c13d000000200aa000390000004000c0043f0000000000b90435000000a002b000c9000000000ba2001900000000005b004b000035940000213d0000000000ab004b000034d00000a13d000000000c0900190000000002a5004900001c0f0020009c000035940000213d000000a00020008c000035940000413d000000400d00043d00001bb400d0009c000035960000213d000000a002d00039000000400020043f0000000002a3034f000000000202043b000000050020008c000035940000213d000000000f2d0436000000200ea000390000000002e3034f000000000202043b00001ba70020009c000035940000213d000000200cc0003900000000002f04350000002002e00039000000000223034f000000000202043b000000400fd0003900000000002f04350000004002e00039000000000223034f000000000202043b000000600fd0003900000000002f04350000006002e00039000000000223034f000000000202043b000000800ed0003900000000002e04350000000000dc0435000000a00aa000390000000000ba004b000034a70000413d000000e00210003900000000009204350000006002700039000000000223034f000000000202043b00001bce0020009c000035940000213d00000000097200190000001f02900039000000000052004b000000000a00001900001c0d0a00804100001c0d02200197000000000b82013f000000000082004b000000000200001900001c0d0200404100001c0d00b0009c00000000020ac019000000000002004b000035940000c13d000000000293034f000000000a02043b00001bce00a0009c000035960000213d0000000502a002100000003f0220003900001c0e02200197000000400800043d000000000b28001900000000008b004b0000000002000039000000010200403900001bce00b0009c000035960000213d0000000100200190000035960000c13d00000020099000390000004000b0043f0000000000a80435000000c002a000c9000000000a92001900000000005a004b000035940000213d00000000009a004b0000352f0000a13d000000000b080019000000000295004900001c0f0020009c000035940000213d000000c00020008c000035940000413d000000400c00043d00001bd400c0009c000035960000213d000000c002c00039000000400020043f000000000293034f000000000202043b000000050020008c000035940000213d000000000e2c0436000000200d9000390000000002d3034f000000000202043b00001ba70020009c000035940000213d00000000002e04350000002002d00039000000000223034f000000000202043b000000400ec0003900000000002e04350000004002d00039000000000223034f000000000202043b000000600ec0003900000000002e04350000006002d00039000000000223034f000000000202043b000000800ec0003900000000002e04350000008002d00039000000000223034f000000000d02043b00001ba700d0009c000035940000213d000000200bb00039000000a002c000390000000000d204350000000000cb0435000000c0099000390000000000a9004b000034ff0000413d000001000210003900000000008204350000008007700039000000000273034f000000000202043b000000040020008c000035940000213d000001200810003900000000002804350000002002700039000000000223034f000000000202043b000001400810003900000000002804350000004002700039000000000223034f000000000202043b000001600810003900000000002804350000006002700039000000000223034f000000000202043b000001800810003900000000002804350000008002700039000000000223034f000000000202043b000001a0081000390000000000280435000000a002700039000000000223034f000000000202043b000001c0081000390000000000280435000000c002700039000000000223034f000000000202043b0000004007100039000000010800003900000000008704350000002007100039000000000087043500000001070000290000000000710435000001e00710003900000000002704350000001f0240003900001c2b022001970000003f0220003900001c2b07200197000000400200043d0000000007720019000000000027004b0000000009000039000000010900403900001bce0070009c000035960000213d0000000100900190000035960000c13d000000400070043f00000000074204360000000009640019000000000059004b000035940000213d000000000563034f00001c2b064001980000001f0840018f00000000036700190000357a0000613d000000000905034f000000000a070019000000009b09043c000000000aba043600000000003a004b000035760000c13d000000000008004b000035870000613d000000000565034f0000000306800210000000000803043300000000086801cf000000000868022f000000000505043b0000010006600089000000000565022f00000000056501cf000000000585019f00000000005304350000000003470019000000000003043500000060031000390000000000230435000000400200043d00001c3b0020009c000035960000213d0000002003200039000000400030043f000000000002043500000080031000390000000000230435000000000001042d000000000100001900006e8d0001043000001c1401000041000000000010043f0000004101000039000000040010043f00001c150100004100006e8d000104300026000000000002000300000004001d001300000003001d001600000002001d000a00000001001d000000400400043d00001c580040009c000045b20000813d0000008001400039000000400010043f00000040014000390000000000010435000000200140003900000000000104350000000000040435000000400100043d00001c120010009c000045b20000213d000000e002100039000000400020043f000000c00210003900000060030000390000000000320435000000a0021000390000000000320435000000400210003900000000003204350000002002100039000000000032043500000080021000390000000000020435000000600210003900000000000204350000000000010435001b00000004001d000000600240003900000000001204350000000a010000290000000012010434001700000001001d000000c0012000390000000001010433001a00000001001d001800000002001d000000a0012000390000000001010433001900000001001d00001c34010000410000000000100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001bd3011001c70000800b020000396e8b6e860000040f0000000100200190000045c90000613d000000000101043b0000001903000029000000000013004b0000001a04000029000045fc0000213d000000000014004b000045fc0000a13d000000180100002900000080011000390000000001010433000000050010008c000045cc0000813d0000000a020000290000004002200039000000000202043300001c1f042001970000001702000029000000000202043300001c1f03200197000000040010008c0000371a0000c13d000000010030008c000046030000c13d000000010040008c000046030000c13d000000400100043d00001c120010009c000045b20000213d000000e002100039000000400020043f000000c00210003900000060030000390000000000320435000000a0021000390000000000320435000000400210003900000000003204350000002002100039000000000032043500000080021000390000000000020435000000600210003900000000000204350000000000010435000000180100002900000040011000390000000004010433000000005304043400001bce0030009c000045b20000213d00000005023002100000003f0120003900001c0e06100197000000400100043d0000000006610019001b00000001001d000000000016004b0000000007000039000000010700403900001bce0060009c000045b20000213d0000000100700190000045b20000c13d000000400060043f0000001b010000290000000006310436000000000003004b0000362c0000613d0000000003000019000000400700043d00001c3a0070009c000045b20000213d0000008008700039000000400080043f0000006008700039000000000008043500000040087000390000000000080435000000200870003900000000000804350000000000070435000000000836001900000000007804350000002003300039000000000023004b0000361b0000413d000000000304043300001bce0030009c000045b20000213d00000005083002100000003f0280003900001c0e07200197000000400100043d0000000007710019001a00000001001d000000000017004b0000000009000039000000010900403900001bce0070009c000045b20000213d0000000100900190000045b20000c13d000000400070043f0000001a0100002900000000073104360000001f0980018f00000000030000310000000203300367000000000008004b0000364b0000613d0000000008870019000000000a03034f000000000b07001900000000ac0a043c000000000bcb043600000000008b004b000036470000c13d000000000009004b0000000008040433000000000008004b0000367d0000613d00000000080000190000000509800210000000000a950019000000000d0a043300000000ec0d04340000000500c0008c000045cc0000213d000000400b00043d00001c3a00b0009c000045b20000213d000000600ad00039000000000e0e0433000000400dd00039000000000d0d0433000000000f0a04330000008002b00039000000400020043f0000006002b000390000000000f204350000004002b000390000000000d2043500001ba702e00197000000200db0003900000000002d04350000000000cb04350000001b010000290000000002010433000000000082004b000045ba0000a13d00000000029600190000000000b204350000001b010000290000000002010433000000000082004b000045ba0000a13d0000001a010000290000000002010433000000000082004b000045ba0000a13d000000000279001900000000090a0433000000000092043500000001088000390000000002040433000000000028004b000036500000413d0000001801000029000000600410003900000000050404330000000019050434001900000001001d00001bce0090009c000045b20000213d00000005089002100000003f0480003900001c0e07400197000000400400043d0000000007740019000000000047004b000000000a000039000000010a00403900001bce0070009c000045b20000213d0000000100a00190000045b20000c13d000000400070043f0000000007940436000000000009004b000036a80000613d0000000009000019000000400a00043d00001bb400a0009c000045b20000213d000000a00ba000390000004000b0043f000000800ba0003900000000000b0435000000600ba0003900000000000b0435000000400ba0003900000000000b0435000000200ba0003900000000000b043500000000000a0435000000000b9700190000000000ab04350000002009900039000000000089004b000036950000413d000000000905043300001bce0090009c000045b20000213d000000050a9002100000003f08a0003900001c0e0b800197000000400800043d000000000bb8001900000000008b004b000000000c000039000000010c00403900001bce00b0009c000045b20000213d0000000100c00190000045b20000c13d0000004000b0043f00000000099804360000001f0ba0018f00000000000a004b000036c20000613d000000000aa90019000000000c090019000000003d03043c000000000cdc04360000000000ac004b000036be0000c13d00000000000b004b0000000003050433000000000003004b000036f60000613d0000000003000019000000050a3002100000001902a00029000000000e02043300000000fd0e04340000000500d0008c000045cc0000213d000000400c00043d00001bb400c0009c000045b20000213d000000600be0003900000000020f0433000000400fe00039000000000f0f043300000000060b0433000000a00ee00039000000000e0e0433000000a001c00039000000400010043f00001ba701e00197000000800ec0003900000000001e04350000006001c0003900000000006104350000004001c000390000000000f1043500001ba7012001970000002002c0003900000000001204350000000000dc04350000000001040433000000000031004b000045ba0000a13d0000000001a700190000000000c104350000000001040433000000000031004b000045ba0000a13d0000000001080433000000000031004b000045ba0000a13d00000000019a001900000000020b0433000000000021043500000001033000390000000001050433000000000013004b000036c70000413d000000400600043d00001c120060009c000045b20000213d0000001802000029000000000102043300000120022000390000000003020433000000e002600039000000400020043f000000c0026000390000000000820435000000a0026000390000001a050000290000000000520435000000800560003900000001020000390000000000250435000000600560003900000000003504350000004003600039000000000043043500000020036000390000001b04000029000000000043043500001ba7011001970000000000160435000000400100043d000000000301001900001c3a0010009c000045b20000213d0000008001300039000000400010043f0000000001230436000200000001001d0000000000210435000038c10000013d000000010230008a000000000042004b000046030000813d001700000003001d001500000004001d000000000043004b000037230000813d00000001001001900000461a0000613d00000018010000296e8b5a830000040f0000001b020000290000000000120435000000000010043f0000000301000039000000200010043f000000000100041400001ba40010009c00001ba401008041000000c00110021000001c17011001c700008010020000396e8b6e860000040f0000000100200190000045b80000613d0000001b060000290000000002060433000000000101043b000000000401041a0000ff00004001900000461d0000c13d0000008807400270000000100140027000001c1f031001980000001705000029000037400000613d000000000073004b000046200000813d000000ff00400190000037450000613d00001c590040009c000037560000813d000037910000013d0000000a010000290000006001100039001900000003001d00000000030104330000001801000029000000000101043300001ba701100197001a00000007001d001400000004001d6e8b5c900000040f000000140400002900000019030000290000001a070000290000001b06000029000000170500002900001c590040009c000037910000413d0000001501000029000000010010008c0000375e0000c13d00000000050700190000000001350019000000000071004b000037640000a13d000037700000013d000000000017004b0000376a0000c13d00000000070100190000000001350019000000000071004b000037700000213d000000000271019f00001c5a0020009c000037760000813d001700000005001d001500000007001d000037910000013d00000000055700a900000000071700a900000000031300a90000000001350019000000000071004b000037640000a13d000000000537004b000045c00000413d0000000001070019000000000271019f00001c5a0020009c000037670000413d000000000007004b000037800000613d00000000030700190000000004010019000000000203001900000000302400d9000000000003004b00000000040200190000377a0000c13d000037830000013d000000000001004b0000000002010019000045a90000613d0000000004050019000000000302001900000000203400d9000000000002004b0000000004030019000037840000c13d00000000013100d900001c1f0010009c000045c00000213d00000000013700d9001500000001001d00001c1f0010009c000045c00000213d00170000003500e1000000400200043d00001c120020009c000045b20000213d0000000001060433001400000001001d000000e001200039000000400010043f000000c00120003900000060030000390000000000310435000000a0012000390000000000310435000000400120003900000000003104350000002001200039000000000031043500000080012000390000000000010435000000600120003900000000000104350000000000020435000000180100002900000040011000390000000005010433000000006405043400001bce0040009c000045b20000213d00000005034002100000003f0130003900001c0e01100197000000400200043d0000000007120019001b00000002001d000000000027004b0000000001000039000000010100403900001bce0070009c000045b20000213d0000000100100190000045b20000c13d000000400070043f0000001b010000290000000007410436000000000004004b000037d00000613d0000000004000019000000400800043d00001c3a0080009c000045b20000213d0000008001800039000000400010043f0000006001800039000000000001043500000040018000390000000000010435000000200180003900000000000104350000000000080435000000000147001900000000008104350000002004400039000000000034004b000037bf0000413d000000000405043300001bce0040009c000045b20000213d00000005094002100000003f0190003900001c0e01100197000000400200043d0000000008120019001a00000002001d000000000028004b0000000001000039000000010100403900001bce0080009c000045b20000213d0000000100100190000045b20000c13d000000400080043f0000001a0100002900000000084104360000001f0a90018f00000000010000310000000204100367000000000009004b000037ef0000613d0000000009980019000000000b04034f000000000108001900000000bc0b043c0000000001c10436000000000091004b000037eb0000c13d00000000000a004b0000000001050433000000000001004b000038210000613d0000000009000019000000050a9002100000000001a60019000000000e01043300000000fd0e04340000000500d0008c000045cc0000213d000000400c00043d00001c3a00c0009c000045b20000213d000000600be0003900000000010f0433000000400ee00039000000000e0e0433000000000f0b04330000008003c00039000000400030043f0000006003c000390000000000f304350000004003c000390000000000e3043500001ba7011001970000002003c0003900000000001304350000000000dc04350000001b010000290000000001010433000000000091004b000045ba0000a13d0000000001a700190000000000c104350000001b010000290000000001010433000000000091004b000045ba0000a13d0000001a010000290000000001010433000000000091004b000045ba0000a13d00000000018a001900000000030b0433000000000031043500000001099000390000000001050433000000000019004b000037f40000413d000000180100002900000060011000390000000006010433000000001a060434001900000001001d00001bce00a0009c000045b20000213d0000000509a002100000003f0190003900001c0e01100197000000400500043d0000000008150019000000000058004b0000000001000039000000010100403900001bce0080009c000045b20000213d0000000100100190000045b20000c13d000000400080043f0000000008a5043600000000000a004b0000384c0000613d000000000a000019000000400b00043d00001bb400b0009c000045b20000213d000000a001b00039000000400010043f0000008001b0003900000000000104350000006001b0003900000000000104350000004001b0003900000000000104350000002001b00039000000000001043500000000000b04350000000001a800190000000000b10435000000200aa0003900000000009a004b000038390000413d000000000a06043300001bce00a0009c000045b20000213d000000050ba002100000003f01b0003900001c0e01100197000000400900043d000000000c19001900000000009c004b0000000001000039000000010100403900001bce00c0009c000045b20000213d0000000100100190000045b20000c13d0000004000c0043f000000000aa904360000001f0cb0018f00000000000b004b000038660000613d000000000bba001900000000010a0019000000004d04043c0000000001d104360000000000b1004b000038620000c13d00000000000c004b0000000001060433000000000001004b0000389a0000613d0000000004000019000000050b4002100000001901b00029000000000f010433000000001e0f04340000000500e0008c000045cc0000213d000000400d00043d00001bb400d0009c000045b20000213d000000600cf0003900000000010104330000004003f00039000000000303043300000000070c0433000000a00ff00039000000000f0f0433000000a002d00039000000400020043f00001ba702f00197000000800fd0003900000000002f04350000006002d0003900000000007204350000004002d00039000000000032043500001ba7011001970000002002d0003900000000001204350000000000ed04350000000001050433000000000041004b000045ba0000a13d0000000001b800190000000000d104350000000001050433000000000041004b000045ba0000a13d0000000001090433000000000041004b000045ba0000a13d0000000001ab001900000000020c0433000000000021043500000001044000390000000001060433000000000014004b0000386b0000413d000000400600043d00001c120060009c000045b20000213d000000170100002900001c1f041001970000001802000029000000000102043300000120022000390000000002020433000000e003600039000000400030043f000000c0036000390000000000930435000000a0036000390000001a07000029000000000073043500000080036000390000000000430435000000600360003900000000002304350000004002600039000000000052043500000020026000390000001b03000029000000000032043500001ba7011001970000000000160435000000400100043d000000000301001900001c3a0010009c000045b20000213d0000008001300039000000400010043f00000014010000290000000001130436000200000001001d0000000000410435000000150100002900001c1f021001970000006001300039000900000001001d0000000000610435000600000003001d0000004001300039000100000001001d000000000021043500000016010000290000000021010434001500000002001d001400000001001d000000000001004b000039730000613d0000000a010000290000000001010433001100400010003d001200600010003d0000000002000019000038db0000013d0000000001010433000000000001004b000039700000c13d00000018020000290000000102200039000000140020006c000039730000813d00000016010000290000000001010433000000000021004b000045ba0000a13d001800000002001d000000050120021000000015011000290000000001010433000000200210003900000000020204330000000003010433000000000003004b000045ca0000c13d000000010020008c000045cc0000213d00000040031000390000000003030433000000000002004b000038f40000613d000000120200002900000000020204330000000004020433000000000043004b000038f90000413d000045d80000013d000000110200002900000000020204330000000004020433000000000043004b000045ee0000813d00000005033002100000000002230019000000200220003900000000020204330000000003020433000000050030008c000045cc0000213d00000040042000390000000005040433000000040030008c000000030300003900000002030060390000000000320435000000600210003900000000030204330000000000340435000045d20000413d00000080011000390000000001010433000000000005004b000038d40000613d001a00000001001d001700000005001d0000000003020433000000400100043d00000020020000390000000002210436000000000032043500001ba80010009c000045b20000213d0000004003100039000000400030043f00001ba40020009c00001ba4020080410000004002200210000000000101043300001ba40010009c00001ba4010080410000006001100210000000000121019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f0000000100200190000045b80000613d000000000101043b0000001a020000290000000032020434001900000003001d000000000002004b0000396e0000613d0000000003000019001b00000003001d00000005023002100000001905200029000000400200043d000000400420003900000020032000390000000005050433000000000051004b0000394d0000a13d000000000053043500000000001404350000004001000039000000000012043500001bd10020009c000045b20000213d0000006001200039000000400010043f00001ba40030009c00001ba4030080410000004001300210000000000202043300001ba40020009c00001ba4020080410000006002200210000000000112019f00000000020004140000395e0000013d000000000013043500000000005404350000004001000039000000000012043500001bd10020009c000045b20000213d0000006001200039000000400010043f00001ba40030009c00001ba4030080410000004001300210000000000202043300001ba40020009c00001ba4020080410000006002200210000000000112019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f0000000100200190000045b80000613d000000000101043b0000001b0300002900000001033000390000001a020000290000000002020433000000000023004b000039320000413d000000170010006c000038d70000613d000000400100043d00001c6002000041000045f60000013d0000000a0100002900000000030104330000006001300039001700000001001d00000000010104330000000021010434000000000001004b000500000003001d001800800030003d000039980000613d0000000003000019000039820000013d0000000103300039000000000013004b000039980000813d0000000504300210000000000442001900000000040404330000000005040433000000050050008c000045cc0000213d000000030050008c0000397f0000a13d00000018050000290000000005050433000000040050008c000045cc0000213d000039930000c13d00000040044000390000000004040433000000000004004b0000397f0000613d000000400100043d0000002402100039000000000032043500001c6202000041000039b80000013d0000000501000029000000400d10003900000000010d04330000000021010434000000000001004b000039c00000613d0000000003000019000039a30000013d0000000103300039000000000013004b000039c00000813d0000000504300210000000000442001900000000040404330000000005040433000000050050008c000045cc0000213d000000030050008c000039a00000a13d00000018050000290000000005050433000000040050008c000045cc0000213d000039b40000c13d00000040044000390000000004040433000000000004004b000039a00000613d000000400100043d0000002402100039000000000032043500001c630200004100000000002104350000000402100039000000000002043500001ba40010009c00001ba401008041000000400110021000001c36011001c700006e8d00010430002600050000002d000000400100043d000400000001001d00001c120010009c000045b20000213d00000001010000290000000002010433000000020100002900000000010104330000000405000029000000e003500039000000400030043f000000c00350003900000060040000390000000000430435000000a0035000390000000000430435000000400a50003900000000004a0435000000200e50003900000000004e043500000080035000390000000000030435000000600350003900000000000304350000000000050435000000400b00043d00001bb400b0009c000045b20000213d0000000504000029000000a0034000390000000003030433000000c0044000390000000004040433000000a005b00039000000400050043f0000008005b00039001500000005001d00000000004504350000006004b00039001400000004001d0000000000340435000000200cb0003900000000002c043500000000001b04350000004001b00039000000000001043500000000010d0433000000000401043300001bce0040009c000045b20000213d00000005014002100000003f0210003900001c0e03200197000000400200043d0000000003320019000000000023004b0000000005000039000000010500403900001bce0030009c000045b20000213d0000000100500190000045b20000c13d000000400030043f0000000003420436000000000004004b00003a150000613d0000000004000019000000400500043d00001c3a0050009c000045b20000213d0000008006500039000000400060043f0000006006500039000000000006043500000040065000390000000000060435000000200650003900000000000604350000000000050435000000000643001900000000005604350000002004400039000000000014004b00003a040000413d00000000002e043500000000010d04330000000002010433000000000002004b00120000000a001d00110000000b001d00100000000c001d00003ae40000613d000000000f00001900080000000d001d00070000000e001d0000000507f002100000000001710019000000200110003900000000060104330000000021060434001900000002001d000000050010008c000045cc0000213d000000000001004b00003a2f0000c13d00000018020000290000000002020433000000040020008c000045cc0000213d000045f10000c13d00000000030c043300000000020b04330000008004600039000000000504043300000060046000390000000004040433000000000054004b001a00000006001d00003a3c0000c13d000000000032004b00003a440000c13d001b00000004001d00003ac20000013d0000000006000415000000250660008a0000000506600210000000000032004b00003a590000c13d001b00000004001d000000000805001900003a830000013d00000000054200a9000000000004004b00003a4a0000613d00000000064500d9000000000026004b000045c00000c13d000000000003004b000045ac0000613d001b0000003500e10000001b063000b9000000000035004b00003a530000413d0000001b056000fa000000000035004b000045c00000c13d000000000002004b000045ac0000613d00000000022600d9000000000042004b00003ac20000613d000045c60000013d000000000907001900000000064200a9000000000004004b00003a600000613d00000000074600d9000000000027004b000045c00000c13d000000000003004b000045ac0000613d001b0000003600e10000001b073000b9000000000036004b00003a690000413d0000001b067000fa000000000036004b000045c00000c13d000000000002004b000045ac0000613d00000000062700d9000000000046004b000045c60000c13d00000000045200a9000000000005004b00003a740000613d00000000065400d9000000000026004b000045c00000c13d00000000063400d9000000000806001900000000063600a9000000000034004b00003a7c0000413d00000000048600d9000000000034004b000045c00000c13d00000000022600d90000000006000415000000240660008a0000000506600210000000000052004b0000000007090019000045c60000c13d0000000502600270000000000208001f0000001b0080006b00003ac20000613d001600000008001d000b00000007001d0000001501000029000000000201043300000014010000290000000003010433000c00000002001d000000000132004b000045c00000413d000d00000003001d000e00000001001d000f0000000f001d00001c34010000410000000000100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001bd3011001c70000800b020000396e8b6e860000040f0000000100200190000045c90000613d000000000101043b0000000d06000029000000000161004b000000120a000029000000110b000029000000100c000029000000080d000029000000070e0000290000000f0f0000290000000e05000029000045c00000413d000000000315004b000045c00000413d0000001b023000b90000001b0000006b00003ab10000613d0000001b042000fa000000000034004b000045c00000c13d00000016031000b9000000160000006b00003ab70000613d00000016043000fa000000000014004b000045c00000c13d000000000032001a000045c00000413d0000000c0060006b000045ac0000613d0000001a010000290000000001010433000000050010008c0000000b07000029000045cc0000213d0000000002320019001b0000005200e1000000400200043d00001c3a0020009c000045b20000213d000000190300002900000000030304330000001a04000029000000400440003900000000040404330000008005200039000000400050043f00000060052000390000001b0600002900000000006504350000004005200039000000000045043500001ba70330019700000020042000390000000000340435000000000012043500000000010e043300000000030104330000000000f3004b000045ba0000a13d00000000031700190000002003300039000000000023043500000000010104330000000000f1004b000045ba0000a13d000000010ff0003900000000010d0433000000000201043300000000002f004b00003a200000413d00000017010000290000000001010433000000000401043300001bce0040009c000045b20000213d00000005014002100000003f0210003900001c0e03200197000000400200043d0000000003320019000000000023004b0000000005000039000000010500403900001bce0030009c000045b20000213d0000000100500190000045b20000c13d000000400030043f0000000003420436000000000004004b00003b0d0000613d0000000004000019000000400500043d00001bb40050009c000045b20000213d000000a006500039000000400060043f000000800650003900000000000604350000006006500039000000000006043500000040065000390000000000060435000000200650003900000000000604350000000000050435000000000643001900000000005604350000002004400039000000000014004b00003afa0000413d00000000002a0435000000170100002900000000030104330000000001030433000000000001004b00003bd10000613d000000000700001900000000020c043300000000010b0433000000050470021000000020094000390000000003390019000000000d0304330000008003d0003900000000040304330000006003d000390000000003030433000000000043004b00003b240000c13d000000000021004b00003b2c0000c13d000000000e03001900003baa0000013d0000000005000415000000230550008a0000000505500210000000000021004b00003b410000c13d000000000e030019000000000604001900003b680000013d00000000043100a9000000000003004b00003b320000613d00000000053400d9000000000015004b000045c00000c13d000000000002004b000045ac0000613d000000000e2400d900000000052e00a9000000000024004b00003b3b0000413d0000000004e500d9000000000024004b000045c00000c13d000000000001004b000045ac0000613d00000000011500d9000000000031004b00003baa0000613d000045c60000013d00000000053100a9000000000003004b00003b470000613d00000000063500d9000000000016004b000045c00000c13d000000000002004b000045ac0000613d000000000e2500d900000000062e00a9000000000025004b00003b500000413d0000000005e600d9000000000025004b000045c00000c13d000000000001004b000045ac0000613d00000000051600d9000000000035004b000045c60000c13d00000000034100a9000000000004004b00003b5b0000613d00000000054300d9000000000015004b000045c00000c13d00000000062300d900000000052600a9000000000023004b00003b620000413d00000000036500d9000000000023004b000045c00000c13d00000000011500d90000000005000415000000220550008a0000000505500210000000000041004b000045c60000c13d0000000501500270000000000106001f00000000006e004b00003baa0000613d0000001501000029000000000201043300000014010000290000000003010433000c00000002001d000000000132004b000045c00000413d000d00000003001d000e00000001001d000f00000006001d00160000000e001d00190000000d001d001a00000009001d001b00000007001d00001c34010000410000000000100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001bd3011001c70000800b020000396e8b6e860000040f0000000100200190000045c90000613d000000000101043b0000000d08000029000000000181004b000000120a000029000000110b000029000000100c0000290000001b070000290000001a09000029000000190d00002900000016040000290000000f050000290000000e06000029000045c00000413d000000000316004b000045c00000413d0000000c0080006b000045c00000613d00000000024300a9000000000004004b00003b9c0000613d00000000044200d9000000000034004b000045c00000c13d00000000035100a9000000000005004b00003ba20000613d00000000045300d9000000000014004b000045c00000c13d000000000032001a000045c00000413d000000010160008a0000000002320019000000000021001a000045c00000413d0000000001210019000000000e6100d900000000320d0434000000050020008c000045cc0000213d000000400100043d00001bb40010009c000045b20000213d00000000030304330000004004d000390000000004040433000000a005d000390000000005050433000000a006100039000000400060043f00001ba7055001970000008006100039000000000056043500000060051000390000000000e504350000004005100039000000000045043500001ba70330019700000020041000390000000000340435000000000021043500000000020a04330000000003020433000000000073004b000045ba0000a13d000000000329001900000000001304350000000001020433000000000071004b000045ba0000a13d0000000107700039000000170100002900000000030104330000000001030433000000000017004b00003b140000413d000000090100002900000004020000290000000000210435000000400600043d00001c3b0060009c000045b20000213d0000002001600039000000400010043f000000000006043500000018010000290000000002010433000000040020008c000045cc0000213d00000009010000290000000001010433001b00000001001d00003cb50000c13d0000000a01000029000000000201043300000140012000390000000001010433001a00000002001d000000600220003900000000020204330000000002020433000000000012004b000046260000c13d0000001b010000290000004001100039001800000001001d0000000003010433000000004803043400001bce0080009c000045b20000213d00000005078002100000003f0170003900001c0e02100197000000400100043d0000000005210019000000000015004b0000000002000039000000010200403900001bce0050009c000045b20000213d0000000100200190000045b20000c13d0000000a02000029000000800220003900000000020204330000001b06000029000000200f60003900000000060f0433000000400050043f0000000005810436000000000008004b00003c1b0000613d0000000008000019000000400900043d00001c3a0090009c000045b20000213d000000800a9000390000004000a0043f000000600a90003900000000000a0435000000400a90003900000000000a0435000000200a90003900000000000a04350000000000090435000000000a85001900000000009a04350000002008800039000000000078004b00003c0a0000413d0000000007030433000000000007004b00003c430000613d000000000700001900000005087002100000000009840019000000000b09043300000000ca0b04340000000500a0008c000045cc0000213d000000400900043d00001c3a0090009c000045b20000213d000000000c0c0433000000400db00039000000000d0d0433000000600bb00039000000000b0b0433000000800e9000390000004000e0043f000000600e9000390000000000be0435000000400b9000390000000000db043500001ba70bc00197000000200c9000390000000000bc04350000000000a90435000000000a01043300000000007a004b000045ba0000a13d000000000885001900000000009804350000000008010433000000000078004b000045ba0000a13d00000001077000390000000008030433000000000087004b00003c1f0000413d0000001a030000290000000005030433000000400400043d000000440340003900000080070000390000000000730435000000200340003900001c660700004100000000007304350000002407400039000000000800041100000000008704350000000008060433000000a4074000390000000000870435000000c407400039000000000008004b00003c6b0000613d00000000090000190000002006600039000000000a06043300000000bc0a04340000000500c0008c000045cc0000213d000000000cc70436000000000b0b043300001ba70bb001970000000000bc0435000000400ba00039000000000b0b0433000000400c7000390000000000bc0435000000600aa00039000000000a0a0433000000600b7000390000000000ab043500000080077000390000000109900039000000000089004b00003c560000413d0000000006470049000000240660008a0000006408400039000000000068043500000000080104330000000006870436000000000008004b00003c890000613d00000000070000190000002001100039000000000901043300000000ab0904340000000500b0008c000045cc0000213d000000000bb60436000000000a0a043300001ba70aa001970000000000ab0435000000400a900039000000000a0a0433000000400b6000390000000000ab043500000060099000390000000009090433000000600a60003900000000009a043500000080066000390000000107700039000000000087004b00003c740000413d0000000001460049000000240110008a0000008407400039000000000017043500000000720204340000000001260436000000000002004b00003c990000613d000000000600001900000000081600190000000009670019000000000909043300000000009804350000002006600039000000000026004b00003c920000413d000000000621001900000000000604350000001f0220003900001c2b0220019700000000024200490000000001120019000000200210008a00000000002404350000001f0110003900001c2b021001970000000001420019000000000021004b0000000002000039000000010200403900001bce0010009c000045b20000213d0000000100200190000045b20000c13d00001ba702500197000000400010043f00000000040404330000000001000414000000040020008c00160000000f001d00003d860000c13d0000000109000039000000010100003100003d970000013d0000000601000029000000000f01043300000005030000290000000041030434000000e00330003900000000030304330000000004040433000000020020008c00003cc30000c13d00000000050004150000001d0550008a0000000505500210001d00010000003d00003cca0000013d00000000050004150000001c0550008a0000000505500210000000030020008c001c00000000003d001c00010000603d000040460000c13d00001ba7024001970000000009000411000000000029004b0000000504500270000000000400003f000000010400c03f000040460000613d000000400800043d00001c3d0080009c000045b20000213d00001ba70a1001970000001b0400002900000040014000390000002004400039000000000b040433000000000c0104330000000a04000029000000800140003900000000070104330000000001040433000000a0041000390000000005040433000000c00110003900000000040104330000014001800039000000400010043f0000012001800039000000000031043500000100038000390000000000430435000000e0048000390000000000540435000000c0058000390000000000650435000000a006800039000000000076043500000080078000390000000000c70435000000600c8000390000000000bc0435000000400b8000390000000000ab0435000000200a80003900000000009a04350000000000f8043500001c3e09000041000000400e00043d00000000009e04350000000409e00039000000200d0000390000000000d9043500000000080804330000002409e00039000000000089043500000000080a043300001ba7088001970000004409e00039000000000089043500000000080b043300001ba7088001970000006409e00039000000000089043500000000090c04330000014008000039000000840ae0003900000000008a04350000016408e00039000000000a0904330000000000a80435001b0000000e001d0000018408e0003900000000000a004b00003d290000613d000000000b0000190000002009900039000000000c09043300000000de0c04340000000500e0008c000045cc0000213d000000000ee80436000000000d0d043300001ba70dd001970000000000de0435000000400dc00039000000000d0d0433000000400e8000390000000000de0435000000600cc00039000000000c0c0433000000600d8000390000000000cd04350000008008800039000000010bb000390000000000ab004b00003d140000413d0000001b0b0000290000000009b80049000000240a90008a0000000009070433000000a407b000390000000000a70435000000000a0904330000000007a8043600000000000a004b00003d4e0000613d00000000080000190000002009900039000000000b09043300000000cd0b04340000000500d0008c000045cc0000213d000000000dd70436000000000c0c043300001ba70cc001970000000000cd0435000000400cb00039000000000c0c0433000000400d7000390000000000cd0435000000600cb00039000000000c0c0433000000600d7000390000000000cd0435000000800bb00039000000000b0b043300001ba70bb00197000000800c7000390000000000bc0435000000a00770003900000001088000390000000000a8004b00003d340000413d0000001b0c0000290000000008c70049000000240880008a0000000006060433000000c409c00039000000000089043500000000980604340000000006870436000000000008004b00003d600000613d0000000007000019000000000a670019000000000b790019000000000b0b04330000000000ba04350000002007700039000000000087004b00003d590000413d000000000786001900000000000704350000001f0780003900001c2b0770019700000000087600190000000006c80049000000240760008a0000000006050433000000e405c00039000000000075043500000000070604330000000005780436000000000007004b00003d750000613d00000000080000190000002006600039000000000906043300000000059504360000000108800039000000000078004b00003d6f0000413d00000000040404330000010406c00039000000000046043500000000030304330000012404c0003900000000003404350000014403c00039000000000101043300000000001304350000000001000414000000040020008c00003fff0000c13d0000000103000031000000200030008c00000020040000390000000004034019000040310000013d00001ba40030009c00001ba403008041000000400330021000001ba40040009c00001ba4040080410000006004400210000000000334019f00001ba40010009c00001ba401008041000000c001100210000000000113019f6e8b6e810000040f000000010920018f0003000000010355000000600110027000011ba40010019d00001ba401100197000000000001004b0000008008000039001900600000003d00003dc60000613d00001bce0010009c000045b20000213d0000001f0210003900001c2b022001970000003f0220003900001c2b02200197000000400300043d0000000002230019001900000003001d000000000032004b0000000003000039000000010300403900001bce0020009c000045b20000213d0000000100300190000045b20000c13d000000400020043f0000001902000029000000000812043600001c2b021001980000001f0310018f0000000001280019000000030400036700003db90000613d000000000504034f0000000006080019000000005705043c0000000006760436000000000016004b00003db50000c13d000000000003004b00003dc60000613d000000000224034f0000000303300210000000000401043300000000043401cf000000000434022f000000000202043b0000010003300089000000000232022f00000000023201cf000000000242019f0000000000210435001700000009001d001500000008001d0000001a01000029000000000101043300001ba701100197000000000010043f0000000401000039000000200010043f000000000100041400001ba40010009c00001ba401008041000000c00110021000001c17011001c700008010020000396e8b6e860000040f0000000100200190000045b80000613d000000000201043b000000000102041a000000010310003a0000001704000029000045c00000613d000000000032041b0000001a02000029000000000202043300000060022002100014000000120143000000000004004b000046290000613d000000400100043d00001c670010009c000045b20000213d000000240210003900001c68030000410000000000320435000000440210003900000000030004140000006004000039000000000042043500001c69020000410000000000210435000000640210003900000000000204350000000402100039000000000002043500001ba40010009c00001ba401008041000000400110021000001ba40030009c00001ba403008041000000c002300210000000000121019f00001c6a011001c700008006020000396e8b6e810000040f0000000100200190000046350000613d000000000101043b000000000001004b00000015070000290000463b0000613d000000400d00043d00001c6b02000041000000000f2d04360000000402d0003900000020030000390000000000320435000000190200002900000000030204330000002402d0003900000000003204350000004404d00039000000000003004b00003e180000613d000000000200001900000000054200190000000006270019000000000606043300000000006504350000002002200039000000000032004b00003e110000413d00000000023400190000000000020435000000000500041400001ba702100197000000040020008c00003e2a0000c13d0000000006000415000000210660008a00000005066002100000000005000415000000200550008a000000050550021000000003010003670000000102000031002000000000003d002100000000003d000000160e00002900003e4f0000013d00170000000f001d0000001f0130003900001c2b011001970000000001d10049000000000141001900001ba40010009c00001ba401008041000000600110021000001ba400d0009c00190000000d001d00001ba40300004100000000030d40190000004003300210000000000131019f00001ba40050009c00001ba405008041000000c003500210000000000131019f6e8b6e860000040f00000000060004150000001f0660008a000000050660021000000000050004150000001e0550008a00000005055002100000000003010019000000600330027000011ba40030019d0003000000010355001f00000000003d001e00000000003d0000000100200190000000160e00002900003fbd0000613d00001ba402300197000000190d000029000000170f00002900001c2b042001980000001f0720018f00000000034d001900003e590000613d000000000801034f00000000090d0019000000008a08043c0000000009a90436000000000039004b00003e550000c13d000000000007004b00003e660000613d000000000141034f0000000304700210000000000703043300000000074701cf000000000747022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000171019f00000000001304350000001f0120003900001c2b011001970000000003d10019000000000013004b0000000001000039000000010100403900001bce0030009c000045b20000213d0000000100100190000045b20000c13d000000400030043f00001c0f0020009c000045b80000213d000000400020008c000045b80000413d00000000010d043300001bce0010009c000045b80000213d0000000004d100190000000007d2001900001c0d017001970000001f0240003900001c0d08200197000000000918013f000000000018004b000000000800001900001c0d08004041000000000072004b000000000200001900001c0d0200804100001c0d0090009c000000000802c019000000000008004b000045b80000c13d000000002804043400001bce0080009c000045b20000213d00000005048002100000003f0440003900001c0e04400197000000000434001900001bce0040009c000045b20000213d000000400040043f000000000483043600000007088002100000000008820019000000000078004b000045b80000213d000000000082004b00003eb80000813d0000000009040019000000000a27004900001c0f00a0009c000045b80000213d0000008000a0008c000045b80000413d000000400a00043d00001c3a00a0009c000045b20000213d000000800ba000390000004000b0043f00000000bc0204340000000500c0008c000045b80000213d000000000cca0436000000000b0b043300001ba700b0009c000045b80000213d0000000000bc0435000000400b200039000000000b0b0433000000400ca000390000000000bc0435000000600b200039000000000b0b0433000000600ca000390000000000bc04350000000009a904360000008002200039000000000082004b00003e9a0000413d00000000020f043300001bce0020009c000045b80000213d0000000002d200190000001f08200039000000000078004b000000000900001900001c0d0900804100001c0d08800197000000000a18013f000000000018004b000000000100001900001c0d0100404100001c0d00a0009c000000000109c019000000000001004b000045b80000c13d000000008902043400001bce0090009c000045b20000213d00000005019002100000003f0110003900001c0e02100197000000400100043d0000000002210019000000000012004b000000000a000039000000010a00403900001bce0020009c000045b20000213d0000000100a00190000045b20000c13d000000400020043f0000000002910436000000a0099000c90000000009980019000000000079004b000045b80000213d000000000098004b00003f050000813d000000000a020019000000000b87004900001c0f00b0009c000045b80000213d000000a000b0008c000045b80000413d000000400b00043d00001bb400b0009c000045b20000213d000000a00cb000390000004000c0043f00000000cd0804340000000500d0008c000045b80000213d000000000ddb0436000000000c0c043300001ba700c0009c000045b80000213d0000000000cd0435000000400c800039000000000c0c0433000000400db000390000000000cd0435000000600cb00039000000600d800039000000000d0d04330000000000dc0435000000800c800039000000000c0c043300001ba700c0009c000045b80000213d000000800db000390000000000cd0435000000000aba0436000000a008800039000000000098004b00003ee10000413d0000000506600270000000000603001f0000000505500270000000000501001f0000001a050000290000004005500039000000000505043300000000050504330000000006030433000000000065004b00003fbd0000213d000000000005004b00003f450000613d000000000600001900000000070e04330000000008070433000000000068004b000045ba0000a13d0000000008030433000000000068004b000045ba0000a13d000000050960021000000000077900190000002007700039000000000b070433000000008a0b04340000000500a0008c000045cc0000213d0000000007940019000000000c0704330000000300a0008c0000004007b000390000004009c0003900003f2e0000a13d000000000d07043300000000000d004b00003f2e0000c13d000000020aa0008a0000000000ab0435000000000d0904330000000000d70435000000600dc00039000000000d0d0433000000600bb00039000000000b0b04330000000000db004b00003fbd0000213d00000000bc0c04340000000500c0008c000045cc0000213d0000000000ca004b00003fbd0000c13d0000000008080433000000000a0b043300000000088a013f00001ba70080019800003fbd0000c13d00000000080904330000000007070433000000000087004b00003fbd0000c13d0000000106600039000000000056004b00003f130000413d00000000003e0435000000000503043300001bce0050009c000045b20000213d00000005075002100000003f0670003900001c0e08600197000000400600043d0000000008860019000000000068004b0000000009000039000000010900403900001bce0080009c000045b20000213d0000000100900190000045b20000c13d000000400080043f00000000095604360000001f0870018f00000000050000310000000205500367000000000007004b00003f620000613d0000000007790019000000000a05034f00000000ab0a043c0000000009b90436000000000079004b00003f5e0000c13d000000000008004b0000001b07000029000000a00770003900000000006704350000000006030433000000000006004b00003f7a0000613d000000000600001900000000080704330000000009080433000000000069004b000045ba0000a13d0000000509600210000000000889001900000000099400190000000009090433000000600990003900000000090904330000002008800039000000000098043500000001066000390000000008030433000000000086004b00003f6a0000413d0000000003010433000000180400002900000000040404330000000067040434000000000073004b00003fbd0000213d000000000003004b00003fc80000613d000000000700001900003f870000013d0000000107700039000000000037004b00003fc80000813d0000000008010433000000000078004b000045ba0000a13d0000000008040433000000000078004b000045ba0000a13d00000005097002100000000008960019000000000808043300000000bd0804340000000500d0008c000045cc0000213d000000000992001900000000090904330000000300d0008c000000400a800039000000400c90003900003fa00000a13d000000000e0a043300000000000e004b00003fa00000c13d000000020dd0008a0000000000d80435000000000e0c04330000000000ea0435000000600e800039000000000e0e0433000000600f900039000000000f0f04330000000000ef004b00003fbd0000213d00000000ef0904340000000500f0008c000045cc0000213d0000000000fd004b00003fbd0000c13d000000000b0b0433000000000d0e0433000000000bbd013f00001ba700b0019800003fbd0000c13d000000000b0c0433000000000a0a04330000000000ba004b00003fbd0000c13d0000008008800039000000000808043300001ba70880019800003f840000613d0000008009900039000000000909043300001ba709900197000000000098004b00003f840000613d000000400100043d00001c6e02000041000000000021043500000004021000390000001403000029000000000032043500001ba40010009c00001ba401008041000000400110021000001c15011001c700006e8d0001043000000018030000290000000000130435000000000601043300001bce0060009c000045b20000213d00000005046002100000003f0340003900001c0e07300197000000400300043d0000000007730019000000000037004b0000000008000039000000010800403900001bce0070009c000045b20000213d0000000100800190000045b20000c13d000000400070043f00000000076304360000001f0640018f000000000004004b00003fe30000613d0000000004470019000000005805043c0000000007870436000000000047004b00003fdf0000c13d000000000006004b0000001b04000029000000c00440003900000000003404350000000003010433000000000003004b00003ffb0000613d000000000300001900000000050404330000000006050433000000000036004b000045ba0000a13d0000000506300210000000000556001900000000066200190000000006060433000000600660003900000000060604330000002005500039000000000065043500000001033000390000000005010433000000000053004b00003feb0000413d0000000601000029000000140200002900000000002104350000409b0000013d00190000000f001d0000000003c5004900001ba40030009c00001ba403008041000000600330021000001ba400c0009c00001ba40400004100000000040c40190000004004400210000000000334019f00001ba40010009c00001ba401008041000000c001100210000000000131019f6e8b6e810000040f0000001b0c0000290000000003010019000000600330027000001ba403300197000000200030008c000000200400003900000000040340190000001f0640018f000000200740019000000000057c00190000401f0000613d000000000801034f00000000090c0019000000008a08043c0000000009a90436000000000059004b0000401b0000c13d000000000006004b0000402c0000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f0000000000650435000100000003001f00030000000103550000000100200190000000190f000029000046a60000613d0000001f01400039000000600210018f0000000001c20019000000000021004b0000000002000039000000010200403900001bce0010009c000045b20000213d0000000100200190000045b20000c13d000000400010043f000000200030008c000045b80000413d00000000020c043300001c3f00200198000045b80000c13d00001c400220019700001c3e0020009c000046770000c13d0000000601000029000000000f01043300000002010000290000000001010433000000000001004b0000409b0000613d001b00000001001d00000001010000290000000001010433001a00000001001d00190000000f001d0000000000f0043f0000000301000039000000200010043f000000000100041400001ba40010009c00001ba401008041000000c00110021000001c17011001c700008010020000396e8b6e860000040f0000000100200190000045b80000613d000000000101043b000000000201041a0000008805200272000040690000613d000000100220027000001c1f022001970000001a06000029000000000065004b0000001b030000290000406c0000c13d0000000004020019000000000203001900000000030600190000407c0000013d0000001b050000290000001a03000029000040950000013d00000000046200a9000000000002004b000040720000613d00000000022400d9000000000062004b000045c00000c13d00000000023500a900000000033200d9000000000053004b000045c00000c13d000000000006004b000045a00000613d00000000036500a900000000066300d9000000000056004b000045c00000c13d000000000042001a000045c00000413d0000000002420019000000000032004b000045a30000213d000000000423019f00001c5a0040009c000040860000813d0000000005020019000040950000013d000000000003004b000045ac0000613d00000000050300190000000006020019000000000405001900000000504600d9000000000005004b00000000060400190000408a0000c13d00000000054200d900001c1f0050009c000045c00000213d00000000034300d900001c1f0030009c000045c00000213d0000008802300210000000100350021000001c4203300197000000000223019f00000001022001bf000000000021041b000000400100043d001a00000001001d00001ba80010009c000045b20000213d000000090100002900000000040104330000001a030000290000004001300039000000400010043f00000020023000390000006001000039001200000002001d00000000001204350000000000030435001400260000002d001100000004001d0000002001400039001900000001001d00000000010104330000000002010433000000000002004b0000414e0000613d000000140300002900000120023000390000000002020433001700000002001d000000000203043300161ba70020019b000000030200002900001ba709200197000000000a000019001800000009001d000040c90000013d0000001602000029000000000309001900000017060000290000001a070000296e8b46c00000040f00000018090000290000001b0a000029000000010aa0003900000019010000290000000001010433000000000201043300000000002a004b0000414e0000813d0000000502a002100000000001210019000000200110003900000000040104330000000012040434000000050020008c000045cc0000213d000000400300043d00001bb40030009c000045b20000213d0000006005400039000000000505043300000040044000390000000004040433000000000101043300001ba701100197000000a006300039000000400060043f000000800630003900000000009604350000006006300039000000000056043500000040063000390000000000460435000000200630003900000000001604350000000000230435000000000002004b000040f10000613d000000010020008c001b0000000a001d000040fe0000613d000000020020008c000040bc0000c13d0000001602000029000000000309001900000017060000290000001a070000296e8b48f10000040f000040c10000013d00000000004101a0000045d50000c13d000000000005004b000045db0000613d0000000001000414000000040090008c001500000005001d000041090000c13d00000001010000310000000102000039000000000001004b0000411c0000c13d000041430000013d000000000004004b000045d50000c13d00000016020000290000000003090019000000000405001900000017050000290000001a060000296e8b604a0000040f0000001b0a0000290000001809000029000040c30000013d00001ba40010009c00001ba401008041000000c00110021000001bcd011001c70000800902000039000000000305001900000000040900190000000005000019001b0000000a001d6e8b6e810000040f0000001b0a0000290000001809000029000000010220018f0003000000010355000000600110027000011ba40010019d00001ba401100197000000000001004b000041430000613d00001bce0010009c000045b20000213d0000001f0310003900001c2b033001970000003f0330003900001c2b04300197000000400300043d0000000004430019000000000034004b0000000005000039000000010500403900001bce0040009c000045b20000213d0000000100500190000045b20000c13d000000400040043f000000000613043600001c2b0410019800000000034600190000000305000367000041360000613d000000000705034f000000007807043c0000000006860436000000000036004b000041320000c13d0000001f01100190000041430000613d000000000445034f0000000301100210000000000503043300000000051501cf000000000515022f000000000404043b0000010001100089000000000414022f00000000011401cf000000000151019f0000000000130435000000000002004b000040c30000c13d000000400100043d00000024021000390000001503000029000000000032043500001c4502000041000000000021043500000004021000390000000000920435000039bb0000013d00000011010000290000004001100039001900000001001d00000000010104330000000002010433000000000002004b000042090000613d0000000002000411001800000002001d00000000090000190000416b0000013d0000006001600039000000000501043300000080016000390000000002010433000000000103043300001ba70110019700001ba703200197000000180200002900000013060000290000001a070000296e8b48f10000040f0000001b090000290000000109900039000000190100002900000000010104330000000002010433000000000029004b000042090000813d00000005029002100000000001120019000000200110003900000000060104330000000031060434000000050010008c000045cc0000213d000000000001004b001b00000009001d000041900000c13d001700000003001d001500000006001d00000060016000390000000001010433001600000001001d00001c6c01000041000000000010044300000000010004100000000400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c27011001c70000800a020000396e8b6e860000040f0000000100200190000045c90000613d000000000101043b000000160010006b0000001b090000290000001703000029000045f40000213d00000015060000290000000001060433000000050010008c000045cc0000213d00000040026000390000000004020433000000000001004b000041b20000613d000000010010008c000041a40000613d000000020010008c000041590000613d0000006001600039000000000501043300000080016000390000000002010433000000000103043300001ba70110019700001ba703200197000000180200002900000013060000290000001a070000296e8b46c00000040f000041640000013d000000000004004b000045d50000c13d0000006001600039000000000401043300000080016000390000000002010433000000000103043300001ba70110019700001ba703200197000000180200002900000013050000290000001a060000296e8b604a0000040f000041640000013d000000000103043300001ba70110019700000000004101a0000045d50000c13d00000060016000390000000003010433000000000003004b000045db0000613d0000008001600039000000000101043300001ba7041001970000000001000414000000040040008c001700000003001d001600000004001d000041c70000c13d00000001010000310000000102000039000000000001004b000041d60000c13d000041fd0000013d00001ba40010009c00001ba401008041000000c00110021000001bcd011001c7000080090200003900000000050000196e8b6e810000040f0000001b09000029000000010220018f0003000000010355000000600110027000011ba40010019d00001ba401100197000000000001004b000041fd0000613d00001bce0010009c000045b20000213d0000001f0310003900001c2b033001970000003f0330003900001c2b04300197000000400300043d0000000004430019000000000034004b0000000005000039000000010500403900001bce0040009c000045b20000213d0000000100500190000045b20000c13d000000400040043f000000000613043600001c2b0410019800000000034600190000000305000367000041f00000613d000000000705034f000000007807043c0000000006860436000000000036004b000041ec0000c13d0000001f01100190000041fd0000613d000000000445034f0000000301100210000000000503043300000000051501cf000000000515022f000000000404043b0000010001100089000000000414022f00000000011401cf000000000151019f0000000000130435000000000002004b000041650000c13d000000400100043d00000024021000390000001703000029000000000032043500001c45020000410000000000210435000000040210003900000016030000290000000000320435000039bb0000013d000000120100002900000000010104330000000001010433000000000001004b000042eb0000613d0000001a010000290000000001010433001a00000001001d000000400100043d001b00000001001d000000200210003900001c4801000041001900000002001d000000000012043500001c100100004100000000001004430000000001000412000000040010044300000120010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f0000000100200190000045c90000613d000000000101043b0000001b0400002900000060024000390000001a030000290000000000320435000000400240003900001ba701100197000000000012043500001c100100004100000000001004430000000001000412000000040010044300000160010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f0000000100200190000045c90000613d000000000101043b0000001b04000029000000a00240003900001c4903000041000000000032043500000080024000390000000000120435000000a001000039000000000014043500001bd40040009c000045b20000213d0000001b02000029000000c001200039000000400010043f000000190100002900001ba40010009c00001ba4010080410000004001100210000000000202043300001ba40020009c00001ba4020080410000006002200210000000000112019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f0000000100200190000045b80000613d000000000101043b00001c4a02000041000000000020044300001ba701100197001b00000001001d0000000400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c27011001c700008002020000396e8b6e860000040f0000000100200190000045c90000613d000000400b00043d0000002404b000390000000403b00039000000000101043b000000000001004b000046060000613d0000001201000029000000000201043300001c4b0100004100000000001b043500000020010000390000000000130435000000000302043300000000003404350000004401b00039000000000003004b0000429e0000613d0000000004000019000000200220003900000000050204330000000067050434000000040070008c000045cc0000813d0000000007710436000000000606043300001ba70660019700000000006704350000004006500039000000000606043300001ba706600197000000400710003900000000006704350000006006500039000000000606043300001ba706600197000000600710003900000000006704350000008006500039000000000606043300000080071000390000000000670435000000a0055000390000000005050433000000a0061000390000000000560435000000c0011000390000000104400039000000000034004b0000427f0000413d00000000040004140000001b02000029000000040020008c000042a70000c13d0000000103000031000000200030008c00000020040000390000000004034019000042d80000013d0000000001b1004900001ba40010009c00001ba401008041000000600110021000001ba400b0009c00001ba40300004100000000030b40190000004003300210000000000131019f00001ba40040009c00001ba404008041000000c003400210000000000131019f001b0000000b001d6e8b6e810000040f0000001b0b0000290000000003010019000000600330027000001ba403300197000000200030008c000000200400003900000000040340190000001f0640018f000000200740019000000000057b0019000042c70000613d000000000801034f00000000090b0019000000008a08043c0000000009a90436000000000059004b000042c30000c13d000000000006004b000042d40000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f0000000000650435000100000003001f000300000001035500000001002001900000465d0000613d0000001f01400039000000600210018f0000000001b20019000000000021004b0000000002000039000000010200403900001bce0010009c000045b20000213d0000000100200190000045b20000c13d000000400010043f000000200030008c000045b80000413d00000000010b043300001c3f00100198000045b80000c13d00000060010000390000001202000029000000000012043500001c6c01000041000000000010044300000000010004100000000400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c27011001c70000800a020000396e8b6e860000040f0000000100200190000045c90000613d000000000101043b000000000001004b0000434f0000613d00001c6c01000041000000000010044300000000010004100000000400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c27011001c70000800a020000396e8b6e860000040f0000000100200190000045c90000613d000000000301043b000000000003004b000045db0000613d0000000001000414000000000200041100001ba704200197000000040040008c001b00000003001d001a00000004001d000043170000c13d00000001020000390000000101000031000000000001004b000043250000c13d0000434d0000013d00001ba40010009c00001ba401008041000000c00110021000001bcd011001c7000080090200003900000000050000196e8b6e810000040f000000010220018f0003000000010355000000600110027000011ba40010019d00001ba401100197000000000001004b0000434d0000613d00001bce0010009c000045b20000213d0000001f0410003900001c2b044001970000003f0440003900001c2b05400197000000400400043d0000000005540019000000000045004b0000000006000039000000010600403900001bce0050009c000045b20000213d0000000100600190000045b20000c13d000000400050043f000000000614043600001c2b031001980000001f0410018f00000000013600190000000305000367000043400000613d000000000705034f000000007807043c0000000006860436000000000016004b0000433c0000c13d000000000004004b0000434d0000613d000000000335034f0000000304400210000000000501043300000000054501cf000000000545022f000000000303043b0000010004400089000000000343022f00000000034301cf000000000353019f0000000000310435000000000002004b000046110000613d000000400100043d00001ba80010009c000045b20000213d0000004002100039000000400020043f0000000102000039000000000221043600000000030000310000000203300367000000000303043b0000000000320435000000060300002900000000030304330000000000320435000000140200002900000080022000390000000004020433000000040040008c000045cc0000213d0000000607000029000000000c0704330000000902000029000000000602043300001c6f05400197000000400d00043d000000140200002900000000f202043400001ba703200197000000020050008c000044290000c13d00000000020f043300001ba7022001970000000009000411000000000029004b000045390000613d00001c3d00d0009c000045b20000213d0000001404000029000000e004400039000000000504043300000040046000390000002006600039000000000a060433000000000b0404330000000a06000029000000800460003900000000080404330000000004060433000000a0064000390000000007060433000000c00440003900000000060404330000014004d00039000000400040043f0000012004d0003900000000005404350000010005d000390000000000650435000000e006d000390000000000760435000000c007d000390000000000170435000000a001d0003900000000008104350000008008d000390000000000b80435000000600bd000390000000000ab0435000000400ad0003900000000003a04350000002003d000390000000000930435001b0000000c001d0000000000cd043500001c4d09000041000000400e00043d00000000009e04350000000409e00039000000200c0000390000000000c9043500000000090d0433000000240ce0003900000000009c0435000000000303043300001ba7033001970000004409e00039000000000039043500000000030a043300001ba7033001970000006409e00039000000000039043500000000090b04330000014003000039000000840ae0003900000000003a04350000016403e00039000000000a0904330000000000a30435001a0000000e001d0000018403e0003900000000000a004b000043cb0000613d000000000b0000190000002009900039000000000c09043300000000de0c04340000000500e0008c000045cc0000213d000000000ee30436000000000d0d043300001ba70dd001970000000000de0435000000400dc00039000000000d0d0433000000400e3000390000000000de0435000000600cc00039000000000c0c0433000000600d3000390000000000cd04350000008003300039000000010bb000390000000000ab004b000043b60000413d0000001a0a0000290000000009a30049000000240990008a0000000008080433000000a40aa0003900000000009a043500000000090804330000000003930436000000000009004b000043f00000613d000000000a0000190000002008800039000000000b08043300000000cd0b04340000000500d0008c000045cc0000213d000000000dd30436000000000c0c043300001ba70cc001970000000000cd0435000000400cb00039000000000c0c0433000000400d3000390000000000cd0435000000600cb00039000000000c0c0433000000600d3000390000000000cd0435000000800bb00039000000000b0b043300001ba70bb00197000000800c3000390000000000bc0435000000a003300039000000010aa0003900000000009a004b000043d60000413d0000001a0c0000290000000008c30049000000240880008a0000000001010433000000c409c00039000000000089043500000000980104340000000001830436000000000008004b000044020000613d0000000003000019000000000a130019000000000b390019000000000b0b04330000000000ba04350000002003300039000000000083004b000043fb0000413d000000000381001900000000000304350000001f0380003900001c2b0330019700000000013100190000000003c10049000000240830008a0000000003070433000000e407c00039000000000087043500000000070304330000000001710436000000000007004b000044170000613d00000000080000190000002003300039000000000903043300000000019104360000000108800039000000000078004b000044110000413d00000000030604330000010406c00039000000000036043500000000030504330000012405c0003900000000003504350000014403c00039000000000404043300000000004304350000000003000414000000040020008c000044f20000c13d0000000103000031000000200030008c000000200400003900000000040340190000001b02000029000045250000013d000000040040008c000045390000c13d001b0000000c001d0000000a0400002900000080044000390000000004040433000000400560003900000000050504330000002006600039000000000706043300001c6d0600004100000000006d04350000000406d00039000000a0080000390000000000860435000000a406d0003900000000080704330000000000860435000000c406d00039000000000008004b000044540000613d00000000090000190000002007700039000000000a07043300000000bc0a04340000000500c0008c000045cc0000213d000000000cc60436000000000b0b043300001ba70bb001970000000000bc0435000000400ba00039000000000b0b0433000000400c6000390000000000bc0435000000600aa00039000000000a0a0433000000600b6000390000000000ab043500000080066000390000000109900039000000000089004b0000443f0000413d0000000007d60049000000040770008a0000002408d00039000000000078043500000000070504330000000006760436000000000007004b000044770000613d00000000080000190000002005500039000000000905043300000000ab0904340000000500b0008c000045cc0000213d000000000bb60436000000000a0a043300001ba70aa001970000000000ab0435000000400a900039000000000a0a0433000000400b6000390000000000ab0435000000600a900039000000000a0a0433000000600b6000390000000000ab04350000008009900039000000000909043300001ba709900197000000800a60003900000000009a0435000000a0066000390000000108800039000000000078004b0000445d0000413d0000000005d60049000000040550008a0000004407d00039000000000057043500000000750404340000000004560436000000000005004b000044870000613d000000000600001900000000084600190000000009670019000000000909043300000000009804350000002006600039000000000056004b000044800000413d000000000654001900000000000604350000001f0550003900001c2b0550019700000000045400190000000005d40049000000040550008a0000006406d00039000000000056043500000000050104330000000004540436000000000005004b0000001b080000290000449c0000613d00000000060000190000002001100039000000000701043300000000047404360000000106600039000000000056004b000044960000413d0000006001200210000000000181013f0000008402d0003900000000001204350000000001000414000000040030008c000044a80000c13d0000000103000031000000200030008c00000020040000390000000004034019000044dd0000013d00190000000f001d0000000002d4004900001ba40020009c00001ba402008041000000600220021000001ba400d0009c00001ba40400004100000000040d40190000004004400210000000000242019f00001ba40010009c00001ba401008041000000c001100210000000000112019f0000000002030019001a0000000d001d6e8b6e810000040f0000001a0d0000290000000003010019000000600330027000001ba403300197000000200030008c000000200400003900000000040340190000001f0640018f000000200740019000000000057d0019000044ca0000613d000000000801034f00000000090d0019000000008a08043c0000000009a90436000000000059004b000044c60000c13d000000000006004b000044d70000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f0000000000650435000100000003001f00030000000103550000000100200190000000190f0000290000001b080000290000467c0000613d0000001f01400039000000600210018f0000000001d20019000000000021004b0000000002000039000000010200403900001bce0010009c000045b20000213d0000000100200190000045b20000c13d000000400010043f000000200030008c000045b80000413d00000000020d043300001c3f00200198000045b80000c13d00001c400220019700001c6d0020009c000046690000c13d000000000d010019000045380000013d00190000000f001d0000000001c1004900001ba40010009c00001ba401008041000000600110021000001ba400c0009c00001ba40400004100000000040c40190000004004400210000000000141019f00001ba40030009c00001ba403008041000000c003300210000000000113019f6e8b6e810000040f0000001a0c0000290000000003010019000000600330027000001ba403300197000000200030008c000000200400003900000000040340190000001f0640018f000000200740019000000000057c0019000045120000613d000000000801034f00000000090c0019000000008a08043c0000000009a90436000000000059004b0000450e0000c13d000000000006004b0000451f0000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f0000000000650435000100000003001f00030000000103550000000100200190000000190f0000290000001b02000029000046880000613d0000001f01400039000000600110018f000000000dc1001900000000001d004b0000000001000039000000010100403900001bce00d0009c000045b20000213d0000000100100190000045b20000c13d0000004000d0043f000000200030008c000045b80000413d00000000010c043300001c3f00100198000045b80000c13d00001c400110019700001c4d0010009c0000466e0000c13d000000060700002900000009010000290000000004010433000000400140003900000000030104330000001401000029000000000101043300000000020f04330000002004400039000000000404043300000000050704330000004006d0003900000080070000390000000000760435000000030600002900001ba7066001970000002007d00039000000000067043500000000005d04350000008005d0003900000000060404330000000000650435000000a005d00039000000000006004b000045670000613d000000000700001900000020044000390000000008040433000000009a0804340000000500a0008c000045cc0000213d000000000aa50436000000000909043300001ba70990019700000000009a043500000040098000390000000009090433000000400a50003900000000009a0435000000600880003900000000080804330000006009500039000000000089043500000080055000390000000107700039000000000067004b000045520000413d0000000004d500490000006006d00039000000000046043500000000060304330000000004650436000000000006004b000045890000613d0000000005000019000000200330003900000000070304330000000089070434000000050090008c000045cc0000213d0000000009940436000000000808043300001ba7088001970000000000890435000000400870003900000000080804330000004009400039000000000089043500000060087000390000000008080433000000600940003900000000008904350000008007700039000000000707043300001ba70770019700000080084000390000000000780435000000a0044000390000000105500039000000000065004b0000456f0000413d00001ba70620019700001ba7051001970000000001d4004900001ba40010009c00001ba401008041000000600110021000001ba400d0009c00001ba40d0080410000004002d00210000000000121019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000121019f00001bcd011001c70000800d02000039000000030300003900001c3c040000416e8b6e810000040f0000000100200190000045b80000613d000000000001042d0000000003000019000000000032004b000040810000a13d000000400100043d00001c200200004100000000002104350000000402100039000000190300002900003fc20000013d000000000005004b0000000003050019000037890000c13d00001c1401000041000000000010043f0000001201000039000000040010043f00001c150100004100006e8d0001043000001c1401000041000000000010043f0000004101000039000000040010043f00001c150100004100006e8d00010430000000000100001900006e8d0001043000001c1401000041000000000010043f0000003201000039000000040010043f00001c150100004100006e8d0001043000001c1401000041000000000010043f0000001101000039000000040010043f00001c150100004100006e8d00010430000000400100043d00001c6502000041000045f60000013d000000000001042f000000010020008c000045de0000a13d00001c1401000041000000000010043f0000002101000039000000040010043f00001c150100004100006e8d00010430000000400100043d00001c6102000041000045f60000013d000000400100043d00001c4e02000041000045f60000013d000000400100043d00001c5e02000041000045f60000013d000000400100043d00001c4602000041000045f60000013d000000400300043d001b00000003001d00001c5d01000041000000000013043500000004013000396e8b5fad0000040f0000001b02000029000000000121004900001ba40010009c00001ba401008041000000600110021000001ba40020009c00001ba4020080410000004002200210000000000121019f00006e8d00010430000000400100043d00001c5f02000041000045f60000013d000000400100043d00001c6402000041000045f60000013d000000400100043d00001c4702000041000000000021043500001ba40010009c00001ba401008041000000400110021000001bd6011001c700006e8d00010430000000400100043d0000002402100039000000000042043500001c350200004100000000002104350000000402100039000042070000013d000000400100043d00001c5c02000041000045f60000013d00001c4c0100004100000000001b04350000001a0100002900000000001304350000001b01000029000000000014043500001ba400b0009c00001ba40b0080410000004001b0021000001c36011001c700006e8d00010430000000400100043d00000024021000390000001b03000029000000000032043500001c4502000041000000000021043500000004021000390000001a03000029000042070000013d000000400100043d00001c5b02000041000045f60000013d000000400100043d00001c1e03000041000046220000013d000000400100043d00001c200300004100000000003104350000000403100039000000000023043500003fc30000013d000000400100043d00001c2102000041000045f60000013d6e8b27330000040f00001c6e01000041000000400200043d000000000012043500000004012000390000001403000029000000000031043500001ba40020009c00001ba402008041000000400120021000001c15011001c700006e8d0001043000030000000103550000000002010019000000600220027000011ba40020019d00001ba4022001970000463d0000013d0000000301000367000000010200003100001c2b052001980000001f0620018f000000400300043d0000000004530019000046480000613d000000000701034f0000000008030019000000007907043c0000000008980436000000000048004b000046440000c13d000000000006004b000046550000613d000000000151034f0000000305600210000000000604043300000000065601cf000000000656022f000000000101043b0000010005500089000000000151022f00000000015101cf000000000161019f000000000014043500001ba40030009c00001ba403008041000000400130021000001ba40020009c00001ba4020080410000006002200210000000000112019f00006e8d000104300000001f0530018f00001ba606300198000000400200043d0000000004620019000046930000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000046640000c13d000046930000013d00001c6e0200004100000000002104350000000402100039000000000082043500003fc30000013d00001c410100004100000000001d04350000000401d00039000000000021043500001ba400d0009c00001ba40d0080410000004001d0021000001c15011001c700006e8d0001043000001c4102000041000000000021043500000004021000390000000000f2043500003fc30000013d0000001f0530018f00001ba606300198000000400200043d0000000004620019000046930000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000046830000c13d000046930000013d0000001f0530018f00001ba606300198000000400200043d0000000004620019000046930000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b0000468f0000c13d000000000005004b000046a00000613d000000000161034f0000000305500210000000000604043300000000065601cf000000000656022f000000000101043b0000010005500089000000000151022f00000000015101cf000000000161019f0000000000140435000000600130021000001ba40020009c00001ba4020080410000004002200210000000000112019f00006e8d000104300000001f0530018f00001ba606300198000000400200043d0000000004620019000046b10000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000046ad0000c13d000000000005004b000046be0000613d000000000161034f0000000305500210000000000604043300000000065601cf000000000656022f000000000101043b0000010005500089000000000151022f00000000015101cf000000000161019f00000000001404350000006001300210000045e90000013d000b000000000002000700000004001d000800000003001d000900000002001d000a00000001001d000600000005001d000000000005004b000048a30000613d0000000012070434000b00000001001d000000000062004b000047b00000613d0000000b0100002900000000010104330000000001010433000000000001004b000047b00000613d000400000002001d000100000006001d000200000007001d000000400100043d000500000001001d000000200210003900001c4801000041000300000002001d000000000012043500001c100100004100000000001004430000000001000412000000040010044300000120010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f0000000100200190000048a00000613d000000000101043b0000000504000029000000600240003900000004030000290000000000320435000000400240003900001ba701100197000000000012043500001c100100004100000000001004430000000001000412000000040010044300000160010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f0000000100200190000048a00000613d000000000101043b0000000504000029000000a00240003900001c4903000041000000000032043500000080024000390000000000120435000000a001000039000000000014043500001c700040009c000048940000813d0000000502000029000000c001200039000000400010043f000000030100002900001ba40010009c00001ba4010080410000004001100210000000000202043300001ba40020009c00001ba4020080410000006002200210000000000112019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f0000000100200190000048a10000613d000000000101043b00001c4a02000041000000000020044300001ba701100197000500000001001d0000000400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c27011001c700008002020000396e8b6e860000040f0000000100200190000048a00000613d000000400b00043d0000002404b000390000000403b00039000000000101043b000000000001004b000048b50000613d0000000b01000029000000000201043300001c4b0100004100000000001b043500000020010000390000000000130435000000000302043300000000003404350000004401b00039000000000003004b000047610000613d0000000004000019000000200220003900000000050204330000000067050434000000040070008c0000489a0000813d0000000007710436000000000606043300001ba70660019700000000006704350000004006500039000000000606043300001ba706600197000000400710003900000000006704350000006006500039000000000606043300001ba706600197000000600710003900000000006704350000008006500039000000000606043300000080071000390000000000670435000000a0055000390000000005050433000000a0061000390000000000560435000000c0011000390000000104400039000000000034004b000047420000413d00000000040004140000000502000029000000040020008c0000476a0000c13d0000000103000031000000200030008c000000200400003900000000040340190000479b0000013d0000000001b1004900001ba40010009c00001ba401008041000000600110021000001ba400b0009c00001ba40300004100000000030b40190000004003300210000000000131019f00001ba40040009c00001ba404008041000000c003400210000000000131019f00050000000b001d6e8b6e810000040f000000050b0000290000000003010019000000600330027000001ba403300197000000200030008c000000200400003900000000040340190000001f0640018f000000200740019000000000057b00190000478a0000613d000000000801034f00000000090b0019000000008a08043c0000000009a90436000000000059004b000047860000c13d000000000006004b000047970000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f0000000000650435000100000003001f00030000000103550000000100200190000048cd0000613d0000001f01400039000000600210018f0000000001b20019000000000021004b0000000002000039000000010200403900001bce0010009c000048940000213d0000000100200190000048940000c13d000000400010043f000000200030008c000048a10000413d00000000010b043300001c3f00100198000048a10000c13d00000060010000390000000b02000029000000000012043500000002070000290000000106000029000000000006004b0000483c0000613d000000000f060019000000000e0700190000000b0100002900000000010104330000000001010433000000010010003a000048eb0000413d000000010310003900001bce0030009c000048940000213d00000005043002100000003f0240003900001c0e05200197000000400200043d0000000005520019000000000025004b0000000006000039000000010600403900001bce0050009c000048940000213d0000000100600190000048940000c13d000000400050043f00000000033204360000000005000019000000400600043d00001bd40060009c000048940000213d000000c007600039000000400070043f000000a0076000390000000000070435000000800760003900000000000704350000006007600039000000000007043500000040076000390000000000070435000000200760003900000000000704350000000000060435000000000753001900000000006704350000002005500039000000000045004b000047cb0000413d000000000001004b000048160000613d00000000040000190000000b0500002900000000060504330000000005060433000000000045004b0000488e0000a13d00000005054002100000000006650019000000200660003900000000080604330000000097080434000000030070008c0000489a0000213d000000400600043d00001bd40060009c000048940000213d0000000009090433000000400a800039000000000a0a0433000000600b800039000000000b0b0433000000800c800039000000000c0c0433000000a0088000390000000008080433000000c00d6000390000004000d0043f000000a00d60003900000000008d043500000080086000390000000000c8043500001ba708b00197000000600b60003900000000008b043500001ba708a00197000000400a60003900000000008a043500001ba7089001970000002009600039000000000089043500000000007604350000000007020433000000000047004b0000488e0000a13d000000000553001900000000006504350000000005020433000000000045004b0000488e0000a13d0000000104400039000000000014004b000047e30000413d000000400400043d00001bd40040009c000048940000213d000000c005400039000000400050043f000000a00540003900000006060000290000000000650435000000800540003900000007060000290000000000650435000000080500002900001ba70550019700000060064000390000000000560435000000090500002900001ba705500197000000400640003900000000005604350000000a0500002900001ba70550019700000020064000390000000000560435000000030500003900000000005404350000000005020433000000000015004b0000488e0000a13d0000000505100210000000000353001900000000004304350000000003020433000000000013004b0000488e0000a13d0000000b0100002900000000002104350000000000fe0435000000000001042d00001c4a0100004100000000001004430000000a010000290000000400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c27011001c700008002020000396e8b6e860000040f0000000100200190000048a00000613d0000000a0200002900001ba703200197000000000101043b000000000001004b000048ab0000613d00001c4a010000410000000000100443000b00000003001d0000000400300443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c27011001c700008002020000396e8b6e860000040f0000000100200190000048a00000613d000000000101043b000000000001004b000048a10000613d000000400400043d0000008401400039000000a0020000390000000000210435000000640140003900000006020000290000000000210435000000440140003900000007020000290000000000210435000000080100002900001ba7011001970000002402400039000000000012043500001c71010000410000000000140435000000090100002900001ba70110019700000004024000390000000000120435000000a401400039000000000001043500000000010004140000000b02000029000000040020008c0000488a0000613d00001ba40040009c00001ba4030000410000000003044019000000400330021000001ba40010009c00001ba401008041000000c001100210000000000131019f00001c72011001c7000b00000004001d6e8b6e810000040f0000000b040000290000000003010019000000600330027000011ba40030019d00030000000103550000000100200190000048c00000613d00001bce0040009c000048940000213d000000400040043f000000000001042d00001c1401000041000000000010043f0000003201000039000000040010043f00001c150100004100006e8d0001043000001c1401000041000000000010043f0000004101000039000000040010043f00001c150100004100006e8d0001043000001c1401000041000000000010043f0000002101000039000000040010043f00001c150100004100006e8d00010430000000000001042f000000000100001900006e8d00010430000000400100043d00001c4602000041000000000021043500001ba40010009c00001ba401008041000000400110021000001bd6011001c700006e8d00010430000000400100043d00001c730200004100000000002104350000000402100039000000000032043500001ba40010009c00001ba401008041000000400110021000001c15011001c700006e8d0001043000001c4c0100004100000000001b0435000000040100002900000000001304350000000501000029000000000014043500001ba400b0009c00001ba40b0080410000004001b0021000001c36011001c700006e8d0001043000001ba4033001970000001f0530018f00001ba606300198000000400200043d0000000004620019000048d80000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000048c80000c13d000048d80000013d0000001f0530018f00001ba606300198000000400200043d0000000004620019000048d80000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000048d40000c13d000000000005004b000048e50000613d000000000161034f0000000305500210000000000604043300000000065601cf000000000656022f000000000101043b0000010005500089000000000151022f00000000015101cf000000000161019f0000000000140435000000600130021000001ba40020009c00001ba4020080410000004002200210000000000112019f00006e8d0001043000001c1401000041000000000010043f0000001101000039000000040010043f00001c150100004100006e8d00010430000b000000000002000800000004001d000900000003001d000a00000002001d000b00000001001d000600000007001d00000000f2070434000000000062004b000700000006001d000049de0000613d00000000010f04330000000001010433000000000001004b000049de0000613d000300000002001d000100000005001d00040000000f001d000000400100043d000500000001001d000000200210003900001c4801000041000200000002001d000000000012043500001c100100004100000000001004430000000001000412000000040010044300000120010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f000000010020019000004ac50000613d000000000101043b0000000504000029000000600240003900000003030000290000000000320435000000400240003900001ba701100197000000000012043500001c100100004100000000001004430000000001000412000000040010044300000160010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f000000010020019000004ac50000613d000000000101043b0000000504000029000000a00240003900001c4903000041000000000032043500000080024000390000000000120435000000a001000039000000000014043500001c700040009c00004ab90000813d0000000502000029000000c001200039000000400010043f000000020100002900001ba40010009c00001ba4010080410000004001100210000000000202043300001ba40020009c00001ba4020080410000006002200210000000000112019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f000000010020019000004ac60000613d000000000101043b00001c4a02000041000000000020044300001ba701100197000500000001001d0000000400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c27011001c700008002020000396e8b6e860000040f000000010020019000004ac50000613d000000400b00043d0000002404b000390000000403b00039000000000101043b000000000001004b00004ad80000613d0000000401000029000000000201043300001c4b0100004100000000001b043500000020010000390000000000130435000000000302043300000000003404350000004401b00039000000000003004b0000498f0000613d0000000004000019000000200220003900000000050204330000000067050434000000040070008c00004abf0000813d0000000007710436000000000606043300001ba70660019700000000006704350000004006500039000000000606043300001ba706600197000000400710003900000000006704350000006006500039000000000606043300001ba706600197000000600710003900000000006704350000008006500039000000000606043300000080071000390000000000670435000000a0055000390000000005050433000000a0061000390000000000560435000000c0011000390000000104400039000000000034004b000049700000413d00000000040004140000000502000029000000040020008c000049980000c13d0000000103000031000000200030008c00000020040000390000000004034019000049c90000013d0000000001b1004900001ba40010009c00001ba401008041000000600110021000001ba400b0009c00001ba40300004100000000030b40190000004003300210000000000131019f00001ba40040009c00001ba404008041000000c003400210000000000131019f00050000000b001d6e8b6e810000040f000000050b0000290000000003010019000000600330027000001ba403300197000000200030008c000000200400003900000000040340190000001f0640018f000000200740019000000000057b0019000049b80000613d000000000801034f00000000090b0019000000008a08043c0000000009a90436000000000059004b000049b40000c13d000000000006004b000049c50000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f0000000000650435000100000003001f0003000000010355000000010020019000004af00000613d0000001f01400039000000600210018f0000000001b20019000000000021004b0000000002000039000000010200403900001bce0010009c00004ab90000213d000000010020019000004ab90000c13d000000400010043f000000200030008c00004ac60000413d00000000010b043300001c3f0010019800004ac60000c13d0000006001000039000000040f00002900000000001f043500000007060000290000000105000029000000000006004b00004a670000613d000000000e05001900000000010f04330000000001010433000000010010003a00004b0e0000413d000000010310003900001bce0030009c00004ab90000213d00000005043002100000003f0240003900001c0e05200197000000400200043d0000000005520019000000000025004b0000000006000039000000010600403900001bce0050009c00004ab90000213d000000010060019000004ab90000c13d000000400050043f00000000033204360000000005000019000000400600043d00001bd40060009c00004ab90000213d000000c007600039000000400070043f000000a0076000390000000000070435000000800760003900000000000704350000006007600039000000000007043500000040076000390000000000070435000000200760003900000000000704350000000000060435000000000753001900000000006704350000002005500039000000000045004b000049f70000413d000000000001004b00004a410000613d000000000400001900000000060f04330000000005060433000000000045004b00004ab30000a13d00000005054002100000000006650019000000200660003900000000080604330000000097080434000000030070008c00004abf0000213d000000400600043d00001bd40060009c00004ab90000213d0000000009090433000000400a800039000000000a0a0433000000600b800039000000000b0b0433000000800c800039000000000c0c0433000000a0088000390000000008080433000000c00d6000390000004000d0043f000000a00d60003900000000008d043500000080086000390000000000c8043500001ba708b00197000000600b60003900000000008b043500001ba708a00197000000400a60003900000000008a043500001ba7089001970000002009600039000000000089043500000000007604350000000007020433000000000047004b00004ab30000a13d000000000553001900000000006504350000000005020433000000000045004b00004ab30000a13d0000000104400039000000000014004b00004a0f0000413d000000400400043d00001bd40040009c00004ab90000213d000000c005400039000000400050043f000000a0054000390000000000e50435000000800540003900000008060000290000000000650435000000090500002900001ba705500197000000600640003900000000005604350000000a0500002900001ba705500197000000400640003900000000005604350000000b0500002900001ba70550019700000020064000390000000000560435000000020500003900000000005404350000000005020433000000000015004b00004ab30000a13d0000000505100210000000000353001900000000004304350000000003020433000000000013004b00004ab30000a13d00000000002f0435000000060100002900000007020000290000000000210435000000000001042d000000010050008c00004ac80000c13d00001c4a0100004100000000001004430000000b010000290000000400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c27011001c700008002020000396e8b6e860000040f000000010020019000004ac50000613d0000000b0200002900001ba703200197000000000101043b000000000001004b00004ace0000613d00001c4a010000410000000000100443000b00000003001d0000000400300443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c27011001c700008002020000396e8b6e860000040f000000010020019000004ac50000613d000000000101043b000000000001004b00004ac60000613d000000400400043d000000440140003900000008020000290000000000210435000000090100002900001ba7011001970000002402400039000000000012043500001c750100004100000000001404350000000a0100002900001ba7011001970000000402400039000000000012043500000000010004140000000b02000029000000040020008c00004aaf0000613d00001ba40040009c00001ba4030000410000000003044019000000400330021000001ba40010009c00001ba401008041000000c001100210000000000131019f00001c76011001c7000b00000004001d6e8b6e810000040f0000000b040000290000000003010019000000600330027000011ba40030019d0003000000010355000000010020019000004ae30000613d00001bce0040009c00004ab90000213d000000400040043f000000000001042d00001c1401000041000000000010043f0000003201000039000000040010043f00001c150100004100006e8d0001043000001c1401000041000000000010043f0000004101000039000000040010043f00001c150100004100006e8d0001043000001c1401000041000000000010043f0000002101000039000000040010043f00001c150100004100006e8d00010430000000000001042f000000000100001900006e8d00010430000000400100043d00001c740200004100000000002104350000000402100039000000000052043500004ad30000013d000000400100043d00001c730200004100000000002104350000000402100039000000000032043500001ba40010009c00001ba401008041000000400110021000001c15011001c700006e8d0001043000001c4c0100004100000000001b0435000000030100002900000000001304350000000501000029000000000014043500001ba400b0009c00001ba40b0080410000004001b0021000001c36011001c700006e8d0001043000001ba4033001970000001f0530018f00001ba606300198000000400200043d000000000462001900004afb0000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b00004aeb0000c13d00004afb0000013d0000001f0530018f00001ba606300198000000400200043d000000000462001900004afb0000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b00004af70000c13d000000000005004b00004b080000613d000000000161034f0000000305500210000000000604043300000000065601cf000000000656022f000000000101043b0000010005500089000000000151022f00000000015101cf000000000161019f0000000000140435000000600130021000001ba40020009c00001ba4020080410000004002200210000000000112019f00006e8d0001043000001c1401000041000000000010043f0000001101000039000000040010043f00001c150100004100006e8d000104300023000000000002000100000003001d000001e00020043f000001400040043f001000000001001d0000000012010434000300000001001d00001c310020009c000059db0000813d00000005012002100000003f0310003900001c0e03300197000000400400043d0000000003340019001200000004001d000000000043004b0000000004000039000000010400403900001bce0030009c000059db0000213d0000000100400190000059db0000c13d000000400030043f00000012030000290000000002230436000f00000002001d0000001f0210018f000000000001004b00004b390000613d0000000f04000029000000000114001900000000030000310000000203300367000000003503043c0000000004540436000000000014004b00004b350000c13d000000000002004b0000001001000029000000000201043300001bce0020009c000059db0000213d0000000501200210000000400300043d000001600030043f0000003f0410003900001c0e044001970000000004430019000000000034004b0000000005000039000000010500403900001bce0040009c000059db0000213d0000000100500190000059db0000c13d000000400040043f0000000000230435000000000002004b00004b5e0000613d0000000002000019000000400300043d00001ba80030009c000059db0000213d0000004004300039000000400040043f0000002004300039000000000004043500000000000304350000002002200039000001600400043d00000000044200190000000000340435000000000012004b00004b500000413d002300000000003d00000010010000290000000001010433000000000001004b000052940000613d000200000000001d001300000000001d0000000002000019000c00000002001d0000000502200210000b00000002001d00000003012000290000000005010433000001a00050043f000000400400043d00001c3a0040009c000059db0000213d000001400100043d0000000001010433000e00000001001d0000008001400039000000400010043f00000040014000390000000000010435000000200140003900000000000104350000000000040435000000400100043d00001c120010009c000059db0000213d000000e002100039000000400020043f000000c00210003900000060030000390000000000320435000000a0021000390000000000320435000000400210003900000000003204350000002002100039000000000032043500000080021000390000000000020435000000600210003900000000000204350000000000010435000900000004001d00000060024000390000000000120435000a00000005001d0000000012050434000800000001001d000000c0012000390000000001010433001100000001001d000d00000002001d000000a0012000390000000001010433001400000001001d00001c34010000410000000000100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001bd3011001c70000800b020000396e8b6e860000040f0000000100200190000059fc0000613d000000000101043b0000001403000029000000000031004b00004ce60000413d000000110010006c00004ce60000813d0000000d0100002900000080011000390000000001010433000000040010008c00005a0c0000213d0000000a020000290000004002200039000000000202043300001c1f042001970000000802000029000000000202043300001c1f0320019700004e100000c13d000000010030008c00005a310000c13d000000010040008c00005a310000c13d000000400100043d00001c120010009c000059db0000213d000000e002100039000000400020043f000000c00210003900000060030000390000000000320435000000a00210003900000000003204350000004002100039000000000032043500000020021000390000000000320435000000800210003900000000000204350000006002100039000000000002043500000000000104350000000d0100002900000040011000390000000004010433000000005304043400001bce0030009c000059db0000213d00000005023002100000003f0120003900001c0e06100197000000400100043d0000000006610019001400000001001d000000000016004b0000000007000039000000010700403900001bce0060009c000059db0000213d0000000100700190000059db0000c13d000000400060043f00000014010000290000000006310436000000000003004b00004bf80000613d0000000003000019000000400700043d00001c3a0070009c000059db0000213d0000008008700039000000400080043f0000006008700039000000000008043500000040087000390000000000080435000000200870003900000000000804350000000000070435000000000836001900000000007804350000002003300039000000000023004b00004be70000413d000000000304043300001bce0030009c000059db0000213d00000005083002100000003f0280003900001c0e07200197000000400100043d0000000007710019001100000001001d000000000017004b0000000009000039000000010900403900001bce0070009c000059db0000213d0000000100900190000059db0000c13d000000400070043f0000001101000029000000000731043600000000030000310000000203300367000000000008004b00004c160000613d0000000009870019000000000a03034f000000000b07001900000000ac0a043c000000000bcb043600000000009b004b00004c120000c13d0000001f008001900000000008040433000000000008004b00004c480000613d00000000080000190000000509800210000000000a950019000000000d0a043300000000ec0d04340000000500c0008c00005a0c0000213d000000400b00043d00001c3a00b0009c000059db0000213d000000600ad00039000000000e0e0433000000400dd00039000000000d0d0433000000000f0a04330000008002b00039000000400020043f0000006002b000390000000000f204350000004002b000390000000000d2043500001ba702e00197000000200db0003900000000002d04350000000000cb043500000014010000290000000002010433000000000082004b000059d50000a13d00000000029600190000000000b2043500000014010000290000000002010433000000000082004b000059d50000a13d00000011010000290000000002010433000000000082004b000059d50000a13d000000000279001900000000090a0433000000000092043500000001088000390000000002040433000000000028004b00004c1b0000413d0000000d01000029000000600410003900000000050404330000000019050434000e00000001001d00001bce0090009c000059db0000213d00000005089002100000003f0480003900001c0e07400197000000400400043d0000000007740019000000000047004b000000000a000039000000010a00403900001bce0070009c000059db0000213d0000000100a00190000059db0000c13d000000400070043f0000000007940436000000000009004b00004c730000613d0000000009000019000000400a00043d00001bb400a0009c000059db0000213d000000a00ba000390000004000b0043f000000800ba0003900000000000b0435000000600ba0003900000000000b0435000000400ba0003900000000000b0435000000200ba0003900000000000b043500000000000a0435000000000b9700190000000000ab04350000002009900039000000000089004b00004c600000413d000000000905043300001bce0090009c000059db0000213d000000050a9002100000003f08a0003900001c0e0b800197000000400800043d000000000bb8001900000000008b004b000000000c000039000000010c00403900001bce00b0009c000059db0000213d0000000100c00190000059db0000c13d0000004000b0043f000000000998043600000000000a004b00004c8c0000613d000000000ba90019000000000c090019000000003d03043c000000000cdc04360000000000bc004b00004c880000c13d0000001f00a001900000000003050433000000000003004b00004cc00000613d0000000003000019000000050a3002100000000e02a00029000000000e02043300000000fd0e04340000000500d0008c00005a0c0000213d000000400c00043d00001bb400c0009c000059db0000213d000000600be0003900000000020f0433000000400fe00039000000000f0f043300000000060b0433000000a00ee00039000000000e0e0433000000a001c00039000000400010043f00001ba701e00197000000800ec0003900000000001e04350000006001c0003900000000006104350000004001c000390000000000f1043500001ba7012001970000002002c0003900000000001204350000000000dc04350000000001040433000000000031004b000059d50000a13d0000000001a700190000000000c104350000000001040433000000000031004b000059d50000a13d0000000001080433000000000031004b000059d50000a13d00000000019a001900000000020b0433000000000021043500000001033000390000000001050433000000000013004b00004c910000413d000000400600043d00001c120060009c000059db0000213d0000000d02000029000000000102043300000120022000390000000002020433000000e003600039000000400030043f000000c0036000390000000000830435000000a00360003900000011050000290000000000530435000000800360003900000001050000390000000000530435000000600360003900000000002304350000004002600039000000000042043500000020026000390000001403000029000000000032043500001ba7011001970000000000160435000000400100043d00001c3a0010009c000059db0000213d0000008002100039000000400020043f00000001030000390000000002310436001400000002001d00000000003204350000000002030019000000000403001900004f650000013d000000400100043d0000000e0000006b00005a250000c13d00001c120010009c000059db0000213d000000e002100039000000400020043f000000c00210003900000060030000390000000000320435000000a00210003900000000003204350000004002100039000000000032043500000020021000390000000000320435000000800210003900000000000204350000006002100039000000000002043500000000000104350000000d0100002900000040011000390000000004010433000000005304043400001bce0030009c000059db0000213d00000005023002100000003f0120003900001c0e06100197000000400100043d0000000006610019001400000001001d000000000016004b0000000007000039000000010700403900001bce0060009c000059db0000213d0000000100700190000059db0000c13d000000400060043f00000014010000290000000006310436000000000003004b00004d250000613d0000000003000019000000400700043d00001c3a0070009c000059db0000213d0000008008700039000000400080043f0000006008700039000000000008043500000040087000390000000000080435000000200870003900000000000804350000000000070435000000000836001900000000007804350000002003300039000000000023004b00004d140000413d000000000304043300001bce0030009c000059db0000213d00000005083002100000003f0280003900001c0e07200197000000400100043d0000000007710019001100000001001d000000000017004b0000000009000039000000010900403900001bce0070009c000059db0000213d0000000100900190000059db0000c13d000000400070043f0000001101000029000000000731043600000000030000310000000203300367000000000008004b00004d430000613d0000000009870019000000000a03034f000000000b07001900000000ac0a043c000000000bcb043600000000009b004b00004d3f0000c13d0000001f008001900000000008040433000000000008004b00004d750000613d00000000080000190000000509800210000000000a950019000000000d0a043300000000ec0d04340000000600c0008c00005a0c0000813d000000400b00043d00001c3a00b0009c000059db0000213d000000600ad00039000000000e0e0433000000400dd00039000000000d0d0433000000000f0a04330000008002b00039000000400020043f0000006002b000390000000000f204350000004002b000390000000000d2043500001ba702e00197000000200db0003900000000002d04350000000000cb043500000014010000290000000002010433000000000082004b000059d50000a13d00000000029600190000000000b2043500000014010000290000000002010433000000000082004b000059d50000a13d00000011010000290000000002010433000000000082004b000059d50000a13d000000000279001900000000090a0433000000000092043500000001088000390000000002040433000000000028004b00004d480000413d0000000d01000029000000600410003900000000050404330000000019050434000e00000001001d00001bce0090009c000059db0000213d00000005089002100000003f0480003900001c0e07400197000000400400043d0000000007740019000000000047004b000000000a000039000000010a00403900001bce0070009c000059db0000213d0000000100a00190000059db0000c13d000000400070043f0000000007940436000000000009004b00004da00000613d0000000009000019000000400a00043d00001bb400a0009c000059db0000213d000000a00ba000390000004000b0043f000000800ba0003900000000000b0435000000600ba0003900000000000b0435000000400ba0003900000000000b0435000000200ba0003900000000000b043500000000000a0435000000000b9700190000000000ab04350000002009900039000000000089004b00004d8d0000413d000000000905043300001bce0090009c000059db0000213d000000050a9002100000003f08a0003900001c0e0b800197000000400800043d000000000bb8001900000000008b004b000000000c000039000000010c00403900001bce00b0009c000059db0000213d0000000100c00190000059db0000c13d0000004000b0043f000000000998043600000000000a004b00004db90000613d000000000ba90019000000000c090019000000003d03043c000000000cdc04360000000000bc004b00004db50000c13d0000001f00a001900000000003050433000000000003004b00004ded0000613d0000000003000019000000050a3002100000000e02a00029000000000e02043300000000fd0e04340000000500d0008c00005a0c0000213d000000400c00043d00001bb400c0009c000059db0000213d000000600be0003900000000020f0433000000400fe00039000000000f0f043300000000060b0433000000a00ee00039000000000e0e0433000000a001c00039000000400010043f00001ba701e00197000000800ec0003900000000001e04350000006001c0003900000000006104350000004001c000390000000000f1043500001ba7012001970000002002c0003900000000001204350000000000dc04350000000001040433000000000031004b000059d50000a13d0000000001a700190000000000c104350000000001040433000000000031004b000059d50000a13d0000000001080433000000000031004b000059d50000a13d00000000019a001900000000020b0433000000000021043500000001033000390000000001050433000000000013004b00004dbe0000413d000000400600043d00001c120060009c000059db0000213d0000000d02000029000000000102043300000120022000390000000002020433000000e003600039000000400030043f000000c0036000390000000000830435000000a00360003900000011050000290000000000530435000000600360003900000000002304350000004002600039000000000042043500000020026000390000001403000029000000000032043500001ba701100197000000000016043500000080016000390000000000010435000000400100043d00001c3a0010009c000059db0000213d0000008002100039000000400020043f0000000002010436001400000002001d0000000000020435000000000200001900004f630000013d000000010230008a000000000042004b00005a310000813d000700000003001d000800000004001d000000000043004b00004e190000813d000000010010019000005a3a0000613d0000000d010000296e8b5a830000040f00000009020000290000000000120435000000000010043f0000000301000039000000200010043f000000000100041400001ba40010009c00001ba401008041000000c00110021000001c17011001c700008010020000396e8b6e860000040f0000000100200190000059f20000613d00000009060000290000000002060433000000000101043b000000000401041a0000ff000040019000004e330000613d000a00000002001d0000000e0000006b00004e3c0000613d00005a710000013d0000008807400270000000100140027000001c1f03100198000051000000613d000000000073004b000051000000413d000a00000002001d0000000e0000006b00005a740000c13d000000400100043d00001c120010009c000059db0000213d000000e002100039000000400020043f000000c00210003900000060030000390000000000320435000000a00210003900000000003204350000004002100039000000000032043500000020021000390000000000320435000000800210003900000000000204350000006002100039000000000002043500000000000104350000000d0100002900000040011000390000000005010433000000006405043400001bce0040009c000059db0000213d00000005034002100000003f0130003900001c0e02100197000000400100043d0000000007210019001400000001001d000000000017004b0000000002000039000000010200403900001bce0070009c000059db0000213d0000000100200190000059db0000c13d000000400070043f00000014010000290000000007410436000000000004004b00004e790000613d0000000004000019000000400800043d00001c3a0080009c000059db0000213d0000008002800039000000400020043f0000006002800039000000000002043500000040028000390000000000020435000000200280003900000000000204350000000000080435000000000247001900000000008204350000002004400039000000000034004b00004e680000413d000000000405043300001bce0040009c000059db0000213d00000005094002100000003f0290003900001c0e03200197000000400100043d0000000008310019001100000001001d000000000018004b0000000003000039000000010300403900001bce0080009c000059db0000213d0000000100300190000059db0000c13d000000400080043f0000001101000029000000000841043600000000030000310000000204300367000000000009004b00004e970000613d000000000a980019000000000b04034f000000000308001900000000bc0b043c0000000003c304360000000000a3004b00004e930000c13d0000001f009001900000000003050433000000000003004b00004ec90000613d0000000009000019000000050a9002100000000003a60019000000000e03043300000000fd0e04340000000500d0008c00005a0c0000213d000000400c00043d00001c3a00c0009c000059db0000213d000000600be0003900000000030f0433000000400ee00039000000000e0e0433000000000f0b04330000008002c00039000000400020043f0000006002c000390000000000f204350000004002c000390000000000e2043500001ba7023001970000002003c0003900000000002304350000000000dc043500000014010000290000000002010433000000000092004b000059d50000a13d0000000002a700190000000000c2043500000014010000290000000002010433000000000092004b000059d50000a13d00000011010000290000000002010433000000000092004b000059d50000a13d00000000028a001900000000030b0433000000000032043500000001099000390000000002050433000000000029004b00004e9c0000413d0000000d0100002900000060031000390000000006030433000000001a060434000e00000001001d00001bce00a0009c000059db0000213d0000000509a002100000003f0390003900001c0e03300197000000400500043d0000000008350019000000000058004b0000000003000039000000010300403900001bce0080009c000059db0000213d0000000100300190000059db0000c13d000000400080043f0000000008a5043600000000000a004b00004ef40000613d000000000a000019000000400b00043d00001bb400b0009c000059db0000213d000000a003b00039000000400030043f0000008003b0003900000000000304350000006003b0003900000000000304350000004003b0003900000000000304350000002003b00039000000000003043500000000000b04350000000003a800190000000000b30435000000200aa0003900000000009a004b00004ee10000413d000000000a06043300001bce00a0009c000059db0000213d000000050ba002100000003f03b0003900001c0e03300197000000400900043d000000000c39001900000000009c004b0000000003000039000000010300403900001bce00c0009c000059db0000213d0000000100300190000059db0000c13d0000004000c0043f000000000aa9043600000000000b004b00004f0d0000613d000000000cba001900000000030a0019000000004d04043c0000000003d304360000000000c3004b00004f090000c13d0000001f00b001900000000003060433000000000003004b00004f410000613d0000000004000019000000050b4002100000000e02b00029000000000f020433000000003e0f04340000000500e0008c00005a0c0000213d000000400d00043d00001bb400d0009c000059db0000213d000000600cf0003900000000020304330000004003f00039000000000303043300000000070c0433000000a00ff00039000000000f0f0433000000a001d00039000000400010043f00001ba701f00197000000800fd0003900000000001f04350000006001d0003900000000007104350000004001d00039000000000031043500001ba7012001970000002002d0003900000000001204350000000000ed04350000000001050433000000000041004b000059d50000a13d0000000001b800190000000000d104350000000001050433000000000041004b000059d50000a13d0000000001090433000000000041004b000059d50000a13d0000000001ab001900000000020c0433000000000021043500000001044000390000000001060433000000000014004b00004f120000413d000000400600043d00001c120060009c000059db0000213d0000000d02000029000000000102043300000120022000390000000002020433000000e003600039000000400030043f000000c0036000390000000000930435000000a00360003900000011040000290000000000430435000000600360003900000000002304350000004002600039000000000052043500000020026000390000001403000029000000000032043500001ba701100197000000000016043500000080016000390000000000010435000000400100043d00001c3a0010009c000059db0000213d0000008002100039000000400020043f0000000a020000290000000003210436001400000003001d00000000000304350000000004000019000000000300001900000060091000390000000000690435000000400a10003900000000003a0435000000000004004b000050e50000613d0000000003020019000000120100002900000000010104330000000c0010006c000059d50000a13d0000000b020000290000000f012000290000000000310435000000400100043d00001ba80010009c000059db0000213d0000001402000029000000000202043300000000030a04330000004004100039000000400040043f000000200410003900000000003404350000000000210435000001600200043d00000000030204330000000c0030006c000059d50000a13d0000000b0220002900000020022000390000000000120435000001600100043d00000000010104330000000c0010006c000059d50000a13d000001a00200043d000000000302043300000040013000390000000001010433000001800010043f00000080033000390000000003030433000001c00030043f000000040030008c00005a0c0000213d000000010030008c00000000030000390000000103002039000000020000006b0000000004000039000000010400c03900000000003401a00000000205000029000000010500c039000200000005001d0000000003010433000000000003004b001400140000002d000e00000009001d000d0000000a001d000050430000613d000000000b0000190000000502b00210000000200c20003900000000011c00190000000002010433000000130000006b00004fb50000c13d0000000001020433000000050010008c00005a0c0000213d000000000001004b000000000100001900004fb40000c13d000001c00100043d000000040010008c0000000001000039000000010100c03900130001001001930000008001200039000000000e01043300000000040a043300000014030000290000000003030433000000000043004b00004fbf0000c13d000000600d20003900000000080d043300004fea0000013d00000000063e00a900000000000e004b00004fc50000613d0000000005e600d9000000000035004b000059e10000c13d000000000004004b000052820000613d00000000054600d900000000074500a9000000000046004b00004fce0000413d00000000065700d9000000000046004b000059e10000c13d000000000003004b000052820000613d00000000063700d90000000000e6004b000059f40000c13d000000600d20003900000000020d04330000000000e2004b0000000008020019000000000805601900004fe90000613d00000000063200a9000000000002004b00004fdf0000613d00000000072600d9000000000037004b000059e10000c13d00000000084600d900000000074800a9000000000046004b00004fe60000413d00000000068700d9000000000046004b000059e10000c13d00000000033700d9000000000023004b000059f40000c13d000000000e05001900000000008d04350000000000e104350000000000e8004b000050290000613d000001a00100043d0000000001010433000000c0021000390000000002020433000000a0011000390000000003010433000600000002001d000000000132004b000059e10000413d000700000003001d000800000001001d000900000008001d000a0000000e001d000b0000000d001d000c0000000c001d00110000000b001d00001c34010000410000000000100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001bd3011001c70000800b020000396e8b6e860000040f0000000100200190000059fc0000613d000000000101043b0000000707000029000000000271004b0000000e090000290000000d0a000029000000110b0000290000000c0c0000290000000b0d0000290000000a0500002900000009040000290000000806000029000059e10000413d000000000326004b000059e10000413d00000000014300a9000000000004004b0000501d0000613d00000000044100d9000000000034004b000059e10000c13d00000000035200a9000000000005004b000050230000613d00000000045300d9000000000024004b000059e10000c13d000000000031001a000059e10000413d000000060070006b000052820000613d0000000001310019000000000e6100d90000000000ed043500000000010904330000002001100039000000000101043300000000020104330000000000b2004b000059d50000a13d00000000011c0019000000000101043300000060011000390000000000e104350000000001090433000000a001100039000000000101043300000000020104330000000000b2004b000059d50000a13d00000000011c001900000000020d04330000000000210435000000010bb00039000001800100043d000000000201043300000000002b004b00004fa40000413d000001a00200043d00000000010204330000006001100039000000000701043300000000b1070434000000000001004b000050eb0000613d000000000c000019000500000007001d00040000000b001d000000050dc002100000000001db001900000000040104330000008001400039000000000f01043300000000020a043300000014010000290000000001010433000000000021004b0000505c0000c13d000000600e40003900000000080e043300000000008e04350000000000f8004b0000508b0000c13d000050cb0000013d00000000051f00a900000000000f004b000050620000613d0000000003f500d9000000000013004b000059e10000c13d000000000002004b000052820000613d00000000032500d900000000062300a9000000000025004b0000506b0000413d00000000053600d9000000000025004b000059e10000c13d000000000001004b000052820000613d00000000051600d90000000000f5004b000059f40000c13d000000600e40003900000000040e04330000000000f4004b00000000080400190000000008036019000050870000613d00000000051400a9000000000004004b0000507c0000613d00000000064500d9000000000016004b000059e10000c13d00000000062500d9000000000806001900000000062600a9000000000025004b000050840000413d00000000058600d9000000000025004b000059e10000c13d00000000011600d9000000000041004b000059f40000c13d000000000f03001900000000008e04350000000000f8004b000050cb0000613d001100000008001d000001a00100043d0000000001010433000000c0021000390000000002020433000000a0011000390000000003010433000600000002001d000000000132004b000059e10000413d000700000003001d000800000001001d00090000000f001d000a0000000e001d000b0000000d001d000c0000000c001d00001c34010000410000000000100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001bd3011001c70000800b020000396e8b6e860000040f0000000100200190000059fc0000613d000000000101043b0000000704000029000000000141004b0000000e090000290000000d0a0000290000000507000029000000040b0000290000000c0c0000290000000b0d0000290000000a0e00002900000009050000290000000806000029000059e10000413d000000000316004b000059e10000413d000000060040006b000059e10000613d00000011023000b9000000110000006b000050bd0000613d00000011042000fa000000000034004b000059e10000c13d00000000035100a9000000000005004b000050c30000613d00000000045300d9000000000014004b000059e10000c13d000000000032001a000059e10000413d000000010160008a0000000002320019000000000021001a000059e10000413d0000000001210019000000000f6100d90000000000fe043500000000010904330000004001100039000000000201043300000000010204330000000000c1004b000059d50000a13d0000002001d000390000000002210019000000000202043300000060022000390000000000f204350000000002090433000000c002200039000000000202043300000000030204330000000000c3004b000059d50000a13d000000000121001900000000020e04330000000000210435000000010cc00039000000000107043300000000001c004b0000504c0000413d000050eb0000013d000001a00100043d00000020011000390000000000010435000000000109043300000080011000390000000000010435000001e00200043d00000000030204330000002301000029000000000013004b000059d50000a13d00000005031002100000000002320019000000200220003900000000030904330000000000320435000001e00200043d0000000002020433000000000012004b000059d50000a13d002300010010003d000000010210003900000010010000290000000001010433000000000012004b00004b660000413d000052880000013d000000ff00400190000051050000613d00001c590040009c000051150000813d000051510000013d0000000a010000290000006001100039001100000003001d00000000030104330000000d01000029000000000101043300001ba701100197001400000007001d000e00000004001d6e8b5c900000040f0000000e0400002900000011030000290000001407000029000000090600002900001c590040009c000051510000413d0000000801000029000000010010008c0000511d0000c13d00000000050700190000000001350019000000000071004b000051240000a13d000051300000013d000000000017004b0000512a0000c13d000000000701001900000007050000290000000001350019000000000071004b000051300000213d000000000271019f00001c5a0020009c000051360000813d000700000005001d000800000007001d000051510000013d00000007057000b900000000071700a900000000031300a90000000001350019000000000071004b000051240000a13d000000000537004b000059e10000413d0000000001070019000000000271019f00001c5a0020009c000051270000413d000000000007004b000051400000613d00000000030700190000000004010019000000000203001900000000302400d9000000000003004b00000000040200190000513a0000c13d000051430000013d000000000001004b00000000020100190000527f0000613d0000000004050019000000000302001900000000203400d9000000000002004b0000000004030019000051440000c13d00000000013100d900001c1f0010009c000059e10000213d00000000013700d900001c1f0010009c000059e10000213d000800000001001d00070000003500e1000000400100043d00001c120010009c000059db0000213d0000000002060433000a00000002001d000000e002100039000000400020043f000000c00210003900000060030000390000000000320435000000a00210003900000000003204350000004002100039000000000032043500000020021000390000000000320435000000800210003900000000000204350000006002100039000000000002043500000000000104350000000d0100002900000040011000390000000005010433000000006405043400001bce0040009c000059db0000213d00000005034002100000003f0130003900001c0e02100197000000400100043d0000000007210019001400000001001d000000000017004b0000000002000039000000010200403900001bce0070009c000059db0000213d0000000100200190000059db0000c13d000000400070043f00000014010000290000000007410436000000000004004b000051900000613d0000000004000019000000400800043d00001c3a0080009c000059db0000213d0000008002800039000000400020043f0000006002800039000000000002043500000040028000390000000000020435000000200280003900000000000204350000000000080435000000000247001900000000008204350000002004400039000000000034004b0000517f0000413d000000000405043300001bce0040009c000059db0000213d00000005094002100000003f0290003900001c0e02200197000000400100043d0000000008210019001100000001001d000000000018004b0000000002000039000000010200403900001bce0080009c000059db0000213d0000000100200190000059db0000c13d000000400080043f0000001101000029000000000841043600000000020000310000000204200367000000000009004b000051ae0000613d000000000a980019000000000b04034f000000000208001900000000bc0b043c0000000002c204360000000000a2004b000051aa0000c13d0000001f009001900000000002050433000000000002004b000051e00000613d0000000009000019000000050a9002100000000002a60019000000000e020433000000002d0e04340000000500d0008c00005a0c0000213d000000400c00043d00001c3a00c0009c000059db0000213d000000600be000390000000002020433000000400ee00039000000000e0e0433000000000f0b04330000008003c00039000000400030043f0000006003c000390000000000f304350000004003c000390000000000e3043500001ba7022001970000002003c0003900000000002304350000000000dc043500000014010000290000000002010433000000000092004b000059d50000a13d0000000002a700190000000000c2043500000014010000290000000002010433000000000092004b000059d50000a13d00000011010000290000000002010433000000000092004b000059d50000a13d00000000028a001900000000030b0433000000000032043500000001099000390000000002050433000000000029004b000051b30000413d0000000d0100002900000060021000390000000006020433000000001a060434000e00000001001d00001bce00a0009c000059db0000213d0000000509a002100000003f0290003900001c0e02200197000000400500043d0000000008250019000000000058004b0000000002000039000000010200403900001bce0080009c000059db0000213d0000000100200190000059db0000c13d000000400080043f0000000008a5043600000000000a004b0000520b0000613d000000000a000019000000400b00043d00001bb400b0009c000059db0000213d000000a002b00039000000400020043f0000008002b0003900000000000204350000006002b0003900000000000204350000004002b0003900000000000204350000002002b00039000000000002043500000000000b04350000000002a800190000000000b20435000000200aa0003900000000009a004b000051f80000413d000000000a06043300001bce00a0009c000059db0000213d000000050ba002100000003f02b0003900001c0e02200197000000400900043d000000000c29001900000000009c004b0000000002000039000000010200403900001bce00c0009c000059db0000213d0000000100200190000059db0000c13d0000004000c0043f000000000aa9043600000000000b004b000052240000613d000000000cba001900000000020a0019000000004d04043c0000000002d204360000000000c2004b000052200000c13d0000001f00b001900000000002060433000000000002004b000052580000613d0000000004000019000000050b4002100000000e02b00029000000000f020433000000002e0f04340000000500e0008c00005a0c0000213d000000400d00043d00001bb400d0009c000059db0000213d000000600cf0003900000000020204330000004003f00039000000000303043300000000070c0433000000a00ff00039000000000f0f0433000000a001d00039000000400010043f00001ba701f00197000000800fd0003900000000001f04350000006001d0003900000000007104350000004001d00039000000000031043500001ba7012001970000002002d0003900000000001204350000000000ed04350000000001050433000000000041004b000059d50000a13d0000000001b800190000000000d104350000000001050433000000000041004b000059d50000a13d0000000001090433000000000041004b000059d50000a13d0000000001ab001900000000020c0433000000000021043500000001044000390000000001060433000000000014004b000052290000413d000000400600043d00001c120060009c000059db0000213d000000070100002900001c1f041001970000000d02000029000000000102043300000120022000390000000002020433000000e003600039000000400030043f000000c0036000390000000000930435000000a0036000390000001107000029000000000073043500000080036000390000000000430435000000600360003900000000002304350000004002600039000000000052043500000020026000390000001403000029000000000032043500001ba7011001970000000000160435000000400100043d00001c3a0010009c000059db0000213d0000008002100039000000400020043f0000000a020000290000000003210436001400000003001d0000000000430435000000080300002900001c1f0330019700004f650000013d000000000005004b0000000003050019000051490000c13d00001c1401000041000000000010043f0000001201000039000000040010043f00001c150100004100006e8d00010430000000130000006b000052950000613d0000000201000367000000000101043b00001c400110019700001c770010009c000052950000613d00001c780010009c000052950000613d000000400100043d00001c6402000041000059f60000013d000200000000001d00000001010000290000000021010434000d00000002001d000c00000001001d000000000001004b000053450000613d0000000002000019000052a40000013d0000000001010433000000000001004b000053420000c13d0000000e0200002900000001022000390000000c0020006c000053450000813d00000001010000290000000001010433000000000021004b000059d50000a13d000e00000002001d00000005012002100000000d0110002900000000010104330000000023010434000001e00400043d0000000005040433000000000053004b00005a090000813d00000005033002100000000003340019000000200330003900000000030304330000008004300039000000000404043300001c1f00400198000052a00000613d0000000004020433000000010040008c00005a0c0000213d00000040021000390000000002020433000000000004004b000052c60000613d000000400330003900000000030304330000000004030433000000000042004b000052cb0000413d00005a340000013d000000200330003900000000030304330000000004030433000000000042004b00005a3d0000813d00000005022002100000000002320019000000200220003900000000020204330000000003020433000000050030008c00005a0c0000213d00000040042000390000000005040433000000040030008c00000003030000390000000203006039000000000032043500000060021000390000000003020433000000000034043500005a120000413d00000080011000390000000001010433000000000005004b0000529d0000613d001300000001001d000b00000005001d0000000003020433000000400100043d00000020020000390000000002210436000000000032043500001ba80010009c000059db0000213d0000004003100039000000400030043f00001ba40020009c00001ba4020080410000004002200210000000000101043300001ba40010009c00001ba4010080410000006001100210000000000121019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f0000000100200190000059f20000613d000000000101043b00000013020000290000000032020434001100000003001d000000000002004b000053400000613d0000000003000019001400000003001d00000005023002100000001105200029000000400200043d000000400420003900000020032000390000000005050433000000000051004b0000531f0000a13d000000000053043500000000001404350000004001000039000000000012043500001bd10020009c000059db0000213d0000006001200039000000400010043f00001ba40030009c00001ba4030080410000004001300210000000000202043300001ba40020009c00001ba4020080410000006002200210000000000112019f0000000002000414000053300000013d000000000013043500000000005404350000004001000039000000000012043500001bd10020009c000059db0000213d0000006001200039000000400010043f00001ba40030009c00001ba4030080410000004001300210000000000202043300001ba40020009c00001ba4020080410000006002200210000000000112019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f0000000100200190000059f20000613d000000000101043b0000001403000029000000010330003900000013020000290000000002020433000000000023004b000053040000413d0000000b0010006c000052a00000613d000000400100043d00001c6002000041000059f60000013d000001e00100043d0000000032010434000000000002004b0000539e0000613d00000000010000190000534e0000013d0000000101100039000000000021004b0000539e0000813d0000000504100210000000000543001900000000050504330000008006500039000000000606043300001c1f006001980000534b0000613d000000200650003900000000060604330000000076060434000000000006004b0000000304400029000053780000613d0000000008000019000053600000013d0000000108800039000000000068004b000053780000813d000000050980021000000000099700190000000009090433000000000a0904330000000500a0008c00005a0c0000213d0000000300a0008c0000535d0000a13d000000100a000029000000000a0a043300000000001a004b000059d50000a13d000000000a040433000000000a0a0433000000800aa00039000000000a0a04330000000400a0008c00005a0c0000213d000059fd0000c13d00000040099000390000000009090433000000000009004b0000535d0000613d000059fd0000013d000000400550003900000000050504330000000065050434000000000005004b0000534b0000613d0000000007000019000053820000013d0000000107700039000000000057004b0000534b0000813d0000000508700210000000000886001900000000080804330000000009080433000000050090008c00005a0c0000213d000000040090008c0000537f0000413d00000010090000290000000009090433000000000019004b000059d50000a13d0000000009040433000000000909043300000080099000390000000009090433000000040090008c00005a0c0000213d000053990000c13d00000040088000390000000008080433000000000008004b0000537f0000613d000000400200043d0000002403200039000000000073043500001c620300004100005a010000013d002100000000003d002200000000003d00000010010000290000000001010433000000000001004b00005a7a0000613d0000000005000019000053b70000013d00000011010000290000000000010435000001e00100043d0000000002010433000000000072004b000059d50000a13d0000000e011000290000000001010433000000800110003900000000000104350000002101000029002100010010003d000000010510003900000010010000290000000001010433000000000015004b000059d00000813d00000012010000290000000001010433000000000051004b000059d50000a13d00000005025002100000000f032000290000000001030433000000000001004b000053b00000613d002000200000003d000001400100043d00000020041000390000000001040433000000000001004b000054e00000613d000c00000004001d001100000003001d0000000301200029000a00000001001d0000000001010433000000000f010433001f0000000f001d000001e00300043d0000000004030433000000000054004b000059d50000a13d001300000005001d00001bce0050009c000059db0000213d0000003f0420003900001c0e04400197000000400600043d0000000004460019000000000064004b0000000005000039000000010500403900001bce0040009c000059db0000213d0000000100500190000059db0000c13d000e00200020003d0000000e033000290000000003030433000000400040043f000000130a0000290000000004a60436000000000002004b000053ef0000613d0000000005240019000000000700003100000002077003670000000008040019000000007907043c0000000008980436000000000058004b000053eb0000c13d0000001f0020019000000000000a004b000054020000613d000000000200001900000012050000290000000005050433000000000025004b000059d50000a13d0000000005060433000000000025004b000059d50000a13d000000050520021000000000074500190000000f055000290000000005050433000000000057043500000001022000390000000000a2004b000053f30000413d000000120200002900000000020204330000000000a2004b000059d50000a13d0000000002000415001400000002001d000000000401043300000080024000390000000002020433000000040020008c00005a0c0000213d000001400500043d00000000080504330000001105000029000000000d05043300000000050004150000001e0550008a0000000505500210000000020020008c0000541b0000613d00000000050004150000001d0550008a0000000505500210000000030020008c000055320000c13d0000002002400039000000000202043300001ba7022001970000000007000411000000000027004b0000000505500270000000000500003f000000010500c03f000055320000613d000800000008001d000000400800043d00001c3d0080009c000059db0000213d0000008001100039000000400530003900000020033000390000000009030433000000000a0504330000000007010433000000a0014000390000000005010433000000c001400039000000000b010433000000000c040433000000e00140003900000000030104330000014001800039000000400010043f0000012001800039000000000031043500000100038000390000000000b30435000000e0048000390000000000540435000000c0058000390000000000650435000000a006800039000000000076043500000080078000390000000000a70435000000600a80003900000000009a043500001ba709c00197000000400b80003900000000009b04350000002009800039000000000c0004110000000000c9043500090000000d001d0000000000d80435000000400e00043d00001c3e0c0000410000000000ce0435000000040ce00039000000200d0000390000000000dc04350000000008080433000000240ce0003900000000008c0435000000000809043300001ba7088001970000004409e00039000000000089043500000000080b043300001ba7088001970000006409e00039000000000089043500000000090a04330000008408e00039000001400a0000390000000000a804350000016408e00039000000000a0904330000000000a80435000b0000000e001d0000018408e0003900000000000a004b0000547f0000613d000000000b0000190000002009900039000000000c09043300000000de0c04340000000500e0008c00005a0c0000213d000000000ee80436000000000d0d043300001ba70dd001970000000000de0435000000400dc00039000000000d0d0433000000400e8000390000000000de0435000000600cc00039000000000c0c0433000000600d8000390000000000cd04350000008008800039000000010bb000390000000000ab004b0000546a0000413d0000000b0b0000290000000009b80049000000240a90008a0000000009070433000000a407b000390000000000a70435000000000a0904330000000007a8043600000000000a004b000054a40000613d00000000080000190000002009900039000000000b09043300000000cd0b04340000000500d0008c00005a0c0000213d000000000dd70436000000000c0c043300001ba70cc001970000000000cd0435000000400cb00039000000000c0c0433000000400d7000390000000000cd0435000000600cb00039000000000c0c0433000000600d7000390000000000cd0435000000800bb00039000000000b0b043300001ba70bb00197000000800c7000390000000000bc0435000000a00770003900000001088000390000000000a8004b0000548a0000413d0000000b0c0000290000000008c70049000000240880008a0000000006060433000000c409c00039000000000089043500000000980604340000000006870436000000000008004b000054b60000613d0000000007000019000000000a670019000000000b790019000000000b0b04330000000000ba04350000002007700039000000000087004b000054af0000413d000000000786001900000000000704350000001f0780003900001c2b0770019700000000087600190000000006c80049000000240760008a0000000006050433000000e405c00039000000000075043500000000070604330000000005780436000000000007004b000000090a000029000054cc0000613d00000000080000190000002006600039000000000906043300000000059504360000000108800039000000000078004b000054c60000413d00000000040404330000010406c00039000000000046043500000000030304330000012404c0003900000000003404350000014403c00039000000000101043300000000001304350000000001000414000000040020008c000054e80000c13d00000000010004150000001c0110008a00000005011002100000000103000031000000200030008c000000200400003900000000040340190000551d0000013d0000000000030435000001e00100043d0000000003010433000000000053004b000059d50000a13d00000000011200190000002001100039000053ad0000013d000d0000000f001d0000000003c5004900001ba40030009c00001ba403008041000000600330021000001ba400c0009c00001ba40400004100000000040c40190000004004400210000000000343019f00001ba40010009c00001ba401008041000000c001100210000000000131019f6e8b6e810000040f0000000b0c0000290000000003010019000000600330027000001ba403300197000000200030008c00000020040000390000000004034019000000200640019000000000056c0019000055070000613d000000000701034f00000000080c0019000000007907043c0000000008980436000000000058004b000055030000c13d0000001f074001900000000d0f000029000000090a000029000055160000613d000000000661034f0000000307700210000000000805043300000000087801cf000000000878022f000000000606043b0000010007700089000000000676022f00000000067601cf000000000686019f0000000000650435000100000003001f000300000001035500000000010004150000001b0110008a00000005011002100000000100200190000058cb0000613d0000001f02400039000000600420018f0000000002c40019000000000042004b0000000004000039000000010400403900001bce0020009c000059db0000213d0000000100400190000059db0000c13d000000400020043f000000200030008c000059f20000413d00000000030c043300001c3f00300198000059f20000c13d0000000501100270000000000103001f00001c400130019700001c3e0010009c00005a680000c13d0000000001000415000000140110006900000000010000020000008001f000390000000002010433000000040020008c00005a0c0000213d0000561b0000c13d000001e00100043d00000000020104330000001303000029000000000032004b000059d50000a13d00000010020000290000000002020433000000000032004b000059d50000a13d0000000002000415000700000002001d0000014002f0003900000000020204330000006003f0003900000000030304330000000003030433000000000023004b00005a370000c13d0000000e011000290000000001010433000b00000001001d0000004001100039000900000001001d0000000003010433000000004803043400001bce0080009c000059db0000213d00000005078002100000003f0170003900001c0e02100197000000400100043d0000000005210019000000000015004b0000000002000039000000010200403900001bce0050009c000059db0000213d0000000100200190000059db0000c13d000001400200043d0000000002020433000400000002001d0000000a020000290000000002020433000000800220003900000000020204330000000b060000290000002006600039001400000006001d0000000006060433000000400050043f0000000005810436000000000008004b000055820000613d0000000008000019000000400900043d00001c3a0090009c000059db0000213d000000800a9000390000004000a0043f000000600a90003900000000000a0435000000400a90003900000000000a0435000000200a90003900000000000a04350000000000090435000000000a85001900000000009a04350000002008800039000000000078004b000055710000413d0000000007030433000000000007004b000055aa0000613d000000000700001900000005087002100000000009840019000000000b09043300000000ca0b04340000000500a0008c00005a0c0000213d000000400900043d00001c3a0090009c000059db0000213d000000000c0c0433000000400db00039000000000d0d0433000000600bb00039000000000b0b0433000000800e9000390000004000e0043f000000600e9000390000000000be0435000000400b9000390000000000db043500001ba70bc00197000000200c9000390000000000bc04350000000000a90435000000000a01043300000000007a004b000059d50000a13d000000000885001900000000009804350000000008010433000000000078004b000059d50000a13d00000001077000390000000008030433000000000087004b000055860000413d00000000050f0433000000400400043d000000440340003900000080070000390000000000730435000000200340003900001c660700004100000000007304350000002407400039000000000800041100000000008704350000000008060433000000a4074000390000000000870435000000c407400039000000000008004b000055d10000613d00000000090000190000002006600039000000000a06043300000000bc0a04340000000500c0008c00005a0c0000213d000000000cc70436000000000b0b043300001ba70bb001970000000000bc0435000000400ba00039000000000b0b0433000000400c7000390000000000bc0435000000600aa00039000000000a0a0433000000600b7000390000000000ab043500000080077000390000000109900039000000000089004b000055bc0000413d0000000006470049000000240660008a0000006408400039000000000068043500000000080104330000000006870436000000000008004b000055ef0000613d00000000070000190000002001100039000000000901043300000000ab0904340000000500b0008c00005a0c0000213d000000000bb60436000000000a0a043300001ba70aa001970000000000ab0435000000400a900039000000000a0a0433000000400b6000390000000000ab043500000060099000390000000009090433000000600a60003900000000009a043500000080066000390000000107700039000000000087004b000055da0000413d0000000001460049000000240110008a0000008407400039000000000017043500000000720204340000000001260436000000000002004b000055ff0000613d000000000600001900000000081600190000000009670019000000000909043300000000009804350000002006600039000000000026004b000055f80000413d000000000621001900000000000604350000001f0220003900001c2b0220019700000000024200490000000001210019000000200210008a00000000002404350000001f0110003900001c2b021001970000000001420019000000000021004b0000000002000039000000010200403900001bce0010009c000059db0000213d0000000100200190000059db0000c13d00001ba702500197000000400010043f00000000040404330000000001000414000000040020008c000d0000000f001d000056380000c13d000000010100003100000001090000390000564a0000013d000000120100002900000000010104330000001305000029000000000051004b000059d50000a13d000001600300043d0000000004030433000000000054004b000059d50000a13d000000110400002900000000060404330000000e03300029000000000303043300000000380304340000000007030433000001400300043d0000000003030433000000000003004b0000000109000039000058eb0000c13d0000002003f000390000000003030433000000020020008c000058dc0000c13d0000000004000415000000160440008a0000000504400210001600010000003d000058e40000013d00001ba40030009c00001ba403008041000000400330021000001ba40040009c00001ba4040080410000006004400210000000000334019f00001ba40010009c00001ba401008041000000c001100210000000000113019f6e8b6e810000040f0000000d0f000029000000010920018f0003000000010355000000600110027000011ba40010019d00001ba401100197000000000001004b0000008008000039000a00600000003d000056780000613d00001bce0010009c000059db0000213d0000001f0210003900001c2b022001970000003f0220003900001c2b02200197000000400300043d0000000002230019000a00000003001d000000000032004b0000000003000039000000010300403900001bce0020009c000059db0000213d0000000100300190000059db0000c13d000000400020043f0000000a02000029000000000812043600001c2b03100198000000000238001900000003040003670000566b0000613d000000000504034f0000000006080019000000005705043c0000000006760436000000000026004b000056670000c13d0000001f01100190000056780000613d000000000334034f0000000301100210000000000402043300000000041401cf000000000414022f000000000303043b0000010001100089000000000313022f00000000011301cf000000000141019f0000000000120435000800000009001d000600000008001d00000000010f043300001ba701100197000000000010043f0000000401000039000000200010043f000000000100041400001ba40010009c00001ba401008041000000c00110021000001c17011001c700008010020000396e8b6e860000040f0000000d040000290000000100200190000059f20000613d000000000201043b000000000102041a000000010310003a0000000805000029000059e10000613d000000000032041b000000000204043300000060022002100005000000120143000000400100043d000000000005004b000056db0000613d00001c670010009c000059db0000213d000000240210003900001c68030000410000000000320435000000440210003900000000030004140000006004000039000000000042043500001c69020000410000000000210435000000640210003900000000000204350000000402100039000000000002043500001ba40010009c00001ba401008041000000400110021000001ba40030009c00001ba403008041000000c002300210000000000121019f00001c6a011001c700008006020000396e8b6e810000040f000000010020019000005a400000613d000000000101043b000000000001004b000000060700002900005a460000613d000000400d00043d00001c6b02000041000000000f2d04360000000402d00039000000200300003900000000003204350000000a0200002900000000030204330000002402d0003900000000003204350000004404d00039000000000003004b0000000d0e000029000056ca0000613d000000000200001900000000054200190000000006270019000000000606043300000000006504350000002002200039000000000032004b000056c30000413d00000000023400190000000000020435000000000500041400001ba702100197000000040020008c000056f80000c13d00000000060004150000001a0660008a00000005066002100000000005000415000000190550008a000000050550021000000003010003670000000102000031001900000000003d001a00000000003d0000571d0000013d00001c120010009c000059db0000213d000000e002100039000000400020043f000000c00210003900000060030000390000000000320435000000a0021000390000000000320435000000400210003900000000003204350000002002100039000000000032043500000080021000390000000000020435000000600210003900000000000204350000000000010435000000040000006b000059e70000c13d000000000100041500000007011000690000000001000002000000120100002900000000010104330000001307000029000000000071004b000053a60000213d000059d50000013d00080000000f001d0000001f0130003900001c2b011001970000000001d10049000000000141001900001ba40010009c00001ba401008041000000600110021000001ba400d0009c000a0000000d001d00001ba40300004100000000030d40190000004003300210000000000131019f00001ba40050009c00001ba405008041000000c003500210000000000131019f6e8b6e860000040f0000000006000415000000180660008a00000005066002100000000005000415000000170550008a00000005055002100000000003010019000000600330027000011ba40030019d0003000000010355001800000000003d001700000000003d0000000100200190000059e70000613d00001ba4023001970000000d0e0000290000000a0d000029000000080f00002900001c2b0420019800000000034d0019000057260000613d000000000701034f00000000080d0019000000007907043c0000000008980436000000000038004b000057220000c13d0000001f07200190000057330000613d000000000141034f0000000304700210000000000703043300000000074701cf000000000747022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000171019f00000000001304350000001f0120003900001c2b011001970000000003d10019000000000013004b0000000001000039000000010100403900001bce0030009c000059db0000213d0000000100100190000059db0000c13d000000400030043f00001c0f0020009c000059f20000213d000000400020008c000059f20000413d00000000010d043300001bce0010009c000059f20000213d0000000004d100190000000007d2001900001c0d017001970000001f0240003900001c0d08200197000000000918013f000000000018004b000000000800001900001c0d08004041000000000072004b000000000200001900001c0d0200804100001c0d0090009c000000000802c019000000000008004b000059f20000c13d000000002804043400001bce0080009c000059db0000213d00000005048002100000003f0440003900001c0e04400197000000000434001900001bce0040009c000059db0000213d000000400040043f000000000483043600000007088002100000000008280019000000000078004b000059f20000213d000000000082004b000057850000813d0000000009040019000000000a27004900001c0f00a0009c000059f20000213d0000008000a0008c000059f20000413d000000400a00043d00001c3a00a0009c000059db0000213d000000800ba000390000004000b0043f00000000bc0204340000000500c0008c000059f20000213d000000000cca0436000000000b0b043300001ba700b0009c000059f20000213d0000000000bc0435000000400b200039000000000b0b0433000000400ca000390000000000bc0435000000600b200039000000000b0b0433000000600ca000390000000000bc04350000000009a904360000008002200039000000000082004b000057670000413d00000000020f043300001bce0020009c000059f20000213d0000000002d200190000001f08200039000000000078004b000000000900001900001c0d0900804100001c0d08800197000000000a18013f000000000018004b000000000100001900001c0d0100404100001c0d00a0009c000000000109c019000000000001004b000059f20000c13d000000008902043400001bce0090009c000059db0000213d00000005019002100000003f0110003900001c0e02100197000000400100043d0000000002210019000000000012004b000000000a000039000000010a00403900001bce0020009c000059db0000213d0000000100a00190000059db0000c13d000000400020043f0000000002910436000000a0099000c90000000009890019000000000079004b000059f20000213d000000000098004b000057d20000813d000000000a020019000000000b87004900001c0f00b0009c000059f20000213d000000a000b0008c000059f20000413d000000400b00043d00001bb400b0009c000059db0000213d000000a00cb000390000004000c0043f00000000cd0804340000000500d0008c000059f20000213d000000000ddb0436000000000c0c043300001ba700c0009c000059f20000213d0000000000cd0435000000400c800039000000000c0c0433000000400db000390000000000cd0435000000600cb00039000000600d800039000000000d0d04330000000000dc0435000000800c800039000000000c0c043300001ba700c0009c000059f20000213d000000800db000390000000000cd0435000000000aba0436000000a008800039000000000098004b000057ae0000413d0000000506600270000000000603001f0000000505500270000000000501001f0000004005e00039000000000505043300000000050504330000000006030433000000000065004b000059e70000213d000000000005004b000058120000613d0000000006000019000000140700002900000000070704330000000008070433000000000068004b000059d50000a13d0000000008030433000000000068004b000059d50000a13d000000050960021000000000077900190000002007700039000000000b070433000000008a0b04340000000500a0008c00005a0c0000213d0000000007490019000000000c0704330000000300a0008c0000004007b000390000004009c00039000057fb0000a13d000000000d07043300000000000d004b000057fb0000c13d000000020aa0008a0000000000ab0435000000000d0904330000000000d70435000000600dc00039000000000d0d0433000000600bb00039000000000b0b04330000000000db004b000059e70000213d00000000bc0c04340000000500c0008c00005a0c0000213d0000000000ca004b000059e70000c13d0000000008080433000000000a0b043300000000088a013f00001ba700800198000059e70000c13d00000000080904330000000007070433000000000087004b000059e70000c13d0000000106600039000000000056004b000057df0000413d00000014050000290000000000350435000000000503043300001bce0050009c000059db0000213d00000005075002100000003f0670003900001c0e08600197000000400600043d0000000008860019000000000068004b0000000009000039000000010900403900001bce0080009c000059db0000213d0000000100900190000059db0000c13d000000400080043f000000000856043600000000050000310000000205500367000000000007004b0000582f0000613d0000000009780019000000000a05034f00000000ab0a043c0000000008b80436000000000098004b0000582b0000c13d0000001f007001900000000b07000029000000a00770003900000000006704350000000006030433000000000006004b000058470000613d000000000600001900000000080704330000000009080433000000000069004b000059d50000a13d0000000509600210000000000889001900000000094900190000000009090433000000600990003900000000090904330000002008800039000000000098043500000001066000390000000008030433000000000086004b000058370000413d0000000003010433000000090400002900000000040404330000000067040434000000000073004b000059e70000213d000000000003004b0000588b0000613d0000000007000019000058540000013d0000000107700039000000000037004b0000588b0000813d0000000008010433000000000078004b000059d50000a13d0000000008040433000000000078004b000059d50000a13d00000005097002100000000008960019000000000808043300000000bd0804340000000500d0008c00005a0c0000213d000000000929001900000000090904330000000300d0008c000000400a800039000000400c9000390000586d0000a13d000000000e0a043300000000000e004b0000586d0000c13d000000020dd0008a0000000000d80435000000000e0c04330000000000ea0435000000600e800039000000000e0e0433000000600f900039000000000f0f04330000000000ef004b000059e70000213d00000000ef0904340000000500f0008c00005a0c0000213d0000000000fd004b000059e70000c13d000000000b0b0433000000000d0e0433000000000bbd013f00001ba700b00198000059e70000c13d000000000b0c0433000000000a0a04330000000000ba004b000059e70000c13d0000008008800039000000000808043300001ba708800198000058510000613d0000008009900039000000000909043300001ba709900197000000000098004b000058510000613d000059e70000013d00000009030000290000000000130435000000000601043300001bce0060009c000059db0000213d00000005046002100000003f0340003900001c0e07300197000000400300043d0000000007730019000000000037004b0000000008000039000000010800403900001bce0070009c000059db0000213d0000000100800190000059db0000c13d000000400070043f0000000006630436000000000004004b000058a50000613d0000000007460019000000005805043c0000000006860436000000000076004b000058a10000c13d0000001f004001900000000b04000029000000c00440003900000000003404350000000003010433000000000003004b0000001307000029000058be0000613d000000000300001900000000050404330000000006050433000000000036004b000059d50000a13d0000000506300210000000000556001900000000062600190000000006060433000000600660003900000000060604330000002005500039000000000065043500000001033000390000000005010433000000000053004b000058ae0000413d00000000010004150000000701100069000000000100000200000012010000290000000001010433000000000071004b000059d50000a13d000000110100002900000005020000290000000000210435000000000002004b000059510000c13d000053a80000013d000000080000006b00005a7d0000c13d000000000100041500000014011000690000000001000002000000120100002900000000010104330000001303000029000000000031004b000059d50000a13d00000011010000290000000000010435000001e00100043d0000000002010433000000000032004b000053ac0000213d000059d50000013d0000000004000415000000150440008a0000000504400210000000030020008c001500000000003d001500010000603d0000000009000019000058eb0000c13d00001ba7023001970000000003000411000000000032004b0000000009000039000000010900c0390000000502400270000000000209001f000000000008004b000059290000613d000b00000009001d000d00000008001d001400000007001d000a00000006001d000000000060043f0000000301000039000000200010043f000000000100041400001ba40010009c00001ba401008041000000c00110021000001c17011001c700008010020000396e8b6e860000040f0000000100200190000059f20000613d000000000101043b000000000201041a000000880520027200000014060000290000590c0000613d000000100220027000001c1f02200197000000000065004b0000000d030000290000590e0000c13d0000000004020019000000000203001900000000030600190000000b070000290000591f0000013d0000000d050000290000594b0000013d00000000046200a9000000000002004b0000000b07000029000059150000613d00000000022400d9000000000062004b000059e10000c13d00000000023500a900000000033200d9000000000053004b000059e10000c13d000000000006004b000059320000613d00000000036500a900000000066300d9000000000056004b000059e10000c13d000000000042001a000059e10000413d0000000002420019000000000032004b0000001305000029000059360000a13d000000000007004b00005a740000c13d00000012010000290000000001010433000000000051004b000059d50000a13d00000011010000290000000000010435000001e00100043d0000000002010433000000000052004b000053ac0000213d000059d50000013d0000000003000019000000000032004b0000001305000029000059250000213d000000000423019f00001c5a0040009c0000593c0000813d000000000502001900000000060300190000594b0000013d000000000003004b000052820000613d00000000050300190000000006020019000000000405001900000000504600d9000000000005004b0000000006040019000059400000c13d00000000054200d900001c1f0050009c000059e10000213d00000000064300d900001c1f0060009c000059e10000213d0000008802600210000000100350021000001c4203300197000000000223019f00000001022001bf000000000021041b0000000c010000290000000001010433000000000001004b000059e10000613d000000010110008a0000000c020000290000000000120435000001e00100043d00000000030104330000002102000029000000000023004b000059d50000a13d00000012030000290000000003030433000000000023004b000059d50000a13d0000000502200210000000000121001900000020011000390000000001010433000000400310003900000000030304330000000f0620002900000020011000290000001f0700002900000020027000290000000002020433000000000501043300000000060604330000000004070433000001400100043d00000040011000390000000007010433000000400100043d00000040081000390000008009000039000000000098043500001ba707700197000000200810003900000000007804350000000000610435000000000705043300000080061000390000000000760435000000a006100039000000000007004b000059960000613d00000000080000190000002005500039000000000905043300000000ab0904340000000500b0008c00005a0c0000213d000000000bb60436000000000a0a043300001ba70aa001970000000000ab0435000000400a900039000000000a0a0433000000400b6000390000000000ab043500000060099000390000000009090433000000600a60003900000000009a043500000080066000390000000108800039000000000078004b000059810000413d00000000051600490000006007100039000000000057043500000000050304330000000007560436000000000005004b000059b80000613d000000000600001900000020033000390000000008030433000000009a0804340000000500a0008c00005a0c0000213d000000000aa70436000000000909043300001ba70990019700000000009a043500000040098000390000000009090433000000400a70003900000000009a043500000060098000390000000009090433000000600a70003900000000009a04350000008008800039000000000808043300001ba70880019700000080097000390000000000890435000000a0077000390000000106600039000000000056004b0000599e0000413d00001ba70540019700001ba706200197000000000217004900001ba40020009c00001ba402008041000000600220021000001ba40010009c00001ba4010080410000004001100210000000000112019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000121019f00001bcd011001c70000800d02000039000000030300003900001c3c040000416e8b6e810000040f0000000100200190000059f20000613d002200010000003d000053b00000013d000000220000002a00005a7a0000613d00000012010000290000000202000029000000000001042d00001c1401000041000000000010043f0000003201000039000000040010043f00001c150100004100006e8d0001043000001c1401000041000000000010043f0000004101000039000000040010043f00001c150100004100006e8d0001043000001c1401000041000000000010043f0000001101000039000000040010043f00001c150100004100006e8d00010430000000400100043d00001c6e02000041000000000021043500000004021000390000000503000029000000000032043500001ba40010009c00001ba401008041000000400110021000001c15011001c700006e8d00010430000000000100001900006e8d00010430000000400100043d00001c6502000041000000000021043500001ba40010009c00001ba401008041000000400110021000001bd6011001c700006e8d00010430000000000001042f000000400200043d0000002403200039000000000083043500001c630300004100000000003204350000000403200039000000000013043500001ba40020009c00001ba402008041000000400120021000001c36011001c700006e8d000104300000000002020433000000010020008c00005a150000a13d00001c1401000041000000000010043f0000002101000039000000040010043f00001c150100004100006e8d00010430000000400100043d00001c6102000041000059f60000013d000000400300043d001400000003001d00001c5d01000041000000000013043500000004013000396e8b5fad0000040f0000001402000029000000000121004900001ba40010009c00001ba401008041000000600110021000001ba40020009c00001ba4020080410000004002200210000000000121019f00006e8d0001043000000024021000390000001104000029000000000042043500001c350200004100000000002104350000000402100039000000000032043500001ba40010009c00001ba401008041000000400110021000001c36011001c700006e8d00010430000000400100043d00001c5c02000041000059f60000013d000000400100043d00001c5e02000041000059f60000013d000000400100043d00001c2102000041000059f60000013d000000400100043d00001c5b02000041000059f60000013d000000400100043d00001c5f02000041000059f60000013d00030000000103550000000002010019000000600220027000011ba40020019d00001ba40220019700005a480000013d0000000301000367000000010200003100001c2b052001980000001f0620018f000000400300043d000000000453001900005a530000613d000000000701034f0000000008030019000000007907043c0000000008980436000000000048004b00005a4f0000c13d000000000006004b00005a600000613d000000000151034f0000000305600210000000000604043300000000065601cf000000000656022f000000000101043b0000010005500089000000000151022f00000000015101cf000000000161019f000000000014043500001ba40020009c00001ba402008041000000600120021000001ba40030009c00001ba4030080410000004002300210000000000112019f00006e8d0001043000001c4101000041000000000012043500000004012000390000000000a1043500001ba40020009c00001ba402008041000000400120021000001c15011001c700006e8d00010430000000400100043d00001c1e0200004100005a760000013d000000400100043d00001c2002000041000000000021043500000004021000390000000a03000029000059ec0000013d000000400100043d00001c7902000041000059f60000013d000000400100043d00001c4102000041000000000021043500000004021000390000000000a20435000059ed0000013d000d0000000000020000014002100039000a00000002001d00000000030204330000006002100039000400000002001d00000000020204330000000002020433000000000032004b00005c880000413d000300000001001d0000000021010434000200000002001d00001ba701100197000000000010043f0000000201000039000000200010043f000000000100041400001ba40010009c00001ba401008041000000c00110021000001c17011001c700008010020000396e8b6e860000040f000000010020019000005c7f0000613d000000000101043b00000003020000290000004002200039000900000002001d0000000002020433000000000302043300001c310030009c00005c790000813d00000005023002100000003f0420003900001c0e04400197000000400700043d0000000004470019000000000074004b0000000005000039000000010500403900001bce0040009c00005c790000213d000000010050019000005c790000c13d000000000101041a000100000001001d000000400040043f0000000001370436000700000001001d0000001f0320018f00000000010000310000000201100367000000000002004b00005ac20000613d00000007050000290000000002250019000000000401034f000000004604043c0000000005650436000000000025004b00005abe0000c13d000000000003004b0000000a02000029000000000302043300001bce0030009c00005c790000213d00000005023002100000003f0420003900001c0e04400197000000400600043d0000000004460019000000000064004b0000000005000039000000010500403900001bce0040009c00005c790000213d000000010050019000005c790000c13d000000400040043f0000000003360436000600000003001d0000001f0320018f000000000002004b00005adf0000613d00000006040000290000000002240019000000001501043c0000000004540436000000000024004b00005adb0000c13d000d00000007001d000800000006001d000000000003004b00001c100100004100000000001004430000000001000412000000040010044300000060010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f000000010020019000005c870000613d000000000101043b000500000001001d000000090100002900000000010104330000000002010433000000000002004b00005b3e0000613d0000000004000019000b0005004002180000000b01100029000000200110003900000000010104330000000032010434000000060020008c00005c810000813d000c00000004001d0000000003030433000000400410003900000000040404330000006005100039000000000505043300000080011000390000000006010433000000400100043d000000c0071000390000000000670435000000a0061000390000000000560435000000800510003900000000004504350000004004100039000000000024043500001ba70230019700000060031000390000000000230435000000200210003900000005030000290000000000320435000000c003000039000000000031043500001c120010009c00005c790000213d000000e003100039000000400030043f00001ba40020009c00001ba4020080410000004002200210000000000101043300001ba40010009c00001ba4010080410000006001100210000000000121019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f000000010020019000005c7f0000613d0000000d0200002900000000020204330000000c04000029000000000042004b00005c730000a13d0000000b030000290000000702300029000000000101043b00000000001204350000000104400039000000090100002900000000010104330000000002010433000000000024004b00005af90000413d00001c100100004100000000001004430000000001000412000000040010044300000080010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f000000010020019000005c870000613d000000000101043b000900000001001d0000000a010000290000000001010433000000000001004b0000000d0700002900005ba40000613d0000000004000019000000040100002900000000010104330000000002010433000000000042004b00005c730000a13d000b0005004002180000000b01100029000000200110003900000000010104330000000032010434000000050020008c00005c810000213d000c00000004001d0000000003030433000000a0041000390000000004040433000000400510003900000000050504330000006006100039000000000606043300000080011000390000000007010433000000400100043d000000c0081000390000000000780435000000a0071000390000000000670435000000800610003900000000005604350000004005100039000000000025043500001ba702400197000000e004100039000000000024043500001ba70230019700000060031000390000000000230435000000200210003900000009030000290000000000320435000000e003000039000000000031043500001c130010009c00005c790000213d0000010003100039000000400030043f00001ba40020009c00001ba4020080410000004002200210000000000101043300001ba40010009c00001ba4010080410000006001100210000000000121019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f000000010020019000005c7f0000613d000000080200002900000000020204330000000c04000029000000000042004b0000000d0700002900005c730000a13d0000000b030000290000000602300029000000000101043b000000000012043500000001044000390000000a010000290000000001010433000000000014004b00005b550000413d000000400100043d000000200210003900000003030000290000000003030433000d00000003001d00000002030000290000000003030433000c00000003001d0000000003070433000000000003004b000000000402001900005bb80000613d000000000500001900000000040200190000002007700039000000000607043300000000046404360000000105500039000000000035004b00005bb20000413d0000000003140049000000200430008a00000000004104350000001f0330003900001c2b043001970000000003140019000000000043004b0000000004000039000000010400403900001bce0030009c00005c790000213d000000010040019000005c790000c13d000000400030043f00001ba40020009c00001ba4020080410000004002200210000000000101043300001ba40010009c00001ba4010080410000006001100210000000000121019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f000000010020019000005c7f0000613d000000400200043d0000002003200039000000000101043b000b00000001001d00000008070000290000000001070433000000000001004b000000000403001900005be90000613d000000000500001900000000040300190000002007700039000000000607043300000000046404360000000105500039000000000015004b00005be30000413d0000000001240049000000200410008a00000000004204350000001f0110003900001c2b041001970000000001240019000000000041004b0000000004000039000000010400403900001bce0010009c00005c790000213d000000010040019000005c790000c13d000000400010043f00001ba40030009c00001ba4030080410000004001300210000000000202043300001ba40020009c00001ba4020080410000006002200210000000000112019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f000000010020019000005c7f0000613d000000000101043b000a00000001001d000000030100002900000080011000390000000001010433000900000001001d000000040010008c00005c810000213d000000030200002900000120012000390000000001010433000200000001001d00000100012000390000000001010433000400000001001d000000e0012000390000000001010433000500000001001d000000c0012000390000000001010433000600000001001d000000a0012000390000000001010433000700000001001d000000400100043d000800000001001d00001c1001000041000000000010044300000000010004120000000400100443000000a0010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f000000010020019000005c870000613d0000000d0200002900001ba7022001970000000c0300002900001ba703300197000000000401043b0000000806000029000001800160003900000001050000290000000000510435000001600160003900000002050000290000000000510435000001400160003900000004050000290000000000510435000001200160003900000005050000290000000000510435000001000160003900000006050000290000000000510435000000e00160003900000007050000290000000000510435000000c00160003900000009050000290000000000510435000000a0016000390000000a05000029000000000051043500000080016000390000000b0500002900000000005104350000006001600039000000000031043500000040016000390000000000210435000000200160003900000000004104350000018002000039000000000026043500001c160060009c00005c790000213d000001a002600039000000400020043f00001ba40010009c00001ba4010080410000004001100210000000000206043300001ba40020009c00001ba4020080410000006002200210000000000112019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f000000010020019000005c7f0000613d000000000101043b000000000001042d00001c1401000041000000000010043f0000003201000039000000040010043f00001c150100004100006e8d0001043000001c1401000041000000000010043f0000004101000039000000040010043f00001c150100004100006e8d00010430000000000100001900006e8d0001043000001c1401000041000000000010043f0000002101000039000000040010043f00001c150100004100006e8d00010430000000000001042f000000400100043d00001c4f02000041000000000021043500001ba40010009c00001ba401008041000000400110021000001bd6011001c700006e8d00010430000a000000000002000002000030043f00001ba7041001970000000003000411000000000034004b00005f580000613d000900000002001d000400000001001d000300000004001d00001c1001000041000000000010044300000000010004120000000400100443000000e0010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f000000010020019000005f670000613d000000000101043b000a00000001001d00001bd2010000410000000000100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001bd3011001c70000800b020000396e8b6e860000040f000000010020019000005f670000613d000000000201043b00001c10010000410000000000100443000000000100041200000004001004430000000a0020006c000000400100003900005cc90000c13d00000100010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f000000010020019000005d200000c13d00005f670000013d000800000002001d000000400200043d000a00000002001d0000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f000000010020019000005f670000613d0000000a020000290000002002200039000000000101043b000700000002001d000000000012043500001c10010000410000000000100443000000000100041200000004001004430000002400000443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f000000010020019000005f670000613d000000000101043b0000000a020000290000004002200039000000000012043500001c100100004100000000001004430000000001000412000000040010044300000020010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f000000010020019000005f670000613d000000000101043b0000000a04000029000000a0024000390000000003000410000000000032043500000080024000390000000803000029000000000032043500000060024000390000000000120435000000a001000039000000000014043500001c700040009c00005f610000813d0000000a02000029000000c001200039000000400010043f000000070100002900001ba40010009c00001ba4010080410000004001100210000000000202043300001ba40020009c00001ba4020080410000006002200210000000000112019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f000000010020019000005f5f0000613d000000000401043b000000400100043d000000420210003900000009030000290000000000320435000000200210003900001c7a030000410000000000320435000000420300003900000000003104350000002203100039000100000004001d000000000043043500001c3a0010009c00005f610000213d0000008003100039000000400030043f00001ba40020009c00001ba4020080410000004002200210000000000101043300001ba40010009c00001ba4010080410000006001100210000000000121019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f000000010020019000005f5f0000613d000000000401043b000002000500043d0000000001050433000003450210008a00001c850020009c000200000004001d00005d4c0000813d000a00000005001d00005e890000013d0000001d021000390000001e00200190000a00000005001d000000040200002900005e8a0000c13d000000010110018f000000410210015f0000001f01200039000000600110018f0000003f03100039000000e00330018f000000400400043d0000000003340019000a00000004001d000000000043004b0000000004000039000000010400403900001bce0030009c00005f610000213d000000010040019000005f610000c13d000000400030043f0000000a030000290000000003230436000000000413001900000000010000310000000201100367000000000501034f0000000006030019000000005705043c0000000006760436000000000046004b00005d690000c13d0000000004000019000002000500043d0000000006050433000000000046004b00005f590000a13d0000000a060000290000000006060433000000000046004b00005f590000a13d0000000006340019000000000706043300001c7b0770019700000000055400190000002005500039000000000505043300001c7c05500197000000000557019f00000000005604350000000104400039000000000024004b00005d6e0000413d000002000300043d0000000034030434000000000624004b00005f590000a13d0000000105200039000000000054004b00005f590000a13d00000002072001bf000000000074004b00005f590000a13d00001c7e0060009c00005f610000213d00001c2b086001970000003f0480003900001c0e04400197000000400a00043d00000000094a001900080000000a001d0000000000a9004b0000000004000039000000010400403900001bce0090009c00005f610000213d000000010040019000005f610000c13d000000000423001900000000040404330000000005530019000000000505043300000000037300190000000003030433000000050a600270000000400090043f000000080700002900060000000a001d0000000007a70436000700000007001d000000000008004b00005db00000613d00000007090000290000000007890019000000000801034f000000008a08043c0000000009a90436000000000079004b00005dac0000c13d000000200060008c00005dea0000413d0000000302200039000000200600003900000000070000190000000508700210000000000007004b00005dbb0000613d00000000097800d9000000200090008c00005f680000c13d000000000028001a00005f680000413d000000400a00043d00001ba800a0009c00005f610000213d000000000b2800190000004009a00039000000400090043f00000000096a0436000000000c01043b0000000000c90435000000000c000019000000000dbc0019000002000e00043d000000000f0e04330000000000df004b00005f590000a13d000000000f0a04330000000000cf004b00005f590000a13d000000000ded0019000000000e9c0019000000000f0e043300001c7b0ff00197000000200dd00039000000000d0d043300001c7c0dd00197000000000ddf019f0000000000de04350000001f00c0008c000000010cc0003900005dc70000413d000000000a0a043300001c0f00a0009c00005f5f0000213d0000002000a0008c00005f5f0000413d000000080a000029000000000a0a043300000000007a004b00005f590000a13d0000000708800029000000000909043300000000009804350000000107700039000000060070006c00005db50000413d00000008010000290000000001010433000000000001004b00005e370000613d000000e801400270000000f00250027000001c7d011001970000ff000220018f000000000112019f000000f80230027000050000002101a30000000008000019000000090600002900000005018002100000000704100029000000400100043d000000400310003900000020021000390000000004040433000000ff0080008c000900000008001d00005e150000213d000000010580020f000000050050018000005e150000613d000000000042043500000000006304350000004003000039000000000031043500001bd10010009c00005f610000213d0000006003100039000000400030043f00001ba40020009c00001ba4020080410000004002200210000000000101043300001ba40010009c00001ba4010080410000006001100210000000000121019f000000000200041400005e260000013d000000000062043500000000004304350000004003000039000000000031043500001bd10010009c00005f610000213d0000006003100039000000400030043f00001ba40020009c00001ba4020080410000004002200210000000000101043300001ba40010009c00001ba4010080410000006001100210000000000121019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f000000010020019000005f5f0000613d0000000908000029000000000601043b000000010880003900000008010000290000000001010433000000000018004b00005df70000413d00005e380000013d0000000906000029000900000006001d0000000601000029000000000010043f000000200000043f000000000100041400001ba40010009c00001ba401008041000000c00110021000001c17011001c700008010020000396e8b6e860000040f000000010020019000005f5f0000613d000000000101043b000000000301041a000000400100043d000000400210003900000009040000290000000000420435000000200210003900000000003204350000004003000039000000000031043500001bd10010009c00005f610000213d0000006003100039000000400030043f00001ba40020009c00001ba4020080410000004002200210000000000101043300001ba40010009c00001ba4010080410000006001100210000000000121019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f000000010020019000005f5f0000613d000000000201043b000000400100043d00000042031000390000000000230435000000200210003900001c7a0300004100000000003204350000002203100039000000010400002900000000004304350000004203000039000000000031043500001c3a0010009c00005f610000213d0000008003100039000000400030043f00001ba40020009c00001ba4020080410000004002200210000000000101043300001ba40010009c00001ba4010080410000006001100210000000000121019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f000000010020019000005f5f0000613d000002000500043d000000000401043b0000000402000029000900000005001d000800000004001d00001c4a0100004100000000001004430000000400200443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c27011001c700008002020000396e8b6e860000040f000000010020019000005f670000613d000000000101043b000000000001004b000000020300002900005ebe0000613d000000400b00043d0000002401b000390000004002000039000000000021043500001c7f0100004100000000001b04350000000401b000390000000000310435000000090100002900000000370104340000004401b0003900000000007104350000006401b00039000000000007004b00005eb30000613d000000000400001900000000051400190000000006430019000000000606043300000000006504350000002004400039000000000074004b00005eac0000413d0000000003710019000000000003043500000000030004140000000302000029000000040020008c00005ece0000c13d0000000103000031000000200030008c0000002004000039000000000403401900005f020000013d0000000a030000290000000012030434000000400020008c00005f170000613d000000410020008c00005f9b0000c13d00000060023000390000000002020433000000f80220027000000000050300190000001d0320008a00001c860030009c00005fa30000a13d0000004003500039000000000303043300005f1c0000013d0000001f0570003900001c2b045001970000000004b40049000000000114001900001ba40010009c00001ba401008041000000600110021000001ba400b0009c00001ba40400004100000000040b40190000004004400210000000000141019f00001ba40030009c00001ba403008041000000c003300210000000000131019f000a0000000b001d6e8b6e860000040f0000000a0b0000290000000003010019000000600330027000001ba403300197000000200030008c000000200400003900000000040340190000001f0640018f000000200740019000000000057b001900005ef10000613d000000000801034f00000000090b0019000000008a08043c0000000009a90436000000000059004b00005eed0000c13d000000000006004b00005efe0000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f0000000000650435000100000003001f0003000000010355000000010020019000005f7d0000613d0000001f01400039000000600210018f0000000001b20019000000000021004b0000000002000039000000010200403900001bce0010009c00005f610000213d000000010020019000005f610000c13d000000400010043f000000200030008c00005f5f0000413d00000000020b043300001c3f0020019800005f5f0000c13d00001c400220019700001c7f0020009c00005f580000613d00001c800200004100005f9d0000013d0000004002300039000000000202043300001c0f03200197000000ff022002700000001b022000390000000001010433000000400400043d00000060054000390000000000350435000000400340003900000000001304350000002001400039000000000021043500000008010000290000000000140435000000000000043f00001ba40040009c00001ba4040080410000004001400210000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001c82011001c700000001020000396e8b6e860000040f0000000003010019000000600330027000001ba403300197000000200030008c000000200400003900000000040340190000001f0540018f000000200440019000005f410000613d000000000601034f0000000007000019000000006806043c0000000007870436000000000047004b00005f3d0000c13d000000000005004b00005f4e0000613d000000000641034f0000000305500210000000000704043300000000075701cf000000000757022f000000000606043b0000010005500089000000000656022f00000000055601cf000000000575019f0000000000540435000100000003001f0003000000010355000000010020019000005f6e0000613d000000000100043d00001ba701100198000000030200002900005f7a0000613d000000000021004b00005f7a0000c13d000000000001042d00001c1401000041000000000010043f0000003201000039000000040010043f00001c150100004100006e8d00010430000000000100001900006e8d0001043000001c1401000041000000000010043f0000004101000039000000040010043f00001c150100004100006e8d00010430000000000001042f00001c1401000041000000000010043f0000001101000039000000040010043f00001c150100004100006e8d000104300000001f0530018f00001ba606300198000000400200043d000000000462001900005f880000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b00005f750000c13d00005f880000013d000000400100043d00001c830200004100005f9d0000013d0000001f0530018f00001ba606300198000000400200043d000000000462001900005f880000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b00005f840000c13d000000000005004b00005f950000613d000000000161034f0000000305500210000000000604043300000000065601cf000000000656022f000000000101043b0000010005500089000000000151022f00000000015101cf000000000161019f0000000000140435000000600130021000001ba40020009c00001ba4020080410000004002200210000000000112019f00006e8d00010430000000400100043d00001c8402000041000000000021043500001ba40010009c00001ba401008041000000400110021000001bd6011001c700006e8d00010430000000400100043d00001c810300004100000000003104350000000403100039000000000023043500001ba40010009c00001ba401008041000000400110021000001c15011001c700006e8d00010430000000020020008c00005fb10000813d0000000001210436000000000001042d00001c1401000041000000000010043f0000002101000039000000040010043f00001c150100004100006e8d00010430000300000000000200001c1001000041000000000010044300000000010004120000000400100443000000e0010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f0000000100200190000060410000613d000000000101043b000300000001001d00001bd2010000410000000000100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001bd3011001c70000800b020000396e8b6e860000040f0000000100200190000060410000613d000000000201043b00001c1001000041000000000010044300000000010004120000000400100443000000030020006c00005fe70000c13d00000100010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f00000001002001900000603f0000c13d000060410000013d000200000002001d000000400100043d000300000001001d00000040010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f0000000100200190000060410000613d00000003020000290000002002200039000000000101043b000100000002001d000000000012043500001c10010000410000000000100443000000000100041200000004001004430000002400000443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f0000000100200190000060410000613d000000000101043b00000003020000290000004002200039000000000012043500001c100100004100000000001004430000000001000412000000040010044300000020010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f0000000100200190000060410000613d000000000101043b0000000304000029000000a0024000390000000003000410000000000032043500000080024000390000000203000029000000000032043500000060024000390000000000120435000000a001000039000000000014043500001c700040009c000060420000813d0000000302000029000000c001200039000000400010043f000000010100002900001ba40010009c00001ba4010080410000004001100210000000000202043300001ba40020009c00001ba4020080410000006002200210000000000112019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f0000000100200190000060480000613d000000000101043b000000000001042d000000000001042f00001c1401000041000000000010043f0000004101000039000000040010043f00001c150100004100006e8d00010430000000000100001900006e8d00010430000a000000000002000600000003001d000700000002001d000800000004001d000000000004004b0000625c0000613d0000000023060434000a00000002001d000000000053004b000900000001001d0000613a0000613d0000000a0200002900000000020204330000000002020433000000000002004b0000613a0000613d000400000003001d000100000005001d000200000006001d000000400100043d000500000001001d000000200210003900001c4801000041000300000002001d000000000012043500001c100100004100000000001004430000000001000412000000040010044300000120010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f0000000100200190000062590000613d000000000101043b0000000504000029000000600240003900000004030000290000000000320435000000400240003900001ba701100197000000000012043500001c100100004100000000001004430000000001000412000000040010044300000160010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f0000000100200190000062590000613d000000000101043b0000000504000029000000a00240003900001c4903000041000000000032043500000080024000390000000000120435000000a001000039000000000014043500001c700040009c0000624d0000813d0000000502000029000000c001200039000000400010043f000000030100002900001ba40010009c00001ba4010080410000004001100210000000000202043300001ba40020009c00001ba4020080410000006002200210000000000112019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f00000001002001900000625a0000613d000000000101043b00001c4a02000041000000000020044300001ba701100197000500000001001d0000000400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c27011001c700008002020000396e8b6e860000040f0000000100200190000062590000613d000000400b00043d0000002404b000390000000403b00039000000000101043b000000000001004b000062840000613d0000000a01000029000000000201043300001c4b0100004100000000001b043500000020010000390000000000130435000000000302043300000000003404350000004401b00039000000000003004b000060ea0000613d0000000004000019000000200220003900000000050204330000000067050434000000040070008c000062530000813d0000000007710436000000000606043300001ba70660019700000000006704350000004006500039000000000606043300001ba706600197000000400710003900000000006704350000006006500039000000000606043300001ba706600197000000600710003900000000006704350000008006500039000000000606043300000080071000390000000000670435000000a0055000390000000005050433000000a0061000390000000000560435000000c0011000390000000104400039000000000034004b000060cb0000413d00000000040004140000000502000029000000040020008c000060f30000c13d0000000103000031000000200030008c00000020040000390000000004034019000061240000013d0000000001b1004900001ba40010009c00001ba401008041000000600110021000001ba400b0009c00001ba40300004100000000030b40190000004003300210000000000131019f00001ba40040009c00001ba404008041000000c003400210000000000131019f00050000000b001d6e8b6e810000040f000000050b0000290000000003010019000000600330027000001ba403300197000000200030008c000000200400003900000000040340190000001f0640018f000000200740019000000000057b0019000061130000613d000000000801034f00000000090b0019000000008a08043c0000000009a90436000000000059004b0000610f0000c13d000000000006004b000061200000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f0000000000650435000100000003001f00030000000103550000000100200190000062a20000613d0000001f01400039000000600210018f0000000001b20019000000000021004b0000000002000039000000010200403900001bce0010009c0000624d0000213d00000001002001900000624d0000c13d000000400010043f000000200030008c0000625a0000413d00000000010b043300001c3f001001980000625a0000c13d00000060010000390000000a020000290000000000120435000000090100002900000002060000290000000105000029000000000005004b000061c50000613d000000000f050019000000000e0600190000000a0100002900000000010104330000000001010433000000010010003a000062c00000413d000000010310003900001bce0030009c0000624d0000213d00000005043002100000003f0240003900001c0e05200197000000400200043d0000000005520019000000000025004b0000000006000039000000010600403900001bce0050009c0000624d0000213d00000001006001900000624d0000c13d000000400050043f00000000033204360000000005000019000000400600043d00001bd40060009c0000624d0000213d000000c007600039000000400070043f000000a0076000390000000000070435000000800760003900000000000704350000006007600039000000000007043500000040076000390000000000070435000000200760003900000000000704350000000000060435000000000753001900000000006704350000002005500039000000000045004b000061550000413d000000000001004b000061a00000613d00000000040000190000000a0500002900000000060504330000000005060433000000000045004b000062470000a13d00000005054002100000000006650019000000200660003900000000080604330000000097080434000000030070008c000062530000213d000000400600043d00001bd40060009c0000624d0000213d0000000009090433000000400a800039000000000a0a0433000000600b800039000000000b0b0433000000800c800039000000000c0c0433000000a0088000390000000008080433000000c00d6000390000004000d0043f000000a00d60003900000000008d043500000080086000390000000000c8043500001ba708b00197000000600b60003900000000008b043500001ba708a00197000000400a60003900000000008a043500001ba7089001970000002009600039000000000089043500000000007604350000000007020433000000000047004b000062470000a13d000000000553001900000000006504350000000005020433000000000045004b000062470000a13d0000000104400039000000000014004b0000616d0000413d000000400400043d00001bd40040009c0000624d0000213d000000c005400039000000400050043f000000a00540003900000008060000290000000000650435000000060500002900001ba70550019700000060064000390000000000560435000000070500002900001ba70550019700000040064000390000000000560435000000090500002900001ba7055001970000002006400039000000000056043500000001050000390000000000540435000000800540003900000000000504350000000005020433000000000015004b000062470000a13d0000000505100210000000000353001900000000004304350000000003020433000000000013004b000062470000a13d0000000a0100002900000000002104350000000000fe0435000000000001042d00001c4a0200004100000000002004430000000400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c27011001c700008002020000396e8b6e860000040f0000000100200190000062590000613d000000400200043d000000000101043b000000000001004b000062640000613d000000640120003900000008030000290000000000310435000000200120003900001c7503000041000000000031043500000064030000390000000000320435000000060300002900001ba70c30019700000044032000390000000000c30435000000070300002900001ba70b30019700000024032000390000000000b3043500001bb40020009c0000624d0000213d000000a003200039000000400030043f000000000302043300000000040004140000000902000029000000040020008c0000621c0000c13d00000001040000310000000002000019000000000004004b000062330000613d00001bce0040009c0000624d0000213d0000001f0140003900001c2b011001970000003f0110003900001c2b03100197000000400100043d0000000003310019000000000013004b0000000006000039000000010600403900001bce0030009c0000624d0000213d00000001006001900000624d0000c13d000000400030043f000000000341043600001c2b054001980000001f0640018f000000000453001900000003070003670000620e0000613d000000000807034f0000000009030019000000008a08043c0000000009a90436000000000049004b0000620a0000c13d000000000006004b000062350000613d000000000557034f0000000306600210000000000704043300000000076701cf000000000767022f000000000505043b0000010006600089000000000565022f00000000056501cf000000000575019f0000000000540435000062350000013d00001ba40010009c00001ba401008041000000400110021000001ba40030009c00001ba4030080410000006003300210000000000113019f00001ba40040009c00001ba404008041000000c003400210000000000131019f000a0000000b001d00070000000c001d6e8b6e810000040f000000070c0000290000000a0b000029000000010220015f0003000000010355000000600110027000011ba40010019d00001ba404100197000000000004004b000061f20000c13d0000006001000039000000800300003900000001002001900000626f0000c13d0000000001010433000000200010008c000062460000413d00001c0f0010009c0000625a0000213d000000200010008c0000625a0000413d0000000001030433000000000001004b0000000002000039000000010200c039000000000021004b0000625a0000c13d000000000001004b0000628f0000613d000000000001042d00001c1401000041000000000010043f0000003201000039000000040010043f00001c150100004100006e8d0001043000001c1401000041000000000010043f0000004101000039000000040010043f00001c150100004100006e8d0001043000001c1401000041000000000010043f0000002101000039000000040010043f00001c150100004100006e8d00010430000000000001042f000000000100001900006e8d00010430000000400100043d00001c4602000041000000000021043500001ba40010009c00001ba401008041000000400110021000001bd6011001c700006e8d0001043000001c73010000410000000000120435000000090100002900001ba7011001970000000403200039000000000013043500001ba40020009c00001ba402008041000000400120021000001c15011001c700006e8d00010430000000400100043d00000084021000390000000803000029000000000032043500000044021000390000000000c2043500000024021000390000000000b2043500001c89020000410000000000210435000000090200002900001ba702200197000000040310003900000000002304350000006402100039000000000002043500001ba40010009c00001ba401008041000000400110021000001c8a011001c700006e8d0001043000001c4c0100004100000000001b0435000000040100002900000000001304350000000501000029000000000014043500001ba400b0009c00001ba40b0080410000004001b0021000001c36011001c700006e8d00010430000000400100043d00000064021000390000000803000029000000000032043500000044021000390000000000c2043500000024021000390000000000b2043500001c87020000410000000000210435000000090200002900001ba7022001970000000403100039000000000023043500001ba40010009c00001ba401008041000000400110021000001c88011001c700006e8d000104300000001f0530018f00001ba606300198000000400200043d0000000004620019000062ad0000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000062a90000c13d000000000005004b000062ba0000613d000000000161034f0000000305500210000000000604043300000000065601cf000000000656022f000000000101043b0000010005500089000000000151022f00000000015101cf000000000161019f0000000000140435000000600130021000001ba40020009c00001ba4020080410000004002200210000000000112019f00006e8d0001043000001c1401000041000000000010043f0000001101000039000000040010043f00001c150100004100006e8d00010430001d000000000002000100000006001d001400000005001d000200000004001d001c00000003001d000900000002001d000600000001001d0000000012010434000500000001001d00001c310020009c00006d2b0000813d00000005012002100000003f0310003900001c0e03300197000000400400043d0000000003340019000400000004001d000000000043004b0000000004000039000000010400403900001bce0030009c00006d2b0000213d000000010040019000006d2b0000c13d000000400030043f00000004030000290000000002230436000300000002001d0000001f0210018f000000000001004b000062ed0000613d0000000304000029000000000114001900000000030000310000000203300367000000003503043c0000000004540436000000000014004b000062e90000c13d000000000002004b000000400100043d001300000001001d00001ba80010009c00006d2b0000213d00000013020000290000004001200039000000400010043f000000200e200039000000600100003900000000001e043500000000000204350000001c010000290000000021010434001b00000002001d000000000001004b00120000000e001d000063b70000613d0000000009000019000063100000013d000000000503043300000080017000390000000003010433000000000108043300001ba70110019700001ba70330019700000013070000296e8b46c00000040f000000120e0000290000001d0900002900000001099000390000001c010000290000000001010433000000000019004b000063b70000813d00000005019002100000001b011000290000000006010433000000005706043400000060037000390000000002030433000000000002004b0000630b0000613d0000000081070434000000060010008c00006d310000813d000000000001004b001d00000009001d0000633c0000c13d001900000002001d001500000006001d001600000005001d001700000008001d001800000003001d001a00000007001d00001c6c01000041000000000010044300000000010004100000000400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c27011001c70000800a020000396e8b6e860000040f000000010020019000006d460000613d000000000101043b000000190010006b0000001a0700002900006e070000213d0000000001070433000000120e0000290000001d090000290000001803000029000000170800002900000016050000290000001506000029000000050010008c00006d310000213d00000040027000390000000004020433000000000001004b000063530000613d00000040026000390000000006020433000000000205043300001ba702200197000000010010008c000063670000613d000000020010008c000063010000c13d000000000503043300000080017000390000000003010433000000000108043300001ba70110019700001ba70330019700000013070000296e8b48f10000040f000063090000013d000000000108043300001ba70110019700000000004101a000006d4c0000c13d0000000003030433000000000003004b00006d490000613d0000008001700039000000000101043300001ba7041001970000000001000414000000040040008c001a00000003001d001900000004001d000063750000c13d00000001010000310000000102000039000000000001004b000063850000c13d000063ac0000013d000000000004004b00006d4c0000c13d000000000403043300000080017000390000000003010433000000000108043300001ba70110019700001ba703300197000000000506001900000013060000296e8b604a0000040f0000001d09000029000000120e0000290000630b0000013d00001ba40010009c00001ba401008041000000c00110021000001bcd011001c7000080090200003900000000050000196e8b6e810000040f0000001d09000029000000120e000029000000010220018f0003000000010355000000600110027000011ba40010019d00001ba401100197000000000001004b000063ac0000613d00001bce0010009c00006d2b0000213d0000001f0310003900001c2b033001970000003f0330003900001c2b04300197000000400300043d0000000004430019000000000034004b0000000005000039000000010500403900001bce0040009c00006d2b0000213d000000010050019000006d2b0000c13d000000400040043f000000000613043600001c2b04100198000000000346001900000003050003670000639f0000613d000000000705034f000000007807043c0000000006860436000000000036004b0000639b0000c13d0000001f01100190000063ac0000613d000000000445034f0000000301100210000000000503043300000000051501cf000000000515022f000000000404043b0000010001100089000000000414022f00000000011401cf000000000151019f0000000000130435000000000002004b0000630b0000c13d000000400100043d00000024021000390000001a03000029000000000032043500001c450200004100000000002104350000000402100039000000190300002900006d5c0000013d00000009010000290000000021010434000a00000002001d000000000001004b000069e20000613d000000140200002900181ba70020019b0000000004000019000063c60000013d000000090100002900000000010104330000000b040000290000000104400039000000000014004b000069e20000813d00000005024002100000000a0320002900000000050304330000008003500039000000000303043300001c1f00300198000063c30000613d000c00000005001d00000004010000290000000001010433000b00000004001d000000000041004b00006d250000a13d000000030120002900000001030000390000000000310435000000060100002900000000010104330000000b0010006c00006d250000a13d0000000c0100002900000020011000390000000001010433001b00000001001d0000000001010433001600000001001d000000000001004b000069c60000613d00000005012000290000000c02000029001500a00020003d00000000010104330000000001010433001000000001001d000f01200010003d0000000004000019000063f50000013d00000000002e043500000013010000290000000000f104350000001d040000290000001a030000290000001c0100002900000000003104350000000104400039000000160040006c000069c60000813d0000001b010000290000000001010433001d00000004001d000000000041004b00006d250000a13d0000001501000029000000000101043300000000020104330000001d0020006c00006d250000a13d0000001d04000029000000050240021000000020032000390000001b023000290000000002020433000000600520003900000000011300190000000003010433001c00000005001d0000000001050433000000000001004b000063f00000613d001a00000003001d000000400100043d00001bb40010009c00006d2b0000213d000000a003100039000000400030043f0000008003100039000000000003043500000060031000390000000000030435000000400310003900000000000304350000002003100039000000000003043500000000000104350000000041020434000000050010008c00006d310000213d000000400600043d00001bb40060009c00006d2b0000213d0000001c05000029000000000305043300000040022000390000000007020433000000000204043300001ba705200197000000a002600039000000400020043f0000008002600039000000180400002900000000004204350000006002600039000000000032043500000040026000390000000000720435000000200260003900000000005204350000000000160435000000000001004b001700000003001d000065840000613d0000000f02000029000000000f0204330000001002000029000000000202043300141ba70020019b000000010010008c001900000005001d000064e00000613d000000020010008c001100000007001d000065900000c13d000000130100002900000000020104330000000000f2004b000066b20000613d00000000010e04330000000001010433000000000001004b000066b20000613d000800000002001d000e0000000f001d000000400100043d000d00000001001d000000200210003900001c4801000041000700000002001d000000000012043500001c100100004100000000001004430000000001000412000000040010044300000120010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f000000010020019000006d460000613d000000000101043b0000000d04000029000000600240003900000008030000290000000000320435000000400240003900001ba701100197000000000012043500001c100100004100000000001004430000000001000412000000040010044300000160010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f000000010020019000006d460000613d000000000101043b0000000d04000029000000a00240003900001c4903000041000000000032043500000080024000390000000000120435000000a001000039000000000014043500001bd40040009c00006d2b0000213d0000000d02000029000000c001200039000000400010043f000000070100002900001ba40010009c00001ba4010080410000004001100210000000000202043300001ba40020009c00001ba4020080410000006002200210000000000112019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f000000010020019000006d470000613d000000000101043b00001c4a02000041000000000020044300001ba701100197000d00000001001d0000000400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c27011001c700008002020000396e8b6e860000040f000000010020019000006d460000613d000000400a00043d0000002404a000390000000403a00039000000000101043b000000000001004b00006d680000613d000000120e00002900000000020e043300001c4b0100004100000000001a043500000020010000390000000000130435000000000302043300000000003404350000004401a00039000000000003004b000064d70000613d0000000004000019000000200220003900000000050204330000000067050434000000040070008c00006d310000813d0000000007710436000000000606043300001ba70660019700000000006704350000004006500039000000000606043300001ba706600197000000400710003900000000006704350000006006500039000000000606043300001ba706600197000000600710003900000000006704350000008006500039000000000606043300000080071000390000000000670435000000a0055000390000000005050433000000a0061000390000000000560435000000c0011000390000000104400039000000000034004b000064b80000413d00000000040004140000000d02000029000000040020008c0000666d0000c13d0000000103000031000000200030008c000000200400003900000000040340190000669e0000013d000000000007004b00006d4c0000c13d000000000003004b00006d490000613d000000130100002900000000020104330000000000f2004b000068c60000613d00000000010e04330000000001010433000000000001004b000068c60000613d000d00000002001d000e0000000f001d000000400100043d001100000001001d000000200210003900001c4801000041000800000002001d000000000012043500001c100100004100000000001004430000000001000412000000040010044300000120010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f000000010020019000006d460000613d000000000101043b000000110400002900000060024000390000000d030000290000000000320435000000400240003900001ba701100197000000000012043500001c100100004100000000001004430000000001000412000000040010044300000160010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f000000010020019000006d460000613d000000000101043b0000001104000029000000a00240003900001c4903000041000000000032043500000080024000390000000000120435000000a001000039000000000014043500001bd40040009c00006d2b0000213d0000001102000029000000c001200039000000400010043f000000080100002900001ba40010009c00001ba4010080410000004001100210000000000202043300001ba40020009c00001ba4020080410000006002200210000000000112019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f000000010020019000006d470000613d000000000101043b00001c4a02000041000000000020044300001ba701100197001100000001001d0000000400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c27011001c700008002020000396e8b6e860000040f000000010020019000006d460000613d000000400a00043d0000002404a000390000000403a00039000000000101043b000000000001004b00006d980000613d000000120e00002900000000020e043300001c4b0100004100000000001a043500000020010000390000000000130435000000000302043300000000003404350000004401a00039000000000003004b0000657b0000613d0000000004000019000000200220003900000000050204330000000067050434000000040070008c00006d310000813d0000000007710436000000000606043300001ba70660019700000000006704350000004006500039000000000606043300001ba706600197000000400710003900000000006704350000006006500039000000000606043300001ba706600197000000600710003900000000006704350000008006500039000000000606043300000080071000390000000000670435000000a0055000390000000005050433000000a0061000390000000000560435000000c0011000390000000104400039000000000034004b0000655c0000413d00000000040004140000001102000029000000040020008c000068810000c13d0000000103000031000000200030008c00000020040000390000000004034019000068b20000013d00000000007501a000006d4c0000c13d000000000003004b00006d490000613d0000000001000414000000040040008c000066320000c13d00000001010000310000000102000039000000000001004b000066410000c13d000066680000013d000000000003004b00006d490000613d000000130100002900000000020104330000000000f2004b000067b60000613d00000000010e04330000000001010433000000000001004b000067b60000613d000800000002001d000e0000000f001d000000400100043d000d00000001001d000000200210003900001c4801000041000700000002001d000000000012043500001c100100004100000000001004430000000001000412000000040010044300000120010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f000000010020019000006d460000613d000000000101043b0000000d04000029000000600240003900000008030000290000000000320435000000400240003900001ba701100197000000000012043500001c100100004100000000001004430000000001000412000000040010044300000160010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f000000010020019000006d460000613d000000000101043b0000000d04000029000000a00240003900001c4903000041000000000032043500000080024000390000000000120435000000a001000039000000000014043500001bd40040009c00006d2b0000213d0000000d02000029000000c001200039000000400010043f000000070100002900001ba40010009c00001ba4010080410000004001100210000000000202043300001ba40020009c00001ba4020080410000006002200210000000000112019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f000000010020019000006d470000613d000000000101043b00001c4a02000041000000000020044300001ba701100197000d00000001001d0000000400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c27011001c700008002020000396e8b6e860000040f000000010020019000006d460000613d000000400a00043d0000002404a000390000000403a00039000000000101043b000000000001004b00006d680000613d000000120e00002900000000020e043300001c4b0100004100000000001a043500000020010000390000000000130435000000000302043300000000003404350000004401a00039000000000003004b000066290000613d0000000004000019000000200220003900000000050204330000000067050434000000040070008c00006d310000813d0000000007710436000000000606043300001ba70660019700000000006704350000004006500039000000000606043300001ba706600197000000400710003900000000006704350000006006500039000000000606043300001ba706600197000000600710003900000000006704350000008006500039000000000606043300000080071000390000000000670435000000a0055000390000000005050433000000a0061000390000000000560435000000c0011000390000000104400039000000000034004b0000660a0000413d00000000040004140000000d02000029000000040020008c000067710000c13d0000000103000031000000200030008c00000020040000390000000004034019000067a20000013d00001ba40010009c00001ba401008041000000c00110021000001bcd011001c7000080090200003900000000050000196e8b6e810000040f000000120e000029000000010220018f0003000000010355000000600110027000011ba40010019d00001ba401100197000000000001004b000066680000613d00001bce0010009c00006d2b0000213d0000001f0310003900001c2b033001970000003f0330003900001c2b04300197000000400300043d0000000004430019000000000034004b0000000005000039000000010500403900001bce0040009c00006d2b0000213d000000010050019000006d2b0000c13d000000400040043f000000000613043600001c2b04100198000000000346001900000003050003670000665b0000613d000000000705034f000000007807043c0000000006860436000000000036004b000066570000c13d0000001f01100190000066680000613d000000000445034f0000000301100210000000000503043300000000051501cf000000000515022f000000000404043b0000010001100089000000000414022f00000000011401cf000000000151019f0000000000130435000000000002004b0000001d040000290000001a03000029000063f00000c13d00006d540000013d0000000001a1004900001ba40010009c00001ba401008041000000600110021000001ba400a0009c00001ba40300004100000000030a40190000004003300210000000000131019f00001ba40040009c00001ba404008041000000c003400210000000000131019f000d0000000a001d6e8b6e810000040f0000000d0a0000290000000003010019000000600330027000001ba403300197000000200030008c00000020040000390000000004034019000000200640019000000000056a00190000668c0000613d000000000701034f00000000080a0019000000007907043c0000000008980436000000000058004b000066880000c13d0000001f07400190000066990000613d000000000661034f0000000307700210000000000805043300000000087801cf000000000878022f000000000606043b0000010007700089000000000676022f00000000067601cf000000000686019f0000000000650435000100000003001f00030000000103550000000100200190000000120e00002900006dd10000613d0000001f01400039000000600210018f0000000001a20019000000000021004b0000000002000039000000010200403900001bce0010009c00006d2b0000213d000000010020019000006d2b0000c13d000000400010043f000000200030008c00006d470000413d00000000010a043300001c3f0010019800006d470000c13d000000600100003900000000001e043500000017030000290000000e0f00002900000000000f004b0000672a0000613d00000000010e04330000000001010433000000010010003a00006e470000413d000000010310003900001bce0030009c00006d2b0000213d00000005043002100000003f0240003900001c0e05200197000000400200043d0000000005520019000000000025004b0000000006000039000000010600403900001bce0050009c00006d2b0000213d000000010060019000006d2b0000c13d000000400050043f00000000033204360000000005000019000000400600043d00001bd40060009c00006d2b0000213d000000c007600039000000400070043f000000a0076000390000000000070435000000800760003900000000000704350000006007600039000000000007043500000040076000390000000000070435000000200760003900000000000704350000000000060435000000000735001900000000006704350000002005500039000000000045004b000066ca0000413d000000000001004b000067140000613d000000000400001900000000060e04330000000005060433000000000045004b00006d250000a13d00000005054002100000000006650019000000200660003900000000080604330000000097080434000000030070008c00006d310000213d000000400600043d00001bd40060009c00006d2b0000213d0000000009090433000000400a800039000000000a0a0433000000600b800039000000000b0b0433000000800c800039000000000c0c0433000000a0088000390000000008080433000000c00d6000390000004000d0043f000000a00d60003900000000008d043500000080086000390000000000c8043500001ba708b00197000000600b60003900000000008b043500001ba708a00197000000400a60003900000000008a043500001ba7089001970000002009600039000000000089043500000000007604350000000007020433000000000047004b00006d250000a13d000000000535001900000000006504350000000005020433000000000045004b00006d250000a13d0000000104400039000000000014004b000066e20000413d000000400400043d00001bd40040009c00006d2b0000213d000000c005400039000000400050043f000000a0054000390000001706000029000000000065043500000080054000390000001106000029000000000065043500000060054000390000001806000029000000000065043500000040054000390000001406000029000000000065043500000020054000390000001906000029000000000065043500000002050000390000682d0000013d000000010030008c00006d6e0000c13d00001c4a01000041000000000010044300000019010000290000000400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c27011001c700008002020000396e8b6e860000040f000000010020019000006d460000613d000000000101043b000000000001004b00006d620000613d00001c4a01000041000000000010044300000019010000290000000400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c27011001c700008002020000396e8b6e860000040f000000010020019000006d460000613d000000000101043b000000000001004b000000120e000029000000180400002900006d470000613d000000400500043d0000004401500039000000110200002900000000002104350000002401500039000000000041043500001c7501000041000000000015043500000004015000390000001402000029000000000021043500000000010004140000001902000029000000040020008c0000687d0000613d00001ba40050009c00001ba4030000410000000003054019000000400330021000001ba40010009c00001ba401008041000000c001100210000000000131019f00001c76011001c7001900000005001d6e8b6e810000040f0000001905000029000000120e0000290000000003010019000000600330027000011ba40030019d000300000001035500000001002001900000687d0000c13d00006da30000013d0000000001a1004900001ba40010009c00001ba401008041000000600110021000001ba400a0009c00001ba40300004100000000030a40190000004003300210000000000131019f00001ba40040009c00001ba404008041000000c003400210000000000131019f000d0000000a001d6e8b6e810000040f0000000d0a0000290000000003010019000000600330027000001ba403300197000000200030008c00000020040000390000000004034019000000200640019000000000056a0019000067900000613d000000000701034f00000000080a0019000000007907043c0000000008980436000000000058004b0000678c0000c13d0000001f074001900000679d0000613d000000000661034f0000000307700210000000000805043300000000087801cf000000000878022f000000000606043b0000010007700089000000000676022f00000000067601cf000000000686019f0000000000650435000100000003001f00030000000103550000000100200190000000120e00002900006ddd0000613d0000001f01400039000000600210018f0000000001a20019000000000021004b0000000002000039000000010200403900001bce0010009c00006d2b0000213d000000010020019000006d2b0000c13d000000400010043f000000200030008c00006d470000413d00000000010a043300001c3f0010019800006d470000c13d000000600100003900000000001e043500000019050000290000000e0f00002900000000000f004b000068320000613d00000000010e04330000000001010433000000010010003a00006e470000413d000000010310003900001bce0030009c00006d2b0000213d00000005043002100000003f0240003900001c0e05200197000000400200043d0000000005520019000000000025004b0000000006000039000000010600403900001bce0050009c00006d2b0000213d000000010060019000006d2b0000c13d000000400050043f00000000033204360000000005000019000000400600043d00001bd40060009c00006d2b0000213d000000c007600039000000400070043f000000a0076000390000000000070435000000800760003900000000000704350000006007600039000000000007043500000040076000390000000000070435000000200760003900000000000704350000000000060435000000000735001900000000006704350000002005500039000000000045004b000067ce0000413d000000000001004b000068180000613d000000000400001900000000060e04330000000005060433000000000045004b00006d250000a13d00000005054002100000000006650019000000200660003900000000080604330000000097080434000000030070008c00006d310000213d000000400600043d00001bd40060009c00006d2b0000213d0000000009090433000000400a800039000000000a0a0433000000600b800039000000000b0b0433000000800c800039000000000c0c0433000000a0088000390000000008080433000000c00d6000390000004000d0043f000000a00d60003900000000008d043500000080086000390000000000c8043500001ba708b00197000000600b60003900000000008b043500001ba708a00197000000400a60003900000000008a043500001ba7089001970000002009600039000000000089043500000000007604350000000007020433000000000047004b00006d250000a13d000000000535001900000000006504350000000005020433000000000045004b00006d250000a13d0000000104400039000000000014004b000067e60000413d000000400400043d00001bd40040009c00006d2b0000213d000000c005400039000000400050043f000000a00540003900000017060000290000000000650435000000800540003900000011060000290000000000650435000000600540003900000018060000290000000000650435000000400540003900000014060000290000000000650435000000200540003900000019060000290000000000650435000000030500003900000000005404350000000005020433000000000015004b000069400000213d00006d250000013d00001c4a0100004100000000001004430000000400500443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c27011001c700008002020000396e8b6e860000040f000000010020019000006d460000613d000000000101043b000000000001004b00006d620000613d00001c4a01000041000000000010044300000019010000290000000400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c27011001c700008002020000396e8b6e860000040f000000010020019000006d460000613d000000000101043b000000000001004b000000120e000029000000180400002900006d470000613d000000400500043d0000008401500039000000a00200003900000000002104350000006401500039000000170200002900000000002104350000004401500039000000110200002900000000002104350000002401500039000000000041043500001c71010000410000000000150435000000040150003900000014020000290000000000210435000000a401500039000000000001043500000000010004140000001902000029000000040020008c0000687d0000613d00001ba40050009c00001ba4030000410000000003054019000000400330021000001ba40010009c00001ba401008041000000c001100210000000000131019f00001c72011001c7001900000005001d6e8b6e810000040f0000001905000029000000120e0000290000000003010019000000600330027000011ba40030019d0003000000010355000000010020019000006db00000613d00001bce0050009c00006d2b0000213d000000400050043f000063ee0000013d0000000001a1004900001ba40010009c00001ba401008041000000600110021000001ba400a0009c00001ba40300004100000000030a40190000004003300210000000000131019f00001ba40040009c00001ba404008041000000c003400210000000000131019f00110000000a001d6e8b6e810000040f000000110a0000290000000003010019000000600330027000001ba403300197000000200030008c00000020040000390000000004034019000000200640019000000000056a0019000068a00000613d000000000701034f00000000080a0019000000007907043c0000000008980436000000000058004b0000689c0000c13d0000001f07400190000068ad0000613d000000000661034f0000000307700210000000000805043300000000087801cf000000000878022f000000000606043b0000010007700089000000000676022f00000000067601cf000000000686019f0000000000650435000100000003001f00030000000103550000000100200190000000120e00002900006de90000613d0000001f01400039000000600210018f0000000001a20019000000000021004b0000000002000039000000010200403900001bce0010009c00006d2b0000213d000000010020019000006d2b0000c13d000000400010043f000000200030008c00006d470000413d00000000010a043300001c3f0010019800006d470000c13d000000600100003900000000001e043500000019050000290000000e0f00002900000000000f004b000069470000613d00000000010e04330000000001010433000000010010003a00006e470000413d000000010310003900001bce0030009c00006d2b0000213d00000005043002100000003f0240003900001c0e05200197000000400200043d0000000005520019000000000025004b0000000006000039000000010600403900001bce0050009c00006d2b0000213d000000010060019000006d2b0000c13d000000400050043f00000000033204360000000005000019000000400600043d00001bd40060009c00006d2b0000213d000000c007600039000000400070043f000000a0076000390000000000070435000000800760003900000000000704350000006007600039000000000007043500000040076000390000000000070435000000200760003900000000000704350000000000060435000000000735001900000000006704350000002005500039000000000045004b000068de0000413d000000000001004b000069280000613d000000000400001900000000060e04330000000005060433000000000045004b00006d250000a13d00000005054002100000000006650019000000200660003900000000080604330000000097080434000000030070008c00006d310000213d000000400600043d00001bd40060009c00006d2b0000213d0000000009090433000000400a800039000000000a0a0433000000600b800039000000000b0b0433000000800c800039000000000c0c0433000000a0088000390000000008080433000000c00d6000390000004000d0043f000000a00d60003900000000008d043500000080086000390000000000c8043500001ba708b00197000000600b60003900000000008b043500001ba708a00197000000400a60003900000000008a043500001ba7089001970000002009600039000000000089043500000000007604350000000007020433000000000047004b00006d250000a13d000000000535001900000000006504350000000005020433000000000045004b00006d250000a13d0000000104400039000000000014004b000068f60000413d000000400400043d00001bd40040009c00006d2b0000213d000000c005400039000000400050043f000000a0054000390000001706000029000000000065043500000060054000390000001806000029000000000065043500000040054000390000001406000029000000000065043500000020054000390000001906000029000000000065043500000001050000390000000000540435000000800540003900000000000504350000000005020433000000000015004b00006d250000a13d0000000505100210000000000353001900000000004304350000000003020433000000000013004b000063eb0000213d00006d250000013d00001c4a0100004100000000001004430000000400500443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c27011001c700008002020000396e8b6e860000040f000000010020019000006d460000613d000000400200043d000000000101043b000000000001004b00006d780000613d000000640120003900000017030000290000000000310435000000440120003900000018030000290000000000310435000000200120003900001c750300004100000000003104350000002403200039000000140400002900000000004304350000006403000039000000000032043500001bb40020009c000000120e00002900006d2b0000213d000000a003200039000000400030043f000000000302043300000000040004140000001902000029000000040020008c000069720000c13d00000001040000310000000002000019000069840000013d00001ba40010009c00001ba401008041000000400110021000001ba40030009c00001ba4030080410000006003300210000000000113019f00001ba40040009c00001ba404008041000000c003400210000000000131019f6e8b6e810000040f000000120e000029000000010220015f0003000000010355000000600110027000011ba40010019d00001ba404100197000000000004004b00000080010000390000006003000039000069b00000613d00001bce0040009c00006d2b0000213d0000001f0140003900001c2b011001970000003f0110003900001c2b01100197000000400300043d0000000001130019000000000031004b0000000005000039000000010500403900001bce0010009c00006d2b0000213d000000010050019000006d2b0000c13d000000400010043f000000000143043600001c2b0640019800000000056100190000000307000367000069a30000613d000000000807034f0000000009010019000000008a08043c0000000009a90436000000000059004b0000699f0000c13d0000001f04400190000069b00000613d000000000667034f0000000304400210000000000705043300000000074701cf000000000747022f000000000606043b0000010004400089000000000646022f00000000044601cf000000000474019f0000000000450435000000010020019000006d820000c13d0000000002030433000000200020008c0000001d040000290000001a03000029000063f00000413d00001c0f0020009c00006d470000213d000000200020008c00006d470000413d0000000001010433000000000001004b0000000002000039000000010200c039000000000021004b00006d470000c13d000000000001004b0000001d040000290000001a03000029000063f00000c13d00006dbd0000013d0000000c04000029000000400140003900000000010104330000000023010434000000000003004b000063c00000613d000000c004400039000000000300001900000005053002100000000006520019000000000606043300000060066000390000000007060433000000000007004b00006d370000c13d00000000070404330000000008070433000000000038004b00006d250000a13d000000000575001900000020055000390000000005050433000000000056043500000001033000390000000005010433000000000053004b000069ce0000413d000063c00000013d00000000010e04330000000001010433000000000001004b00006ac30000613d00000013010000290000000001010433001c00000001001d000000400100043d001d00000001001d000000200210003900001c4801000041001b00000002001d000000000012043500001c100100004100000000001004430000000001000412000000040010044300000120010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f000000010020019000006d460000613d000000000101043b0000001d0400002900000060024000390000001c030000290000000000320435000000400240003900001ba701100197000000000012043500001c100100004100000000001004430000000001000412000000040010044300000160010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f000000010020019000006d460000613d000000000101043b0000001d04000029000000a00240003900001c4903000041000000000032043500000080024000390000000000120435000000a001000039000000000014043500001bd40040009c00006d2b0000213d0000001d02000029000000c001200039000000400010043f0000001b0100002900001ba40010009c00001ba4010080410000004001100210000000000202043300001ba40020009c00001ba4020080410000006002200210000000000112019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f000000010020019000006d470000613d000000000101043b00001c4a02000041000000000020044300001ba701100197001d00000001001d0000000400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c27011001c700008002020000396e8b6e860000040f000000010020019000006d460000613d000000400b00043d0000002404b000390000000403b00039000000000101043b000000000001004b00006e270000613d0000001208000029000000000208043300001c4b0100004100000000001b043500000020010000390000000000130435000000000302043300000000003404350000004401b00039000000000003004b00006a760000613d0000000004000019000000200220003900000000050204330000000067050434000000040070008c00006d310000813d0000000007710436000000000606043300001ba70660019700000000006704350000004006500039000000000606043300001ba706600197000000400710003900000000006704350000006006500039000000000606043300001ba706600197000000600710003900000000006704350000008006500039000000000606043300000080071000390000000000670435000000a0055000390000000005050433000000a0061000390000000000560435000000c0011000390000000104400039000000000034004b00006a570000413d00000000040004140000001d02000029000000040020008c00006a7f0000c13d0000000103000031000000200030008c0000002004000039000000000403401900006ab10000013d0000000001b1004900001ba40010009c00001ba401008041000000600110021000001ba400b0009c00001ba40300004100000000030b40190000004003300210000000000131019f00001ba40040009c00001ba404008041000000c003400210000000000131019f001d0000000b001d6e8b6e810000040f0000001d0b0000290000000003010019000000600330027000001ba403300197000000200030008c000000200400003900000000040340190000001f0640018f000000200740019000000000057b001900006a9f0000613d000000000801034f00000000090b0019000000008a08043c0000000009a90436000000000059004b00006a9b0000c13d000000000006004b00006aac0000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f0000000000650435000100000003001f00030000000103550000000100200190000000120800002900006e3b0000613d0000001f01400039000000600210018f0000000001b20019000000000021004b0000000002000039000000010200403900001bce0010009c00006d2b0000213d000000010020019000006d2b0000c13d000000400010043f000000200030008c00006d470000413d00000000010b043300001c3f0010019800006d470000c13d0000006001000039000000000018043500001c6c01000041000000000010044300000000010004100000000400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c27011001c70000800a020000396e8b6e860000040f000000010020019000006d460000613d000000000101043b000000000001004b000000000f00041100006b290000613d00001c6c01000041000000000010044300000000010004100000000400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c27011001c70000800a020000396e8b6e860000040f000000010020019000006d460000613d000000000301043b000000000003004b000000000f00041100006d490000613d000000000100041400001ba704f00197000000040040008c001d00000003001d001c00000004001d00006af00000c13d00000001020000390000000101000031000000000001004b00006aff0000c13d00006b270000013d00001ba40010009c00001ba401008041000000c00110021000001bcd011001c7000080090200003900000000050000196e8b6e810000040f000000000f000411000000010220018f0003000000010355000000600110027000011ba40010019d00001ba401100197000000000001004b00006b270000613d00001bce0010009c00006d2b0000213d0000001f0310003900001c2b033001970000003f0330003900001c2b04300197000000400300043d0000000004430019000000000034004b0000000005000039000000010500403900001bce0040009c00006d2b0000213d000000010050019000006d2b0000c13d000000400040043f000000000613043600001c2b031001980000001f0410018f0000000001360019000000030500036700006b1a0000613d000000000705034f000000007807043c0000000006860436000000000016004b00006b160000c13d000000000004004b00006b270000613d000000000335034f0000000304400210000000000501043300000000054501cf000000000545022f000000000303043b0000010004400089000000000343022f00000000034301cf000000000353019f0000000000310435000000000002004b00006e320000613d000000010000006b00006d230000613d00000009010000290000000001010433000000000001004b00006d230000613d0000000201000029001b00200010003d000000000800001900006b380000013d000000010880003900000009010000290000000001010433000000000018004b00006d230000813d00000005018002100000000a0210002900000000040204330000008002400039000000000202043300001c1f0020019800006b330000613d00000006020000290000000002020433000000000082004b00006d250000a13d00000002020000290000000002020433000000000082004b00006d250000a13d001d00000008001d00000005021000290000000006020433000000000506043300000080025000390000000002020433000000040020008c00006d310000213d0000001b01100029000000000d01043300001c6f08200197000000007104043400001ba703100197000000020080008c00006c110000c13d0000002001500039000000000101043300001ba70210019700000000002f004b0000001d0800002900006b330000613d000000400900043d00001c3d0090009c00006d2b0000213d000000e001500039000000000801043300000080016000390000004004400039000000000a070433000000000b040433000000000c010433000000a0015000390000000006010433000000c00150003900000000050104330000014001900039000000400010043f0000012001900039000000000081043500000100049000390000000000540435000000e0059000390000000000650435000000c00690003900000002070000290000000000760435000000a0079000390000000000c7043500000080089000390000000000b80435000000600b9000390000000000ab0435000000400a90003900000000003a043500000020039000390000000000f30435001c0000000d001d0000000000d90435000000400e00043d00001c4d0c0000410000000000ce0435000000040ce00039000000200d0000390000000000dc04350000000009090433000000240ce0003900000000009c0435000000000303043300001ba7033001970000004409e00039000000000039043500000000030a043300001ba7033001970000006409e00039000000000039043500000000090b04330000008403e00039000001400a0000390000000000a304350000016403e00039000000000a0904330000000000a30435001a0000000e001d0000018403e0003900000000000a004b00006bb30000613d000000000b0000190000002009900039000000000c09043300000000de0c04340000000500e0008c00006d310000213d000000000ee30436000000000d0d043300001ba70dd001970000000000de0435000000400dc00039000000000d0d0433000000400e3000390000000000de0435000000600cc00039000000000c0c0433000000600d3000390000000000cd04350000008003300039000000010bb000390000000000ab004b00006b9e0000413d0000001a0a0000290000000009a30049000000240990008a0000000008080433000000a40aa0003900000000009a043500000000090804330000000003930436000000000009004b00006bd80000613d000000000a0000190000002008800039000000000b08043300000000cd0b04340000000500d0008c00006d310000213d000000000dd30436000000000c0c043300001ba70cc001970000000000cd0435000000400cb00039000000000c0c0433000000400d3000390000000000cd0435000000600cb00039000000000c0c0433000000600d3000390000000000cd0435000000800bb00039000000000b0b043300001ba70bb00197000000800c3000390000000000bc0435000000a003300039000000010aa0003900000000009a004b00006bbe0000413d0000001a0c0000290000000008c30049000000240880008a0000000007070433000000c409c00039000000000089043500000000870704340000000003730436000000000007004b00006bea0000613d0000000009000019000000000a390019000000000b980019000000000b0b04330000000000ba04350000002009900039000000000079004b00006be30000413d000000000873001900000000000804350000001f0770003900001c2b0770019700000000037300190000000007c30049000000240770008a0000000006060433000000e408c00039000000000078043500000000070604330000000003730436000000000007004b00006bff0000613d00000000080000190000002006600039000000000906043300000000039304360000000108800039000000000078004b00006bf90000413d00000000050504330000010406c00039000000000056043500000000040404330000012405c0003900000000004504350000014404c00039000000000101043300000000001404350000000001000414000000040020008c00006cd90000c13d0000000103000031000000200030008c000000200400003900000000040340190000001c0500002900006d0a0000013d000000040020008c0000001d0800002900006b330000c13d001c0000000d001d00000080026000390000000002020433000000400440003900000000040404330000000006070433000000400c00043d00001c6d0500004100000000005c04350000000405c00039000000a0070000390000000000750435000000a405c0003900000000070604330000000000750435000000c405c00039000000000007004b00006c3c0000613d00000000080000190000002006600039000000000906043300000000ab0904340000000500b0008c00006d310000213d000000000bb50436000000000a0a043300001ba70aa001970000000000ab0435000000400a900039000000000a0a0433000000400b5000390000000000ab043500000060099000390000000009090433000000600a50003900000000009a043500000080055000390000000108800039000000000078004b00006c270000413d0000000006c50049000000040660008a0000002407c00039000000000067043500000000060404330000000005650436000000000006004b00006c5f0000613d000000000700001900000020044000390000000008040433000000009a0804340000000500a0008c00006d310000213d000000000aa50436000000000909043300001ba70990019700000000009a043500000040098000390000000009090433000000400a50003900000000009a043500000060098000390000000009090433000000600a50003900000000009a04350000008008800039000000000808043300001ba70880019700000080095000390000000000890435000000a0055000390000000107700039000000000067004b00006c450000413d0000000004c50049000000040440008a0000004406c00039000000000046043500000000640204340000000002450436000000000004004b00006c6f0000613d000000000500001900000000072500190000000008560019000000000808043300000000008704350000002005500039000000000045004b00006c680000413d000000000542001900000000000504350000001f0440003900001c2b0440019700000000024200190000000004c20049000000040440008a0000006405c000390000000000450435000000020600002900000000040604330000000002420436000000000004004b0000001c0900002900006c850000613d00000000050000190000002006600039000000000706043300000000027204360000000105500039000000000045004b00006c7f0000413d0000006001100210000000000191013f0000008404c0003900000000001404350000000001000414000000040030008c00006c910000c13d0000000103000031000000200030008c0000002004000039000000000403401900006cc40000013d0000000002c2004900001ba40020009c00001ba402008041000000600220021000001ba400c0009c00001ba40400004100000000040c40190000004004400210000000000242019f00001ba40010009c00001ba401008041000000c001100210000000000112019f0000000002030019001a0000000c001d6e8b6e810000040f0000001a0c0000290000000003010019000000600330027000001ba403300197000000200030008c00000020040000390000000004034019000000200640019000000000056c001900006cb10000613d000000000701034f00000000080c0019000000007907043c0000000008980436000000000058004b00006cad0000c13d0000001f0740019000006cbe0000613d000000000661034f0000000307700210000000000805043300000000087801cf000000000878022f000000000606043b0000010007700089000000000676022f00000000067601cf000000000686019f0000000000650435000100000003001f00030000000103550000000100200190000000000f0004110000001c0900002900006e0f0000613d0000001f01400039000000600210018f0000000001c20019000000000021004b0000000002000039000000010200403900001bce0010009c00006d2b0000213d000000010020019000006d2b0000c13d000000400010043f000000200030008c00006d470000413d00000000020c043300001c3f0020019800006d470000c13d00001c400220019700001c6d0020009c0000001d0800002900006b330000613d00006e0a0000013d0000000003c3004900001ba40030009c00001ba403008041000000600330021000001ba400c0009c00001ba40400004100000000040c40190000004004400210000000000343019f00001ba40010009c00001ba401008041000000c001100210000000000131019f6e8b6e810000040f0000001a0c0000290000000003010019000000600330027000001ba403300197000000200030008c00000020040000390000000004034019000000200640019000000000056c001900006cf70000613d000000000701034f00000000080c0019000000007907043c0000000008980436000000000058004b00006cf30000c13d0000001f0740019000006d040000613d000000000661034f0000000307700210000000000805043300000000087801cf000000000878022f000000000606043b0000010007700089000000000676022f00000000067601cf000000000686019f0000000000650435000100000003001f00030000000103550000000100200190000000000f0004110000001c0500002900006e1b0000613d0000001f01400039000000600210018f0000000001c20019000000000021004b0000000002000039000000010200403900001bce0010009c00006d2b0000213d000000010020019000006d2b0000c13d000000400010043f000000200030008c00006d470000413d00000000020c043300001c3f0020019800006d470000c13d00001c400220019700001c4d0020009c0000001d0800002900006b330000613d00001c410200004100000000002104350000000402100039000000000052043500006d730000013d0000000401000029000000000001042d00001c1401000041000000000010043f0000003201000039000000040010043f00001c150100004100006e8d0001043000001c1401000041000000000010043f0000004101000039000000040010043f00001c150100004100006e8d0001043000001c1401000041000000000010043f0000002101000039000000040010043f00001c150100004100006e8d00010430000000400100043d000000440210003900000000007204350000002402100039000000000032043500001c8b02000041000000000021043500000004021000390000000b03000029000000000032043500001ba40010009c00001ba401008041000000400110021000001c76011001c700006e8d00010430000000000001042f000000000100001900006e8d00010430000000400100043d00001c460200004100006d4e0000013d000000400100043d00001c4e02000041000000000021043500001ba40010009c00001ba401008041000000400110021000001bd6011001c700006e8d00010430000000400100043d00000024021000390000001703000029000000000032043500001c4502000041000000000021043500000004021000390000001803000029000000000032043500001ba40010009c00001ba401008041000000400110021000001c36011001c700006e8d00010430000000400100043d00001c730200004100000000002104350000000402100039000000190300002900006d720000013d00001c4c0100004100000000001a0435000000080100002900000000001304350000000d0100002900006d9d0000013d000000400100043d00001c740200004100000000002104350000000402100039000000000032043500001ba40010009c00001ba401008041000000400110021000001c15011001c700006e8d0001043000001c7301000041000000000012043500000004012000390000001903000029000000000031043500001ba40020009c00001ba402008041000000400120021000001c15011001c700006e8d00010430000000400100043d00000084021000390000001703000029000000000032043500000044021000390000001803000029000000000032043500000024021000390000001403000029000000000032043500001c890200004100000000002104350000000402100039000000190300002900000000003204350000006402100039000000000002043500001ba40010009c00001ba401008041000000400110021000001c8a011001c700006e8d0001043000001c4c0100004100000000001a04350000000d0100002900000000001304350000001101000029000000000014043500001ba400a0009c00001ba40a0080410000004001a0021000001c36011001c700006e8d0001043000001ba4033001970000001f0530018f00001ba606300198000000400200043d000000000462001900006df40000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b00006dab0000c13d00006df40000013d00001ba4033001970000001f0530018f00001ba606300198000000400200043d000000000462001900006df40000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b00006db80000c13d00006df40000013d000000400100043d00000064021000390000001703000029000000000032043500000044021000390000001803000029000000000032043500000024021000390000001403000029000000000032043500001c8702000041000000000021043500000004021000390000001903000029000000000032043500001ba40010009c00001ba401008041000000400110021000001c88011001c700006e8d000104300000001f0530018f00001ba606300198000000400200043d000000000462001900006df40000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b00006dd80000c13d00006df40000013d0000001f0530018f00001ba606300198000000400200043d000000000462001900006df40000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b00006de40000c13d00006df40000013d0000001f0530018f00001ba606300198000000400200043d000000000462001900006df40000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b00006df00000c13d000000000005004b00006e010000613d000000000161034f0000000305500210000000000604043300000000065601cf000000000656022f000000000101043b0000010005500089000000000151022f00000000015101cf000000000161019f0000000000140435000000600130021000001ba40020009c00001ba4020080410000004002200210000000000112019f00006e8d00010430000000400100043d00001c470200004100006d4e0000013d00001c6e0200004100000000002104350000000402100039000000000092043500006d730000013d0000001f0530018f00001ba606300198000000400200043d000000000462001900006df40000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b00006e160000c13d00006df40000013d0000001f0530018f00001ba606300198000000400200043d000000000462001900006df40000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b00006e220000c13d00006df40000013d00001c4c0100004100000000001b04350000001c0100002900000000001304350000001d01000029000000000014043500001ba400b0009c00001ba40b0080410000004001b0021000001c36011001c700006e8d00010430000000400100043d00000024021000390000001d03000029000000000032043500001c4502000041000000000021043500000004021000390000001c0300002900006d5c0000013d0000001f0530018f00001ba606300198000000400200043d000000000462001900006df40000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b00006e420000c13d00006df40000013d00001c1401000041000000000010043f0000001101000039000000040010043f00001c150100004100006e8d00010430000000000001042f00001ba40010009c00001ba401008041000000400110021000001ba40020009c00001ba4020080410000006002200210000000000112019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f000000010020019000006e610000613d000000000101043b000000000001042d000000000100001900006e8d0001043000000000050100190000000000200443000000050030008c00006e710000413d000000040100003900000000020000190000000506200210000000000664001900000005066002700000000006060031000000000161043a0000000102200039000000000031004b00006e690000413d00001ba40030009c00001ba4030080410000006001300210000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001c8c011001c700000000020500196e8b6e860000040f000000010020019000006e800000613d000000000101043b000000000001042d000000000001042f00006e84002104210000000102000039000000000001042d0000000002000019000000000001042d00006e89002104230000000102000039000000000001042d0000000002000019000000000001042d00006e8b0000043200006e8c0001042e00006e8d000104300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffff00000000000000000000000000000000000000000000000000000001ffffffe000000000000000000000000000000000000000000000000000000000ffffffe0000000000000000000000000ffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000000000000000ffffffffffffffbf536561706f7274000000000000000000000000000000000000000000000000000200000000000000000000000000000000000007000000000000000000000000312e36000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000030000000000000000000000004f666665724974656d280000000000000000000000000000000000000000000075696e7438206974656d547970652c00000000000000000000000000000000006164647265737320746f6b656e2c00000000000000000000000000000000000075696e74323536206964656e7469666965724f7243726974657269612c00000075696e74323536207374617274416d6f756e742c00000000000000000000000075696e7432353620656e64416d6f756e740000000000000000000000000000002900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff5f436f6e73696465726174696f6e4974656d28000000000000000000000000000075696e7432353620656e64416d6f756e742c00000000000000000000000000006164647265737320726563697069656e74000000000000000000000000000000000000000000000000000000000000000000000000000000fffffffffffffe9f6e2c00000000000000000000000000000000000000000000000000000000000075696e7438206f72646572547970652c0000000000000000000000000000000075696e7432353620737461727454696d652c000000000000000000000000000075696e7432353620656e6454696d652c0000000000000000000000000000000062797465733332207a6f6e65486173682c0000000000000000000000000000004f72646572436f6d706f6e656e7473280000000000000000000000000000000061646472657373206f6666657265722c0000000000000000000000000000000075696e743235362073616c742c0000000000000000000000000000000000000061646472657373207a6f6e652c000000000000000000000000000000000000006279746573333220636f6e647569744b65792c000000000000000000000000004f666665724974656d5b5d206f666665722c000000000000000000000000000075696e7432353620636f756e7465720000000000000000000000000000000000436f6e73696465726174696f6e4974656d5b5d20636f6e73696465726174696f000000000000000000000000000000000000000000000000fffffffffffffd9f454950373132446f6d61696e2800000000000000000000000000000000000000737472696e67206e616d652c0000000000000000000000000000000000000000737472696e672076657273696f6e2c000000000000000000000000000000000075696e7432353620636861696e49642c000000000000000000000000000000006164647265737320766572696679696e67436f6e747261637400000000000000000000000000000000000000000000000000000000000000fffffffffffffd1f0200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffff325d5b325d5b325d5b325d5b325d20747265652900000000000000000000000042756c6b4f72646572284f72646572436f6d706f6e656e74735b325d5b325d5b000000000000000000000000000000000000000000000000ffffffffffffff9f9a8a0592ac89c5ad3bc6df8224c17b485976f597df104ee20d0df415241f670b0200000200000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff3f0a96ad390000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000003ca2711d29384747a8f61d60aad3c450405f7aaff5613541dee28df2d6986d32ada5013122d395ba3c54772283fb069b10426056ef8ca54750cb9bb552a59e7dbf8e29b89f29ed9b529c154a63038ffca562f8d7cd1e2545dda53a1b582dde30abbb5caa7dda850e60932de0934eb1f9d0f59695050f761dc64e443e5030a56953c6f6856e13104584dd0797ca2b2779202dc2597c6066a42e0d8fe990b0024d101e368776582e57ab3d116ffe2517c0a585cd5b23174b01e275c2d8329c3d83a02eb7ff164c884e5e2c336dc85f81c6a93329d8e9adf214b32729b894de2af139c9d33c18e050dda0aeb9a8086fb16fc12d5d64536780e1da7405a800b0b9f61c19f71958cdd8f081b4c31f7caf5c010b29d12950be2fa1c95070dc47e30b55ca74fab2fece9a1d58234a274220ad05ca096a92ef6a1ca1750b9d90c948955c7ff98d9d4e55d876c5cfac10b43c04039522f3ddfb0ea9bfe70c68cfb5c7cc14bed7be92d41c56f9e59ac7a6272185299b815ddfabc3f25deb51fe55fe2f9e8ad1d97d1ef5eaa37a4ee5fbf234e6f6d64eb511eb562221cd7edfbdde0848da05896c3f349c4da741c19b37fec49ed2e44d738e775a21d9c9860a69d67a3dae53bb98d87cc12922b83759626c5f07d72266da9702d19ffad6a514c73a89002f5fe6ae19322608dd1f8a8d56aab48ed9c28be489b689f4b6c91268563efc85f20e6b5b04cbae4fcb1a9d78e7b2dfc51a36933d023cf6e347e03d517b472a852590d1eb68309202b7106b891e109739dbbd334a1817fe5d6202c939e75cf5e35ca91da3eed3ecef6ebaa6e5023c057ec2c75150693fd0dac5c90f4a142f9879fde8eee9a1392aa395c7002308119a58f2582777a75e54e0c1d5d5437bd2e8bf6222c3939feff011e53ab8c35ca3370aad54c5df1fc2938cd62543174fa6e7d858770efca7572ac20f5ae84db0e2940674f7eca0a4726fa1060ffc2d18cef54b203d5a4f867d3d458dabecad65f6201ceeaba0096df2d0c491cc32e6ea4e6435001780987079d291feebf21c2230e69add0f283cee0b8be492ca8050b4185a2ff7193bd8cff538aba49a9c374c806d277181e9651624b3e31111bc0624574f8bca1d5d6a3f098a0bc373f808c619b1bb4028208721b3c4f8d6bc8a874d659814eb761d51df90cba8de7637ca3e8fe1e3511d1dc2f23487d05dbdecb781860c21ac1c54cdd369e4e8a8515e52ca72ec816c2101831ad1f18bf44102ed171459c9b4f80000000200000000000000000000000000000340000001000000000000000000a61be9f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000220000000000000000000000000000000000000000000000000000000000000000000000000a900866a00000000000000000000000000000000000000000000000000000000f07ec37200000000000000000000000000000000000000000000000000000000f47b773f00000000000000000000000000000000000000000000000000000000f47b774000000000000000000000000000000000000000000000000000000000fb0f3ee100000000000000000000000000000000000000000000000000000000fd9f1e1000000000000000000000000000000000000000000000000000000000f07ec37300000000000000000000000000000000000000000000000000000000f2d12b1200000000000000000000000000000000000000000000000000000000e7acab2300000000000000000000000000000000000000000000000000000000e7acab2400000000000000000000000000000000000000000000000000000000ed98a57400000000000000000000000000000000000000000000000000000000a900866b00000000000000000000000000000000000000000000000000000000b3a34c4c0000000000000000000000000000000000000000000000000000000079df72bc0000000000000000000000000000000000000000000000000000000088147731000000000000000000000000000000000000000000000000000000008814773200000000000000000000000000000000000000000000000000000000a81744040000000000000000000000000000000000000000000000000000000079df72bd0000000000000000000000000000000000000000000000000000000087201b410000000000000000000000000000000000000000000000000000000046423aa60000000000000000000000000000000000000000000000000000000046423aa7000000000000000000000000000000000000000000000000000000005b34b9660000000000000000000000000000000000000000000000000000000006fdde0380000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff310ab089e4439a4c15d089f94afb7896ff553aecb10793d0ab882de59d99a32e0200000200000000000000000000000000000044000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff1f000000000000000000000000000000000000000000000000fffffffffffffeff4e487b71000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000000000000000000000000000000000000000000000fffffffffffffe5f0200000000000000000000000000000000000040000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000002000000000000000000000000000000000000200000000000000000000000006bacc01dbe442496068f7d234edd811f1a5f833243e0aec824f86ab861f3c90dfed398fc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000022000000000000000001a515574000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffff10fda3e1000000000000000000000000000000000000000000000000000000002165628a00000000000000000000000000000000000000000000000000000000f280791efe782edcf06ce15c8f4dff17601db3b88eb3805a0db7d77faf757f047fa8a98700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000220000000000000000042cbb15ccdc3cad6266b0e7a08c0454b23bf29dc2df74b6f3c209e9336465bd180b41246c05cbb406f874e82aa2faf7db11bba9792fe09929e56ef1eee2c2da30200000200000000000000000000000000000024000000000000000000000000721c20121297512b72821b97f5326877ea8ecf4bb9948fea5bfcb6453074d37f00000000000000000000000000000000000000800000022000000000000000000000000000000000000000000000000000000000000002600000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff40ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000fffffffffffffea0000000000000000000000000000000000000000000000000ffffffffffffffe00000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000ffffffffffffff60000000000000000000000000000000000000000000000000fffffffffffffdff796b89b91644bc98cd93958e4c9038275d622183e25ac5af08cc6b5d9553913221ccfeb700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004400000000000000000000000003fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7000000000000000000000000000000000000000000000000ffffffffffffff20000000000000000000000000000000000000000000000000fffffffffffffffe000000000000000000000000000000000000000000000000ffffffffffffff7f000000000000000000000000000000000000000000000000ffffffffffffffdf9d9af8e38d66c62e2c12f0225249fd9d721c54b83f48d9352c97c6cacdcb6f31000000000000000000000000000000000000000000000000fffffffffffffebf01e4d72a0000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000fb5014fc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffff0000ee9e0e63000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000010001bc806b960000000000000000000000000000000000000000000000000000000091b3e514000000000000000000000000000000000000000000000000000000008ffff980000000000000000000000000000000000000000000000000000000002020dba91b30cc0006188af794c2fb30dd8520db7e2c088b7fc7c103c00ca494c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4701806aa1896bbf26568e884a7374b41e002500962caba6a15023a8d90e8508b834ce34aa2000000000000000000000000000000000000000000000000000000001cf99b260000000000000000000000000000000000000000000000000000000017b1f942000000000000000000000000000000000000000000000000000000006ab37ce700000000000000000000000000000000000000000000000000000000466aa6160000000000000000000000000000000000000000000000000000000039f3e3fd00000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1000000000000000000000000000000000000000000000000ffffffffffffffa07fda727900000000000000000000000000000000000000000000000000000000375c24c1000000000000000000000000000000000000000000000000000000004b9f2d36e1b4c93de62cc077b00b1a91d84b6c31b4a14e012718dcca230689e7bced929d0000000000000000000000000000000000000000000000000000000098e9db6e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff8000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000a11b63ff000000000000000000000000000000000000000000000000000000005a052b3200000000000000000000000000000000000000000000000000000000133c37c6000000000000000000000000000000000000000000000000000000006088d7de00000000000000000000000000000000000000000000000000000000bfb3f8ce0000000000000000000000000000000000000000000000000000000009bde3390000000000000000000000000000000000000000000000000000000094eb6af600000000000000000000000000000000000000000000000000000000a8930e9a00000000000000000000000000000000000000000000000000000000d69293320000000000000000000000000000000000000000000000000000000012d3f5a300000000000000000000000000000000000000000000000000000000c63cf089000000000000000000000000000000000000000000000000000000009891976500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff7b01000057a627b91c5eda3bbb2ea057376bba86242bfc8b7d1b705328ea56a6709c4d535bdea7cd8a978f128b93471df48c7dbab89d703809115bdc118c235bfd0200000000000000000000000000000000000084000000000000000000000000e5c5e9a3000000000000000000000000000000000000000000000000000000009cc7f708afc65944829bd487b90b72536b1951864fbfc14e125fc972a6507f39f4dd92ce000000000000000000000000000000000000000000000000000000009397928500000000000000000000000000000000000000000000000000000000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe000000000000000000000000000000000000000000000000ffffffffffffff40f242432a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c40000000000000000000000005f15d6720000000000000000000000000000000000000000000000000000000069f958270000000000000000000000000000000000000000000000000000000023b872dd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064000000000000000000000000a817440400000000000000000000000000000000000000000000000000000000f2d12b1200000000000000000000000000000000000000000000000000000000d5da9a1b00000000000000000000000000000000000000000000000000000000190100000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ff000000000000000000000000000000000000000000000000001fffffffffffffffff1626ba7e000000000000000000000000000000000000000000000000000000004f7fb80d000000000000000000000000000000000000000000000000000000001f003d0a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000815e1d64000000000000000000000000000000000000000000000000000000008baa579f00000000000000000000000000000000000000000000000000000000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd1efffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd98891923000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000084000000000000000000000000f486bc870000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a4000000000000000000000000a5f54208000000000000000000000000000000000000000000000000000000000200000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000036cf21cf339d50a423dd7cd2323b399e4a1b9dbe2136b230750aea542b93d229

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

0000000000000000000000001972ddfa941670a9f5fa2a0094f4490347b99d7b

-----Decoded View---------------
Arg [0] : conduitController (address): 0x1972ddFa941670A9F5fa2A0094f4490347B99D7B

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000001972ddfa941670a9f5fa2a0094f4490347b99d7b


Block Transaction 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  ]
[ 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.