Contract 0x9b1f4c3091e825a6abe451d0a266ee18005839e7

Txn Hash Method
Block
From
To
Value [Txn Fee]
0x12601fbb7edb28511bc643745cb748295c2f6cb4c2a431866ddc5a2d69234b530x6080604020290382022-10-20 9:44:2443 days 23 hrs ago0xdb13888fc7aa45d8c828325becd7c4b5c6e98779 IN  Create: CrossDelegateV40 CLV0.04302712
[ Download CSV Export 
Parent Txn Hash Block From To Value
Loading
This contract contains unverified libraries: RapidityLibV4
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.

Contract Source Code Verified (Exact Match)

Contract Name:
CrossDelegateV4

Compiler Version
v0.4.26+commit.4563c3fc

Optimization Enabled:
Yes with 200 runs

Other Settings:
byzantium EvmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at clvscan.com on 2022-10-21
*/

// File: contracts/components/Proxy.sol

/*

  Copyright 2019 Wanchain Foundation.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

*/

//                            _           _           _
//  __      ____ _ _ __   ___| |__   __ _(_)_ __   __| | _____   __
//  \ \ /\ / / _` | '_ \ / __| '_ \ / _` | | '_ \@/ _` |/ _ \ \ / /
//   \ V  V / (_| | | | | (__| | | | (_| | | | | | (_| |  __/\ V /
//    \_/\_/ \__,_|_| |_|\___|_| |_|\__,_|_|_| |_|\__,_|\___| \_/
//
//

pragma solidity ^0.4.24;

/**
 * Math operations with safety checks
 */


contract Proxy {

    event Upgraded(address indexed implementation);

    address internal _implementation;

    function implementation() public view returns (address) {
        return _implementation;
    }

    function () external payable {
        address _impl = _implementation;
        require(_impl != address(0), "implementation contract not set");

        assembly {
            let ptr := mload(0x40)
            calldatacopy(ptr, 0, calldatasize)
            let result := delegatecall(gas, _impl, ptr, calldatasize, 0, 0)
            let size := returndatasize
            returndatacopy(ptr, 0, size)

            switch result
            case 0 { revert(ptr, size) }
            default { return(ptr, size) }
        }
    }
}

// File: contracts/components/Owned.sol

/*

  Copyright 2019 Wanchain Foundation.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

*/

//                            _           _           _
//  __      ____ _ _ __   ___| |__   __ _(_)_ __   __| | _____   __
//  \ \ /\ / / _` | '_ \ / __| '_ \ / _` | | '_ \@/ _` |/ _ \ \ / /
//   \ V  V / (_| | | | | (__| | | | (_| | | | | | (_| |  __/\ V /
//    \_/\_/ \__,_|_| |_|\___|_| |_|\__,_|_|_| |_|\__,_|\___| \_/
//
//

pragma solidity ^0.4.24;

/// @dev `Owned` is a base level contract that assigns an `owner` that can be
///  later changed
contract Owned {

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /// @dev `owner` is the only address that can call a function with this
    /// modifier
    modifier onlyOwner() {
        require(msg.sender == owner, "Not owner");
        _;
    }

    address public owner;

    /// @notice The Constructor assigns the message sender to be `owner`
    constructor() public {
        owner = msg.sender;
    }

    address public newOwner;

    function transferOwner(address _newOwner) public onlyOwner {
        require(_newOwner != address(0), "New owner is the zero address");
        emit OwnershipTransferred(owner, _newOwner);
        owner = _newOwner;
    }

    /// @notice `owner` can step down and assign some other address to this role
    /// @param _newOwner The address of the new owner. 0x0 can be used to create
    ///  an unowned neutral vault, however that cannot be undone
    function changeOwner(address _newOwner) public onlyOwner {
        newOwner = _newOwner;
    }

    function acceptOwnership() public {
        if (msg.sender == newOwner) {
            owner = newOwner;
        }
    }

    function renounceOwnership() public onlyOwner {
        owner = address(0);
    }
}

// File: contracts/components/Halt.sol

/*

  Copyright 2019 Wanchain Foundation.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

*/

//                            _           _           _
//  __      ____ _ _ __   ___| |__   __ _(_)_ __   __| | _____   __
//  \ \ /\ / / _` | '_ \ / __| '_ \ / _` | | '_ \@/ _` |/ _ \ \ / /
//   \ V  V / (_| | | | | (__| | | | (_| | | | | | (_| |  __/\ V /
//    \_/\_/ \__,_|_| |_|\___|_| |_|\__,_|_|_| |_|\__,_|\___| \_/
//
//

pragma solidity ^0.4.24;


contract Halt is Owned {

    bool public halted = false;

    modifier notHalted() {
        require(!halted, "Smart contract is halted");
        _;
    }

    modifier isHalted() {
        require(halted, "Smart contract is not halted");
        _;
    }

    /// @notice function Emergency situation that requires
    /// @notice contribution period to stop or not.
    function setHalt(bool halt)
        public
        onlyOwner
    {
        halted = halt;
    }
}

// File: contracts/components/ReentrancyGuard.sol

pragma solidity 0.4.26;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
contract ReentrancyGuard {
    bool private _notEntered;

    constructor () internal {
        // Storing an initial non-zero value makes deployment a bit more
        // expensive, but in exchange the refund on every call to nonReentrant
        // will be lower in amount. Since refunds are capped to a percetange of
        // the total transaction's gas, it is best to keep them low in cases
        // like this one, to increase the likelihood of the full refund coming
        // into effect.
        _notEntered = true;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and make it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_notEntered, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _notEntered = false;

        _;

        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _notEntered = true;
    }
}

// File: contracts/lib/BasicStorageLib.sol

pragma solidity ^0.4.24;

library BasicStorageLib {

    struct UintData {
        mapping(bytes => mapping(bytes => uint))           _storage;
    }

    struct BoolData {
        mapping(bytes => mapping(bytes => bool))           _storage;
    }

    struct AddressData {
        mapping(bytes => mapping(bytes => address))        _storage;
    }

    struct BytesData {
        mapping(bytes => mapping(bytes => bytes))          _storage;
    }

    struct StringData {
        mapping(bytes => mapping(bytes => string))         _storage;
    }

    /* uintStorage */

    function setStorage(UintData storage self, bytes memory key, bytes memory innerKey, uint value) internal {
        self._storage[key][innerKey] = value;
    }

    function getStorage(UintData storage self, bytes memory key, bytes memory innerKey) internal view returns (uint) {
        return self._storage[key][innerKey];
    }

    function delStorage(UintData storage self, bytes memory key, bytes memory innerKey) internal {
        delete self._storage[key][innerKey];
    }

    /* boolStorage */

    function setStorage(BoolData storage self, bytes memory key, bytes memory innerKey, bool value) internal {
        self._storage[key][innerKey] = value;
    }

    function getStorage(BoolData storage self, bytes memory key, bytes memory innerKey) internal view returns (bool) {
        return self._storage[key][innerKey];
    }

    function delStorage(BoolData storage self, bytes memory key, bytes memory innerKey) internal {
        delete self._storage[key][innerKey];
    }

    /* addressStorage */

    function setStorage(AddressData storage self, bytes memory key, bytes memory innerKey, address value) internal {
        self._storage[key][innerKey] = value;
    }

    function getStorage(AddressData storage self, bytes memory key, bytes memory innerKey) internal view returns (address) {
        return self._storage[key][innerKey];
    }

    function delStorage(AddressData storage self, bytes memory key, bytes memory innerKey) internal {
        delete self._storage[key][innerKey];
    }

    /* bytesStorage */

    function setStorage(BytesData storage self, bytes memory key, bytes memory innerKey, bytes memory value) internal {
        self._storage[key][innerKey] = value;
    }

    function getStorage(BytesData storage self, bytes memory key, bytes memory innerKey) internal view returns (bytes memory) {
        return self._storage[key][innerKey];
    }

    function delStorage(BytesData storage self, bytes memory key, bytes memory innerKey) internal {
        delete self._storage[key][innerKey];
    }

    /* stringStorage */

    function setStorage(StringData storage self, bytes memory key, bytes memory innerKey, string memory value) internal {
        self._storage[key][innerKey] = value;
    }

    function getStorage(StringData storage self, bytes memory key, bytes memory innerKey) internal view returns (string memory) {
        return self._storage[key][innerKey];
    }

    function delStorage(StringData storage self, bytes memory key, bytes memory innerKey) internal {
        delete self._storage[key][innerKey];
    }

}

// File: contracts/components/BasicStorage.sol

pragma solidity ^0.4.24;


contract BasicStorage {
    /************************************************************
     **
     ** VARIABLES
     **
     ************************************************************/

    //// basic variables
    using BasicStorageLib for BasicStorageLib.UintData;
    using BasicStorageLib for BasicStorageLib.BoolData;
    using BasicStorageLib for BasicStorageLib.AddressData;
    using BasicStorageLib for BasicStorageLib.BytesData;
    using BasicStorageLib for BasicStorageLib.StringData;

    BasicStorageLib.UintData    internal uintData;
    BasicStorageLib.BoolData    internal boolData;
    BasicStorageLib.AddressData internal addressData;
    BasicStorageLib.BytesData   internal bytesData;
    BasicStorageLib.StringData  internal stringData;
}

// File: contracts/interfaces/IRC20Protocol.sol

/*

  Copyright 2019 Wanchain Foundation.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

*/

//                            _           _           _
//  __      ____ _ _ __   ___| |__   __ _(_)_ __   __| | _____   __
//  \ \ /\ / / _` | '_ \ / __| '_ \ / _` | | '_ \@/ _` |/ _ \ \ / /
//   \ V  V / (_| | | | | (__| | | | (_| | | | | | (_| |  __/\ V /
//    \_/\_/ \__,_|_| |_|\___|_| |_|\__,_|_|_| |_|\__,_|\___| \_/
//
//

pragma solidity ^0.4.26;

interface IRC20Protocol {
    function transfer(address, uint) external returns (bool);
    function transferFrom(address, address, uint) external returns (bool);
    function balanceOf(address _owner) external view returns (uint);
}

// File: contracts/interfaces/IQuota.sol

/*

  Copyright 2019 Wanchain Foundation.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

*/

//                            _           _           _
//  __      ____ _ _ __   ___| |__   __ _(_)_ __   __| | _____   __
//  \ \ /\ / / _` | '_ \ / __| '_ \ / _` | | '_ \@/ _` |/ _ \ \ / /
//   \ V  V / (_| | | | | (__| | | | (_| | | | | | (_| |  __/\ V /
//    \_/\_/ \__,_|_| |_|\___|_| |_|\__,_|_|_| |_|\__,_|\___| \_/
//
//

pragma solidity 0.4.26;

interface IQuota {
  function userLock(uint tokenId, bytes32 storemanGroupId, uint value) external;
  function userBurn(uint tokenId, bytes32 storemanGroupId, uint value) external;

  function smgRelease(uint tokenId, bytes32 storemanGroupId, uint value) external;
  function smgMint(uint tokenId, bytes32 storemanGroupId, uint value) external;

  function upgrade(bytes32 storemanGroupId) external;

  function transferAsset(bytes32 srcStoremanGroupId, bytes32 dstStoremanGroupId) external;
  function receiveDebt(bytes32 srcStoremanGroupId, bytes32 dstStoremanGroupId) external;

  function getUserMintQuota(uint tokenId, bytes32 storemanGroupId) external view returns (uint);
  function getSmgMintQuota(uint tokenId, bytes32 storemanGroupId) external view returns (uint);

  function getUserBurnQuota(uint tokenId, bytes32 storemanGroupId) external view returns (uint);
  function getSmgBurnQuota(uint tokenId, bytes32 storemanGroupId) external view returns (uint);

  function getAsset(uint tokenId, bytes32 storemanGroupId) external view returns (uint asset, uint asset_receivable, uint asset_payable);
  function getDebt(uint tokenId, bytes32 storemanGroupId) external view returns (uint debt, uint debt_receivable, uint debt_payable);

  function isDebtClean(bytes32 storemanGroupId) external view returns (bool);
}

// File: contracts/interfaces/IStoremanGroup.sol

/*

  Copyright 2019 Wanchain Foundation.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

*/

//                            _           _           _
//  __      ____ _ _ __   ___| |__   __ _(_)_ __   __| | _____   __
//  \ \ /\ / / _` | '_ \ / __| '_ \ / _` | | '_ \@/ _` |/ _ \ \ / /
//   \ V  V / (_| | | | | (__| | | | (_| | | | | | (_| |  __/\ V /
//    \_/\_/ \__,_|_| |_|\___|_| |_|\__,_|_|_| |_|\__,_|\___| \_/
//
//

pragma solidity ^0.4.24;

interface IStoremanGroup {
    function getSelectedSmNumber(bytes32 groupId) external view returns(uint number);
    function getStoremanGroupConfig(bytes32 id) external view returns(bytes32 groupId, uint8 status, uint deposit, uint chain1, uint chain2, uint curve1, uint curve2,  bytes gpk1, bytes gpk2, uint startTime, uint endTime);
    function getDeposit(bytes32 id) external view returns(uint);
    function getStoremanGroupStatus(bytes32 id) external view returns(uint8 status, uint startTime, uint endTime);
    function setGpk(bytes32 groupId, bytes gpk1, bytes gpk2) external;
    function setInvalidSm(bytes32 groupId, uint[] indexs, uint8[] slashTypes) external returns(bool isContinue);
    function getThresholdByGrpId(bytes32 groupId) external view returns (uint);
    function getSelectedSmInfo(bytes32 groupId, uint index) external view returns(address wkAddr, bytes PK, bytes enodeId);
    function recordSmSlash(address wk) external;
}

// File: contracts/interfaces/ITokenManager.sol

/*

  Copyright 2019 Wanchain Foundation.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

*/

//                            _           _           _
//  __      ____ _ _ __   ___| |__   __ _(_)_ __   __| | _____   __
//  \ \ /\ / / _` | '_ \ / __| '_ \ / _` | | '_ \@/ _` |/ _ \ \ / /
//   \ V  V / (_| | | | | (__| | | | (_| | | | | | (_| |  __/\ V /
//    \_/\_/ \__,_|_| |_|\___|_| |_|\__,_|_|_| |_|\__,_|\___| \_/
//
//

pragma solidity 0.4.26;

interface ITokenManager {
    function getTokenPairInfo(uint id) external view
      returns (uint origChainID, bytes tokenOrigAccount, uint shadowChainID, bytes tokenShadowAccount);

    function getTokenPairInfoSlim(uint id) external view
      returns (uint origChainID, bytes tokenOrigAccount, uint shadowChainID);

    function getAncestorInfo(uint id) external view
      returns (bytes account, string name, string symbol, uint8 decimals, uint chainId);

    function mintToken(address tokenAddress, address to, uint value) external;

    function burnToken(address tokenAddress, address from, uint value) external;

    function mapTokenPairType(uint tokenPairID) external view
      returns (uint8 tokenPairType);

    // erc1155
    function mintNFT(uint tokenCrossType, address tokenAddress, address to, uint[] ids, uint[] values, bytes data) public;
    function burnNFT(uint tokenCrossType, address tokenAddress, address from, uint[] ids, uint[] values) public;
}

// File: contracts/interfaces/ISignatureVerifier.sol

/*

  Copyright 2019 Wanchain Foundation.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

*/

//                            _           _           _
//  __      ____ _ _ __   ___| |__   __ _(_)_ __   __| | _____   __
//  \ \ /\ / / _` | '_ \ / __| '_ \ / _` | | '_ \@/ _` |/ _ \ \ / /
//   \ V  V / (_| | | | | (__| | | | (_| | | | | | (_| |  __/\ V /
//    \_/\_/ \__,_|_| |_|\___|_| |_|\__,_|_|_| |_|\__,_|\___| \_/
//
//

pragma solidity 0.4.26;

interface ISignatureVerifier {
  function verify(
        uint curveId,
        bytes32 signature,
        bytes32 groupKeyX,
        bytes32 groupKeyY,
        bytes32 randomPointX,
        bytes32 randomPointY,
        bytes32 message
    ) external returns (bool);
}

// File: openzeppelin-eth/contracts/math/SafeMath.sol

pragma solidity ^0.4.24;


/**
 * @title SafeMath
 * @dev Math operations with safety checks that revert on error
 */
library SafeMath {

  /**
  * @dev Multiplies two numbers, reverts on overflow.
  */
  function mul(uint256 a, uint256 b) internal pure returns (uint256) {
    // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
    // benefit is lost if 'b' is also tested.
    // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
    if (a == 0) {
      return 0;
    }

    uint256 c = a * b;
    require(c / a == b);

    return c;
  }

  /**
  * @dev Integer division of two numbers truncating the quotient, reverts on division by zero.
  */
  function div(uint256 a, uint256 b) internal pure returns (uint256) {
    require(b > 0); // Solidity only automatically asserts when dividing by 0
    uint256 c = a / b;
    // assert(a == b * c + a % b); // There is no case in which this doesn't hold

    return c;
  }

  /**
  * @dev Subtracts two numbers, reverts on overflow (i.e. if subtrahend is greater than minuend).
  */
  function sub(uint256 a, uint256 b) internal pure returns (uint256) {
    require(b <= a);
    uint256 c = a - b;

    return c;
  }

  /**
  * @dev Adds two numbers, reverts on overflow.
  */
  function add(uint256 a, uint256 b) internal pure returns (uint256) {
    uint256 c = a + b;
    require(c >= a);

    return c;
  }

  /**
  * @dev Divides two numbers and returns the remainder (unsigned integer modulo),
  * reverts when dividing by zero.
  */
  function mod(uint256 a, uint256 b) internal pure returns (uint256) {
    require(b != 0);
    return a % b;
  }
}

// File: contracts/crossApproach/lib/HTLCTxLib.sol

/*

  Copyright 2019 Wanchain Foundation.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

*/

//                            _           _           _
//  __      ____ _ _ __   ___| |__   __ _(_)_ __   __| | _____   __
//  \ \ /\ / / _` | '_ \ / __| '_ \ / _` | | '_ \@/ _` |/ _ \ \ / /
//   \ V  V / (_| | | | | (__| | | | (_| | | | | | (_| |  __/\ V /
//    \_/\_/ \__,_|_| |_|\___|_| |_|\__,_|_|_| |_|\__,_|\___| \_/
//
//

pragma solidity ^0.4.26;
pragma experimental ABIEncoderV2;


library HTLCTxLib {
    using SafeMath for uint;

    /**
     *
     * ENUMS
     *
     */

    /// @notice tx info status
    /// @notice uninitialized,locked,redeemed,revoked
    enum TxStatus {None, Locked, Redeemed, Revoked, AssetLocked, DebtLocked}

    /**
     *
     * STRUCTURES
     *
     */

    /// @notice struct of HTLC user mint lock parameters
    struct HTLCUserParams {
        bytes32 xHash;                  /// hash of HTLC random number
        bytes32 smgID;                  /// ID of storeman group which user has selected
        uint tokenPairID;               /// token pair id on cross chain
        uint value;                     /// exchange token value
        uint lockFee;                   /// exchange token value
        uint lockedTime;                /// HTLC lock time
    }

    /// @notice HTLC(Hashed TimeLock Contract) tx info
    struct BaseTx {
        bytes32 smgID;                  /// HTLC transaction storeman ID
        uint lockedTime;                /// HTLC transaction locked time
        uint beginLockedTime;           /// HTLC transaction begin locked time
        TxStatus status;                /// HTLC transaction status
    }

    /// @notice user  tx info
    struct UserTx {
        BaseTx baseTx;
        uint tokenPairID;
        uint value;
        uint fee;
        address userAccount;            /// HTLC transaction sender address for the security check while user's revoke
    }
    /// @notice storeman  tx info
    struct SmgTx {
        BaseTx baseTx;
        uint tokenPairID;
        uint value;
        address  userAccount;          /// HTLC transaction user address for the security check while user's redeem
    }
    /// @notice storeman  debt tx info
    struct DebtTx {
        BaseTx baseTx;
        bytes32 srcSmgID;              /// HTLC transaction sender(source storeman) ID
    }

    struct Data {
        /// @notice mapping of hash(x) to UserTx -- xHash->htlcUserTxData
        mapping(bytes32 => UserTx) mapHashXUserTxs;

        /// @notice mapping of hash(x) to SmgTx -- xHash->htlcSmgTxData
        mapping(bytes32 => SmgTx) mapHashXSmgTxs;

        /// @notice mapping of hash(x) to DebtTx -- xHash->htlcDebtTxData
        mapping(bytes32 => DebtTx) mapHashXDebtTxs;

    }

    /**
     *
     * MANIPULATIONS
     *
     */

    /// @notice                     add user transaction info
    /// @param params               parameters for user tx
    function addUserTx(Data storage self, HTLCUserParams memory params)
        public
    {
        UserTx memory userTx = self.mapHashXUserTxs[params.xHash];
        // UserTx storage userTx = self.mapHashXUserTxs[params.xHash];
        // require(params.value != 0, "Value is invalid");
        require(userTx.baseTx.status == TxStatus.None, "User tx exists");

        userTx.baseTx.smgID = params.smgID;
        userTx.baseTx.lockedTime = params.lockedTime;
        userTx.baseTx.beginLockedTime = now;
        userTx.baseTx.status = TxStatus.Locked;
        userTx.tokenPairID = params.tokenPairID;
        userTx.value = params.value;
        userTx.fee = params.lockFee;
        userTx.userAccount = msg.sender;

        self.mapHashXUserTxs[params.xHash] = userTx;
    }

    /// @notice                     refund coins from HTLC transaction, which is used for storeman redeem(outbound)
    /// @param x                    HTLC random number
    function redeemUserTx(Data storage self, bytes32 x)
        external
        returns(bytes32 xHash)
    {
        xHash = sha256(abi.encodePacked(x));

        UserTx storage userTx = self.mapHashXUserTxs[xHash];
        require(userTx.baseTx.status == TxStatus.Locked, "Status is not locked");
        require(now < userTx.baseTx.beginLockedTime.add(userTx.baseTx.lockedTime), "Redeem timeout");

        userTx.baseTx.status = TxStatus.Redeemed;

        return xHash;
    }

    /// @notice                     revoke user transaction
    /// @param  xHash               hash of HTLC random number
    function revokeUserTx(Data storage self, bytes32 xHash)
        external
    {
        UserTx storage userTx = self.mapHashXUserTxs[xHash];
        require(userTx.baseTx.status == TxStatus.Locked, "Status is not locked");
        require(now >= userTx.baseTx.beginLockedTime.add(userTx.baseTx.lockedTime), "Revoke is not permitted");

        userTx.baseTx.status = TxStatus.Revoked;
    }

    /// @notice                    function for get user info
    /// @param xHash               hash of HTLC random number
    /// @return smgID              ID of storeman which user has selected
    /// @return tokenPairID        token pair ID of cross chain
    /// @return value              exchange value
    /// @return fee                exchange fee
    /// @return userAccount        HTLC transaction sender address for the security check while user's revoke
    function getUserTx(Data storage self, bytes32 xHash)
        external
        view
        returns (bytes32, uint, uint, uint, address)
    {
        UserTx storage userTx = self.mapHashXUserTxs[xHash];
        return (userTx.baseTx.smgID, userTx.tokenPairID, userTx.value, userTx.fee, userTx.userAccount);
    }

    /// @notice                     add storeman transaction info
    /// @param  xHash               hash of HTLC random number
    /// @param  smgID               ID of the storeman which user has selected
    /// @param  tokenPairID         token pair ID of cross chain
    /// @param  value               HTLC transfer value of token
    /// @param  userAccount            user account address on the destination chain, which is used to redeem token
    function addSmgTx(Data storage self, bytes32 xHash, bytes32 smgID, uint tokenPairID, uint value, address userAccount, uint lockedTime)
        external
    {
        SmgTx memory smgTx = self.mapHashXSmgTxs[xHash];
        // SmgTx storage smgTx = self.mapHashXSmgTxs[xHash];
        require(value != 0, "Value is invalid");
        require(smgTx.baseTx.status == TxStatus.None, "Smg tx exists");

        smgTx.baseTx.smgID = smgID;
        smgTx.baseTx.status = TxStatus.Locked;
        smgTx.baseTx.lockedTime = lockedTime;
        smgTx.baseTx.beginLockedTime = now;
        smgTx.tokenPairID = tokenPairID;
        smgTx.value = value;
        smgTx.userAccount = userAccount;

        self.mapHashXSmgTxs[xHash] = smgTx;
    }

    /// @notice                     refund coins from HTLC transaction, which is used for users redeem(inbound)
    /// @param x                    HTLC random number
    function redeemSmgTx(Data storage self, bytes32 x)
        external
        returns(bytes32 xHash)
    {
        xHash = sha256(abi.encodePacked(x));

        SmgTx storage smgTx = self.mapHashXSmgTxs[xHash];
        require(smgTx.baseTx.status == TxStatus.Locked, "Status is not locked");
        require(now < smgTx.baseTx.beginLockedTime.add(smgTx.baseTx.lockedTime), "Redeem timeout");

        smgTx.baseTx.status = TxStatus.Redeemed;

        return xHash;
    }

    /// @notice                     revoke storeman transaction
    /// @param  xHash               hash of HTLC random number
    function revokeSmgTx(Data storage self, bytes32 xHash)
        external
    {
        SmgTx storage smgTx = self.mapHashXSmgTxs[xHash];
        require(smgTx.baseTx.status == TxStatus.Locked, "Status is not locked");
        require(now >= smgTx.baseTx.beginLockedTime.add(smgTx.baseTx.lockedTime), "Revoke is not permitted");

        smgTx.baseTx.status = TxStatus.Revoked;
    }

    /// @notice                     function for get smg info
    /// @param xHash                hash of HTLC random number
    /// @return smgID               ID of storeman which user has selected
    /// @return tokenPairID         token pair ID of cross chain
    /// @return value               exchange value
    /// @return userAccount            user account address for redeem
    function getSmgTx(Data storage self, bytes32 xHash)
        external
        view
        returns (bytes32, uint, uint, address)
    {
        SmgTx storage smgTx = self.mapHashXSmgTxs[xHash];
        return (smgTx.baseTx.smgID, smgTx.tokenPairID, smgTx.value, smgTx.userAccount);
    }

    /// @notice                     add storeman transaction info
    /// @param  xHash               hash of HTLC random number
    /// @param  srcSmgID            ID of source storeman group
    /// @param  destSmgID           ID of the storeman which will take over of the debt of source storeman group
    /// @param  lockedTime          HTLC lock time
    /// @param  status              Status, should be 'Locked' for asset or 'DebtLocked' for debt
    function addDebtTx(Data storage self, bytes32 xHash, bytes32 srcSmgID, bytes32 destSmgID, uint lockedTime, TxStatus status)
        external
    {
        DebtTx memory debtTx = self.mapHashXDebtTxs[xHash];
        // DebtTx storage debtTx = self.mapHashXDebtTxs[xHash];
        require(debtTx.baseTx.status == TxStatus.None, "Debt tx exists");

        debtTx.baseTx.smgID = destSmgID;
        debtTx.baseTx.status = status;//TxStatus.Locked;
        debtTx.baseTx.lockedTime = lockedTime;
        debtTx.baseTx.beginLockedTime = now;
        debtTx.srcSmgID = srcSmgID;

        self.mapHashXDebtTxs[xHash] = debtTx;
    }

    /// @notice                     refund coins from HTLC transaction
    /// @param x                    HTLC random number
    /// @param status               Status, should be 'Locked' for asset or 'DebtLocked' for debt
    function redeemDebtTx(Data storage self, bytes32 x, TxStatus status)
        external
        returns(bytes32 xHash)
    {
        xHash = sha256(abi.encodePacked(x));

        DebtTx storage debtTx = self.mapHashXDebtTxs[xHash];
        // require(debtTx.baseTx.status == TxStatus.Locked, "Status is not locked");
        require(debtTx.baseTx.status == status, "Status is not locked");
        require(now < debtTx.baseTx.beginLockedTime.add(debtTx.baseTx.lockedTime), "Redeem timeout");

        debtTx.baseTx.status = TxStatus.Redeemed;

        return xHash;
    }

    /// @notice                     revoke debt transaction, which is used for source storeman group
    /// @param  xHash               hash of HTLC random number
    /// @param  status              Status, should be 'Locked' for asset or 'DebtLocked' for debt
    function revokeDebtTx(Data storage self, bytes32 xHash, TxStatus status)
        external
    {
        DebtTx storage debtTx = self.mapHashXDebtTxs[xHash];
        // require(debtTx.baseTx.status == TxStatus.Locked, "Status is not locked");
        require(debtTx.baseTx.status == status, "Status is not locked");
        require(now >= debtTx.baseTx.beginLockedTime.add(debtTx.baseTx.lockedTime), "Revoke is not permitted");

        debtTx.baseTx.status = TxStatus.Revoked;
    }

    /// @notice                     function for get debt info
    /// @param xHash                hash of HTLC random number
    /// @return srcSmgID            ID of source storeman
    /// @return destSmgID           ID of destination storeman
    function getDebtTx(Data storage self, bytes32 xHash)
        external
        view
        returns (bytes32, bytes32)
    {
        DebtTx storage debtTx = self.mapHashXDebtTxs[xHash];
        return (debtTx.srcSmgID, debtTx.baseTx.smgID);
    }

    function getLeftTime(uint endTime) private view returns (uint) {
        if (now < endTime) {
            return endTime.sub(now);
        }
        return 0;
    }

    /// @notice                     function for get debt info
    /// @param xHash                hash of HTLC random number
    /// @return leftTime            the left lock time
    function getLeftLockedTime(Data storage self, bytes32 xHash)
        external
        view
        returns (uint)
    {
        UserTx storage userTx = self.mapHashXUserTxs[xHash];
        if (userTx.baseTx.status != TxStatus.None) {
            return getLeftTime(userTx.baseTx.beginLockedTime.add(userTx.baseTx.lockedTime));
        }
        SmgTx storage smgTx = self.mapHashXSmgTxs[xHash];
        if (smgTx.baseTx.status != TxStatus.None) {
            return getLeftTime(smgTx.baseTx.beginLockedTime.add(smgTx.baseTx.lockedTime));
        }
        DebtTx storage debtTx = self.mapHashXDebtTxs[xHash];
        if (debtTx.baseTx.status != TxStatus.None) {
            return getLeftTime(debtTx.baseTx.beginLockedTime.add(debtTx.baseTx.lockedTime));
        }
        require(false, 'invalid xHash');
    }
}

// File: contracts/crossApproach/lib/RapidityTxLib.sol

/*

  Copyright 2019 Wanchain Foundation.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

*/

//                            _           _           _
//  __      ____ _ _ __   ___| |__   __ _(_)_ __   __| | _____   __
//  \ \ /\ / / _` | '_ \ / __| '_ \ / _` | | '_ \@/ _` |/ _ \ \ / /
//   \ V  V / (_| | | | | (__| | | | (_| | | | | | (_| |  __/\ V /
//    \_/\_/ \__,_|_| |_|\___|_| |_|\__,_|_|_| |_|\__,_|\___| \_/
//
//

pragma solidity ^0.4.26;

library RapidityTxLib {

    /**
     *
     * ENUMS
     *
     */

    /// @notice tx info status
    /// @notice uninitialized,Redeemed
    enum TxStatus {None, Redeemed}

    /**
     *
     * STRUCTURES
     *
     */
    struct Data {
        /// @notice mapping of uniqueID to TxStatus -- uniqueID->TxStatus
        mapping(bytes32 => TxStatus) mapTxStatus;

    }

    /**
     *
     * MANIPULATIONS
     *
     */

    /// @notice                     add user transaction info
    /// @param  uniqueID            Rapidity random number
    function addRapidityTx(Data storage self, bytes32 uniqueID)
        internal
    {
        TxStatus status = self.mapTxStatus[uniqueID];
        require(status == TxStatus.None, "Rapidity tx exists");
        self.mapTxStatus[uniqueID] = TxStatus.Redeemed;
    }
}

// File: contracts/crossApproach/lib/CrossTypesV1.sol

/*

  Copyright 2019 Wanchain Foundation.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

*/

//                            _           _           _
//  __      ____ _ _ __   ___| |__   __ _(_)_ __   __| | _____   __
//  \ \ /\ / / _` | '_ \ / __| '_ \ / _` | | '_ \@/ _` |/ _ \ \ / /
//   \ V  V / (_| | | | | (__| | | | (_| | | | | | (_| |  __/\ V /
//    \_/\_/ \__,_|_| |_|\___|_| |_|\__,_|_|_| |_|\__,_|\___| \_/
//
//

pragma solidity ^0.4.26;








library CrossTypesV1 {
    using SafeMath for uint;

    /**
     *
     * STRUCTURES
     *
     */

    struct Data {

        /// map of the htlc transaction info
        HTLCTxLib.Data htlcTxData;

        /// map of the rapidity transaction info
        RapidityTxLib.Data rapidityTxData;

        /// quota data of storeman group
        IQuota quota;

        /// token manager instance interface
        ITokenManager tokenManager;

        /// storemanGroup admin instance interface
        IStoremanGroup smgAdminProxy;

        /// storemanGroup fee admin instance address
        address smgFeeProxy;

        ISignatureVerifier sigVerifier;

        /// @notice transaction fee, smgID => fee
        mapping(bytes32 => uint) mapStoremanFee;

        /// @notice transaction fee, origChainID => shadowChainID => fee
        mapping(uint => mapping(uint =>uint)) mapContractFee;

        /// @notice transaction fee, origChainID => shadowChainID => fee
        mapping(uint => mapping(uint =>uint)) mapAgentFee;

    }

    /**
     *
     * MANIPULATIONS
     *
     */

    // /// @notice       convert bytes32 to address
    // /// @param b      bytes32
    // function bytes32ToAddress(bytes32 b) internal pure returns (address) {
    //     return address(uint160(bytes20(b))); // high
    //     // return address(uint160(uint256(b))); // low
    // }

    /// @notice       convert bytes to address
    /// @param b      bytes
    function bytesToAddress(bytes b) internal pure returns (address addr) {
        assembly {
            addr := mload(add(b,20))
        }
    }

    function transfer(address tokenScAddr, address to, uint value)
        internal
        returns(bool)
    {
        uint beforeBalance;
        uint afterBalance;
        beforeBalance = IRC20Protocol(tokenScAddr).balanceOf(to);
        // IRC20Protocol(tokenScAddr).transfer(to, value);
        tokenScAddr.call(bytes4(keccak256("transfer(address,uint256)")), to, value);
        afterBalance = IRC20Protocol(tokenScAddr).balanceOf(to);
        return afterBalance == beforeBalance.add(value);
    }

    function transferFrom(address tokenScAddr, address from, address to, uint value)
        internal
        returns(bool)
    {
        uint beforeBalance;
        uint afterBalance;
        beforeBalance = IRC20Protocol(tokenScAddr).balanceOf(to);
        // IRC20Protocol(tokenScAddr).transferFrom(from, to, value);
        tokenScAddr.call(bytes4(keccak256("transferFrom(address,address,uint256)")), from, to, value);
        afterBalance = IRC20Protocol(tokenScAddr).balanceOf(to);
        return afterBalance == beforeBalance.add(value);
    }
}

// File: contracts/crossApproach/CrossStorageV1.sol

/*

  Copyright 2019 Wanchain Foundation.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

*/

//                            _           _           _
//  __      ____ _ _ __   ___| |__   __ _(_)_ __   __| | _____   __
//  \ \ /\ / / _` | '_ \ / __| '_ \ / _` | | '_ \@/ _` |/ _ \ \ / /
//   \ V  V / (_| | | | | (__| | | | (_| | | | | | (_| |  __/\ V /
//    \_/\_/ \__,_|_| |_|\___|_| |_|\__,_|_|_| |_|\__,_|\___| \_/
//
//

pragma solidity ^0.4.26;





contract CrossStorageV1 is BasicStorage {
    using HTLCTxLib for HTLCTxLib.Data;
    using RapidityTxLib for RapidityTxLib.Data;

    /************************************************************
     **
     ** VARIABLES
     **
     ************************************************************/

    CrossTypesV1.Data internal storageData;

    /// @notice locked time(in seconds)
    uint public lockedTime = uint(3600*36);

    /// @notice Since storeman group admin receiver address may be changed, system should make sure the new address
    /// @notice can be used, and the old address can not be used. The solution is add timestamp.
    /// @notice unit: second
    uint public smgFeeReceiverTimeout = uint(10*60);

    enum GroupStatus { none, initial, curveSeted, failed, selected, ready, unregistered, dismissed }

}

// File: contracts/crossApproach/CrossStorageV2.sol

/*

  Copyright 2019 Wanchain Foundation.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

*/

//                            _           _           _
//  __      ____ _ _ __   ___| |__   __ _(_)_ __   __| | _____   __
//  \ \ /\ / / _` | '_ \ / __| '_ \ / _` | | '_ \@/ _` |/ _ \ \ / /
//   \ V  V / (_| | | | | (__| | | | (_| | | | | | (_| |  __/\ V /
//    \_/\_/ \__,_|_| |_|\___|_| |_|\__,_|_|_| |_|\__,_|\___| \_/
//
//

pragma solidity ^0.4.26;





contract CrossStorageV2 is CrossStorageV1, ReentrancyGuard, Halt, Proxy {

    /************************************************************
     **
     ** VARIABLES
     **
     ************************************************************/

    /** STATE VARIABLES **/
    uint256 public currentChainID;
    address public admin;

    /** STRUCTURES **/
    struct SetFeesParam {
        uint256 srcChainID;
        uint256 destChainID;
        uint256 contractFee;
        uint256 agentFee;
    }

    struct GetFeesParam {
        uint256 srcChainID;
        uint256 destChainID;
    }

    struct GetFeesReturn {
        uint256 contractFee;
        uint256 agentFee;
    }
}

// File: contracts/crossApproach/CrossStorageV3.sol

/*

  Copyright 2019 Wanchain Foundation.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

*/

//                            _           _           _
//  __      ____ _ _ __   ___| |__   __ _(_)_ __   __| | _____   __
//  \ \ /\ / / _` | '_ \ / __| '_ \ / _` | | '_ \@/ _` |/ _ \ \ / /
//   \ V  V / (_| | | | | (__| | | | (_| | | | | | (_| |  __/\ V /
//    \_/\_/ \__,_|_| |_|\___|_| |_|\__,_|_|_| |_|\__,_|\___| \_/
//
//

pragma solidity ^0.4.26;


contract CrossStorageV3 is CrossStorageV2 {

    /************************************************************
     **
     ** VARIABLES
     **
     ************************************************************/

    /** STATE VARIABLES **/
    // tokenPairID => fee
    mapping(uint256 => uint256) mapTokenPairContractFee;

    struct SetTokenPairFeesParam {
        uint256 tokenPairID;
        uint256 contractFee;
    }

}

// File: contracts/crossApproach/CrossStorageV4.sol

/*

  Copyright 2019 Wanchain Foundation.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

*/

//                            _           _           _
//  __      ____ _ _ __   ___| |__   __ _(_)_ __   __| | _____   __
//  \ \ /\ / / _` | '_ \ / __| '_ \ / _` | | '_ \@/ _` |/ _ \ \ / /
//   \ V  V / (_| | | | | (__| | | | (_| | | | | | (_| |  __/\ V /
//    \_/\_/ \__,_|_| |_|\___|_| |_|\__,_|_|_| |_|\__,_|\___| \_/
//
//

pragma solidity ^0.4.26;


contract CrossStorageV4 is CrossStorageV3 {

    /************************************************************
     **
     ** VARIABLES
     **
     ************************************************************/
     uint internal maxBatchSize;
}

// File: contracts/crossApproach/lib/RapidityLibV4.sol

/*

  Copyright 2019 Wanchain Foundation.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

*/

//                            _           _           _
//  __      ____ _ _ __   ___| |__   __ _(_)_ __   __| | _____   __
//  \ \ /\ / / _` | '_ \ / __| '_ \ / _` | | '_ \@/ _` |/ _ \ \ / /
//   \ V  V / (_| | | | | (__| | | | (_| | | | | | (_| |  __/\ V /
//    \_/\_/ \__,_|_| |_|\___|_| |_|\__,_|_|_| |_|\__,_|\___| \_/
//
//

pragma solidity ^0.4.26;






library RapidityLibV4 {
    using SafeMath for uint;
    using RapidityTxLib for RapidityTxLib.Data;

    enum TokenCrossType {ERC20, ERC721, ERC1155}

    /**
    *
    * STRUCTURES
    *
    */

    /// @notice struct of Rapidity storeman mint lock parameters
    struct RapidityUserLockParams {
        bytes32 smgID;                    /// ID of storeman group which user has selected
        uint tokenPairID;                 /// token pair id on cross chain
        uint value;                       /// exchange token value
        uint currentChainID;              /// current chain ID
        uint tokenPairContractFee;        /// fee of token pair
        bytes destUserAccount;            /// account of shadow chain, used to receive token
        address smgFeeProxy;              /// address of the proxy to store fee for storeman group
    }

    /// @notice struct of Rapidity storeman mint lock parameters
    struct RapiditySmgMintParams {
        bytes32 uniqueID;                 /// Rapidity random number
        bytes32 smgID;                    /// ID of storeman group which user has selected
        uint tokenPairID;                 /// token pair id on cross chain
        uint value;                       /// exchange token value
        uint fee;                         /// exchange token fee
        address destTokenAccount;         /// shadow token account
        address destUserAccount;          /// account of shadow chain, used to receive token
        address smgFeeProxy;              /// address of the proxy to store fee for storeman group
    }

    /// @notice struct of Rapidity user burn lock parameters
    struct RapidityUserBurnParams {
        bytes32 smgID;                  /// ID of storeman group which user has selected
        uint tokenPairID;               /// token pair id on cross chain
        uint value;                     /// exchange token value
        uint currentChainID;            /// current chain ID
        uint fee;                       /// exchange token fee
        uint tokenPairContractFee;      /// fee of token pair
        address srcTokenAccount;        /// shadow token account
        bytes destUserAccount;          /// account of token destination chain, used to receive token
        address smgFeeProxy;            /// address of the proxy to store fee for storeman group
    }

    /// @notice struct of Rapidity user burn lock parameters
    struct RapiditySmgReleaseParams {
        bytes32 uniqueID;               /// Rapidity random number
        bytes32 smgID;                  /// ID of storeman group which user has selected
        uint tokenPairID;               /// token pair id on cross chain
        uint value;                     /// exchange token value
        uint fee;                       /// exchange token fee
        address destTokenAccount;       /// original token/coin account
        address destUserAccount;        /// account of token original chain, used to receive token
        address smgFeeProxy;            /// address of the proxy to store fee for storeman group
    }

    /**
     *
     * EVENTS
     *
     **/


    /// @notice                         event of exchange WRC-20 token with original chain token request
    /// @notice                         event invoked by storeman group
    /// @param smgID                    ID of storemanGroup
    /// @param tokenPairID              token pair ID of cross chain token
    /// @param tokenAccount             Rapidity original token account
    /// @param value                    Rapidity value
    /// @param userAccount              account of shadow chain, used to receive token
    event UserLockLogger(bytes32 indexed smgID, uint indexed tokenPairID, address indexed tokenAccount, uint value, uint contractFee, bytes userAccount);

    /// @notice                         event of exchange WRC-20 token with original chain token request
    /// @notice                         event invoked by storeman group
    /// @param smgID                    ID of storemanGroup
    /// @param tokenPairID              token pair ID of cross chain token
    /// @param tokenAccount             Rapidity shadow token account
    /// @param value                    Rapidity value
    /// @param userAccount              account of shadow chain, used to receive token
    event UserBurnLogger(bytes32 indexed smgID, uint indexed tokenPairID, address indexed tokenAccount, uint value, uint contractFee, uint fee, bytes userAccount);

    /// @notice                         event of exchange WRC-20 token with original chain token request
    /// @notice                         event invoked by storeman group
    /// @param uniqueID                 unique random number
    /// @param smgID                    ID of storemanGroup
    /// @param tokenPairID              token pair ID of cross chain token
    /// @param value                    Rapidity value
    /// @param tokenAccount             Rapidity shadow token account
    /// @param userAccount              account of original chain, used to receive token
    event SmgMintLogger(bytes32 indexed uniqueID, bytes32 indexed smgID, uint indexed tokenPairID, uint value, address tokenAccount, address userAccount);
    event SmgMint(bytes32 indexed uniqueID, bytes32 indexed smgID, uint indexed tokenPairID, string[] keys, bytes[] values);

    /// @notice                         event of exchange WRC-20 token with original chain token request
    /// @notice                         event invoked by storeman group
    /// @param uniqueID                 unique random number
    /// @param smgID                    ID of storemanGroup
    /// @param tokenPairID              token pair ID of cross chain token
    /// @param value                    Rapidity value
    /// @param tokenAccount             Rapidity original token account
    /// @param userAccount              account of original chain, used to receive token
    event SmgReleaseLogger(bytes32 indexed uniqueID, bytes32 indexed smgID, uint indexed tokenPairID, uint value, address tokenAccount, address userAccount);
    event SmgRelease(bytes32 indexed uniqueID, bytes32 indexed smgID, uint indexed tokenPairID, string[] keys, bytes[] values);

    /**
    *
    * MANIPULATIONS
    *
    */

    /// @notice                         mintBridge, user lock token on token original chain
    /// @notice                         event invoked by user mint lock
    /// @param storageData              Cross storage data
    /// @param params                   parameters for user mint lock token on token original chain
    function userLock(CrossTypesV1.Data storage storageData, RapidityUserLockParams memory params)
    public
    {
        ITokenManager tokenManager = storageData.tokenManager;
        uint fromChainID;
        uint toChainID;
        bytes memory fromTokenAccount;
        bytes memory toTokenAccount;
        (fromChainID,fromTokenAccount,toChainID,toTokenAccount) = tokenManager.getTokenPairInfo(params.tokenPairID);
        require(fromChainID != 0, "Token does not exist");

        uint contractFee = params.tokenPairContractFee;
        address tokenScAddr;
        if (params.currentChainID == fromChainID) {
            if (contractFee == 0) {
                contractFee = storageData.mapContractFee[fromChainID][toChainID];
            }
            tokenScAddr = CrossTypesV1.bytesToAddress(fromTokenAccount);
        } else if (params.currentChainID == toChainID) {
            if (contractFee == 0) {
                contractFee = storageData.mapContractFee[toChainID][fromChainID];
            }
            tokenScAddr = CrossTypesV1.bytesToAddress(toTokenAccount);
        } else {
            require(false, "Invalid token pair");
        }
        if (contractFee > 0) {
            params.smgFeeProxy.transfer(contractFee);
        }

        uint left;
        if (tokenScAddr == address(0)) {
            left = (msg.value).sub(params.value).sub(contractFee);
        } else {
            left = (msg.value).sub(contractFee);

            uint8 tokenCrossType = tokenManager.mapTokenPairType(params.tokenPairID);
            require(tokenCrossType == uint8(TokenCrossType.ERC20), "Not support");
            require(CrossTypesV1.transferFrom(tokenScAddr, msg.sender, address(this), params.value), "Lock token failed");
        }
        if (left != 0) {
            (msg.sender).transfer(left);
        }
        emit UserLockLogger(params.smgID, params.tokenPairID, tokenScAddr, params.value, contractFee, params.destUserAccount);
    }

    /// @notice                         burnBridge, user lock token on token original chain
    /// @notice                         event invoked by user burn lock
    /// @param storageData              Cross storage data
    /// @param params                   parameters for user burn lock token on token original chain
    function userBurn(CrossTypesV1.Data storage storageData, RapidityUserBurnParams memory params)
    public
    {
        ITokenManager tokenManager = storageData.tokenManager;
        uint fromChainID;
        uint toChainID;
        bytes memory fromTokenAccount;
        bytes memory toTokenAccount;
        (fromChainID,fromTokenAccount,toChainID,toTokenAccount) = tokenManager.getTokenPairInfo(params.tokenPairID);
        require(fromChainID != 0, "Token does not exist");

        uint256 contractFee = params.tokenPairContractFee;
        address tokenScAddr;
        if (params.currentChainID == toChainID) {
            if (contractFee == 0) {
                contractFee = storageData.mapContractFee[toChainID][fromChainID];
            }
            tokenScAddr = CrossTypesV1.bytesToAddress(toTokenAccount);
        } else if (params.currentChainID == fromChainID) {
            if (contractFee == 0) {
                contractFee = storageData.mapContractFee[fromChainID][toChainID];
            }
            tokenScAddr = CrossTypesV1.bytesToAddress(fromTokenAccount);
        } else {
            require(false, "Invalid token pair");
        }
        require(params.srcTokenAccount == tokenScAddr, "Invalid token account");

        // Reuse variable fromChainID as tokenCrossType; burn token by tokenCrossType
        fromChainID = tokenManager.mapTokenPairType(params.tokenPairID);
        require(fromChainID == uint8(TokenCrossType.ERC20), "Not support");
        require(burnShadowToken(tokenManager, tokenScAddr, msg.sender, params.value), "Burn failed");

        if (contractFee > 0) {
            params.smgFeeProxy.transfer(contractFee);
        }

        uint left = (msg.value).sub(contractFee);
        if (left != 0) {
            (msg.sender).transfer(left);
        }

        emit UserBurnLogger(params.smgID, params.tokenPairID, tokenScAddr, params.value, contractFee, params.fee, params.destUserAccount);
    }

    /// @notice                         mintBridge, storeman mint lock token on token shadow chain
    /// @notice                         event invoked by user mint lock
    /// @param storageData              Cross storage data
    /// @param params                   parameters for storeman mint lock token on token shadow chain
    function smgMint(CrossTypesV1.Data storage storageData, RapiditySmgMintParams memory params)
    public
    {
        storageData.rapidityTxData.addRapidityTx(params.uniqueID);

        ITokenManager tokenManager = storageData.tokenManager;
        uint8 tokenCrossType = tokenManager.mapTokenPairType(params.tokenPairID);
        require(tokenCrossType == uint8(TokenCrossType.ERC20), "Not support");
        if (params.fee > 0) {
            require(mintShadowToken(tokenManager, params.destTokenAccount, params.smgFeeProxy, params.fee), "Mint fee failed");
        }
        require(mintShadowToken(tokenManager, params.destTokenAccount, params.destUserAccount, params.value), "Mint failed");

        string[] memory keys = new string[](4);
        bytes[] memory values = new bytes[](4);
        keys[0] = "value:uint256";
        values[0] = abi.encodePacked(params.value);
        keys[1] = "tokenAccount:address";
        values[1] = abi.encodePacked(params.destTokenAccount);
        keys[2] = "userAccount:address";
        values[2] = abi.encodePacked(params.destUserAccount);
        keys[3] = "fee:uint256";
        values[3] = abi.encodePacked(params.fee);
        emit SmgMint(params.uniqueID, params.smgID, params.tokenPairID, keys, values);
        emit SmgMintLogger(params.uniqueID, params.smgID, params.tokenPairID, params.value, params.destTokenAccount, params.destUserAccount);
    }

    /// @notice                         burnBridge, storeman burn lock token on token shadow chain
    /// @notice                         event invoked by user burn lock
    /// @param storageData              Cross storage data
    /// @param params                   parameters for storeman burn lock token on token shadow chain
    function smgRelease(CrossTypesV1.Data storage storageData, RapiditySmgReleaseParams memory params)
    public
    {
        storageData.rapidityTxData.addRapidityTx(params.uniqueID);

        if (params.destTokenAccount == address(0)) {
            (params.destUserAccount).transfer(params.value);
            if (params.fee > 0) {
                params.smgFeeProxy.transfer(params.fee);
            }
        } else {
            uint8 tokenCrossType = storageData.tokenManager.mapTokenPairType(params.tokenPairID);
            require(tokenCrossType == uint8(TokenCrossType.ERC20), "Not support");
            if (params.fee > 0) {
                require(CrossTypesV1.transfer(params.destTokenAccount, params.smgFeeProxy, params.fee), "Transfer token fee failed");
            }
            require(CrossTypesV1.transfer(params.destTokenAccount, params.destUserAccount, params.value), "Transfer token failed");
        }

        string[] memory keys = new string[](4);
        bytes[] memory values = new bytes[](4);
        keys[0] = "value:uint256";
        values[0] = abi.encodePacked(params.value);
        keys[1] = "tokenAccount:address";
        values[1] = abi.encodePacked(params.destTokenAccount);
        keys[2] = "userAccount:address";
        values[2] = abi.encodePacked(params.destUserAccount);
        keys[3] = "fee:uint256";
        values[3] = abi.encodePacked(params.fee);
        emit SmgRelease(params.uniqueID, params.smgID, params.tokenPairID, keys, values);
        emit SmgReleaseLogger(params.uniqueID, params.smgID, params.tokenPairID, params.value, params.destTokenAccount, params.destUserAccount);
    }

    function burnShadowToken(address tokenManager, address tokenAddress, address userAccount, uint value) private returns (bool) {
        uint beforeBalance;
        uint afterBalance;
        beforeBalance = IRC20Protocol(tokenAddress).balanceOf(userAccount);

        ITokenManager(tokenManager).burnToken(tokenAddress, userAccount, value);

        afterBalance = IRC20Protocol(tokenAddress).balanceOf(userAccount);
        return afterBalance == beforeBalance.sub(value);
    }

    function mintShadowToken(address tokenManager, address tokenAddress, address userAccount, uint value) private returns (bool) {
        uint beforeBalance;
        uint afterBalance;
        beforeBalance = IRC20Protocol(tokenAddress).balanceOf(userAccount);

        ITokenManager(tokenManager).mintToken(tokenAddress, userAccount, value);

        afterBalance = IRC20Protocol(tokenAddress).balanceOf(userAccount);
        return afterBalance == beforeBalance.add(value);
    }
}

// File: contracts/interfaces/IERC1155.sol

/*

  Copyright 2019 Wanchain Foundation.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

*/

//                            _           _           _
//  __      ____ _ _ __   ___| |__   __ _(_)_ __   __| | _____   __
//  \ \ /\ / / _` | '_ \ / __| '_ \ / _` | | '_ \@/ _` |/ _ \ \ / /
//   \ V  V / (_| | | | | (__| | | | (_| | | | | | (_| |  __/\ V /
//    \_/\_/ \__,_|_| |_|\___|_| |_|\__,_|_|_| |_|\__,_|\___| \_/
//
//

pragma solidity ^0.4.26;

//interface IERC1155 is IERC165 {
interface IERC1155  {
    ///**
    // * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.
    // */
    event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);

    ///**
    // * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all
    // * transfers.
    // */
    //event TransferBatch(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);

    /**
     * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to
     * `approved`.
     */
    event ApprovalForAll(address indexed account, address indexed operator, bool approved);

    /**
     * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.
     *
     * If an {URI} event was emitted for `id`, the standard
     * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value
     * returned by {IERC1155MetadataURI-uri}.
     */
    event URI(string value, uint256 indexed id);


    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);

    /**
     * @dev Returns the amount of tokens of token type `id` owned by `account`.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function balanceOf(address account, uint256 id) external view returns (uint256);

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.
     *
     * Requirements:
     *
     * - `accounts` and `ids` must have the same length.
     */
    //function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory);

    /**
     * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,
     *
     * Emits an {ApprovalForAll} event.
     *
     * Requirements:
     *
     * - `operator` cannot be the caller.
     */
    function setApprovalForAll(address operator, bool approved) external;

    /**
     * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.
     *
     * See {setApprovalForAll}.
     */
    function isApprovedForAll(address account, address operator) external view returns (bool);

    /**
     * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.
     *
     * Emits a {TransferSingle} event.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - If the caller is not `from`, it must be have been approved to spend ``from``'s tokens via {setApprovalForAll}.
     * - `from` must have a balance of tokens of type `id` of at least `amount`.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
     * acceptance magic value.
     */
    function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes data) external;

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.
     *
     * Emits a {TransferBatch} event.
     *
     * Requirements:
     *
     * - `ids` and `amounts` must have the same length.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
     * acceptance magic value.
     */
    function safeBatchTransferFrom(address from, address to, uint256[] ids, uint256[] amounts, bytes data) external;
}

// File: openzeppelin-eth/contracts/zos-lib/Initializable.sol

pragma solidity ^0.4.24;


/**
 * @title Initializable
 *
 * @dev Helper contract to support initializer functions. To use it, replace
 * the constructor with a function that has the `initializer` modifier.
 * WARNING: Unlike constructors, initializer functions must be manually
 * invoked. This applies both to deploying an Initializable contract, as well
 * as extending an Initializable contract via inheritance.
 * WARNING: When used with inheritance, manual care must be taken to not invoke
 * a parent initializer twice, or ensure that all initializers are idempotent,
 * because this is not dealt with automatically as with constructors.
 */
contract Initializable {

  /**
   * @dev Indicates that the contract has been initialized.
   */
  bool private initialized;

  /**
   * @dev Indicates that the contract is in the process of being initialized.
   */
  bool private initializing;

  /**
   * @dev Modifier to use in the initializer function of a contract.
   */
  modifier initializer() {
    require(initializing || isConstructor() || !initialized, "Contract instance has already been initialized");

    bool wasInitializing = initializing;
    initializing = true;
    initialized = true;

    _;

    initializing = wasInitializing;
  }

  /// @dev Returns true if and only if the function is running in the constructor
  function isConstructor() private view returns (bool) {
    // extcodesize checks the size of the code stored in an address, and
    // address returns the current address. Since the code is still not
    // deployed when running a constructor, any checks on its code size will
    // yield zero, making it an effective way to detect if a contract is
    // under construction or not.
    uint256 cs;
    assembly { cs := extcodesize(address) }
    return cs == 0;
  }

  // Reserved storage space to allow for layout changes in the future.
  uint256[50] private ______gap;
}

// File: openzeppelin-eth/contracts/introspection/IERC165.sol

pragma solidity ^0.4.24;


/**
 * @title IERC165
 * @dev https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md
 */
interface IERC165 {

  /**
   * @notice Query if a contract implements an interface
   * @param interfaceId The interface identifier, as specified in ERC-165
   * @dev Interface identification is specified in ERC-165. This function
   * uses less than 30,000 gas.
   */
  function supportsInterface(bytes4 interfaceId)
    external
    view
    returns (bool);
}

// File: openzeppelin-eth/contracts/token/ERC721/IERC721.sol

pragma solidity ^0.4.24;




/**
 * @title ERC721 Non-Fungible Token Standard basic interface
 * @dev see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
 */
contract IERC721 is Initializable, IERC165 {

  event Transfer(
    address indexed from,
    address indexed to,
    uint256 indexed tokenId
  );
  event Approval(
    address indexed owner,
    address indexed approved,
    uint256 indexed tokenId
  );
  event ApprovalForAll(
    address indexed owner,
    address indexed operator,
    bool approved
  );

  function balanceOf(address owner) public view returns (uint256 balance);
  function ownerOf(uint256 tokenId) public view returns (address owner);

  function approve(address to, uint256 tokenId) public;
  function getApproved(uint256 tokenId)
    public view returns (address operator);

  function setApprovalForAll(address operator, bool _approved) public;
  function isApprovedForAll(address owner, address operator)
    public view returns (bool);

  function transferFrom(address from, address to, uint256 tokenId) public;
  function safeTransferFrom(address from, address to, uint256 tokenId)
    public;

  function safeTransferFrom(
    address from,
    address to,
    uint256 tokenId,
    bytes data
  )
    public;
}

// File: contracts/crossApproach/lib/NFTLibV1.sol

/*

  Copyright 2019 Wanchain Foundation.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

*/

//                            _           _           _
//  __      ____ _ _ __   ___| |__   __ _(_)_ __   __| | _____   __
//  \ \ /\ / / _` | '_ \ / __| '_ \ / _` | | '_ \@/ _` |/ _ \ \ / /
//   \ V  V / (_| | | | | (__| | | | (_| | | | | | (_| |  __/\ V /
//    \_/\_/ \__,_|_| |_|\___|_| |_|\__,_|_|_| |_|\__,_|\___| \_/
//
//

pragma solidity ^0.4.26;







library NFTLibV1 {
    using SafeMath for uint;
    using RapidityTxLib for RapidityTxLib.Data;

    enum TokenCrossType {ERC20, ERC721, ERC1155}

    /// @notice struct of Rapidity storeman mint lock parameters
    struct RapidityUserLockNFTParams {
        bytes32                 smgID;                  /// ID of storeman group which user has selected
        uint                    tokenPairID;            /// token pair id on cross chain
        uint[]                  tokenIDs;               /// NFT token Ids
        uint[]                  tokenValues;            /// NFT token values
        uint                    currentChainID;         /// current chain ID
        uint                    tokenPairContractFee;   /// fee of token pair
        bytes                   destUserAccount;        /// account of shadow chain, used to receive token
        address                 smgFeeProxy;            /// address of the proxy to store fee for storeman group
    }

    /// @notice struct of Rapidity storeman mint lock parameters
    struct RapiditySmgMintNFTParams {
        bytes32                 uniqueID;               /// Rapidity random number
        bytes32                 smgID;                  /// ID of storeman group which user has selected
        uint                    tokenPairID;            /// token pair id on cross chain
        uint[]                  tokenIDs;               /// NFT token Ids
        uint[]                  tokenValues;            /// NFT token values
        bytes                   extData;                /// storeman data
        address                 destTokenAccount;       /// shadow token account
        address                 destUserAccount;        /// account of shadow chain, used to receive token
    }

    /// @notice struct of Rapidity user burn lock parameters
    struct RapidityUserBurnNFTParams {
        bytes32                 smgID;                  /// ID of storeman group which user has selected
        uint                    tokenPairID;            /// token pair id on cross chain
        uint[]                  tokenIDs;               /// NFT token Ids
        uint[]                  tokenValues;            /// NFT token values
        uint                    currentChainID;         /// current chain ID
        uint                    tokenPairContractFee;   /// fee of token pair
        address                 srcTokenAccount;        /// shadow token account
        bytes                   destUserAccount;        /// account of token destination chain, used to receive token
        address                 smgFeeProxy;            /// address of the proxy to store fee for storeman group
    }

    /// @notice struct of Rapidity user burn lock parameters
    struct RapiditySmgReleaseNFTParams {
        bytes32                 uniqueID;               /// Rapidity random number
        bytes32                 smgID;                  /// ID of storeman group which user has selected
        uint                    tokenPairID;            /// token pair id on cross chain
        uint[]                  tokenIDs;               /// NFT token Ids
        uint[]                  tokenValues;            /// NFT token values
        address                 destTokenAccount;       /// original token/coin account
        address                 destUserAccount;        /// account of token original chain, used to receive token
    }

    event UserLockNFT(bytes32 indexed smgID, uint indexed tokenPairID, address indexed tokenAccount, string[] keys, bytes[] values);

    event UserBurnNFT(bytes32 indexed smgID, uint indexed tokenPairID, address indexed tokenAccount, string[] keys, bytes[] values);

    event SmgMintNFT(bytes32 indexed uniqueID, bytes32 indexed smgID, uint indexed tokenPairID, string[] keys, bytes[] values);

    event SmgReleaseNFT(bytes32 indexed uniqueID, bytes32 indexed smgID, uint indexed tokenPairID, string[] keys, bytes[] values);

    function getTokenScAddrAndContractFee(CrossTypesV1.Data storage storageData, uint tokenPairID, uint tokenPairContractFee, uint currentChainID, uint batchLength)
        public
        view
        returns (address, uint)
    {
        ITokenManager tokenManager = storageData.tokenManager;
        uint fromChainID;
        uint toChainID;
        bytes memory fromTokenAccount;
        bytes memory toTokenAccount;
        (fromChainID,fromTokenAccount,toChainID,toTokenAccount) = tokenManager.getTokenPairInfo(tokenPairID);
        require(fromChainID != 0, "Token does not exist");

        uint contractFee = tokenPairContractFee;
        address tokenScAddr;
        if (currentChainID == fromChainID) {
            if (contractFee == 0) {
                contractFee = storageData.mapContractFee[fromChainID][toChainID];
            }
            tokenScAddr = CrossTypesV1.bytesToAddress(fromTokenAccount);
        } else if (currentChainID == toChainID) {
            if (contractFee == 0) {
                contractFee = storageData.mapContractFee[toChainID][fromChainID];
            }
            tokenScAddr = CrossTypesV1.bytesToAddress(toTokenAccount);
        } else {
            require(false, "Invalid token pair");
        }
        if (contractFee > 0) {
            contractFee = contractFee.mul(9 + batchLength).div(10);
        }
        return (tokenScAddr, contractFee);
    }

    /// @notice                         mintBridge, user lock token on token original chain
    /// @notice                         event invoked by user mint lock
    /// @param storageData              Cross storage data
    /// @param params                   parameters for user mint lock token on token original chain
    function userLockNFT(CrossTypesV1.Data storage storageData, RapidityUserLockNFTParams memory params)
        public
    {
        address tokenScAddr;
        uint contractFee;
        (tokenScAddr, contractFee) = getTokenScAddrAndContractFee(storageData, params.tokenPairID, params.tokenPairContractFee, params.currentChainID, params.tokenIDs.length);

        if (contractFee > 0) {
            params.smgFeeProxy.transfer(contractFee);
        }

        uint left = (msg.value).sub(contractFee);

        uint8 tokenCrossType = storageData.tokenManager.mapTokenPairType(params.tokenPairID);
        if (tokenCrossType == uint8(TokenCrossType.ERC721)) {
            for(uint idx = 0; idx < params.tokenIDs.length; ++idx) {
                IERC721(tokenScAddr).safeTransferFrom(msg.sender, address(this), params.tokenIDs[idx], "");
            }
        } else if(tokenCrossType == uint8(TokenCrossType.ERC1155)) {
            IERC1155(tokenScAddr).safeBatchTransferFrom(msg.sender, address(this), params.tokenIDs, params.tokenValues, "");
        }
        else{
            require(false, "Invalid NFT type");
        }

        if (left != 0) {
            (msg.sender).transfer(left);
        }

        string[] memory keys = new string[](4);
        bytes[] memory values = new bytes[](4);

        keys[0] = "tokenIDs:uint256[]";
        values[0] = abi.encode(params.tokenIDs);

        keys[1] = "tokenValues:uint256[]";
        values[1] = abi.encode(params.tokenValues);

        keys[2] = "userAccount:bytes";
        values[2] = params.destUserAccount;

        keys[3] = "contractFee:uint256";
        values[3] = abi.encodePacked(contractFee);

        emit UserLockNFT(params.smgID, params.tokenPairID, tokenScAddr, keys, values);
    }

    /// @notice                         burnBridge, user lock token on token original chain
    /// @notice                         event invoked by user burn lock
    /// @param storageData              Cross storage data
    /// @param params                   parameters for user burn lock token on token original chain
    function userBurnNFT(CrossTypesV1.Data storage storageData, RapidityUserBurnNFTParams memory params)
        public
    {
        address tokenScAddr;
        uint contractFee;
        (tokenScAddr, contractFee) = getTokenScAddrAndContractFee(storageData, params.tokenPairID, params.tokenPairContractFee, params.currentChainID, params.tokenIDs.length);

        ITokenManager tokenManager = storageData.tokenManager;
        uint8 tokenCrossType = tokenManager.mapTokenPairType(params.tokenPairID);
        require((tokenCrossType == uint8(TokenCrossType.ERC721) || tokenCrossType == uint8(TokenCrossType.ERC1155)), "Invalid NFT type");
        ITokenManager(tokenManager).burnNFT(uint(tokenCrossType), tokenScAddr, msg.sender, params.tokenIDs, params.tokenValues);

        if (contractFee > 0) {
            params.smgFeeProxy.transfer(contractFee);
        }

        uint left = (msg.value).sub(contractFee);
        if (left != 0) {
            (msg.sender).transfer(left);
        }

        string[] memory keys = new string[](4);
        bytes[] memory values = new bytes[](4);

        keys[0] = "tokenIDs:uint256[]";
        values[0] = abi.encode(params.tokenIDs);

        keys[1] = "tokenValues:uint256[]";
        values[1] = abi.encode(params.tokenValues);

        keys[2] = "userAccount:bytes";
        values[2] = params.destUserAccount;

        keys[3] = "contractFee:uint256";
        values[3] = abi.encodePacked(contractFee);
        emit UserBurnNFT(params.smgID, params.tokenPairID, tokenScAddr, keys, values);
    }

    /// @notice                         mintBridge, storeman mint lock token on token shadow chain
    /// @notice                         event invoked by user mint lock
    /// @param storageData              Cross storage data
    /// @param params                   parameters for storeman mint lock token on token shadow chain
    function smgMintNFT(CrossTypesV1.Data storage storageData, RapiditySmgMintNFTParams memory params)
        public
    {
        storageData.rapidityTxData.addRapidityTx(params.uniqueID);

        ITokenManager tokenManager = storageData.tokenManager;
        uint8 tokenCrossType = tokenManager.mapTokenPairType(params.tokenPairID);
        require((tokenCrossType == uint8(TokenCrossType.ERC721) || tokenCrossType == uint8(TokenCrossType.ERC1155)), "Invalid NFT type");
        ITokenManager(tokenManager).mintNFT(uint(tokenCrossType), params.destTokenAccount, params.destUserAccount, params.tokenIDs, params.tokenValues, params.extData);

        string[] memory keys = new string[](5);
        bytes[] memory values = new bytes[](5);

        keys[0] = "tokenIDs:uint256[]";
        values[0] = abi.encode(params.tokenIDs);

        keys[1] = "tokenValues:uint256[]";
        values[1] = abi.encode(params.tokenValues);

        keys[2] = "tokenAccount:address";
        values[2] = abi.encodePacked(params.destTokenAccount);

        keys[3] = "userAccount:address";
        values[3] = abi.encodePacked(params.destUserAccount);

        keys[4] = "extData:bytes";
        values[4] = params.extData;

        emit SmgMintNFT(params.uniqueID, params.smgID, params.tokenPairID, keys, values);
    }

    /// @notice                         burnBridge, storeman burn lock token on token shadow chain
    /// @notice                         event invoked by user burn lock
    /// @param storageData              Cross storage data
    /// @param params                   parameters for storeman burn lock token on token shadow chain
    function smgReleaseNFT(CrossTypesV1.Data storage storageData, RapiditySmgReleaseNFTParams memory params)
        public
    {
        storageData.rapidityTxData.addRapidityTx(params.uniqueID);

        uint8 tokenCrossType = storageData.tokenManager.mapTokenPairType(params.tokenPairID);
        if (tokenCrossType == uint8(TokenCrossType.ERC721)) {
            for(uint idx = 0; idx < params.tokenIDs.length; ++idx) {
                IERC721(params.destTokenAccount).safeTransferFrom(address(this), params.destUserAccount, params.tokenIDs[idx], "");
            }
        }
        else if(tokenCrossType == uint8(TokenCrossType.ERC1155)) {
            IERC1155(params.destTokenAccount).safeBatchTransferFrom(address(this), params.destUserAccount, params.tokenIDs, params.tokenValues, "");
        }
        else {
            require(false, "Invalid NFT type");
        }

        string[] memory keys = new string[](4);
        bytes[] memory values = new bytes[](4);

        keys[0] = "tokenIDs:uint256[]";
        values[0] = abi.encode(params.tokenIDs);

        keys[1] = "tokenValues:uint256[]";
        values[1] = abi.encode(params.tokenValues);

        keys[2] = "tokenAccount:address";
        values[2] = abi.encodePacked(params.destTokenAccount);

        keys[3] = "userAccount:address";
        values[3] = abi.encodePacked(params.destUserAccount);

        emit SmgReleaseNFT(params.uniqueID, params.smgID, params.tokenPairID, keys, values);
    }
}

// File: contracts/crossApproach/CrossDelegateV4.sol

/*

  Copyright 2019 Wanchain Foundation.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

*/

//                            _           _           _
//  __      ____ _ _ __   ___| |__   __ _(_)_ __   __| | _____   __
//  \ \ /\ / / _` | '_ \ / __| '_ \ / _` | | '_ \@/ _` |/ _ \ \ / /
//   \ V  V / (_| | | | | (__| | | | (_| | | | | | (_| |  __/\ V /
//    \_/\_/ \__,_|_| |_|\___|_| |_|\__,_|_|_| |_|\__,_|\___| \_/
//
//

pragma solidity ^0.4.26;






contract CrossDelegateV4 is CrossStorageV4 {
    using SafeMath for uint;

    /**
     *
     * EVENTS
     *
     **/

    /// @notice                         event of admin config
    /// @param adminAccount             account of admin
    event SetAdmin(address adminAccount);

    /// @notice                         event of setFee or setFees
    /// @param srcChainID               source of cross chain
    /// @param destChainID              destination of cross chain
    /// @param contractFee              contract fee
    /// @param agentFee                 agent fee
    event SetFee(uint indexed srcChainID, uint indexed destChainID, uint contractFee, uint agentFee);

    /// @notice                         event of setFee or setFees
    /// @param tokenPairID              ID of token pair
    /// @param contractFee              contract fee
    event SetTokenPairFee(uint indexed tokenPairID, uint contractFee);

    /// @notice                         event of storeman group ID withdraw the original coin to receiver
    /// @param smgID                    ID of storeman group
    /// @param timeStamp                timestamp of the withdraw
    /// @param receiver                 receiver address
    /// @param fee                      shadow coin of the fee which the storeman group pk got it
    event WithdrawHistoryFeeLogger(bytes32 indexed smgID, uint indexed timeStamp, address indexed receiver, uint fee);

    /**
     *
     * MODIFIERS
     *
     */
    /// @notice                                 check the admin or not
    modifier onlyAdmin() {
        require(msg.sender == admin, "not admin");
        _;
    }

    /// @notice                                 check the storeman group is ready
    /// @param smgID                            ID of storeman group
    modifier onlyReadySmg(bytes32 smgID) {
        uint8 status;
        uint startTime;
        uint endTime;
        (status,startTime,endTime) = storageData.smgAdminProxy.getStoremanGroupStatus(smgID);

        require(status == uint8(GroupStatus.ready) && now >= startTime && now <= endTime, "PK is not ready");
        _;
    }


    /**
     *
     * MANIPULATIONS
     *
     */
    /// @notice                                 request exchange orignal coin or token with WRC20 on wanchain
    /// @param  smgID                           ID of storeman
    /// @param  tokenPairID                     token pair ID of cross chain coin/token
    /// @param  value                           exchange value
    /// @param  userAccount                     account of user, used to receive shadow chain token
    function userLock(bytes32 smgID, uint tokenPairID, uint value, bytes userAccount)
    external
    payable
    notHalted
    onlyReadySmg(smgID)
    {
        address smgFeeProxy = getSmgFeeProxy();

        RapidityLibV4.RapidityUserLockParams memory params = RapidityLibV4.RapidityUserLockParams({
        smgID: smgID,
        tokenPairID: tokenPairID,
        value: value,
        currentChainID: currentChainID,
        tokenPairContractFee: mapTokenPairContractFee[tokenPairID],
        destUserAccount: userAccount,
        smgFeeProxy: smgFeeProxy
        });
        RapidityLibV4.userLock(storageData, params);
    }

    /// @notice                                 request exchange RC20 token with WRC20 on wanchain
    /// @param  smgID                           ID of storeman
    /// @param  tokenPairID                     token pair ID of cross chain token
    /// @param  value                           exchange value
    /// @param  userAccount                     account of user, used to receive original chain token
    function userBurn(bytes32 smgID, uint tokenPairID, uint value, uint fee, address tokenAccount, bytes userAccount)
    external
    payable
    notHalted
    onlyReadySmg(smgID)
    {
        address smgFeeProxy = getSmgFeeProxy();

        RapidityLibV4.RapidityUserBurnParams memory params = RapidityLibV4.RapidityUserBurnParams({
        smgID: smgID,
        tokenPairID: tokenPairID,
        value: value,
        fee: fee,
        currentChainID: currentChainID,
        tokenPairContractFee: mapTokenPairContractFee[tokenPairID],
        srcTokenAccount: tokenAccount,
        destUserAccount: userAccount,
        smgFeeProxy: smgFeeProxy
        });
        RapidityLibV4.userBurn(storageData, params);
    }

    /// @notice                                 request exchange RC20 token with WRC20 on wanchain
    /// @param  uniqueID                        fast cross chain random number
    /// @param  smgID                           ID of storeman
    /// @param  tokenPairID                     token pair ID of cross chain token
    /// @param  value                           exchange value
    /// @param  fee                             exchange fee
    /// @param  userAccount                     address of user, used to receive WRC20 token
    /// @param  r                               signature
    /// @param  s                               signature
    function smgMint(bytes32 uniqueID, bytes32 smgID, uint tokenPairID, uint value, uint fee, address tokenAccount, address userAccount, bytes r, bytes32 s)
    external
    notHalted
    {
        uint curveID;
        bytes memory PK;
        (curveID, PK) = acquireReadySmgInfo(smgID);

        RapidityLibV4.RapiditySmgMintParams memory params = RapidityLibV4.RapiditySmgMintParams({
        uniqueID: uniqueID,
        smgID: smgID,
        tokenPairID: tokenPairID,
        value: value,
        fee: fee,
        destTokenAccount: tokenAccount,
        destUserAccount: userAccount,
        smgFeeProxy: (storageData.smgFeeProxy == address(0)) ? owner : storageData.smgFeeProxy // fix: Stack too deep
        });
        RapidityLibV4.smgMint(storageData, params);

        bytes32 mHash = sha256(abi.encode(currentChainID, uniqueID, tokenPairID, value, fee, tokenAccount, userAccount));
        verifySignature(curveID, mHash, PK, r, s);
    }

    /// @notice                                 request exchange RC20 token with WRC20 on wanchain
    /// @param  uniqueID                        fast cross chain random number
    /// @param  smgID                           ID of storeman
    /// @param  tokenPairID                     token pair ID of cross chain token
    /// @param  value                           exchange value
    /// @param  fee                             exchange fee
    /// @param  userAccount                     address of user, used to receive original token/coin
    /// @param  r                               signature
    /// @param  s                               signature
    function smgRelease(bytes32 uniqueID, bytes32 smgID, uint tokenPairID, uint value, uint fee, address tokenAccount, address userAccount, bytes r, bytes32 s)
    external
    notHalted
    {
        uint curveID;
        bytes memory PK;
        (curveID, PK) = acquireReadySmgInfo(smgID);

        RapidityLibV4.RapiditySmgReleaseParams memory params = RapidityLibV4.RapiditySmgReleaseParams({
        uniqueID: uniqueID,
        smgID: smgID,
        tokenPairID: tokenPairID,
        value: value,
        fee: fee,
        destTokenAccount: tokenAccount,
        destUserAccount: userAccount,
        smgFeeProxy: (storageData.smgFeeProxy == address(0)) ? owner : storageData.smgFeeProxy // fix: Stack too deep
        });
        RapidityLibV4.smgRelease(storageData, params);

        bytes32 mHash = sha256(abi.encode(currentChainID, uniqueID, tokenPairID, value, fee, tokenAccount, userAccount));
        verifySignature(curveID, mHash, PK, r, s);
    }

    /// @notice                             set the fee of the storeman group should get
    /// @param param                        struct of setFee parameter
    function setFee(SetFeesParam param) public onlyAdmin {
        storageData.mapContractFee[param.srcChainID][param.destChainID] = param.contractFee;
        storageData.mapAgentFee[param.srcChainID][param.destChainID] = param.agentFee;
        emit SetFee(param.srcChainID, param.destChainID, param.contractFee, param.agentFee);
    }

    /// @notice                             set the fee of the storeman group should get
    /// @param params                        struct of setFees parameter
    function setFees(SetFeesParam [] params) public onlyAdmin {
        for (uint i = 0; i < params.length; ++i) {
            storageData.mapContractFee[params[i].srcChainID][params[i].destChainID] = params[i].contractFee;
            storageData.mapAgentFee[params[i].srcChainID][params[i].destChainID] = params[i].agentFee;
            emit SetFee(params[i].srcChainID, params[i].destChainID, params[i].contractFee, params[i].agentFee);
        }
    }

    /// @notice                             set the fee of the storeman group should get
    /// @param tokenPairID                  ID of token pair
    /// @param contractFee                  contractFee of token pair
    function setTokenPairFee(uint256 tokenPairID, uint256 contractFee) external onlyAdmin {
        mapTokenPairContractFee[tokenPairID] = contractFee;
        emit SetTokenPairFee(tokenPairID, contractFee);
    }

    /// @notice                             set the fee of the storeman group should get
    /// @param params                       struct of setTokenPairFees parameter
    function setTokenPairFees(SetTokenPairFeesParam [] params) public onlyAdmin {
        for (uint i = 0; i < params.length; ++i) {
            mapTokenPairContractFee[params[i].tokenPairID] = params[i].contractFee;
            emit SetTokenPairFee(params[i].tokenPairID, params[i].contractFee);
        }
    }

    function setChainID(uint256 chainID) external onlyAdmin {
        if (currentChainID == 0) {
            currentChainID = chainID;
        }
    }

    function setAdmin(address adminAccount) external onlyOwner {
        admin = adminAccount;
        emit SetAdmin(adminAccount);
    }

    function setUintValue(bytes key, bytes innerKey, uint value) external onlyAdmin {
        return uintData.setStorage(key, innerKey, value);
    }

    function delUintValue(bytes key, bytes innerKey) external onlyAdmin {
        return uintData.delStorage(key, innerKey);
    }

    /// @notice                             update the initialized state value of this contract
    /// @param tokenManager                 address of the token manager
    /// @param smgAdminProxy                address of the storeman group admin
    /// @param smgFeeProxy                  address of the proxy to store fee for storeman group
    /// @param quota                        address of the quota
    /// @param sigVerifier                  address of the signature verifier
    function setPartners(address tokenManager, address smgAdminProxy, address smgFeeProxy, address quota, address sigVerifier)
    external
    onlyOwner
    {
        // require(tokenManager != address(0) && smgAdminProxy != address(0) && quota != address(0) && sigVerifier != address(0),
        //     "Parameter is invalid");
        require(tokenManager != address(0) && smgAdminProxy != address(0) && sigVerifier != address(0),
            "Parameter is invalid");

        storageData.smgAdminProxy = IStoremanGroup(smgAdminProxy);
        storageData.tokenManager = ITokenManager(tokenManager);
        // storageData.quota = IQuota(quota);
        storageData.smgFeeProxy = smgFeeProxy;
        storageData.sigVerifier = ISignatureVerifier(sigVerifier);
    }


    /// @notice                             withdraw the history fee to foundation account
    /// @param smgIDs                       array of storemanGroup ID
    function smgWithdrawHistoryFee(bytes32 [] smgIDs) external {
        uint fee;
        uint currentFee;
        address smgFeeProxy = storageData.smgFeeProxy;
        if (smgFeeProxy == address(0)) {
            smgFeeProxy = owner;
        }
        require(smgFeeProxy != address(0), "invalid smgFeeProxy");

        for (uint i = 0; i < smgIDs.length; ++i) {
            currentFee = storageData.mapStoremanFee[smgIDs[i]];
            delete storageData.mapStoremanFee[smgIDs[i]];
            fee = fee.add(currentFee);
            emit WithdrawHistoryFeeLogger(smgIDs[i], block.timestamp, smgFeeProxy, currentFee);
        }
        if (fee > 0) {
            smgFeeProxy.transfer(fee);
        }
    }


    /** Get Functions */

    function getUintValue(bytes key, bytes innerKey) public view returns (uint) {
        return uintData.getStorage(key, innerKey);
    }

    /// @notice                             get the fee of the storeman group should get
    /// @param key                          key of storeman fee
    /// @return fee                         original coin the storeman group should get
    function getStoremanFee(bytes32 key) external view returns(uint fee) {
        fee = storageData.mapStoremanFee[key];
    }

    /// @notice                             get the fee of the storeman group should get
    /// @param param                        struct of getFee parameter
    /// @return fees                        struct of getFee return
    function getFee(GetFeesParam param) public view returns(GetFeesReturn fee) {
        fee.contractFee = storageData.mapContractFee[param.srcChainID][param.destChainID];
        fee.agentFee = storageData.mapAgentFee[param.srcChainID][param.destChainID];
    }

    /// @notice                             get the fee of the storeman group should get
    /// @param params                       struct of getFees parameter
    /// @return fees                        struct of getFees return
    function getFees(GetFeesParam [] params) public view returns(GetFeesReturn [] fees) {
        fees = new GetFeesReturn[](params.length);
        for (uint i = 0; i < params.length; ++i) {
            fees[i].contractFee = storageData.mapContractFee[params[i].srcChainID][params[i].destChainID];
            fees[i].agentFee = storageData.mapAgentFee[params[i].srcChainID][params[i].destChainID];
        }
    }

    /// @notice                             get the token pair fee of the storeman group should get
    /// @param tokenPairID                  ID of token pair
    /// @return contractFee                 contractFee of token pair
    function getTokenPairFee(uint256 tokenPairID) external view returns(uint256 contractFee) {
        contractFee = mapTokenPairContractFee[tokenPairID];
    }

    /// @notice                             get the token pair fees of the storeman group should get
    /// @param tokenPairIDs                 array of tokenPairID
    /// @return contractFees                array of tokenPair contractFee
    function getTokenPairFees(uint256[] tokenPairIDs) external view returns(uint256 [] contractFees) {
        contractFees = new uint256[](tokenPairIDs.length);
        for (uint i = 0; i < tokenPairIDs.length; ++i) {
            contractFees[i] = mapTokenPairContractFee[tokenPairIDs[i]];
        }
    }

    /// @notice                             get the initialized state value of this contract
    /// @return tokenManager                address of the token manager
    /// @return smgAdminProxy               address of the storeman group admin
    /// @return smgFeeProxy                 address of the proxy to store fee for storeman group
    /// @return quota                       address of the quota
    /// @return sigVerifier                 address of the signature verifier
    function getPartners()
    external
    view
    returns(address tokenManager, address smgAdminProxy, address smgFeeProxy, address quota, address sigVerifier)
    {
        tokenManager = address(storageData.tokenManager);
        smgAdminProxy = address(storageData.smgAdminProxy);
        smgFeeProxy = storageData.smgFeeProxy;
        quota = address(storageData.quota);
        sigVerifier = address(storageData.sigVerifier);
    }


    /** Private and Internal Functions */

    /// @notice                                 check the storeman group is ready or not
    /// @param smgID                            ID of storeman group
    /// @return curveID                         ID of elliptic curve
    /// @return PK                              PK of storeman group
    function acquireReadySmgInfo(bytes32 smgID)
    internal
    view
    returns (uint curveID, bytes memory PK)
    {
        uint8 status;
        uint startTime;
        uint endTime;
        (,status,,,,curveID,,PK,,startTime,endTime) = storageData.smgAdminProxy.getStoremanGroupConfig(smgID);

        require(status == uint8(GroupStatus.ready) && now >= startTime && now <= endTime, "PK is not ready");

        return (curveID, PK);
    }

    /// @notice                                 get the unregistered storeman group info
    /// @param smgID                            ID of storeman group
    /// @return curveID                         ID of elliptic curve
    /// @return PK                              PK of storeman group
    function acquireUnregisteredSmgInfo(bytes32 smgID)
    internal
    view
    returns (uint curveID, bytes memory PK)
    {
        uint8 status;
        (,status,,,,curveID,,PK,,,) = storageData.smgAdminProxy.getStoremanGroupConfig(smgID);

        require(status == uint8(GroupStatus.unregistered), "PK is not unregistered");
    }

    /// @notice       convert bytes to bytes32
    /// @param b      bytes array
    /// @param offset offset of array to begin convert
    function bytesToBytes32(bytes memory b, uint offset) internal pure returns (bytes32 result) {
        assembly {
            result := mload(add(add(b, offset), 32))
        }
    }

    /// @notice             verify signature
    /// @param  curveID     ID of elliptic curve
    /// @param  message     message to be verified
    /// @param  r           Signature info r
    /// @param  s           Signature info s
    function verifySignature(uint curveID, bytes32 message, bytes PK, bytes r, bytes32 s) internal {
        bytes32 PKx = bytesToBytes32(PK, 0);
        bytes32 PKy = bytesToBytes32(PK, 32);

        bytes32 Rx = bytesToBytes32(r, 0);
        bytes32 Ry = bytesToBytes32(r, 32);

        require(storageData.sigVerifier.verify(curveID, s, PKx, PKy, Rx, Ry, message), "Signature verification failed");
    }

    function getSmgFeeProxy() internal view returns (address) {
        address smgFeeProxy = storageData.smgFeeProxy;
        return (smgFeeProxy == address(0)) ? owner : smgFeeProxy;
    }

    //*********************************************************************************************
    //*********************************************************************************************
    // NFT
    /**
     * @notice Handle the receipt of an NFT
     * @dev The ERC721 smart contract calls this function on the recipient
     * after a `safeTransfer`. This function MUST return the function selector,
     * otherwise the caller will revert the transaction. The selector to be
     * returned can be obtained as `this.onERC721Received.selector`. This
     * function MAY throw to revert and reject the transfer.

     * Note: the ERC721 contract address is always the message sender.

     * @param operator The address which called `safeTransferFrom` function
     * @param from The address which previously owned the token
     * @param tokenId The NFT identifier which is being transferred
     * @param data Additional data with no specified format
     * @return `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`
     */
    function onERC721Received(address operator, address from, uint256 tokenId, bytes data)
        public
        pure
        returns(bytes4)
    {
        return this.onERC721Received.selector;
    }

    function onERC1155Received(address, address, uint256, uint256, bytes memory) 
        public 
        pure 
        returns (bytes4)
    {
        return this.onERC1155Received.selector;
    }

    function onERC1155BatchReceived(address, address, uint256[] memory, uint256[] memory, bytes memory) 
        public
        pure
        returns (bytes4)
    {
        return this.onERC1155BatchReceived.selector;
    }


    function userLockNFT(bytes32 smgID, uint tokenPairID, uint[] tokenIDs, uint[] tokenValues, bytes userAccount)
        public
        payable
        notHalted
        onlyReadySmg(smgID)
    {
        require(tokenIDs.length > 0 && tokenIDs.length <= getMaxBatchSize(), "Invalid length");
        require(tokenIDs.length == tokenValues.length, "Length mismatch");

        NFTLibV1.RapidityUserLockNFTParams memory params = NFTLibV1.RapidityUserLockNFTParams({
            smgID: smgID,
            tokenPairID: tokenPairID,
            tokenIDs: tokenIDs,
            tokenValues: tokenValues,
            currentChainID: currentChainID,
            tokenPairContractFee: mapTokenPairContractFee[tokenPairID],
            destUserAccount: userAccount,
            smgFeeProxy: getSmgFeeProxy()
        });
        NFTLibV1.userLockNFT(storageData, params);
    }
    
    function userBurnNFT(bytes32 smgID, uint tokenPairID, uint[] tokenIDs, uint[] tokenValues, address tokenAccount, bytes userAccount)
        public
        payable
        notHalted
        onlyReadySmg(smgID)
    {
        require(tokenIDs.length > 0 && tokenIDs.length <= getMaxBatchSize(), "Invalid length");
        require(tokenIDs.length == tokenValues.length, "Length mismatch");

        NFTLibV1.RapidityUserBurnNFTParams memory params = NFTLibV1.RapidityUserBurnNFTParams({
            smgID: smgID,
            tokenPairID: tokenPairID,
            tokenIDs: tokenIDs,
            tokenValues: tokenValues,
            currentChainID: currentChainID,
            tokenPairContractFee: mapTokenPairContractFee[tokenPairID],
            srcTokenAccount: tokenAccount,
            destUserAccount: userAccount,
            smgFeeProxy: getSmgFeeProxy()
        });
        NFTLibV1.userBurnNFT(storageData, params);
    }

    function smgMintNFT(bytes32 uniqueID, bytes32 smgID, uint tokenPairID, uint[] tokenIDs, uint[] tokenValues, bytes extData, address tokenAccount, address userAccount, bytes r, bytes32 s)
        public
        notHalted
    {
        uint curveID;
        bytes memory PK;
        (curveID, PK) = acquireReadySmgInfo(smgID);

        NFTLibV1.RapiditySmgMintNFTParams memory params = NFTLibV1.RapiditySmgMintNFTParams({
            uniqueID: uniqueID,
            smgID: smgID,
            tokenPairID: tokenPairID,
            tokenIDs: tokenIDs,
            tokenValues: tokenValues,
            extData: extData,
            destTokenAccount: tokenAccount,
            destUserAccount: userAccount
        });

        NFTLibV1.smgMintNFT(storageData, params);
        bytes32 mHash = sha256(abi.encode(currentChainID, uniqueID, tokenPairID, tokenIDs, tokenValues, extData, tokenAccount, userAccount));
        verifySignature(curveID, mHash, PK, r, s);
    }

    function smgReleaseNFT(bytes32 uniqueID, bytes32 smgID, uint tokenPairID, uint[] tokenIDs, uint[] tokenValues, address tokenAccount, address userAccount, bytes r, bytes32 s)
        public
        notHalted
    {
        uint curveID;
        bytes memory PK;
        (curveID, PK) = acquireReadySmgInfo(smgID);

        NFTLibV1.RapiditySmgReleaseNFTParams memory params = NFTLibV1.RapiditySmgReleaseNFTParams({
            uniqueID: uniqueID,
            smgID: smgID,
            tokenPairID: tokenPairID,
            tokenIDs: tokenIDs,
            tokenValues: tokenValues,
            destTokenAccount: tokenAccount,
            destUserAccount: userAccount
        });
        NFTLibV1.smgReleaseNFT(storageData, params);

        bytes32 mHash = sha256(abi.encode(currentChainID, uniqueID, tokenPairID, tokenIDs, tokenValues, tokenAccount, userAccount));
        verifySignature(curveID, mHash, PK, r, s);
    }

    function setMaxBatchSize(uint _maxBatchSize) 
      external
      onlyAdmin
    {
      maxBatchSize = _maxBatchSize;
    }

    function getMaxBatchSize() 
      public
      view
      returns (uint)
    {
      if(maxBatchSize == 0) {
        return 20;
      }
      return maxBatchSize;
    }

    function getBatchFee(uint tokenPairID, uint batchLength) 
      external
      view
      returns (uint)
    {
      uint contractFee;
      (, contractFee) = NFTLibV1.getTokenScAddrAndContractFee(storageData, tokenPairID, mapTokenPairContractFee[tokenPairID], currentChainID, batchLength);
      return contractFee;
    }
}

Contract ABI

[{"constant":false,"inputs":[{"name":"tokenManager","type":"address"},{"name":"smgAdminProxy","type":"address"},{"name":"smgFeeProxy","type":"address"},{"name":"quota","type":"address"},{"name":"sigVerifier","type":"address"}],"name":"setPartners","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"components":[{"name":"srcChainID","type":"uint256"},{"name":"destChainID","type":"uint256"}],"name":"param","type":"tuple"}],"name":"getFee","outputs":[{"components":[{"name":"contractFee","type":"uint256"},{"name":"agentFee","type":"uint256"}],"name":"fee","type":"tuple"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"operator","type":"address"},{"name":"from","type":"address"},{"name":"tokenId","type":"uint256"},{"name":"data","type":"bytes"}],"name":"onERC721Received","outputs":[{"name":"","type":"bytes4"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":false,"inputs":[{"components":[{"name":"tokenPairID","type":"uint256"},{"name":"contractFee","type":"uint256"}],"name":"params","type":"tuple[]"}],"name":"setTokenPairFees","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"smgID","type":"bytes32"},{"name":"tokenPairID","type":"uint256"},{"name":"value","type":"uint256"},{"name":"userAccount","type":"bytes"}],"name":"userLock","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"_maxBatchSize","type":"uint256"}],"name":"setMaxBatchSize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"components":[{"name":"srcChainID","type":"uint256"},{"name":"destChainID","type":"uint256"}],"name":"params","type":"tuple[]"}],"name":"getFees","outputs":[{"components":[{"name":"contractFee","type":"uint256"},{"name":"agentFee","type":"uint256"}],"name":"fees","type":"tuple[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"tokenPairID","type":"uint256"}],"name":"getTokenPairFee","outputs":[{"name":"contractFee","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"smgID","type":"bytes32"},{"name":"tokenPairID","type":"uint256"},{"name":"value","type":"uint256"},{"name":"fee","type":"uint256"},{"name":"tokenAccount","type":"address"},{"name":"userAccount","type":"bytes"}],"name":"userBurn","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"key","type":"bytes"},{"name":"innerKey","type":"bytes"}],"name":"delUintValue","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_newOwner","type":"address"}],"name":"transferOwner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"uniqueID","type":"bytes32"},{"name":"smgID","type":"bytes32"},{"name":"tokenPairID","type":"uint256"},{"name":"value","type":"uint256"},{"name":"fee","type":"uint256"},{"name":"tokenAccount","type":"address"},{"name":"userAccount","type":"address"},{"name":"r","type":"bytes"},{"name":"s","type":"bytes32"}],"name":"smgMint","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"smgIDs","type":"bytes32[]"}],"name":"smgWithdrawHistoryFee","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"components":[{"name":"srcChainID","type":"uint256"},{"name":"destChainID","type":"uint256"},{"name":"contractFee","type":"uint256"},{"name":"agentFee","type":"uint256"}],"name":"param","type":"tuple"}],"name":"setFee","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"implementation","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"adminAccount","type":"address"}],"name":"setAdmin","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"key","type":"bytes32"}],"name":"getStoremanFee","outputs":[{"name":"fee","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getPartners","outputs":[{"name":"tokenManager","type":"address"},{"name":"smgAdminProxy","type":"address"},{"name":"smgFeeProxy","type":"address"},{"name":"quota","type":"address"},{"name":"sigVerifier","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"uniqueID","type":"bytes32"},{"name":"smgID","type":"bytes32"},{"name":"tokenPairID","type":"uint256"},{"name":"value","type":"uint256"},{"name":"fee","type":"uint256"},{"name":"tokenAccount","type":"address"},{"name":"userAccount","type":"address"},{"name":"r","type":"bytes"},{"name":"s","type":"bytes32"}],"name":"smgRelease","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"acceptOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"key","type":"bytes"},{"name":"innerKey","type":"bytes"}],"name":"getUintValue","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"tokenPairIDs","type":"uint256[]"}],"name":"getTokenPairFees","outputs":[{"name":"contractFees","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"key","type":"bytes"},{"name":"innerKey","type":"bytes"},{"name":"value","type":"uint256"}],"name":"setUintValue","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"uniqueID","type":"bytes32"},{"name":"smgID","type":"bytes32"},{"name":"tokenPairID","type":"uint256"},{"name":"tokenIDs","type":"uint256[]"},{"name":"tokenValues","type":"uint256[]"},{"name":"tokenAccount","type":"address"},{"name":"userAccount","type":"address"},{"name":"r","type":"bytes"},{"name":"s","type":"bytes32"}],"name":"smgReleaseNFT","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_newOwner","type":"address"}],"name":"changeOwner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"lockedTime","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"currentChainID","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"smgID","type":"bytes32"},{"name":"tokenPairID","type":"uint256"},{"name":"tokenIDs","type":"uint256[]"},{"name":"tokenValues","type":"uint256[]"},{"name":"userAccount","type":"bytes"}],"name":"userLockNFT","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"halted","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"uniqueID","type":"bytes32"},{"name":"smgID","type":"bytes32"},{"name":"tokenPairID","type":"uint256"},{"name":"tokenIDs","type":"uint256[]"},{"name":"tokenValues","type":"uint256[]"},{"name":"extData","type":"bytes"},{"name":"tokenAccount","type":"address"},{"name":"userAccount","type":"address"},{"name":"r","type":"bytes"},{"name":"s","type":"bytes32"}],"name":"smgMintNFT","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"","type":"address"},{"name":"","type":"uint256[]"},{"name":"","type":"uint256[]"},{"name":"","type":"bytes"}],"name":"onERC1155BatchReceived","outputs":[{"name":"","type":"bytes4"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"name":"tokenPairID","type":"uint256"},{"name":"batchLength","type":"uint256"}],"name":"getBatchFee","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"newOwner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"components":[{"name":"srcChainID","type":"uint256"},{"name":"destChainID","type":"uint256"},{"name":"contractFee","type":"uint256"},{"name":"agentFee","type":"uint256"}],"name":"params","type":"tuple[]"}],"name":"setFees","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"smgID","type":"bytes32"},{"name":"tokenPairID","type":"uint256"},{"name":"tokenIDs","type":"uint256[]"},{"name":"tokenValues","type":"uint256[]"},{"name":"tokenAccount","type":"address"},{"name":"userAccount","type":"bytes"}],"name":"userBurnNFT","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"getMaxBatchSize","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"smgFeeReceiverTimeout","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"chainID","type":"uint256"}],"name":"setChainID","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"tokenPairID","type":"uint256"},{"name":"contractFee","type":"uint256"}],"name":"setTokenPairFee","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"","type":"address"},{"name":"","type":"uint256"},{"name":"","type":"uint256"},{"name":"","type":"bytes"}],"name":"onERC1155Received","outputs":[{"name":"","type":"bytes4"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":false,"inputs":[{"name":"halt","type":"bool"}],"name":"setHalt","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"admin","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":false,"name":"adminAccount","type":"address"}],"name":"SetAdmin","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"srcChainID","type":"uint256"},{"indexed":true,"name":"destChainID","type":"uint256"},{"indexed":false,"name":"contractFee","type":"uint256"},{"indexed":false,"name":"agentFee","type":"uint256"}],"name":"SetFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"tokenPairID","type":"uint256"},{"indexed":false,"name":"contractFee","type":"uint256"}],"name":"SetTokenPairFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"smgID","type":"bytes32"},{"indexed":true,"name":"timeStamp","type":"uint256"},{"indexed":true,"name":"receiver","type":"address"},{"indexed":false,"name":"fee","type":"uint256"}],"name":"WithdrawHistoryFeeLogger","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"implementation","type":"address"}],"name":"Upgraded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"},{"indexed":true,"name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"}]

60806040526201fa406011556102586012556014805460a060020a60ff02191690556013805460ff191660011761010060a860020a0319166101003302179055614bd78061004e6000396000f3006080604052600436106102005763ffffffff60e060020a6000350416630a72b1ab811461025c5780630ec61b791461027e578063150b7a02146102b4578063213a2596146102e1578063257011b6146103015780632b26a6bf14610314578063361b31bf14610334578063392a62b91461036157806341ff1bcc1461038e5780634cc7125b146103a15780634fb2e45d146103c157806350cc6707146103e1578063536686a91461040157806354c0de4a146104215780635c60da1b14610441578063704b6c0214610463578063715018a614610483578063715f250c1461049857806373e29b0d146104b857806373fa58f5146104de57806379ba5097146104fe5780638061babf146105135780638da5cb5b146105335780639011691614610548578063926731ea14610575578063a3d1e38114610595578063a6f9dae1146105b5578063a8b38205146105d5578063b179e1e7146105ea578063b64ed6db146105ff578063b9b8af0b14610612578063bbf485ab14610634578063bc197c8114610654578063be5212a814610674578063d4ee1d9014610694578063d52012bc146106a9578063e02dee8c146106c9578063e7c00f6e146106dc578063e92e2c1b146106f1578063ed8d47e614610706578063f0baef5214610726578063f23a6e6114610746578063f495438714610766578063f851a44014610786575b601554600160a060020a03168015156102375760405160e560020a62461bcd02815260040161022e90614721565b60405180910390fd5b60405136600082376000803683855af43d806000843e818015610258578184f35b8184fd5b34801561026857600080fd5b5061027c6102773660046132ae565b61079b565b005b34801561028a57600080fd5b5061029e610299366004613dd7565b61087d565b6040516102ab91906148cf565b60405180910390f35b3480156102c057600080fd5b506102d46102cf3660046133d3565b6108c8565b6040516102ab91906146f3565b3480156102ed57600080fd5b5061027c6102fc366004613589565b6108f1565b61027c61030f366004613a4e565b6109f1565b34801561032057600080fd5b5061027c61032f3660046135fa565b610c13565b34801561034057600080fd5b5061035461034f36600461351f565b610c45565b6040516102ab91906146b5565b34801561036d57600080fd5b5061038161037c3660046135fa565b610d92565b6040516102ab91906146e5565b61027c61039c366004613acc565b610da4565b3480156103ad57600080fd5b5061027c6103bc366004613c8f565b610feb565b3480156103cd57600080fd5b5061027c6103dc366004613288565b611090565b3480156103ed57600080fd5b5061027c6103fc36600461387b565b611161565b34801561040d57600080fd5b5061027c61041c3660046134dd565b6113f8565b34801561042d57600080fd5b5061027c61043c366004613df5565b611575565b34801561044d57600080fd5b5061045661162d565b6040516102ab919061465b565b34801561046f57600080fd5b5061027c61047e366004613288565b61163d565b34801561048f57600080fd5b5061027c6116d2565b3480156104a457600080fd5b506103816104b33660046135fa565b611724565b3480156104c457600080fd5b506104cd611736565b6040516102ab959493929190614669565b3480156104ea57600080fd5b5061027c6104f936600461387b565b611761565b34801561050a57600080fd5b5061027c6118b5565b34801561051f57600080fd5b5061038161052e366004613d78565b611901565b34801561053f57600080fd5b5061045661191d565b34801561055457600080fd5b506105686105633660046134dd565b611931565b6040516102ab91906146c6565b34801561058157600080fd5b5061027c610590366004613cff565b6119bf565b3480156105a157600080fd5b5061027c6105b0366004613636565b611a67565b3480156105c157600080fd5b5061027c6105d0366004613288565b611c52565b3480156105e157600080fd5b50610381611cb3565b3480156105f657600080fd5b50610381611cb9565b61027c61060d366004613a19565b611cbf565b34801561061e57600080fd5b50610627611f0c565b6040516102ab91906146d7565b34801561064057600080fd5b5061027c61064f366004613742565b611f1c565b34801561066057600080fd5b506102d461066f366004613323565b612101565b34801561068057600080fd5b5061038161068f366004613e13565b61212b565b3480156106a057600080fd5b506104566121ef565b3480156106b557600080fd5b5061027c6106c4366004613554565b6121fe565b61027c6106d736600461394a565b6123e4565b3480156106e857600080fd5b50610381612614565b3480156106fd57600080fd5b50610381612630565b34801561071257600080fd5b5061027c6107213660046135fa565b612636565b34801561073257600080fd5b5061027c610741366004613e13565b612675565b34801561075257600080fd5b506102d461076136600461344c565b6126f1565b34801561077257600080fd5b5061027c6107813660046135be565b61271b565b34801561079257600080fd5b5061045661277c565b6013546101009004600160a060020a031633146107cd5760405160e560020a62461bcd02815260040161022e90614771565b600160a060020a038516158015906107ed5750600160a060020a03841615155b80156108015750600160a060020a03811615155b15156108225760405160e560020a62461bcd02815260040161022e90614711565b600b805473ffffffffffffffffffffffffffffffffffffffff19908116600160a060020a0396871617909155600a8054821696861696909617909555600c805486169385169390931790925550600d80549093169116179055565b610885612c50565b81516000908152600f6020908152604080832082860180518552908352818420548552945183526010825280832094518352938152929020549181019190915290565b7f150b7a0200000000000000000000000000000000000000000000000000000000949350505050565b601754600090600160a060020a031633146109215760405160e560020a62461bcd02815260040161022e906147a1565b5060005b81518110156109ed57818181518110151561093c57fe5b906020019060200201516020015160186000848481518110151561095c57fe5b602090810290910181015151825281019190915260400160002055815182908290811061098557fe5b90602001906020020151600001517fdfa3e1a2556a2caf7af0a1cb98a9eed056ae433c4e109e3398edff9863d45bf583838151811015156109c257fe5b90602001906020020151602001516040516109dd91906146e5565b60405180910390a2600101610925565b5050565b60006109fb612c67565b60145460a060020a900460ff1615610a285760405160e560020a62461bcd02815260040161022e90614741565b600b5460405160e160020a634af46b45028152889160009182918291600160a060020a03909116906395e8d68a90610a649087906004016146e5565b606060405180830381600087803b158015610a7e57600080fd5b505af1158015610a92573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610ab69190810190613e43565b9194509250905060ff83166005148015610ad05750814210155b8015610adc5750804211155b1515610afd5760405160e560020a62461bcd02815260040161022e90614791565b610b0561278b565b6040805160e0810182528d815260208082018e90528183018d9052601654606083015260008e8152601882528390205460808301528251601f8c018290048202810182019093528a83529298509160a0830191908b908b9081908401838280828437505050928452505050600160a060020a0388166020909101526040517fbbb71abb00000000000000000000000000000000000000000000000000000000815290955073990825c5d894385f1c5bd36b6427c5336d984e079063bbb71abb90610bd690600590899060040161486d565b60006040518083038186803b158015610bee57600080fd5b505af4158015610c02573d6000803e3d6000fd5b505050505050505050505050505050565b601754600160a060020a03163314610c405760405160e560020a62461bcd02815260040161022e906147a1565b601955565b606060008251604051908082528060200260200182016040528015610c8457816020015b610c71612c50565b815260200190600190039081610c695790505b509150600090505b8251811015610d8c576005600a0160008483815181101515610caa57fe5b9060200190602002015160000151815260200190815260200160002060008483815181101515610cd657fe5b90602001906020020151602001518152602001908152602001600020548282815181101515610d0157fe5b60209081029091010151528251601090600090859084908110610d2057fe5b9060200190602002015160000151815260200190815260200160002060008483815181101515610d4c57fe5b90602001906020020151602001518152602001908152602001600020548282815181101515610d7757fe5b60209081029091018101510152600101610c8c565b50919050565b60009081526018602052604090205490565b6000610dae612cb1565b60145460a060020a900460ff1615610ddb5760405160e560020a62461bcd02815260040161022e90614741565b600b5460405160e160020a634af46b450281528a9160009182918291600160a060020a03909116906395e8d68a90610e179087906004016146e5565b606060405180830381600087803b158015610e3157600080fd5b505af1158015610e45573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610e699190810190613e43565b9194509250905060ff83166005148015610e835750814210155b8015610e8f5750804211155b1515610eb05760405160e560020a62461bcd02815260040161022e90614791565b610eb861278b565b9550610120604051908101604052808e6000191681526020018d81526020018c815260200160165481526020018b8152602001601860008f81526020019081526020016000205481526020018a600160a060020a0316815260200189898080601f016020809104026020016040519081016040528093929190818152602001838380828437505050928452505050600160a060020a0388166020909101526040517f0f9a9c9a00000000000000000000000000000000000000000000000000000000815290955073990825c5d894385f1c5bd36b6427c5336d984e0790630f9a9c9a90610fac90600590899060040161482d565b60006040518083038186803b158015610fc457600080fd5b505af4158015610fd8573d6000803e3d6000fd5b5050505050505050505050505050505050565b601754600160a060020a031633146110185760405160e560020a62461bcd02815260040161022e906147a1565b61108a84848080601f0160208091040260200160405190810160405280939291908181526020018383808284375050604080516020601f8a0181900481028201810190925288815294508893508792508291508401838280828437506000969594505063ffffffff6127be1692505050565b50505050565b6013546101009004600160a060020a031633146110c25760405160e560020a62461bcd02815260040161022e90614771565b600160a060020a03811615156110ed5760405160e560020a62461bcd02815260040161022e90614731565b601354604051600160a060020a0380841692610100900416907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a360138054600160a060020a039092166101000274ffffffffffffffffffffffffffffffffffffffff0019909216919091179055565b6000606061116d612d13565b60145460009060a060020a900460ff161561119d5760405160e560020a62461bcd02815260040161022e90614741565b6111a68d612884565b8094508195505050610100604051908101604052808f6000191681526020018e6000191681526020018d81526020018c81526020018b81526020018a600160a060020a0316815260200189600160a060020a031681526020016000600160a060020a0316600560070160009054906101000a9004600160a060020a0316600160a060020a03161461124257600c54600160a060020a0316611254565b6013546101009004600160a060020a03165b600160a060020a031690526040517fb3f78be000000000000000000000000000000000000000000000000000000000815290925073990825c5d894385f1c5bd36b6427c5336d984e079063b3f78be0906112b59060059086906004016147d1565b60006040518083038186803b1580156112cd57600080fd5b505af41580156112e1573d6000803e3d6000fd5b5050505060026016548f8e8e8e8e8e6040516020016113069796959493929190614a3b565b6040516020818303038152906040526040518082805190602001908083835b602083106113445780518252601f199092019160209182019101611325565b51815160209384036101000a600019018019909216911617905260405191909301945091925050808303816000865af1158015611385573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052506113a89190810190613618565b90506113e88482858a8a8080601f016020809104026020016040519081016040528093929190818152602001838380828437508e94506129939350505050565b5050505050505050505050505050565b600c546000908190600160a060020a031681811515611425576013546101009004600160a060020a031691505b600160a060020a03821615156114505760405160e560020a62461bcd02815260040161022e90614781565b5060005b8481101561152c57600e600087878481811061146c57fe5b602090810292909201358352508101919091526040016000908120549350600e9087878481811061149957fe5b602090810292909201358352508101919091526040016000908120556114c5848463ffffffff612a9e16565b9350600160a060020a038216428787848181106114de57fe5b9050602002013560001916600019167ff12b3f379096849c585fc75843457b18f02c980d39f9462c0ccefc992f2cb87b8660405161151c91906146e5565b60405180910390a4600101611454565b600084111561156d57604051600160a060020a0383169085156108fc029086906000818181858888f1935050505015801561156b573d6000803e3d6000fd5b505b505050505050565b601754600160a060020a031633146115a25760405160e560020a62461bcd02815260040161022e906147a1565b6040808201805183516000908152600f6020908152848220818701805184529082528583209390935560608601805187518452601083528684208551855290925291859020559051845192519151935190937f2c40e30353ae48a032fd20f1fece20031c1b80a2bc8512a2c172ff4de2e595199261162292909190614a8a565b60405180910390a350565b601554600160a060020a03165b90565b6013546101009004600160a060020a0316331461166f5760405160e560020a62461bcd02815260040161022e90614771565b6017805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0383161790556040517f5a272403b402d892977df56625f4164ccaf70ca3863991c43ecfe76a6905b0a1906116c790839061465b565b60405180910390a150565b6013546101009004600160a060020a031633146117045760405160e560020a62461bcd02815260040161022e90614771565b6013805474ffffffffffffffffffffffffffffffffffffffff0019169055565b6000908152600e602052604090205490565b600a54600b54600c54600954600d54600160a060020a03948516959385169492831693918316921690565b6000606061176d612d13565b60145460009060a060020a900460ff161561179d5760405160e560020a62461bcd02815260040161022e90614741565b6117a68d612884565b8094508195505050610100604051908101604052808f6000191681526020018e6000191681526020018d81526020018c81526020018b81526020018a600160a060020a0316815260200189600160a060020a031681526020016000600160a060020a0316600560070160009054906101000a9004600160a060020a0316600160a060020a03161461184257600c54600160a060020a0316611854565b6013546101009004600160a060020a03165b600160a060020a031690526040517f60b10a2900000000000000000000000000000000000000000000000000000000815290925073990825c5d894385f1c5bd36b6427c5336d984e07906360b10a29906112b59060059086906004016147d1565b601454600160a060020a03163314156118ff5760145460138054600160a060020a039092166101000274ffffffffffffffffffffffffffffffffffffffff00199092169190911790555b565b600061191481848463ffffffff612ab716565b90505b92915050565b6013546101009004600160a060020a031681565b6060600083839050604051908082528060200260200182016040528015611962578160200160208202803883390190505b509150600090505b828110156119b8576018600085858481811061198257fe5b9050602002013581526020019081526020016000205482828151811015156119a657fe5b6020908102909101015260010161196a565b5092915050565b601754600160a060020a031633146119ec5760405160e560020a62461bcd02815260040161022e906147a1565b611a6085858080601f0160208091040260200160405190810160405280939291908181526020018383808284375050604080516020601f8b0181900481028201810190925289815294508993508892508291508401838280828437506000969594508893505063ffffffff612b8016915050565b5050505050565b60006060611a73612d57565b60145460009060a060020a900460ff1615611aa35760405160e560020a62461bcd02815260040161022e90614741565b611aac8c612884565b809450819550505060e0604051908101604052808e6000191681526020018d6000191681526020018c81526020018b81526020018a815260200189600160a060020a0316815260200188600160a060020a03168152509150736a60b5099b68ac80b28f44eb30894c7d165a72f663972c12ea6005846040518363ffffffff1660e060020a028152600401611b419291906147ed565b60006040518083038186803b158015611b5957600080fd5b505af4158015611b6d573d6000803e3d6000fd5b5050505060026016548e8d8d8d8d8d604051602001611b929796959493929190614945565b6040516020818303038152906040526040518082805190602001908083835b60208310611bd05780518252601f199092019160209182019101611bb1565b51815160209384036101000a600019018019909216911617905260405191909301945091925050808303816000865af1158015611c11573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250611c349190810190613618565b9050611c438482858989612993565b50505050505050505050505050565b6013546101009004600160a060020a03163314611c845760405160e560020a62461bcd02815260040161022e90614771565b6014805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b60115481565b60165481565b611cc7612d92565b60145460a060020a900460ff1615611cf45760405160e560020a62461bcd02815260040161022e90614741565b600b5460405160e160020a634af46b45028152879160009182918291600160a060020a03909116906395e8d68a90611d309087906004016146e5565b606060405180830381600087803b158015611d4a57600080fd5b505af1158015611d5e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611d829190810190613e43565b9194509250905060ff83166005148015611d9c5750814210155b8015611da85750804211155b1515611dc95760405160e560020a62461bcd02815260040161022e90614791565b60008851118015611de25750611ddd612614565b885111155b1515611e035760405160e560020a62461bcd02815260040161022e90614701565b8651885114611e275760405160e560020a62461bcd02815260040161022e90614761565b610100604051908101604052808b6000191681526020018a81526020018981526020018881526020016016548152602001601860008c8152602001908152602001600020548152602001878152602001611e7f61278b565b600160a060020a031690526040517f3b737991000000000000000000000000000000000000000000000000000000008152909550736a60b5099b68ac80b28f44eb30894c7d165a72f690633b73799190611ee090600590899060040161484d565b60006040518083038186803b158015611ef857600080fd5b505af41580156113e8573d6000803e3d6000fd5b60145460a060020a900460ff1681565b60006060611f28612de4565b60145460009060a060020a900460ff1615611f585760405160e560020a62461bcd02815260040161022e90614741565b611f618d612884565b8094508195505050610100604051908101604052808f6000191681526020018e6000191681526020018d81526020018c81526020018b81526020018a815260200189600160a060020a0316815260200188600160a060020a03168152509150736a60b5099b68ac80b28f44eb30894c7d165a72f663dbd9a2b56005846040518363ffffffff1660e060020a028152600401611ffd9291906147b1565b60006040518083038186803b15801561201557600080fd5b505af4158015612029573d6000803e3d6000fd5b5050505060026016548f8e8e8e8e8e8e6040516020016120509897969594939291906149af565b6040516020818303038152906040526040518082805190602001908083835b6020831061208e5780518252601f19909201916020918201910161206f565b51815160209384036101000a600019018019909216911617905260405191909301945091925050808303816000865af11580156120cf573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052506120f29190810190613618565b90506113e88482858989612993565b7fbc197c810000000000000000000000000000000000000000000000000000000095945050505050565b6000828152601860205260408082205460165491517fc921ea930000000000000000000000000000000000000000000000000000000081528392736a60b5099b68ac80b28f44eb30894c7d165a72f69263c921ea9392612197926005928a929091908a9060040161488d565b604080518083038186803b1580156121ae57600080fd5b505af41580156121c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506121e691908101906134a3565b95945050505050565b601454600160a060020a031681565b601754600090600160a060020a0316331461222e5760405160e560020a62461bcd02815260040161022e906147a1565b5060005b81518110156109ed57818181518110151561224957fe5b90602001906020020151604001516005600a016000848481518110151561226c57fe5b906020019060200201516000015181526020019081526020016000206000848481518110151561229857fe5b906020019060200201516020015181526020019081526020016000208190555081818151811015156122c657fe5b90602001906020020151606001516005600b01600084848151811015156122e957fe5b906020019060200201516000015181526020019081526020016000206000848481518110151561231557fe5b9060200190602002015160200151815260200190815260200160002081905550818181518110151561234357fe5b9060200190602002015160200151828281518110151561235f57fe5b90602001906020020151600001517f2c40e30353ae48a032fd20f1fece20031c1b80a2bc8512a2c172ff4de2e59519848481518110151561239c57fe5b906020019060200201516040015185858151811015156123b857fe5b90602001906020020151606001516040516123d4929190614a8a565b60405180910390a3600101612232565b6123ec612e27565b60145460a060020a900460ff16156124195760405160e560020a62461bcd02815260040161022e90614741565b600b5460405160e160020a634af46b45028152889160009182918291600160a060020a03909116906395e8d68a906124559087906004016146e5565b606060405180830381600087803b15801561246f57600080fd5b505af1158015612483573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506124a79190810190613e43565b9194509250905060ff831660051480156124c15750814210155b80156124cd5750804211155b15156124ee5760405160e560020a62461bcd02815260040161022e90614791565b600089511180156125075750612502612614565b895111155b15156125285760405160e560020a62461bcd02815260040161022e90614701565b875189511461254c5760405160e560020a62461bcd02815260040161022e90614761565b610120604051908101604052808c6000191681526020018b81526020018a81526020018981526020016016548152602001601860008d815260200190815260200160002054815260200188600160a060020a031681526020018781526020016125b361278b565b600160a060020a031690526040517f06528fbc000000000000000000000000000000000000000000000000000000008152909550736a60b5099b68ac80b28f44eb30894c7d165a72f6906306528fbc90610bd690600590899060040161480d565b6000601954600014156126295750601461163a565b5060195490565b60125481565b601754600160a060020a031633146126635760405160e560020a62461bcd02815260040161022e906147a1565b60165415156126725760168190555b50565b601754600160a060020a031633146126a25760405160e560020a62461bcd02815260040161022e906147a1565b600082815260186020526040908190208290555182907fdfa3e1a2556a2caf7af0a1cb98a9eed056ae433c4e109e3398edff9863d45bf5906126e59084906146e5565b60405180910390a25050565b7ff23a6e610000000000000000000000000000000000000000000000000000000095945050505050565b6013546101009004600160a060020a0316331461274d5760405160e560020a62461bcd02815260040161022e90614771565b6014805491151560a060020a0274ff000000000000000000000000000000000000000019909216919091179055565b601754600160a060020a031681565b600c54600090600160a060020a031680156127a657806127b8565b6013546101009004600160a060020a03165b91505090565b82600001826040518082805190602001908083835b602083106127f25780518252601f1990920191602091820191016127d3565b51815160209384036101000a6000190180199092169116179052920194855250604051938490038101842085519094869450925082918401908083835b6020831061284e5780518252601f19909201916020918201910161282f565b51815160209384036101000a60001901801990921691161790529201948552506040519384900301909220600090555050505050565b600b546040517f44cefb69000000000000000000000000000000000000000000000000000000008152600091606091839182918291600160a060020a0316906344cefb69906128d79089906004016146e5565b600060405180830381600087803b1580156128f157600080fd5b505af1158015612905573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261292d9190810190613b71565b949e50919c50969a5098509096506005955061294a945050505050565b60ff168360ff1614801561295e5750814210155b801561296a5750804211155b151561298b5760405160e560020a62461bcd02815260040161022e90614791565b505050915091565b6000806000806129a4876000612c48565b93506129b1876020612c48565b92506129be866000612c48565b91506129cb866020612c48565b9050600560080160009054906101000a9004600160a060020a0316600160a060020a0316634587b7b48a87878787878f6040518863ffffffff1660e060020a028152600401612a2097969594939291906148dd565b602060405180830381600087803b158015612a3a57600080fd5b505af1158015612a4e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612a7291908101906135dc565b1515612a935760405160e560020a62461bcd02815260040161022e90614751565b505050505050505050565b600082820183811015612ab057600080fd5b9392505050565b600083600001836040518082805190602001908083835b60208310612aed5780518252601f199092019160209182019101612ace565b51815160209384036101000a6000190180199092169116179052920194855250604051938490038101842086519094879450925082918401908083835b60208310612b495780518252601f199092019160209182019101612b2a565b51815160209384036101000a6000190180199092169116179052920194855250604051938490030190922054925050509392505050565b8084600001846040518082805190602001908083835b60208310612bb55780518252601f199092019160209182019101612b96565b51815160209384036101000a6000190180199092169116179052920194855250604051938490038101842087519094889450925082918401908083835b60208310612c115780518252601f199092019160209182019101612bf2565b51815160209384036101000a6000190180199092169116179052920194855250604051938490030190922092909255505050505050565b016020015190565b604080518082019091526000808252602082015290565b60e0604051908101604052806000801916815260200160008152602001600081526020016000815260200160008152602001606081526020016000600160a060020a031681525090565b610120604051908101604052806000801916815260200160008152602001600081526020016000815260200160008152602001600081526020016000600160a060020a03168152602001606081526020016000600160a060020a031681525090565b6040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081019190915290565b6040805160e0810182526000808252602082018190529181018290526060808201819052608082015260a0810182905260c081019190915290565b61010060405190810160405280600080191681526020016000815260200160608152602001606081526020016000815260200160008152602001606081526020016000600160a060020a031681525090565b604080516101008101825260008082526020820181905291810182905260608082018190526080820181905260a082015260c0810182905260e081019190915290565b610120604051908101604052806000801916815260200160008152602001606081526020016060815260200160008152602001600081526020016000600160a060020a03168152602001606081526020016000600160a060020a031681525090565b60006119148235614b1f565b60006119148251614b1f565b600080601f83018413612eb357600080fd5b50813567ffffffffffffffff811115612ecb57600080fd5b602083019150836020820283011115612ee357600080fd5b9250929050565b6000601f82018313612efb57600080fd5b8135612f0e612f0982614acc565b614aa5565b91508181835260208401935060208101905083856040840282011115612f3357600080fd5b60005b83811015612f615781612f4988826131c6565b84525060209092019160409190910190600101612f36565b5050505092915050565b6000601f82018313612f7c57600080fd5b8135612f8a612f0982614acc565b91508181835260208401935060208101905083856080840282011115612faf57600080fd5b60005b83811015612f615781612fc5888261320d565b84525060209092019160809190910190600101612fb2565b6000601f82018313612fee57600080fd5b8135612ffc612f0982614acc565b9150818183526020840193506020810190508385604084028201111561302157600080fd5b60005b83811015612f61578161303788826131c6565b84525060209092019160409190910190600101613024565b6000601f8201831361306057600080fd5b813561306e612f0982614acc565b9150818183526020840193506020810190508385602084028201111561309357600080fd5b60005b83811015612f6157816130a988826130d7565b8452506020928301929190910190600101613096565b60006119148235614b2b565b60006119148251614b2b565b6000611914823561163a565b6000611914825161163a565b600080601f8301841361310157600080fd5b50813567ffffffffffffffff81111561311957600080fd5b602083019150836001820283011115612ee357600080fd5b6000601f8201831361314257600080fd5b8135613150612f0982614aed565b9150808252602083016020830185838301111561316c57600080fd5b613177838284614b5b565b50505092915050565b6000601f8201831361319157600080fd5b815161319f612f0982614aed565b915080825260208301602083018583830111156131bb57600080fd5b613177838284614b67565b6000604082840312156131d857600080fd5b6131e26040614aa5565b905060006131f084846130d7565b8252506020613201848483016130d7565b60208301525092915050565b60006080828403121561321f57600080fd5b6132296080614aa5565b9050600061323784846130d7565b8252506020613248848483016130d7565b602083015250604061325c848285016130d7565b6040830152506060613270848285016130d7565b60608301525092915050565b60006119148251614b55565b60006020828403121561329a57600080fd5b60006132a68484612e89565b949350505050565b600080600080600060a086880312156132c657600080fd5b60006132d28888612e89565b95505060206132e388828901612e89565b94505060406132f488828901612e89565b935050606061330588828901612e89565b925050608061331688828901612e89565b9150509295509295909350565b600080600080600060a0868803121561333b57600080fd5b60006133478888612e89565b955050602061335888828901612e89565b945050604086013567ffffffffffffffff81111561337557600080fd5b6133818882890161304f565b935050606086013567ffffffffffffffff81111561339e57600080fd5b6133aa8882890161304f565b925050608086013567ffffffffffffffff8111156133c757600080fd5b61331688828901613131565b600080600080608085870312156133e957600080fd5b60006133f58787612e89565b945050602061340687828801612e89565b9350506040613417878288016130d7565b925050606085013567ffffffffffffffff81111561343457600080fd5b61344087828801613131565b91505092959194509250565b600080600080600060a0868803121561346457600080fd5b60006134708888612e89565b955050602061348188828901612e89565b9450506040613492888289016130d7565b93505060606133aa888289016130d7565b600080604083850312156134b657600080fd5b60006134c28585612e95565b92505060206134d3858286016130e3565b9150509250929050565b600080602083850312156134f057600080fd5b823567ffffffffffffffff81111561350757600080fd5b61351385828601612ea1565b92509250509250929050565b60006020828403121561353157600080fd5b813567ffffffffffffffff81111561354857600080fd5b6132a684828501612eea565b60006020828403121561356657600080fd5b813567ffffffffffffffff81111561357d57600080fd5b6132a684828501612f6b565b60006020828403121561359b57600080fd5b813567ffffffffffffffff8111156135b257600080fd5b6132a684828501612fdd565b6000602082840312156135d057600080fd5b60006132a684846130bf565b6000602082840312156135ee57600080fd5b60006132a684846130cb565b60006020828403121561360c57600080fd5b60006132a684846130d7565b60006020828403121561362a57600080fd5b60006132a684846130e3565b60008060008060008060008060006101208a8c03121561365557600080fd5b60006136618c8c6130d7565b99505060206136728c828d016130d7565b98505060406136838c828d016130d7565b97505060608a013567ffffffffffffffff8111156136a057600080fd5b6136ac8c828d0161304f565b96505060808a013567ffffffffffffffff8111156136c957600080fd5b6136d58c828d0161304f565b95505060a06136e68c828d01612e89565b94505060c06136f78c828d01612e89565b93505060e08a013567ffffffffffffffff81111561371457600080fd5b6137208c828d01613131565b9250506101006137328c828d016130d7565b9150509295985092959850929598565b6000806000806000806000806000806101408b8d03121561376257600080fd5b600061376e8d8d6130d7565b9a5050602061377f8d828e016130d7565b99505060406137908d828e016130d7565b98505060608b013567ffffffffffffffff8111156137ad57600080fd5b6137b98d828e0161304f565b97505060808b013567ffffffffffffffff8111156137d657600080fd5b6137e28d828e0161304f565b96505060a08b013567ffffffffffffffff8111156137ff57600080fd5b61380b8d828e01613131565b95505060c061381c8d828e01612e89565b94505060e061382d8d828e01612e89565b9350506101008b013567ffffffffffffffff81111561384b57600080fd5b6138578d828e01613131565b9250506101206138698d828e016130d7565b9150509295989b9194979a5092959850565b6000806000806000806000806000806101208b8d03121561389b57600080fd5b60006138a78d8d6130d7565b9a505060206138b88d828e016130d7565b99505060406138c98d828e016130d7565b98505060606138da8d828e016130d7565b97505060806138eb8d828e016130d7565b96505060a06138fc8d828e01612e89565b95505060c061390d8d828e01612e89565b94505060e08b013567ffffffffffffffff81111561392a57600080fd5b6139368d828e016130ef565b93509350506101006138698d828e016130d7565b60008060008060008060c0878903121561396357600080fd5b600061396f89896130d7565b965050602061398089828a016130d7565b955050604087013567ffffffffffffffff81111561399d57600080fd5b6139a989828a0161304f565b945050606087013567ffffffffffffffff8111156139c657600080fd5b6139d289828a0161304f565b93505060806139e389828a01612e89565b92505060a087013567ffffffffffffffff811115613a0057600080fd5b613a0c89828a01613131565b9150509295509295509295565b600080600080600060a08688031215613a3157600080fd5b6000613a3d88886130d7565b9550506020613358888289016130d7565b600080600080600060808688031215613a6657600080fd5b6000613a7288886130d7565b9550506020613a83888289016130d7565b9450506040613a94888289016130d7565b935050606086013567ffffffffffffffff811115613ab157600080fd5b613abd888289016130ef565b92509250509295509295909350565b600080600080600080600060c0888a031215613ae757600080fd5b6000613af38a8a6130d7565b9750506020613b048a828b016130d7565b9650506040613b158a828b016130d7565b9550506060613b268a828b016130d7565b9450506080613b378a828b01612e89565b93505060a088013567ffffffffffffffff811115613b5457600080fd5b613b608a828b016130ef565b925092505092959891949750929550565b60008060008060008060008060008060006101608c8e031215613b9357600080fd5b6000613b9f8e8e6130e3565b9b50506020613bb08e828f0161327c565b9a50506040613bc18e828f016130e3565b9950506060613bd28e828f016130e3565b9850506080613be38e828f016130e3565b97505060a0613bf48e828f016130e3565b96505060c0613c058e828f016130e3565b95505060e08c015167ffffffffffffffff811115613c2257600080fd5b613c2e8e828f01613180565b9450506101008c015167ffffffffffffffff811115613c4c57600080fd5b613c588e828f01613180565b935050610120613c6a8e828f016130e3565b925050610140613c7c8e828f016130e3565b9150509295989b509295989b9093969950565b60008060008060408587031215613ca557600080fd5b843567ffffffffffffffff811115613cbc57600080fd5b613cc8878288016130ef565b9450945050602085013567ffffffffffffffff811115613ce757600080fd5b613cf3878288016130ef565b95989497509550505050565b600080600080600060608688031215613d1757600080fd5b853567ffffffffffffffff811115613d2e57600080fd5b613d3a888289016130ef565b9550955050602086013567ffffffffffffffff811115613d5957600080fd5b613d65888289016130ef565b93509350506040613316888289016130d7565b60008060408385031215613d8b57600080fd5b823567ffffffffffffffff811115613da257600080fd5b613dae85828601613131565b925050602083013567ffffffffffffffff811115613dcb57600080fd5b6134d385828601613131565b600060408284031215613de957600080fd5b60006132a684846131c6565b600060808284031215613e0757600080fd5b60006132a6848461320d565b60008060408385031215613e2657600080fd5b6000613e3285856130d7565b92505060206134d3858286016130d7565b600080600060608486031215613e5857600080fd5b6000613e64868661327c565b9350506020613e75868287016130e3565b9250506040613e86868287016130e3565b9150509250925092565b613e9981614b1f565b82525050565b6000613eaa82614b1b565b808452602084019350613ebc83614b15565b60005b82811015613eec57613ed28683516141f4565b613edb82614b15565b604096909601959150600101613ebf565b5093949350505050565b6000613f0182614b1b565b808452602084019350613f1383614b15565b60005b82811015613eec57613f29868351613f99565b613f3282614b15565b602096909601959150600101613f16565b6000613f4e82614b1b565b808452602084019350613f6083614b15565b60005b82811015613eec57613f76868351613f99565b613f7f82614b15565b602096909601959150600101613f63565b613e9981614b2b565b613e998161163a565b613e9981614b30565b6000613fb682614b1b565b808452613fca816020860160208601614b67565b613fd381614b93565b9093016020019392505050565b600e81527f496e76616c6964206c656e677468000000000000000000000000000000000000602082015260400190565b601481527f506172616d6574657220697320696e76616c6964000000000000000000000000602082015260400190565b601f81527f696d706c656d656e746174696f6e20636f6e7472616374206e6f742073657400602082015260400190565b601d81527f4e6577206f776e657220697320746865207a65726f2061646472657373000000602082015260400190565b601881527f536d61727420636f6e74726163742069732068616c7465640000000000000000602082015260400190565b601d81527f5369676e617475726520766572696669636174696f6e206661696c6564000000602082015260400190565b600f81527f4c656e677468206d69736d617463680000000000000000000000000000000000602082015260400190565b600981527f4e6f74206f776e65720000000000000000000000000000000000000000000000602082015260400190565b601381527f696e76616c696420736d6746656550726f787900000000000000000000000000602082015260400190565b600f81527f504b206973206e6f742072656164790000000000000000000000000000000000602082015260400190565b600981527f6e6f742061646d696e0000000000000000000000000000000000000000000000602082015260400190565b9052565b805160408301906142058482613f99565b50602082015161108a6020850182613f99565b805160009061010084019061422d8582613f99565b5060208301516142406020860182613f99565b5060408301516142536040860182613f99565b506060830151848203606086015261426b8282613f43565b915050608083015184820360808601526142858282613f43565b91505060a083015184820360a086015261429f8282613fab565b91505060c08301516142b460c0860182613e90565b5060e08301516142c760e0860182613e90565b509392505050565b80516101008301906142e18482613f99565b5060208201516142f46020850182613f99565b5060408201516143076040850182613f99565b50606082015161431a6060850182613f99565b50608082015161432d6080850182613f99565b5060a082015161434060a0850182613e90565b5060c082015161435360c0850182613e90565b5060e082015161108a60e0850182613e90565b805160009060e084019061437a8582613f99565b50602083015161438d6020860182613f99565b5060408301516143a06040860182613f99565b50606083015184820360608601526143b88282613f43565b915050608083015184820360808601526143d28282613f43565b91505060a08301516143e760a0860182613e90565b5060c08301516142c760c0860182613e90565b805160009061012084019061440f8582613f99565b5060208301516144226020860182613f99565b506040830151848203604086015261443a8282613f43565b915050606083015184820360608601526144548282613f43565b91505060808301516144696080860182613f99565b5060a083015161447c60a0860182613f99565b5060c083015161448f60c0860182613e90565b5060e083015184820360e08601526144a78282613fab565b9150506101008301516142c7610100860182613e90565b80516000906101208401906144d38582613f99565b5060208301516144e66020860182613f99565b5060408301516144f96040860182613f99565b50606083015161450c6060860182613f99565b5060808301516144696080860182613f99565b80516000906101008401906145348582613f99565b5060208301516145476020860182613f99565b506040830151848203604086015261455f8282613f43565b915050606083015184820360608601526145798282613f43565b915050608083015161458e6080860182613f99565b5060a08301516145a160a0860182613f99565b5060c083015184820360c08601526145b98282613fab565b91505060e08301516142c760e0860182613e90565b805160009060e08401906145e28582613f99565b5060208301516145f56020860182613f99565b5060408301516146086040860182613f99565b50606083015161461b6060860182613f99565b50608083015161462e6080860182613f99565b5060a083015184820360a08601526146468282613fab565b91505060c08301516142c760c0860182613e90565b602081016119178284613e90565b60a081016146778288613e90565b6146846020830187613e90565b6146916040830186613e90565b61469e6060830185613e90565b6146ab6080830184613e90565b9695505050505050565b602080825281016119148184613e9f565b602080825281016119148184613ef6565b602081016119178284613f90565b602081016119178284613f99565b602081016119178284613fa2565b6020808252810161191781613fe0565b6020808252810161191781614010565b6020808252810161191781614040565b6020808252810161191781614070565b60208082528101611917816140a0565b60208082528101611917816140d0565b6020808252810161191781614100565b6020808252810161191781614130565b6020808252810161191781614160565b6020808252810161191781614190565b60208082528101611917816141c0565b604081016147bf82856141f0565b81810360208301526132a68184614218565b61012081016147e082856141f0565b612ab060208301846142cf565b604081016147fb82856141f0565b81810360208301526132a68184614366565b6040810161481b82856141f0565b81810360208301526132a681846143fa565b6040810161483b82856141f0565b81810360208301526132a681846144be565b6040810161485b82856141f0565b81810360208301526132a6818461451f565b6040810161487b82856141f0565b81810360208301526132a681846145ce565b60a0810161489b82886141f0565b6148a86020830187613f99565b6148b56040830186613f99565b6148c26060830185613f99565b6146ab6080830184613f99565b6040810161191782846141f4565b60e081016148eb828a613f99565b6148f86020830189613f99565b6149056040830188613f99565b6149126060830187613f99565b61491f6080830186613f99565b61492c60a0830185613f99565b61493960c0830184613f99565b98975050505050505050565b60e08101614953828a613f99565b6149606020830189613f99565b61496d6040830188613f99565b818103606083015261497f8187613ef6565b905081810360808301526149938186613ef6565b90506149a260a0830185613e90565b61493960c0830184613e90565b61010081016149be828b613f99565b6149cb602083018a613f99565b6149d86040830189613f99565b81810360608301526149ea8188613ef6565b905081810360808301526149fe8187613ef6565b905081810360a0830152614a128186613fab565b9050614a2160c0830185613e90565b614a2e60e0830184613e90565b9998505050505050505050565b60e08101614a49828a613f99565b614a566020830189613f99565b614a636040830188613f99565b614a706060830187613f99565b614a7d6080830186613f99565b6149a260a0830185613e90565b60408101614a988285613f99565b612ab06020830184613f99565b60405181810167ffffffffffffffff81118282101715614ac457600080fd5b604052919050565b600067ffffffffffffffff821115614ae357600080fd5b5060209081020190565b600067ffffffffffffffff821115614b0457600080fd5b506020601f91909101601f19160190565b60200190565b5190565b600160a060020a031690565b151590565b7fffffffff000000000000000000000000000000000000000000000000000000001690565b60ff1690565b82818337506000910152565b60005b83811015614b82578181015183820152602001614b6a565b8381111561108a5750506000910152565b601f01601f1916905600a265627a7a72305820f2bc84465e5a52aaccfb3f929bfb7a3f77e3fb0269d9690d437f40b6eab310d66c6578706572696d656e74616cf50037

Library Used




Deployed ByteCode Sourcemap

89994:25088:0:-;;;;;;;;;-1:-1:-1;;;89994:25088:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1349:15;;-1:-1:-1;;;;;1349:15:0;1383:19;;;1375:63;;;;-1:-1:-1;;;;;1375:63:0;;;;;;;;;;;;;;;;;1492:4;1486:11;1532:12;1529:1;1524:3;1511:34;1620:1;1617;1603:12;1598:3;1591:5;1586:3;1573:49;1648:14;1699:4;1696:1;1691:3;1676:28;1727:6;1747:28;;;;1811:4;1806:3;1799:17;1747:28;1768:4;1763:3;1756:17;100959:778;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;100959:778:0;;;;;;;;;;;103424:261;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;103424:261:0;;;;;;;;;;;;;;;;;;;;;;;;;109985:203;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;109985:203:0;;;;;;;;;;;;;;;;;99550:313;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;99550:313:0;;;;;;;;;92681:645;;;;;;;;;;114427:129;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;114427:129:0;;;;;;;;;103926:417;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;103926:417:0;;;;;;;;;;;;;;;;;104585:158;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;104585:158:0;;;;;;;;;;;;;;;;;93749:736;;;;;;;;;;100328:128;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;100328:128:0;;;;;;;;;3470:225;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;3470:225:0;;;;;;;;;95159:969;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;95159:969:0;;;;;;;;;101910:724;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;101910:724:0;;;;;;;;;97961:337;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;97961:337:0;;;;;;;;;1188:97;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1188:97:0;;;;;;;;;;;;100029:136;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;100029:136:0;;;;;;;;;4168:83;;8:9:-1;5:2;;;30:1;27;20:12;5:2;4168:83:0;;;;103060:125;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;103060:125:0;;;;;;;;;105802:445;;8:9:-1;5:2;;;30:1;27;20:12;5:2;105802:445:0;;;;;;;;;;;;;;;;96810:981;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;96810:981:0;;;;;;;;;4037:123;;8:9:-1;5:2;;;30:1;27;20:12;5:2;4037:123:0;;;;102672:136;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;102672:136:0;;;;;;;;;3269:20;;8:9:-1;5:2;;;30:1;27;20:12;5:2;3269:20:0;;;;104995:307;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;104995:307:0;;;;;;;;;;;;;;;;;100173:147;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;100173:147:0;;;;;;;;;113479:940;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;113479:940:0;;;;;;;;;3933:96;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;3933:96:0;;;;;;;;;43900:38;;8:9:-1;5:2;;;30:1;27;20:12;5:2;43900:38:0;;;;45672:29;;8:9:-1;5:2;;;30:1;27;20:12;5:2;45672:29:0;;;;110636:883;;;;;;;;;;5306:26;;8:9:-1;5:2;;;30:1;27;20:12;5:2;5306:26:0;;;;;;;;;;;;112488:983;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;112488:983:0;;;;;;;;;110402:224;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;110402:224:0;;;;;;;;;114749:330;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;114749:330:0;;;;;;;;;3438:23;;8:9:-1;5:2;;;30:1;27;20:12;5:2;3438:23:0;;;;98470:457;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;98470:457:0;;;;;;;;;111531:949;;;;;;;;;;114564:177;;8:9:-1;5:2;;;30:1;27;20:12;5:2;114564:177:0;;;;44192:47;;8:9:-1;5:2;;;30:1;27;20:12;5:2;44192:47:0;;;;99871:150;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;99871:150:0;;;;;;;;;99158:212;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;99158:212:0;;;;;;;;;110196:198;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;110196:198:0;;;;;;;;;5664:100;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;5664:100:0;;;;;;;;;45708:20;;8:9:-1;5:2;;;30:1;27;20:12;5:2;45708:20:0;;;;100959:778;3222:5;;;;;-1:-1:-1;;;;;3222:5:0;3208:10;:19;3200:41;;;;-1:-1:-1;;;;;3200:41:0;;;;;;;;;-1:-1:-1;;;;;101307:26:0;;;;;;:57;;-1:-1:-1;;;;;;101337:27:0;;;;101307:57;:86;;;;-1:-1:-1;;;;;;101368:25:0;;;;101307:86;101299:132;;;;;;-1:-1:-1;;;;;101299:132:0;;;;;;;;;101444:25;:57;;-1:-1:-1;;101444:57:0;;;-1:-1:-1;;;;;101444:57:0;;;;;;;101512:24;:54;;;;;;;;;;;;;;101624:23;:37;;;;;;;;;;;;;;-1:-1:-1;101672:23:0;:57;;;;;;;;;;100959:778::o;103424:261::-;103480:17;;:::i;:::-;103555:16;;103528:44;;;;:26;:44;;;;;;;;103573:17;;;;;103528:63;;;;;;;;;103510:81;;103641:16;;103617:41;;:23;:41;;;;;103659:17;;103617:60;;;;;;;;;103602:12;;;:75;;;;103510:3;103424:261::o;109985:203::-;110150:30;109985:203;;;;;;:::o;99550:313::-;91650:5;;99642:6;;-1:-1:-1;;;;;91650:5:0;91636:10;:19;91628:41;;;;-1:-1:-1;;;;;91628:41:0;;;;;;;;;-1:-1:-1;99651:1:0;99637:219;99658:6;:13;99654:1;:17;99637:219;;;99742:6;99749:1;99742:9;;;;;;;;;;;;;;;;;;:21;;;99693:23;:46;99717:6;99724:1;99717:9;;;;;;;;;;;;;;;;;;;;:21;99693:46;;;;;;;;;;99717:21;99693:46;:70;99799:9;;:6;;99806:1;;99799:9;;;;;;;;;;;;;;:21;;;99783:61;99822:6;99829:1;99822:9;;;;;;;;;;;;;;;;;;:21;;;99783:61;;;;;;;;;;;;;;;99673:3;;99637:219;;;99550:313;;:::o;92681:645::-;92846:19;92897:50;;:::i;:::-;5382:6;;-1:-1:-1;;;5382:6:0;;;;5381:7;5373:44;;;;-1:-1:-1;;;;;5373:44:0;;;;;;;;;91998:25;;:55;;-1:-1:-1;;;;;91998:55:0;;92823:5;;91898:12;;;;;;-1:-1:-1;;;;;91998:25:0;;;;:48;;:55;;92823:5;;91998:55;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;91998:55:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;91998:55:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;91998:55:0;;;;;;;;;91969:84;;-1:-1:-1;91969:84:0;-1:-1:-1;91969:84:0;-1:-1:-1;92074:34:0;;;92090:17;92074:34;:54;;;;;92119:9;92112:3;:16;;92074:54;:72;;;;;92139:7;92132:3;:14;;92074:72;92066:100;;;;;;-1:-1:-1;;;;;92066:100:0;;;;;;;;;92868:16;:14;:16::i;:::-;92950:314;;;;;;;;;;;;;;;;;;;;;;;;93095:14;;92950:314;;;;-1:-1:-1;93142:36:0;;;:23;:36;;;;;;92950:314;;;;;;;;;;;;;;;;;;;;;;;;92846:38;;-1:-1:-1;92950:314:0;;;;;;93206:11;;;;;;92950:314;;93206:11;;;;92950:314;;-1:-1:-1;;;92950:314:0;;;-1:-1:-1;;;;;;;;92950:314:0;;;;;;;93275:43;;;;;92897:367;;-1:-1:-1;93275:13:0;;:22;;:43;;93298:11;;92897:367;;93275:43;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;93275:43:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;93275:43:0;;;;5428:1;;;;92681:645;;;;;;;:::o;114427:129::-;91650:5;;-1:-1:-1;;;;;91650:5:0;91636:10;:19;91628:41;;;;-1:-1:-1;;;;;91628:41:0;;;;;;;;;114520:12;:28;114427:129::o;103926:417::-;103987:21;104078:6;104048;:13;104028:34;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;104021:41;;104087:1;104078:10;;104073:263;104094:6;:13;104090:1;:17;104073:263;;;104151:11;:26;;:48;104178:6;104185:1;104178:9;;;;;;;;;;;;;;;;;;:20;;;104151:48;;;;;;;;;;;:71;104200:6;104207:1;104200:9;;;;;;;;;;;;;;;;;;:21;;;104151:71;;;;;;;;;;;;104129:4;104134:1;104129:7;;;;;;;;;;;;;;;;;;;:93;104280:9;;104256:23;;104129:19;;104280:6;;104287:1;;104280:9;;;;;;;;;;;;;;:20;;;104256:45;;;;;;;;;;;:68;104302:6;104309:1;104302:9;;;;;;;;;;;;;;;;;;:21;;;104256:68;;;;;;;;;;;;104237:4;104242:1;104237:7;;;;;;;;;;;;;;;;;;;;:16;:87;104109:3;;104073:263;;;103926:417;;;;:::o;104585:158::-;104653:19;104699:36;;;:23;:36;;;;;;;104585:158::o;93749:736::-;93946:19;93997:50;;:::i;:::-;5382:6;;-1:-1:-1;;;5382:6:0;;;;5381:7;5373:44;;;;-1:-1:-1;;;;;5373:44:0;;;;;;;;;91998:25;;:55;;-1:-1:-1;;;;;91998:55:0;;93923:5;;91898:12;;;;;;-1:-1:-1;;;;;91998:25:0;;;;:48;;:55;;93923:5;;91998:55;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;91998:55:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;91998:55:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;91998:55:0;;;;;;;;;91969:84;;-1:-1:-1;91969:84:0;-1:-1:-1;91969:84:0;-1:-1:-1;92074:34:0;;;92090:17;92074:34;:54;;;;;92119:9;92112:3;:16;;92074:54;:72;;;;;92139:7;92132:3;:14;;92074:72;92066:100;;;;;;-1:-1:-1;;;;;92066:100:0;;;;;;;;;93968:16;:14;:16::i;:::-;93946:38;;94050:373;;;;;;;;;94105:5;94050:373;;;;;;;94134:11;94050:373;;;;94163:5;94050:373;;;;94214:14;;94050:373;;;;94184:3;94050:373;;;;94261:23;:36;94285:11;94261:36;;;;;;;;;;;;94050:373;;;;94325:12;-1:-1:-1;;;;;94050:373:0;;;;;94365:11;;94050:373;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;94050:373:0;;;-1:-1:-1;;;;;;;;94050:373:0;;;;;;;94434:43;;;;;93997:426;;-1:-1:-1;94434:13:0;;:22;;:43;;94457:11;;93997:426;;94434:43;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;94434:43:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;94434:43:0;;;;5428:1;;;;93749:736;;;;;;;;;:::o;100328:128::-;91650:5;;-1:-1:-1;;;;;91650:5:0;91636:10;:19;91628:41;;;;-1:-1:-1;;;;;91628:41:0;;;;;;;;;100414:34;100434:3;;100414:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;100414:34:0;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;100439:8:0;;-1:-1:-1;100439:8:0;;-1:-1:-1;100439:8:0;;-1:-1:-1;100414:34:0;;100439:8;;;;100414:34;;-1:-1:-1;100414:8:0;;:34;;-1:-1:-1;;100414:34:0;:19;:34;;-1:-1:-1;;;100414:34:0:i;:::-;100328:128;;;;:::o;3470:225::-;3222:5;;;;;-1:-1:-1;;;;;3222:5:0;3208:10;:19;3200:41;;;;-1:-1:-1;;;;;3200:41:0;;;;;;;;;-1:-1:-1;;;;;3548:23:0;;;;3540:65;;;;-1:-1:-1;;;;;3540:65:0;;;;;;;;;3642:5;;3621:38;;-1:-1:-1;;;;;3621:38:0;;;;3642:5;;;;;3621:38;;;;;3670:5;:17;;-1:-1:-1;;;;;3670:17:0;;;;;-1:-1:-1;;3670:17:0;;;;;;;;;3470:225::o;95159:969::-;95357:12;95380:15;95461:49;;:::i;:::-;5382:6;;95956:13;;-1:-1:-1;;;5382:6:0;;;;5381:7;5373:44;;;;-1:-1:-1;;;;;5373:44:0;;;;;;;;;95422:26;95442:5;95422:19;:26::i;:::-;95406:42;;;;;;;;95513:377;;;;;;;;;95570:8;95513:377;;;;;;;95596:5;95513:377;;;;;;;95625:11;95513:377;;;;95654:5;95513:377;;;;95675:3;95513:377;;;;95707:12;-1:-1:-1;;;;;95513:377:0;;;;;95747:11;-1:-1:-1;;;;;95513:377:0;;;;;95818:1;-1:-1:-1;;;;;95783:37:0;:11;:23;;;;;;;;;;-1:-1:-1;;;;;95783:23:0;-1:-1:-1;;;;;95783:37:0;;95782:73;;95832:23;;-1:-1:-1;;;;;95832:23:0;95782:73;;;95824:5;;;;;-1:-1:-1;;;;;95824:5:0;95782:73;-1:-1:-1;;;;;95513:377:0;;;95901:42;;;;;95461:429;;-1:-1:-1;95901:13:0;;:21;;:42;;95923:11;;95461:429;;95901:42;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;95901:42:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;95901:42:0;;;;95972:96;95990:14;;96006:8;96016:11;96029:5;96036:3;96041:12;96055:11;95979:88;;;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;95979:88:0;;;95972:96;;;;;;;;;;;;;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;-1:-1;;246:30;311:9;;295:26;;;340:21;;377:20;365:33;;95972:96:0;;;;;;;-1:-1:-1;263:2;;-1:-1;;95972:96:0;;;;-1:-1:-1;95972:96:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;95972:96:0;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;95972:96:0;;;;;;;;;95956:112;;96079:41;96095:7;96104:5;96111:2;96115:1;;96079:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;96118:1:0;;-1:-1:-1;96079:15:0;;-1:-1:-1;;;;96079:41:0:i;:::-;95159:969;;;;;;;;;;;;;;:::o;101910:724::-;102047:23;;101980:8;;;;-1:-1:-1;;;;;102047:23:0;101980:8;102085:25;;102081:77;;;102141:5;;;;;-1:-1:-1;;;;;102141:5:0;;-1:-1:-1;102081:77:0;-1:-1:-1;;;;;102176:25:0;;;;102168:57;;;;-1:-1:-1;;;;;102168:57:0;;;;;;;;;-1:-1:-1;102252:1:0;102238:314;102255:17;;;102238:314;;;102307:26;:37;102334:6;;102341:1;102334:9;;;;;;;;;;;;;;;;102307:37;;-1:-1:-1;102307:37:0;;;;;;;;102334:9;102307:37;;;;;-1:-1:-1;102366:26:0;;102393:6;;102400:1;102393:9;;;;;;;;;;;;;;;;102366:37;;-1:-1:-1;102366:37:0;;;;;;;;102393:9;102366:37;;;102359:44;102424:19;:3;102432:10;102424:19;:7;:19;:::i;:::-;102418:25;-1:-1:-1;;;;;;102463:77:0;;102499:15;102488:6;;102495:1;102488:9;;;;;;;;;;;;;;;;102463:77;;;;102529:10;102463:77;;;;;;;;;;;;;;;102274:3;;102238:314;;;102572:1;102566:3;:7;102562:65;;;102590:25;;-1:-1:-1;;;;;102590:20:0;;;:25;;;;;102611:3;;102590:25;;;;102611:3;102590:20;:25;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;102590:25:0;102562:65;101910:724;;;;;;:::o;97961:337::-;91650:5;;-1:-1:-1;;;;;91650:5:0;91636:10;:19;91628:41;;;;-1:-1:-1;;;;;91628:41:0;;;;;;;;;98091:17;;;;;;98052:16;;98025:44;;;;:26;:44;;;;;;;98070:17;;;;;98025:63;;;;;;;;:83;;;;98182:14;;;;;98143:16;;98119:41;;:23;:41;;;;;98161:17;;98119:60;;;;;;;;;:77;98237:17;;98219:16;;98256:17;;98275:14;;98212:78;;98237:17;;98212:78;;;;98256:17;;98275:14;98212:78;;;;;;;;;;97961:337;:::o;1188:97::-;1262:15;;-1:-1:-1;;;;;1262:15:0;1188:97;;:::o;100029:136::-;3222:5;;;;;-1:-1:-1;;;;;3222:5:0;3208:10;:19;3200:41;;;;-1:-1:-1;;;;;3200:41:0;;;;;;;;;100099:5;:20;;-1:-1:-1;;100099:20:0;-1:-1:-1;;;;;100099:20:0;;;;;100135:22;;;;;;100099:20;;100135:22;;;;;;;;;;100029:136;:::o;4168:83::-;3222:5;;;;;-1:-1:-1;;;;;3222:5:0;3208:10;:19;3200:41;;;;-1:-1:-1;;;;;3200:41:0;;;;;;;;;4225:5;:18;;-1:-1:-1;;4225:18:0;;;4168:83::o;103060:125::-;103119:8;103146:31;;;:26;:31;;;;;;;103060:125::o;105802:445::-;106003:24;;106063:25;;106114:23;;106164:17;;106215:23;;-1:-1:-1;;;;;106003:24:0;;;;106063:25;;;;106114:23;;;;106164:17;;;;106215:23;;105802:445::o;96810:981::-;97011:12;97034:15;97115:52;;:::i;:::-;5382:6;;97619:13;;-1:-1:-1;;;5382:6:0;;;;5381:7;5373:44;;;;-1:-1:-1;;;;;5373:44:0;;;;;;;;;97076:26;97096:5;97076:19;:26::i;:::-;97060:42;;;;;;;;97170:380;;;;;;;;;97230:8;97170:380;;;;;;;97256:5;97170:380;;;;;;;97285:11;97170:380;;;;97314:5;97170:380;;;;97335:3;97170:380;;;;97367:12;-1:-1:-1;;;;;97170:380:0;;;;;97407:11;-1:-1:-1;;;;;97170:380:0;;;;;97478:1;-1:-1:-1;;;;;97443:37:0;:11;:23;;;;;;;;;;-1:-1:-1;;;;;97443:23:0;-1:-1:-1;;;;;97443:37:0;;97442:73;;97492:23;;-1:-1:-1;;;;;97492:23:0;97442:73;;;97484:5;;;;;-1:-1:-1;;;;;97484:5:0;97442:73;-1:-1:-1;;;;;97170:380:0;;;97561:45;;;;;97115:435;;-1:-1:-1;97561:13:0;;:24;;:45;;97586:11;;97115:435;;97561:45;;;;4037:123;4100:8;;-1:-1:-1;;;;;4100:8:0;4086:10;:22;4082:71;;;4133:8;;4125:5;:16;;-1:-1:-1;;;;;4133:8:0;;;;4125:16;-1:-1:-1;;4125:16:0;;;;;;;;;4082:71;4037:123::o;102672:136::-;102742:4;102766:34;102742:4;102786:3;102791:8;102766:34;:19;:34;:::i;:::-;102759:41;;102672:136;;;;;:::o;3269:20::-;;;;;;-1:-1:-1;;;;;3269:20:0;;:::o;104995:307::-;105067:23;105168:6;105132:12;;:19;;105118:34;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;105118:34:0;;105103:49;;105177:1;105168:10;;105163:132;105180:23;;;105163:132;;;105243:23;:40;105267:12;;105280:1;105267:15;;;;;;;;;;;;;105243:40;;;;;;;;;;;;105225:12;105238:1;105225:15;;;;;;;;;;;;;;;;;;:58;105205:3;;105163:132;;;104995:307;;;;;:::o;100173:147::-;91650:5;;-1:-1:-1;;;;;91650:5:0;91636:10;:19;91628:41;;;;-1:-1:-1;;;;;91628:41:0;;;;;;;;;100271;100291:3;;100271:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;100271:41:0;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;100296:8:0;;-1:-1:-1;100296:8:0;;-1:-1:-1;100296:8:0;;-1:-1:-1;100271:41:0;;100296:8;;;;100271:41;;-1:-1:-1;100271:8:0;;:41;;-1:-1:-1;100306:5:0;;-1:-1:-1;;100271:41:0;:19;:41;;-1:-1:-1;;100271:41:0:i;:::-;100173:147;;;;;:::o;113479:940::-;113704:12;113727:15;113808:50;;:::i;:::-;5382:6;;114236:13;;-1:-1:-1;;;5382:6:0;;;;5381:7;5373:44;;;;-1:-1:-1;;;;;5373:44:0;;;;;;;;;113769:26;113789:5;113769:19;:26::i;:::-;113753:42;;;;;;;;113861:308;;;;;;;;;113923:8;113861:308;;;;;;;113953:5;113861:308;;;;;;;113986:11;113861:308;;;;114022:8;113861:308;;;;114058:11;113861:308;;;;114102:12;-1:-1:-1;;;;;113861:308:0;;;;;114146:11;-1:-1:-1;;;;;113861:308:0;;;;113808:361;;114180:8;:22;114203:11;114216:6;114180:43;;;;;-1:-1:-1;;;114180:43:0;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;114180:43:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;114180:43:0;;;;114252:107;114270:14;;114286:8;114296:11;114309:8;114319:11;114332:12;114346:11;114259:99;;;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;114259:99:0;;;114252:107;;;;;;;;;;;;;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;-1:-1;;246:30;311:9;;295:26;;;340:21;;377:20;365:33;;114252:107:0;;;;;;;-1:-1:-1;263:2;;-1:-1;;114252:107:0;;;;-1:-1:-1;114252:107:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;114252:107:0;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;114252:107:0;;;;;;;;;114236:123;;114370:41;114386:7;114395:5;114402:2;114406:1;114409;114370:15;:41::i;:::-;113479:940;;;;;;;;;;;;;:::o;3933:96::-;3222:5;;;;;-1:-1:-1;;;;;3222:5:0;3208:10;:19;3200:41;;;;-1:-1:-1;;;;;3200:41:0;;;;;;;;;4001:8;:20;;-1:-1:-1;;4001:20:0;-1:-1:-1;;;;;4001:20:0;;;;;;;;;;3933:96::o;43900:38::-;;;;:::o;45672:29::-;;;;:::o;110636:883::-;111018:48;;:::i;:::-;5382:6;;-1:-1:-1;;;5382:6:0;;;;5381:7;5373:44;;;;-1:-1:-1;;;;;5373:44:0;;;;;;;;;91998:25;;:55;;-1:-1:-1;;;;;91998:55:0;;110820:5;;91898:12;;;;;;-1:-1:-1;;;;;91998:25:0;;;;:48;;:55;;110820:5;;91998:55;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;91998:55:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;91998:55:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;91998:55:0;;;;;;;;;91969:84;;-1:-1:-1;91969:84:0;-1:-1:-1;91969:84:0;-1:-1:-1;92074:34:0;;;92090:17;92074:34;:54;;;;;92119:9;92112:3;:16;;92074:54;:72;;;;;92139:7;92132:3;:14;;92074:72;92066:100;;;;;;-1:-1:-1;;;;;92066:100:0;;;;;;;;;110869:1;110851:8;:15;:19;:59;;;;;110893:17;:15;:17::i;:::-;110874:8;:15;:36;;110851:59;110843:86;;;;;;-1:-1:-1;;;;;110843:86:0;;;;;;;;;110967:18;;110948:15;;:37;110940:65;;;;-1:-1:-1;;;;;110940:65:0;;;;;;;;;111069:390;;;;;;;;;111126:5;111069:390;;;;;;;111159:11;111069:390;;;;111195:8;111069:390;;;;111231:11;111069:390;;;;111273:14;;111069:390;;;;111324:23;:36;111348:11;111324:36;;;;;;;;;;;;111069:390;;;;111392:11;111069:390;;;;111431:16;:14;:16::i;:::-;-1:-1:-1;;;;;111069:390:0;;;111470:41;;;;;111018:441;;-1:-1:-1;111470:8:0;;:20;;:41;;111491:11;;111018:441;;111470:41;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;111470:41:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5306:26:0;;;-1:-1:-1;;;5306:26:0;;;;;:::o;112488:983::-;112725:12;112748:15;112829:47;;:::i;:::-;5382:6;;113279:13;;-1:-1:-1;;;5382:6:0;;;;5381:7;5373:44;;;;-1:-1:-1;;;;;5373:44:0;;;;;;;;;112790:26;112810:5;112790:19;:26::i;:::-;112774:42;;;;;;;;112879:336;;;;;;;;;112938:8;112879:336;;;;;;;112968:5;112879:336;;;;;;;113001:11;112879:336;;;;113037:8;112879:336;;;;113073:11;112879:336;;;;113108:7;112879:336;;;;113148:12;-1:-1:-1;;;;;112879:336:0;;;;;113192:11;-1:-1:-1;;;;;112879:336:0;;;;112829:386;;113228:8;:19;113248:11;113261:6;113228:40;;;;;-1:-1:-1;;;113228:40:0;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;113228:40:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;113228:40:0;;;;113295:116;113313:14;;113329:8;113339:11;113352:8;113362:11;113375:7;113384:12;113398:11;113302:108;;;;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;113302:108:0;;;113295:116;;;;;;;;;;;;;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;-1:-1;;246:30;311:9;;295:26;;;340:21;;377:20;365:33;;113295:116:0;;;;;;;-1:-1:-1;263:2;;-1:-1;;113295:116:0;;;;-1:-1:-1;113295:116:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;113295:116:0;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;113295:116:0;;;;;;;;;113279:132;;113422:41;113438:7;113447:5;113454:2;113458:1;113461;113422:15;:41::i;110402:224::-;110582:36;110402:224;;;;;;;:::o;114749:330::-;114851:4;114978:36;;;:23;:36;;;;;;;115016:14;;114914:130;;;;;114851:4;;114914:8;;:37;;:130;;114952:11;;114965;;114978:36;;115016:14;115032:11;;114914:130;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;114914:130:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;114914:130:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;114914:130:0;;;;;;;;;114896:148;114749:330;-1:-1:-1;;;;;114749:330:0:o;3438:23::-;;;-1:-1:-1;;;;;3438:23:0;;:::o;98470:457::-;91650:5;;98544:6;;-1:-1:-1;;;;;91650:5:0;91636:10;:19;91628:41;;;;-1:-1:-1;;;;;91628:41:0;;;;;;;;;-1:-1:-1;98553:1:0;98539:381;98560:6;:13;98556:1;:17;98539:381;;;98669:6;98676:1;98669:9;;;;;;;;;;;;;;;;;;:21;;;98595:11;:26;;:48;98622:6;98629:1;98622:9;;;;;;;;;;;;;;;;;;:20;;;98595:48;;;;;;;;;;;:71;98644:6;98651:1;98644:9;;;;;;;;;;;;;;;;;;:21;;;98595:71;;;;;;;;;;;:95;;;;98776:6;98783:1;98776:9;;;;;;;;;;;;;;;;;;:18;;;98705:11;:23;;:45;98729:6;98736:1;98729:9;;;;;;;;;;;;;;;;;;:20;;;98705:45;;;;;;;;;;;:68;98751:6;98758:1;98751:9;;;;;;;;;;;;;;;;;;:21;;;98705:68;;;;;;;;;;;:89;;;;98843:6;98850:1;98843:9;;;;;;;;;;;;;;;;;;:21;;;98821:6;98828:1;98821:9;;;;;;;;;;;;;;;;;;:20;;;98814:94;98866:6;98873:1;98866:9;;;;;;;;;;;;;;;;;;:21;;;98889:6;98896:1;98889:9;;;;;;;;;;;;;;;;;;:18;;;98814:94;;;;;;;;;;;;;;;;98575:3;;98539:381;;111531:949;111935:48;;:::i;:::-;5382:6;;-1:-1:-1;;;5382:6:0;;;;5381:7;5373:44;;;;-1:-1:-1;;;;;5373:44:0;;;;;;;;;91998:25;;:55;;-1:-1:-1;;;;;91998:55:0;;111737:5;;91898:12;;;;;;-1:-1:-1;;;;;91998:25:0;;;;:48;;:55;;111737:5;;91998:55;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;91998:55:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;91998:55:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;91998:55:0;;;;;;;;;91969:84;;-1:-1:-1;91969:84:0;-1:-1:-1;91969:84:0;-1:-1:-1;92074:34:0;;;92090:17;92074:34;:54;;;;;92119:9;92112:3;:16;;92074:54;:72;;;;;92139:7;92132:3;:14;;92074:72;92066:100;;;;;;-1:-1:-1;;;;;92066:100:0;;;;;;;;;111786:1;111768:8;:15;:19;:59;;;;;111810:17;:15;:17::i;:::-;111791:8;:15;:36;;111768:59;111760:86;;;;;;-1:-1:-1;;;;;111760:86:0;;;;;;;;;111884:18;;111865:15;;:37;111857:65;;;;-1:-1:-1;;;;;111857:65:0;;;;;;;;;111986:434;;;;;;;;;112043:5;111986:434;;;;;;;112076:11;111986:434;;;;112112:8;111986:434;;;;112148:11;111986:434;;;;112190:14;;111986:434;;;;112241:23;:36;112265:11;112241:36;;;;;;;;;;;;111986:434;;;;112309:12;-1:-1:-1;;;;;111986:434:0;;;;;112353:11;111986:434;;;;112392:16;:14;:16::i;:::-;-1:-1:-1;;;;;111986:434:0;;;112431:41;;;;;111935:485;;-1:-1:-1;112431:8:0;;:20;;:41;;112452:11;;111935:485;;112431:41;;;;114564:177;114634:4;114657:12;;114673:1;114657:17;114654:52;;;-1:-1:-1;114694:2:0;114687:9;;114654:52;-1:-1:-1;114721:12:0;;114564:177;:::o;44192:47::-;;;;:::o;99871:150::-;91650:5;;-1:-1:-1;;;;;91650:5:0;91636:10;:19;91628:41;;;;-1:-1:-1;;;;;91628:41:0;;;;;;;;;99942:14;;:19;99938:76;;;99978:14;:24;;;99938:76;99871:150;:::o;99158:212::-;91650:5;;-1:-1:-1;;;;;91650:5:0;91636:10;:19;91628:41;;;;-1:-1:-1;;;;;91628:41:0;;;;;;;;;99255:36;;;;:23;:36;;;;;;;:50;;;99321:41;99279:11;;99321:41;;;;99294:11;;99321:41;;;;;;;;;;99158:212;;:::o;110196:198::-;110355:31;110196:198;;;;;;;:::o;5664:100::-;3222:5;;;;;-1:-1:-1;;;;;3222:5:0;3208:10;:19;3200:41;;;;-1:-1:-1;;;;;3200:41:0;;;;;;;;;5743:6;:13;;;;;-1:-1:-1;;;5743:13:0;-1:-1:-1;;5743:13:0;;;;;;;;;5664:100::o;45708:20::-;;;-1:-1:-1;;;;;45708:20:0;;:::o;108705:189::-;108796:23;;108754:7;;-1:-1:-1;;;;;108796:23:0;108838:25;;108837:49;;108875:11;108837:49;;;108867:5;;;;;-1:-1:-1;;;;;108867:5:0;108837:49;108830:56;;108705:189;;:::o;8990:147::-;9101:4;:13;;9115:3;9101:18;;;;;;;;;;;;;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;-1:-1;;246:30;311:9;;295:26;;;340:21;;377:20;365:33;;9101:18:0;;;;;-1:-1:-1;9101:18:0;;;;;;;;;;:28;;:18;;:28;;-1:-1:-1;9101:18:0;-1:-1:-1;9101:18:0;;:28;;;;:18;:28;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;-1:-1;;246:30;311:9;;295:26;;;340:21;;377:20;365:33;;9101:28:0;;;;;-1:-1:-1;9101:28:0;;;;;;;;;;-1:-1:-1;9094:35:0;;-1:-1:-1;;;;;8990:147:0:o;106602:455::-;106848:25;;:55;;;;;106684:12;;106698:15;;106684:12;;;;;;-1:-1:-1;;;;;106848:25:0;;:48;;:55;;106897:5;;106848:55;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;106848:55:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;106848:55:0;;;;;;39:16:-1;36:1;17:17;2:54;101:4;106848:55:0;80:15:-1;;;-1:-1;;76:31;65:43;;120:4;113:20;106848:55:0;;;;;;;;;106802:101;;-1:-1:-1;106802:101:0;;-1:-1:-1;106802:101:0;;-1:-1:-1;106802:101:0;-1:-1:-1;106802:101:0;;-1:-1:-1;106940:17:0;;-1:-1:-1;106934:24:0;;-1:-1:-1;;;;;106934:24:0;;106924:34;;:6;:34;;;:54;;;;;106969:9;106962:3;:16;;106924:54;:72;;;;;106989:7;106982:3;:14;;106924:72;106916:100;;;;;;-1:-1:-1;;;;;106916:100:0;;;;;;;;;106602:455;;;;;;:::o;108286:411::-;108392:11;108438;108487:10;108531;108406:21;108421:2;108425:1;108406:14;:21::i;:::-;108392:35;;108452:22;108467:2;108471;108452:14;:22::i;:::-;108438:36;;108500:20;108515:1;108518;108500:14;:20::i;:::-;108487:33;;108544:21;108559:1;108562:2;108544:14;:21::i;:::-;108531:34;;108586:11;:23;;;;;;;;;;-1:-1:-1;;;;;108586:23:0;-1:-1:-1;;;;;108586:30:0;;108617:7;108626:1;108629:3;108634;108639:2;108643;108647:7;108586:69;;;;;-1:-1:-1;;;108586:69:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;108586:69:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;108586:69:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;108586:69:0;;;;;;;;;108578:111;;;;;;-1:-1:-1;;;;;108578:111:0;;;;;;;;;108286:411;;;;;;;;;:::o;22502:136::-;22560:7;22588:5;;;22608:6;;;;22600:15;;;;;;22631:1;22502:136;-1:-1:-1;;;22502:136:0:o;8815:167::-;8922:4;8946;:13;;8960:3;8946:18;;;;;;;;;;;;;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;-1:-1;;246:30;311:9;;295:26;;;340:21;;377:20;365:33;;8946:18:0;;;;;-1:-1:-1;8946:18:0;;;;;;;;;;:28;;:18;;:28;;-1:-1:-1;8946:18:0;-1:-1:-1;8946:18:0;;:28;;;;:18;:28;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;-1:-1;;246:30;311:9;;295:26;;;340:21;;377:20;365:33;;8946:28:0;;;;;-1:-1:-1;8946:28:0;;;;;;;;;;;;-1:-1:-1;;;8815:167:0;;;;;:::o;8647:160::-;8794:5;8763:4;:13;;8777:3;8763:18;;;;;;;;;;;;;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;-1:-1;;246:30;311:9;;295:26;;;340:21;;377:20;365:33;;8763:18:0;;;;;-1:-1:-1;8763:18:0;;;;;;;;;;:28;;:18;;:28;;-1:-1:-1;8763:18:0;-1:-1:-1;8763:18:0;;:28;;;;:18;:28;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;-1:-1;;246:30;311:9;;295:26;;;340:21;;377:20;365:33;;8763:28:0;;;;;-1:-1:-1;8763:28:0;;;;;;;;;;:36;;;;-1:-1:-1;;;;;;8647:160:0:o;107853:185::-;108000:14;108016:2;107996:23;107990:30;;107965:66::o;89994:25088::-;;;;;;;;;;-1:-1:-1;89994:25088:0;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;89994:25088:0;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;89994:25088:0;;;;;;;;;;;-1:-1:-1;;;;;89994:25088:0;;;;;:::o;:::-;;;;;;;;;-1:-1:-1;89994:25088:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;-1:-1:-1;89994:25088:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;89994:25088:0;;;;;:::o;:::-;;;;;;;;;-1:-1:-1;89994:25088:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;89994:25088:0;;;;;;;;;;;-1:-1:-1;;;;;89994:25088:0;;;;;:::o;5:118:-1:-;;72:46;110:6;97:20;72:46;;130:122;;208:39;239:6;233:13;208:39;;277:352;;;400:4;388:17;;384:27;-1:-1;374:2;;425:1;422;415:12;374:2;-1:-1;445:20;;485:18;474:30;;471:2;;;517:1;514;507:12;471:2;551:4;543:6;539:17;527:29;;602:3;594:4;586:6;582:17;572:8;568:32;565:41;562:2;;;619:1;616;609:12;562:2;367:262;;;;;;682:785;;818:4;806:17;;802:27;-1:-1;792:2;;843:1;840;833:12;792:2;880:6;867:20;902:106;917:90;1000:6;917:90;;;902:106;;;893:115;;1025:5;1050:6;1043:5;1036:21;1080:4;1072:6;1068:17;1058:27;;1102:4;1097:3;1093:14;1086:21;;1155:6;1202:3;1194:4;1186:6;1182:17;1177:3;1173:27;1170:36;1167:2;;;1219:1;1216;1209:12;1167:2;1244:1;1229:232;1254:6;1251:1;1248:13;1229:232;;;1312:3;1334:63;1393:3;1381:10;1334:63;;;1322:76;;-1:-1;1421:4;1412:14;;;;1449:4;1440:14;;;;;1276:1;1269:9;1229:232;;;1233:14;785:682;;;;;;;;1520:785;;1656:4;1644:17;;1640:27;-1:-1;1630:2;;1681:1;1678;1671:12;1630:2;1718:6;1705:20;1740:106;1755:90;1838:6;1755:90;;1740:106;1731:115;;1863:5;1888:6;1881:5;1874:21;1918:4;1910:6;1906:17;1896:27;;1940:4;1935:3;1931:14;1924:21;;1993:6;2040:3;2032:4;2024:6;2020:17;2015:3;2011:27;2008:36;2005:2;;;2057:1;2054;2047:12;2005:2;2082:1;2067:232;2092:6;2089:1;2086:13;2067:232;;;2150:3;2172:63;2231:3;2219:10;2172:63;;;2160:76;;-1:-1;2259:4;2250:14;;;;2287:4;2278:14;;;;;2114:1;2107:9;2067:232;;2367:812;;2512:4;2500:17;;2496:27;-1:-1;2486:2;;2537:1;2534;2527:12;2486:2;2574:6;2561:20;2596:115;2611:99;2703:6;2611:99;;2596:115;2587:124;;2728:5;2753:6;2746:5;2739:21;2783:4;2775:6;2771:17;2761:27;;2805:4;2800:3;2796:14;2789:21;;2858:6;2905:3;2897:4;2889:6;2885:17;2880:3;2876:27;2873:36;2870:2;;;2922:1;2919;2912:12;2870:2;2947:1;2932:241;2957:6;2954:1;2951:13;2932:241;;;3015:3;3037:72;3105:3;3093:10;3037:72;;;3025:85;;-1:-1;3133:4;3124:14;;;;3161:4;3152:14;;;;;2979:1;2972:9;2932:241;;3583:707;;3693:4;3681:17;;3677:27;-1:-1;3667:2;;3718:1;3715;3708:12;3667:2;3755:6;3742:20;3777:80;3792:64;3849:6;3792:64;;3777:80;3768:89;;3874:5;3899:6;3892:5;3885:21;3929:4;3921:6;3917:17;3907:27;;3951:4;3946:3;3942:14;3935:21;;4004:6;4051:3;4043:4;4035:6;4031:17;4026:3;4022:27;4019:36;4016:2;;;4068:1;4065;4058:12;4016:2;4093:1;4078:206;4103:6;4100:1;4097:13;4078:206;;;4161:3;4183:37;4216:3;4204:10;4183:37;;;4171:50;;-1:-1;4244:4;4235:14;;;;4263;;;;;4125:1;4118:9;4078:206;;4298:112;;4362:43;4397:6;4384:20;4362:43;;4417:116;;4492:36;4520:6;4514:13;4492:36;;4540:118;;4607:46;4645:6;4632:20;4607:46;;4665:122;;4743:39;4774:6;4768:13;4743:39;;4808:335;;;4915:4;4903:17;;4899:27;-1:-1;4889:2;;4940:1;4937;4930:12;4889:2;-1:-1;4960:20;;5000:18;4989:30;;4986:2;;;5032:1;5029;5022:12;4986:2;5066:4;5058:6;5054:17;5042:29;;5116:3;5109;5101:6;5097:16;5087:8;5083:31;5080:40;5077:2;;;5133:1;5130;5123:12;5152:440;;5246:4;5234:17;;5230:27;-1:-1;5220:2;;5271:1;5268;5261:12;5220:2;5308:6;5295:20;5330:64;5345:48;5386:6;5345:48;;5330:64;5321:73;;5414:6;5407:5;5400:21;5450:4;5442:6;5438:17;5483:4;5476:5;5472:16;5518:3;5509:6;5504:3;5500:16;5497:25;5494:2;;;5535:1;5532;5525:12;5494:2;5545:41;5579:6;5574:3;5569;5545:41;;;5213:379;;;;;;;;5601:442;;5706:4;5694:17;;5690:27;-1:-1;5680:2;;5731:1;5728;5721:12;5680:2;5761:6;5755:13;5783:64;5798:48;5839:6;5798:48;;5783:64;5774:73;;5867:6;5860:5;5853:21;5903:4;5895:6;5891:17;5936:4;5929:5;5925:16;5971:3;5962:6;5957:3;5953:16;5950:25;5947:2;;;5988:1;5985;5978:12;5947:2;5998:39;6030:6;6025:3;6020;5998:39;;6092:480;;6207:4;6195:9;6190:3;6186:19;6182:30;6179:2;;;6225:1;6222;6215:12;6179:2;6243:20;6258:4;6243:20;;;6234:29;-1:-1;6319:1;6350:49;6395:3;6375:9;6350:49;;;6326:74;;-1:-1;6468:2;6501:49;6546:3;6522:22;;;6501:49;;;6494:4;6487:5;6483:16;6476:75;6421:141;6173:399;;;;;7152:779;;7267:4;7255:9;7250:3;7246:19;7242:30;7239:2;;;7285:1;7282;7275:12;7239:2;7303:20;7318:4;7303:20;;;7294:29;-1:-1;7379:1;7410:49;7455:3;7435:9;7410:49;;;7386:74;;-1:-1;7528:2;7561:49;7606:3;7582:22;;;7561:49;;;7554:4;7547:5;7543:16;7536:75;7481:141;7679:2;7712:49;7757:3;7748:6;7737:9;7733:22;7712:49;;;7705:4;7698:5;7694:16;7687:75;7632:141;7827:2;7860:49;7905:3;7896:6;7885:9;7881:22;7860:49;;;7853:4;7846:5;7842:16;7835:75;7783:138;7233:698;;;;;9570:118;;9646:37;9675:6;9669:13;9646:37;;9695:241;;9799:2;9787:9;9778:7;9774:23;9770:32;9767:2;;;9815:1;9812;9805:12;9767:2;9850:1;9867:53;9912:7;9892:9;9867:53;;;9857:63;9761:175;-1:-1;;;;9761:175;9943:743;;;;;;10115:3;10103:9;10094:7;10090:23;10086:33;10083:2;;;10132:1;10129;10122:12;10083:2;10167:1;10184:53;10229:7;10209:9;10184:53;;;10174:63;;10146:97;10274:2;10292:53;10337:7;10328:6;10317:9;10313:22;10292:53;;;10282:63;;10253:98;10382:2;10400:53;10445:7;10436:6;10425:9;10421:22;10400:53;;;10390:63;;10361:98;10490:2;10508:53;10553:7;10544:6;10533:9;10529:22;10508:53;;;10498:63;;10469:98;10598:3;10617:53;10662:7;10653:6;10642:9;10638:22;10617:53;;;10607:63;;10577:99;10077:609;;;;;;;;;10693:1119;;;;;;10924:3;10912:9;10903:7;10899:23;10895:33;10892:2;;;10941:1;10938;10931:12;10892:2;10976:1;10993:53;11038:7;11018:9;10993:53;;;10983:63;;10955:97;11083:2;11101:53;11146:7;11137:6;11126:9;11122:22;11101:53;;;11091:63;;11062:98;11219:2;11208:9;11204:18;11191:32;11243:18;11235:6;11232:30;11229:2;;;11275:1;11272;11265:12;11229:2;11295:78;11365:7;11356:6;11345:9;11341:22;11295:78;;;11285:88;;11170:209;11438:2;11427:9;11423:18;11410:32;11462:18;11454:6;11451:30;11448:2;;;11494:1;11491;11484:12;11448:2;11514:78;11584:7;11575:6;11564:9;11560:22;11514:78;;;11504:88;;11389:209;11657:3;11646:9;11642:19;11629:33;11682:18;11674:6;11671:30;11668:2;;;11714:1;11711;11704:12;11668:2;11734:62;11788:7;11779:6;11768:9;11764:22;11734:62;;11819:721;;;;;11983:3;11971:9;11962:7;11958:23;11954:33;11951:2;;;12000:1;11997;11990:12;11951:2;12035:1;12052:53;12097:7;12077:9;12052:53;;;12042:63;;12014:97;12142:2;12160:53;12205:7;12196:6;12185:9;12181:22;12160:53;;;12150:63;;12121:98;12250:2;12268:53;12313:7;12304:6;12293:9;12289:22;12268:53;;;12258:63;;12229:98;12386:2;12375:9;12371:18;12358:32;12410:18;12402:6;12399:30;12396:2;;;12442:1;12439;12432:12;12396:2;12462:62;12516:7;12507:6;12496:9;12492:22;12462:62;;;12452:72;;12337:193;11945:595;;;;;;;;12547:847;;;;;;12728:3;12716:9;12707:7;12703:23;12699:33;12696:2;;;12745:1;12742;12735:12;12696:2;12780:1;12797:53;12842:7;12822:9;12797:53;;;12787:63;;12759:97;12887:2;12905:53;12950:7;12941:6;12930:9;12926:22;12905:53;;;12895:63;;12866:98;12995:2;13013:53;13058:7;13049:6;13038:9;13034:22;13013:53;;;13003:63;;12974:98;13103:2;13121:53;13166:7;13157:6;13146:9;13142:22;13121:53;;13401:399;;;13533:2;13521:9;13512:7;13508:23;13504:32;13501:2;;;13549:1;13546;13539:12;13501:2;13584:1;13601:64;13657:7;13637:9;13601:64;;;13591:74;;13563:108;13702:2;13720:64;13776:7;13767:6;13756:9;13752:22;13720:64;;;13710:74;;13681:109;13495:305;;;;;;13807:397;;;13946:2;13934:9;13925:7;13921:23;13917:32;13914:2;;;13962:1;13959;13952:12;13914:2;13997:31;;14048:18;14037:30;;14034:2;;;14080:1;14077;14070:12;14034:2;14108:80;14180:7;14171:6;14160:9;14156:22;14108:80;;;14090:98;;;;13976:218;13908:296;;;;;;14211:429;;14366:2;14354:9;14345:7;14341:23;14337:32;14334:2;;;14382:1;14379;14372:12;14334:2;14417:31;;14468:18;14457:30;;14454:2;;;14500:1;14497;14490:12;14454:2;14520:104;14616:7;14607:6;14596:9;14592:22;14520:104;;14647:429;;14802:2;14790:9;14781:7;14777:23;14773:32;14770:2;;;14818:1;14815;14808:12;14770:2;14853:31;;14904:18;14893:30;;14890:2;;;14936:1;14933;14926:12;14890:2;14956:104;15052:7;15043:6;15032:9;15028:22;14956:104;;15083:447;;15247:2;15235:9;15226:7;15222:23;15218:32;15215:2;;;15263:1;15260;15253:12;15215:2;15298:31;;15349:18;15338:30;;15335:2;;;15381:1;15378;15371:12;15335:2;15401:113;15506:7;15497:6;15486:9;15482:22;15401:113;;15941:235;;16042:2;16030:9;16021:7;16017:23;16013:32;16010:2;;;16058:1;16055;16048:12;16010:2;16093:1;16110:50;16152:7;16132:9;16110:50;;16183:257;;16295:2;16283:9;16274:7;16270:23;16266:32;16263:2;;;16311:1;16308;16301:12;16263:2;16346:1;16363:61;16416:7;16396:9;16363:61;;16447:241;;16551:2;16539:9;16530:7;16526:23;16522:32;16519:2;;;16567:1;16564;16557:12;16519:2;16602:1;16619:53;16664:7;16644:9;16619:53;;16695:263;;16810:2;16798:9;16789:7;16785:23;16781:32;16778:2;;;16826:1;16823;16816:12;16778:2;16861:1;16878:64;16934:7;16914:9;16878:64;;16965:1623;;;;;;;;;;17264:3;17252:9;17243:7;17239:23;17235:33;17232:2;;;17281:1;17278;17271:12;17232:2;17316:1;17333:53;17378:7;17358:9;17333:53;;;17323:63;;17295:97;17423:2;17441:53;17486:7;17477:6;17466:9;17462:22;17441:53;;;17431:63;;17402:98;17531:2;17549:53;17594:7;17585:6;17574:9;17570:22;17549:53;;;17539:63;;17510:98;17667:2;17656:9;17652:18;17639:32;17691:18;17683:6;17680:30;17677:2;;;17723:1;17720;17713:12;17677:2;17743:78;17813:7;17804:6;17793:9;17789:22;17743:78;;;17733:88;;17618:209;17886:3;17875:9;17871:19;17858:33;17911:18;17903:6;17900:30;17897:2;;;17943:1;17940;17933:12;17897:2;17963:78;18033:7;18024:6;18013:9;18009:22;17963:78;;;17953:88;;17837:210;18078:3;18097:53;18142:7;18133:6;18122:9;18118:22;18097:53;;;18087:63;;18057:99;18187:3;18206:53;18251:7;18242:6;18231:9;18227:22;18206:53;;;18196:63;;18166:99;18324:3;18313:9;18309:19;18296:33;18349:18;18341:6;18338:30;18335:2;;;18381:1;18378;18371:12;18335:2;18401:62;18455:7;18446:6;18435:9;18431:22;18401:62;;;18391:72;;18275:194;18500:3;18519:53;18564:7;18555:6;18544:9;18540:22;18519:53;;;18509:63;;18479:99;17226:1362;;;;;;;;;;;;18595:1853;;;;;;;;;;;18920:3;18908:9;18899:7;18895:23;18891:33;18888:2;;;18937:1;18934;18927:12;18888:2;18972:1;18989:53;19034:7;19014:9;18989:53;;;18979:63;;18951:97;19079:2;19097:53;19142:7;19133:6;19122:9;19118:22;19097:53;;;19087:63;;19058:98;19187:2;19205:53;19250:7;19241:6;19230:9;19226:22;19205:53;;;19195:63;;19166:98;19323:2;19312:9;19308:18;19295:32;19347:18;19339:6;19336:30;19333:2;;;19379:1;19376;19369:12;19333:2;19399:78;19469:7;19460:6;19449:9;19445:22;19399:78;;;19389:88;;19274:209;19542:3;19531:9;19527:19;19514:33;19567:18;19559:6;19556:30;19553:2;;;19599:1;19596;19589:12;19553:2;19619:78;19689:7;19680:6;19669:9;19665:22;19619:78;;;19609:88;;19493:210;19762:3;19751:9;19747:19;19734:33;19787:18;19779:6;19776:30;19773:2;;;19819:1;19816;19809:12;19773:2;19839:62;19893:7;19884:6;19873:9;19869:22;19839:62;;;19829:72;;19713:194;19938:3;19957:53;20002:7;19993:6;19982:9;19978:22;19957:53;;;19947:63;;19917:99;20047:3;20066:53;20111:7;20102:6;20091:9;20087:22;20066:53;;;20056:63;;20026:99;20184:3;20173:9;20169:19;20156:33;20209:18;20201:6;20198:30;20195:2;;;20241:1;20238;20231:12;20195:2;20261:62;20315:7;20306:6;20295:9;20291:22;20261:62;;;20251:72;;20135:194;20360:3;20379:53;20424:7;20415:6;20404:9;20400:22;20379:53;;;20369:63;;20339:99;18882:1566;;;;;;;;;;;;;;20455:1371;;;;;;;;;;;20714:3;20702:9;20693:7;20689:23;20685:33;20682:2;;;20731:1;20728;20721:12;20682:2;20766:1;20783:53;20828:7;20808:9;20783:53;;;20773:63;;20745:97;20873:2;20891:53;20936:7;20927:6;20916:9;20912:22;20891:53;;;20881:63;;20852:98;20981:2;20999:53;21044:7;21035:6;21024:9;21020:22;20999:53;;;20989:63;;20960:98;21089:2;21107:53;21152:7;21143:6;21132:9;21128:22;21107:53;;;21097:63;;21068:98;21197:3;21216:53;21261:7;21252:6;21241:9;21237:22;21216:53;;;21206:63;;21176:99;21306:3;21325:53;21370:7;21361:6;21350:9;21346:22;21325:53;;;21315:63;;21285:99;21415:3;21434:53;21479:7;21470:6;21459:9;21455:22;21434:53;;;21424:63;;21394:99;21552:3;21541:9;21537:19;21524:33;21577:18;21569:6;21566:30;21563:2;;;21609:1;21606;21599:12;21563:2;21637:64;21693:7;21684:6;21673:9;21669:22;21637:64;;;21619:82;;;;21503:204;21738:3;21757:53;21802:7;21793:6;21782:9;21778:22;21757:53;;21833:1245;;;;;;;22081:3;22069:9;22060:7;22056:23;22052:33;22049:2;;;22098:1;22095;22088:12;22049:2;22133:1;22150:53;22195:7;22175:9;22150:53;;;22140:63;;22112:97;22240:2;22258:53;22303:7;22294:6;22283:9;22279:22;22258:53;;;22248:63;;22219:98;22376:2;22365:9;22361:18;22348:32;22400:18;22392:6;22389:30;22386:2;;;22432:1;22429;22422:12;22386:2;22452:78;22522:7;22513:6;22502:9;22498:22;22452:78;;;22442:88;;22327:209;22595:2;22584:9;22580:18;22567:32;22619:18;22611:6;22608:30;22605:2;;;22651:1;22648;22641:12;22605:2;22671:78;22741:7;22732:6;22721:9;22717:22;22671:78;;;22661:88;;22546:209;22786:3;22805:53;22850:7;22841:6;22830:9;22826:22;22805:53;;;22795:63;;22765:99;22923:3;22912:9;22908:19;22895:33;22948:18;22940:6;22937:30;22934:2;;;22980:1;22977;22970:12;22934:2;23000:62;23054:7;23045:6;23034:9;23030:22;23000:62;;;22990:72;;22874:194;22043:1035;;;;;;;;;23085:1119;;;;;;23316:3;23304:9;23295:7;23291:23;23287:33;23284:2;;;23333:1;23330;23323:12;23284:2;23368:1;23385:53;23430:7;23410:9;23385:53;;;23375:63;;23347:97;23475:2;23493:53;23538:7;23529:6;23518:9;23514:22;23493:53;;24211:741;;;;;;24385:3;24373:9;24364:7;24360:23;24356:33;24353:2;;;24402:1;24399;24392:12;24353:2;24437:1;24454:53;24499:7;24479:9;24454:53;;;24444:63;;24416:97;24544:2;24562:53;24607:7;24598:6;24587:9;24583:22;24562:53;;;24552:63;;24523:98;24652:2;24670:53;24715:7;24706:6;24695:9;24691:22;24670:53;;;24660:63;;24631:98;24788:2;24777:9;24773:18;24760:32;24812:18;24804:6;24801:30;24798:2;;;24844:1;24841;24834:12;24798:2;24872:64;24928:7;24919:6;24908:9;24904:22;24872:64;;;24854:82;;;;24739:203;24347:605;;;;;;;;;24959:993;;;;;;;;25167:3;25155:9;25146:7;25142:23;25138:33;25135:2;;;25184:1;25181;25174:12;25135:2;25219:1;25236:53;25281:7;25261:9;25236:53;;;25226:63;;25198:97;25326:2;25344:53;25389:7;25380:6;25369:9;25365:22;25344:53;;;25334:63;;25305:98;25434:2;25452:53;25497:7;25488:6;25477:9;25473:22;25452:53;;;25442:63;;25413:98;25542:2;25560:53;25605:7;25596:6;25585:9;25581:22;25560:53;;;25550:63;;25521:98;25650:3;25669:53;25714:7;25705:6;25694:9;25690:22;25669:53;;;25659:63;;25629:99;25787:3;25776:9;25772:19;25759:33;25812:18;25804:6;25801:30;25798:2;;;25844:1;25841;25834:12;25798:2;25872:64;25928:7;25919:6;25908:9;25904:22;25872:64;;;25854:82;;;;25738:204;25129:823;;;;;;;;;;;25959:1823;;;;;;;;;;;;26261:3;26249:9;26240:7;26236:23;26232:33;26229:2;;;26278:1;26275;26268:12;26229:2;26313:1;26330:64;26386:7;26366:9;26330:64;;;26320:74;;26292:108;26431:2;26449:62;26503:7;26494:6;26483:9;26479:22;26449:62;;;26439:72;;26410:107;26548:2;26566:64;26622:7;26613:6;26602:9;26598:22;26566:64;;;26556:74;;26527:109;26667:2;26685:64;26741:7;26732:6;26721:9;26717:22;26685:64;;;26675:74;;26646:109;26786:3;26805:64;26861:7;26852:6;26841:9;26837:22;26805:64;;;26795:74;;26765:110;26906:3;26925:64;26981:7;26972:6;26961:9;26957:22;26925:64;;;26915:74;;26885:110;27026:3;27045:64;27101:7;27092:6;27081:9;27077:22;27045:64;;;27035:74;;27005:110;27167:3;27156:9;27152:19;27146:26;27192:18;27184:6;27181:30;27178:2;;;27224:1;27221;27214:12;27178:2;27244:73;27309:7;27300:6;27289:9;27285:22;27244:73;;;27234:83;;27125:198;27375:3;27364:9;27360:19;27354:26;27400:18;27392:6;27389:30;27386:2;;;27432:1;27429;27422:12;27386:2;27452:73;27517:7;27508:6;27497:9;27493:22;27452:73;;;27442:83;;27333:198;27562:3;27581:64;27637:7;27628:6;27617:9;27613:22;27581:64;;;27571:74;;27541:110;27682:3;27702:64;27758:7;27749:6;27738:9;27734:22;27702:64;;;27691:75;;27661:111;26223:1559;;;;;;;;;;;;;;;27789:614;;;;;27948:2;27936:9;27927:7;27923:23;27919:32;27916:2;;;27964:1;27961;27954:12;27916:2;27999:31;;28050:18;28039:30;;28036:2;;;28082:1;28079;28072:12;28036:2;28110:64;28166:7;28157:6;28146:9;28142:22;28110:64;;;28092:82;;;;27978:202;28239:2;28228:9;28224:18;28211:32;28263:18;28255:6;28252:30;28249:2;;;28295:1;28292;28285:12;28249:2;28323:64;28379:7;28370:6;28359:9;28355:22;28323:64;;;27910:493;;;;-1:-1;28305:82;-1:-1;;;;27910:493;28410:739;;;;;;28586:2;28574:9;28565:7;28561:23;28557:32;28554:2;;;28602:1;28599;28592:12;28554:2;28637:31;;28688:18;28677:30;;28674:2;;;28720:1;28717;28710:12;28674:2;28748:64;28804:7;28795:6;28784:9;28780:22;28748:64;;;28730:82;;;;28616:202;28877:2;28866:9;28862:18;28849:32;28901:18;28893:6;28890:30;28887:2;;;28933:1;28930;28923:12;28887:2;28961:64;29017:7;29008:6;28997:9;28993:22;28961:64;;;28943:82;;;;28828:203;29062:2;29080:53;29125:7;29116:6;29105:9;29101:22;29080:53;;29156:574;;;29295:2;29283:9;29274:7;29270:23;29266:32;29263:2;;;29311:1;29308;29301:12;29263:2;29346:31;;29397:18;29386:30;;29383:2;;;29429:1;29426;29419:12;29383:2;29449:62;29503:7;29494:6;29483:9;29479:22;29449:62;;;29439:72;;29325:192;29576:2;29565:9;29561:18;29548:32;29600:18;29592:6;29589:30;29586:2;;;29632:1;29629;29622:12;29586:2;29652:62;29706:7;29697:6;29686:9;29682:22;29652:62;;29737:301;;29871:2;29859:9;29850:7;29846:23;29842:32;29839:2;;;29887:1;29884;29877:12;29839:2;29922:1;29939:83;30014:7;29994:9;29939:83;;30045:302;;30179:3;30167:9;30158:7;30154:23;30150:33;30147:2;;;30196:1;30193;30186:12;30147:2;30231:1;30248:83;30323:7;30303:9;30248:83;;30602:366;;;30723:2;30711:9;30702:7;30698:23;30694:32;30691:2;;;30739:1;30736;30729:12;30691:2;30774:1;30791:53;30836:7;30816:9;30791:53;;;30781:63;;30753:97;30881:2;30899:53;30944:7;30935:6;30924:9;30920:22;30899:53;;30975:531;;;;31122:2;31110:9;31101:7;31097:23;31093:32;31090:2;;;31138:1;31135;31128:12;31090:2;31173:1;31190:62;31244:7;31224:9;31190:62;;;31180:72;;31152:106;31289:2;31307:64;31363:7;31354:6;31343:9;31339:22;31307:64;;;31297:74;;31268:109;31408:2;31426:64;31482:7;31473:6;31462:9;31458:22;31426:64;;;31416:74;;31387:109;31084:422;;;;;;31513:110;31586:31;31611:5;31586:31;;;31581:3;31574:44;31568:55;;;31842:783;;32031:81;32106:5;32031:81;;;32130:6;32125:3;32118:19;32154:4;32149:3;32145:14;32138:21;;32199:83;32276:5;32199:83;;;32303:1;32288:315;32313:6;32310:1;32307:13;32288:315;;;32353:111;32460:3;32451:6;32445:13;32353:111;;;32481:87;32561:6;32481:87;;;32591:4;32582:14;;;;;32471:97;-1:-1;32335:1;32328:9;32288:315;;;-1:-1;32616:3;;32010:615;-1:-1;;;;32010:615;32664:590;;32799:54;32847:5;32799:54;;;32871:6;32866:3;32859:19;32895:4;32890:3;32886:14;32879:21;;32940:56;32990:5;32940:56;;;33017:1;33002:230;33027:6;33024:1;33021:13;33002:230;;;33067:53;33116:3;33107:6;33101:13;33067:53;;;33137:60;33190:6;33137:60;;;33220:4;33211:14;;;;;33127:70;-1:-1;33049:1;33042:9;33002:230;;33293:590;;33432:50;33476:5;33432:50;;;33500:6;33495:3;33488:19;33524:4;33519:3;33515:14;33508:21;;33569:52;33615:5;33569:52;;;33642:1;33627:234;33652:6;33649:1;33646:13;33627:234;;;33692:61;33749:3;33740:6;33734:13;33692:61;;;33770:56;33819:6;33770:56;;;33849:4;33840:14;;;;;33760:66;-1:-1;33674:1;33667:9;33627:234;;33891:101;33958:28;33980:5;33958:28;;33999:110;34072:31;34097:5;34072:31;;34241:107;34312:30;34336:5;34312:30;;34355:297;;34455:38;34487:5;34455:38;;;34510:6;34505:3;34498:19;34522:63;34578:6;34571:4;34566:3;34562:14;34555:4;34548:5;34544:16;34522:63;;;34617:29;34639:6;34617:29;;;34597:50;;;34610:4;34597:50;;34435:217;-1:-1;;;34435:217;34964:296;35119:2;35107:15;;35156:66;35151:2;35142:12;;35135:88;35251:2;35242:12;;35100:160;35269:296;35424:2;35412:15;;35461:66;35456:2;35447:12;;35440:88;35556:2;35547:12;;35405:160;35574:296;35729:2;35717:15;;35766:66;35761:2;35752:12;;35745:88;35861:2;35852:12;;35710:160;35879:296;36034:2;36022:15;;36071:66;36066:2;36057:12;;36050:88;36166:2;36157:12;;36015:160;36184:296;36339:2;36327:15;;36376:66;36371:2;36362:12;;36355:88;36471:2;36462:12;;36320:160;36489:296;36644:2;36632:15;;36681:66;36676:2;36667:12;;36660:88;36776:2;36767:12;;36625:160;36794:296;36949:2;36937:15;;36986:66;36981:2;36972:12;;36965:88;37081:2;37072:12;;36930:160;37099:295;37254:1;37242:14;;37290:66;37285:2;37276:12;;37269:88;37385:2;37376:12;;37235:159;37403:296;37558:2;37546:15;;37595:66;37590:2;37581:12;;37574:88;37690:2;37681:12;;37539:160;37708:296;37863:2;37851:15;;37900:66;37895:2;37886:12;;37879:88;37995:2;37986:12;;37844:160;38013:295;38168:1;38156:14;;38204:66;38199:2;38190:12;;38183:88;38299:2;38290:12;;38149:159;38316:111;38404:18;;38398:29;38515:515;38736:22;;38660:4;38651:14;;;38770:61;38655:3;38736:22;38770:61;;;38680:163;38923:4;38916:5;38912:16;38906:23;38941:62;38997:4;38992:3;38988:14;38975:11;38941:62;;39727:1910;39984:22;;39727:1910;;39910:5;39901:15;;;40018:69;39905:3;39984:22;40018:69;;;39931:168;40176:4;40169:5;40165:16;40159:23;40194:70;40258:4;40253:3;40249:14;40236:11;40194:70;;;40109:167;40359:4;40352:5;40348:16;40342:23;40377:70;40441:4;40436:3;40432:14;40419:11;40377:70;;;40286:173;40539:4;40532:5;40528:16;40522:23;40590:3;40584:4;40580:14;40573:4;40568:3;40564:14;40557:38;40610:106;40711:4;40698:11;40610:106;;;40602:114;;40469:259;40811:4;40804:5;40800:16;40794:23;40862:3;40856:4;40852:14;40845:4;40840:3;40836:14;40829:38;40882:106;40983:4;40970:11;40882:106;;;40874:114;;40738:262;41079:4;41072:5;41068:16;41062:23;41130:3;41124:4;41120:14;41113:4;41108:3;41104:14;41097:38;41150:74;41219:4;41206:11;41150:74;;;41142:82;;41010:226;41324:4;41317:5;41313:16;41307:23;41342:70;41406:4;41401:3;41397:14;41384:11;41342:70;;;41246:178;41511:4;41504:5;41500:16;41494:23;41529:70;41593:4;41588:3;41584:14;41571:11;41529:70;;;-1:-1;41628:4;39883:1754;-1:-1;;;39883:1754;41739:1643;41982:22;;41908:5;41899:15;;;42016:69;41903:3;41982:22;42016:69;;;41929:168;42174:4;42167:5;42163:16;42157:23;42192:70;42256:4;42251:3;42247:14;42234:11;42192:70;;;42107:167;42357:4;42350:5;42346:16;42340:23;42375:70;42439:4;42434:3;42430:14;42417:11;42375:70;;;42284:173;42534:4;42527:5;42523:16;42517:23;42552:70;42616:4;42611:3;42607:14;42594:11;42552:70;;;42467:167;42709:4;42702:5;42698:16;42692:23;42727:70;42791:4;42786:3;42782:14;42769:11;42727:70;;;42644:165;42897:4;42890:5;42886:16;42880:23;42915:70;42979:4;42974:3;42970:14;42957:11;42915:70;;;42819:178;43084:4;43077:5;43073:16;43067:23;43102:70;43166:4;43161:3;43157:14;43144:11;43102:70;;;43007:177;43267:4;43260:5;43256:16;43250:23;43285:70;43349:4;43344:3;43340:14;43327:11;43285:70;;43486:1679;43748:22;;43486:1679;;43675:4;43666:14;;;43782:69;43670:3;43748:22;43782:69;;;43695:168;43940:4;43933:5;43929:16;43923:23;43958:70;44022:4;44017:3;44013:14;44000:11;43958:70;;;43873:167;44123:4;44116:5;44112:16;44106:23;44141:70;44205:4;44200:3;44196:14;44183:11;44141:70;;;44050:173;44303:4;44296:5;44292:16;44286:23;44354:3;44348:4;44344:14;44337:4;44332:3;44328:14;44321:38;44374:106;44475:4;44462:11;44374:106;;;44366:114;;44233:259;44575:4;44568:5;44564:16;44558:23;44626:3;44620:4;44616:14;44609:4;44604:3;44600:14;44593:38;44646:106;44747:4;44734:11;44646:106;;;44638:114;;44502:262;44852:4;44845:5;44841:16;44835:23;44870:70;44934:4;44929:3;44925:14;44912:11;44870:70;;;44774:178;45039:4;45032:5;45028:16;45022:23;45057:70;45121:4;45116:3;45112:14;45099:11;45057:70;;47022:2115;47278:22;;47022:2115;;47207:5;47198:15;;;47312:69;47202:3;47278:22;47312:69;;;47228:165;47476:4;47469:5;47465:16;47459:23;47494:70;47558:4;47553:3;47549:14;47536:11;47494:70;;;47403:173;47656:4;47649:5;47645:16;47639:23;47707:3;47701:4;47697:14;47690:4;47685:3;47681:14;47674:38;47727:106;47828:4;47815:11;47727:106;;;47719:114;;47586:259;47928:4;47921:5;47917:16;47911:23;47979:3;47973:4;47969:14;47962:4;47957:3;47953:14;47946:38;47999:106;48100:4;48087:11;47999:106;;;47991:114;;47855:262;48203:4;48196:5;48192:16;48186:23;48221:70;48285:4;48280:3;48276:14;48263:11;48221:70;;;48127:176;48395:4;48388:5;48384:16;48378:23;48413:70;48477:4;48472:3;48468:14;48455:11;48413:70;;;48313:182;48582:4;48575:5;48571:16;48565:23;48600:70;48664:4;48659:3;48655:14;48642:11;48600:70;;;48505:177;48769:4;48762:5;48758:16;48752:23;48820:3;48814:4;48810:14;48803:4;48798:3;48794:14;48787:38;48840:74;48909:4;48896:11;48840:74;;;48832:82;;48692:234;49009:5;49002;48998:17;48992:24;49028:71;49092:5;49087:3;49083:15;49070:11;49028:71;;49241:1920;49491:22;;49241:1920;;49420:5;49411:15;;;49525:69;49415:3;49491:22;49525:69;;;49441:165;49689:4;49682:5;49678:16;49672:23;49707:70;49771:4;49766:3;49762:14;49749:11;49707:70;;;49616:173;49866:4;49859:5;49855:16;49849:23;49884:70;49948:4;49943:3;49939:14;49926:11;49884:70;;;49799:167;50052:4;50045:5;50041:16;50035:23;50070:70;50134:4;50129:3;50125:14;50112:11;50070:70;;;49976:176;50227:4;50220:5;50216:16;50210:23;50245:70;50309:4;50304:3;50300:14;50287:11;50245:70;;51261:1926;51517:22;;51261:1926;;51446:5;51437:15;;;51551:69;51441:3;51517:22;51551:69;;;51467:165;51715:4;51708:5;51704:16;51698:23;51733:70;51797:4;51792:3;51788:14;51775:11;51733:70;;;51642:173;51895:4;51888:5;51884:16;51878:23;51946:3;51940:4;51936:14;51929:4;51924:3;51920:14;51913:38;51966:106;52067:4;52054:11;51966:106;;;51958:114;;51825:259;52167:4;52160:5;52156:16;52150:23;52218:3;52212:4;52208:14;52201:4;52196:3;52192:14;52185:38;52238:106;52339:4;52326:11;52238:106;;;52230:114;;52094:262;52442:4;52435:5;52431:16;52425:23;52460:70;52524:4;52519:3;52515:14;52502:11;52460:70;;;52366:176;52634:4;52627:5;52623:16;52617:23;52652:70;52716:4;52711:3;52707:14;52694:11;52652:70;;;52552:182;52821:4;52814:5;52810:16;52804:23;52872:3;52866:4;52862:14;52855:4;52850:3;52846:14;52839:38;52892:74;52961:4;52948:11;52892:74;;;52884:82;;52744:234;53061:4;53054:5;53050:16;53044:23;53079:70;53143:4;53138:3;53134:14;53121:11;53079:70;;53291:1555;53540:22;;53291:1555;;53470:4;53461:14;;;53574:69;53465:3;53540:22;53574:69;;;53490:165;53738:4;53731:5;53727:16;53721:23;53756:70;53820:4;53815:3;53811:14;53798:11;53756:70;;;53665:173;53915:4;53908:5;53904:16;53898:23;53933:70;53997:4;53992:3;53988:14;53975:11;53933:70;;;53848:167;54101:4;54094:5;54090:16;54084:23;54119:70;54183:4;54178:3;54174:14;54161:11;54119:70;;;54025:176;54293:4;54286:5;54282:16;54276:23;54311:70;54375:4;54370:3;54366:14;54353:11;54311:70;;;54211:182;54480:4;54473:5;54469:16;54463:23;54531:3;54525:4;54521:14;54514:4;54509:3;54505:14;54498:38;54551:74;54620:4;54607:11;54551:74;;;54543:82;;54403:234;54720:4;54713:5;54709:16;54703:23;54738:70;54802:4;54797:3;54793:14;54780:11;54738:70;;55095:193;55203:2;55188:18;;55217:61;55192:9;55251:6;55217:61;;55295:599;55515:3;55500:19;;55530:61;55504:9;55564:6;55530:61;;;55602:62;55660:2;55649:9;55645:18;55636:6;55602:62;;;55675;55733:2;55722:9;55718:18;55709:6;55675:62;;;55748;55806:2;55795:9;55791:18;55782:6;55748:62;;;55821:63;55879:3;55868:9;55864:19;55855:6;55821:63;;;55486:408;;;;;;;;;55901:449;56113:2;56127:47;;;56098:18;;56188:152;56098:18;56326:6;56188:152;;56357:341;56515:2;56529:47;;;56500:18;;56590:98;56500:18;56674:6;56590:98;;56705:181;56807:2;56792:18;;56821:55;56796:9;56849:6;56821:55;;56893:193;57001:2;56986:18;;57015:61;56990:9;57049:6;57015:61;;57093:189;57199:2;57184:18;;57213:59;57188:9;57245:6;57213:59;;57289:387;57470:2;57484:47;;;57455:18;;57545:121;57455:18;57545:121;;57683:387;57864:2;57878:47;;;57849:18;;57939:121;57849:18;57939:121;;58077:387;58258:2;58272:47;;;58243:18;;58333:121;58243:18;58333:121;;58471:387;58652:2;58666:47;;;58637:18;;58727:121;58637:18;58727:121;;58865:387;59046:2;59060:47;;;59031:18;;59121:121;59031:18;59121:121;;59259:387;59440:2;59454:47;;;59425:18;;59515:121;59425:18;59515:121;;59653:387;59834:2;59848:47;;;59819:18;;59909:121;59819:18;59909:121;;60047:387;60228:2;60242:47;;;60213:18;;60303:121;60213:18;60303:121;;60441:387;60622:2;60636:47;;;60607:18;;60697:121;60607:18;60697:121;;60835:387;61016:2;61030:47;;;61001:18;;61091:121;61001:18;61091:121;;61229:387;61410:2;61424:47;;;61395:18;;61485:121;61395:18;61485:121;;61623:572;61870:2;61855:18;;61884:88;61859:9;61945:6;61884:88;;;62020:9;62014:4;62010:20;62005:2;61994:9;61990:18;61983:48;62045:140;62180:4;62171:6;62045:140;;62202:513;62443:3;62428:19;;62458:88;62432:9;62519:6;62458:88;;;62557:148;62701:2;62690:9;62686:18;62677:6;62557:148;;62722:584;62975:2;62960:18;;62989:88;62964:9;63050:6;62989:88;;;63125:9;63119:4;63115:20;63110:2;63099:9;63095:18;63088:48;63150:146;63291:4;63282:6;63150:146;;63845:576;64094:2;64079:18;;64108:88;64083:9;64169:6;64108:88;;;64244:9;64238:4;64234:20;64229:2;64218:9;64214:18;64207:48;64269:142;64406:4;64397:6;64269:142;;64428:564;64671:2;64656:18;;64685:88;64660:9;64746:6;64685:88;;;64821:9;64815:4;64811:20;64806:2;64795:9;64791:18;64784:48;64846:136;64977:4;64968:6;64846:136;;64999:576;65248:2;65233:18;;65262:88;65237:9;65323:6;65262:88;;;65398:9;65392:4;65388:20;65383:2;65372:9;65368:18;65361:48;65423:142;65560:4;65551:6;65423:142;;65582:564;65825:2;65810:18;;65839:88;65814:9;65900:6;65839:88;;;65975:9;65969:4;65965:20;65960:2;65949:9;65945:18;65938:48;66000:136;66131:4;66122:6;66000:136;;66153:685;66400:3;66385:19;;66415:88;66389:9;66476:6;66415:88;;;66514:70;66580:2;66569:9;66565:18;66556:6;66514:70;;;66595;66661:2;66650:9;66646:18;66637:6;66595:70;;;66676;66742:2;66731:9;66727:18;66718:6;66676:70;;;66757:71;66823:3;66812:9;66808:19;66799:6;66757:71;;66845:317;67015:2;67000:18;;67029:123;67004:9;67125:6;67029:123;;67369:803;67645:3;67630:19;;67660:61;67634:9;67694:6;67660:61;;;67732:62;67790:2;67779:9;67775:18;67766:6;67732:62;;;67805;67863:2;67852:9;67848:18;67839:6;67805:62;;;67878;67936:2;67925:9;67921:18;67912:6;67878:62;;;67951:63;68009:3;67998:9;67994:19;67985:6;67951:63;;;68025;68083:3;68072:9;68068:19;68059:6;68025:63;;;68099;68157:3;68146:9;68142:19;68133:6;68099:63;;;67616:556;;;;;;;;;;;68179:1099;68555:3;68540:19;;68570:61;68544:9;68604:6;68570:61;;;68642:62;68700:2;68689:9;68685:18;68676:6;68642:62;;;68715;68773:2;68762:9;68758:18;68749:6;68715:62;;;68825:9;68819:4;68815:20;68810:2;68799:9;68795:18;68788:48;68850:98;68943:4;68934:6;68850:98;;;68842:106;;68997:9;68991:4;68987:20;68981:3;68970:9;68966:19;68959:49;69022:98;69115:4;69106:6;69022:98;;;69014:106;;69131:63;69189:3;69178:9;69174:19;69165:6;69131:63;;;69205;69263:3;69252:9;69248:19;69239:6;69205:63;;69285:1285;69707:3;69692:19;;69722:61;69696:9;69756:6;69722:61;;;69794:62;69852:2;69841:9;69837:18;69828:6;69794:62;;;69867;69925:2;69914:9;69910:18;69901:6;69867:62;;;69977:9;69971:4;69967:20;69962:2;69951:9;69947:18;69940:48;70002:98;70095:4;70086:6;70002:98;;;69994:106;;70149:9;70143:4;70139:20;70133:3;70122:9;70118:19;70111:49;70174:98;70267:4;70258:6;70174:98;;;70166:106;;70321:9;70315:4;70311:20;70305:3;70294:9;70290:19;70283:49;70346:66;70407:4;70398:6;70346:66;;;70338:74;;70423:63;70481:3;70470:9;70466:19;70457:6;70423:63;;;70497;70555:3;70544:9;70540:19;70531:6;70497:63;;;69678:892;;;;;;;;;;;;70577:803;70853:3;70838:19;;70868:61;70842:9;70902:6;70868:61;;;70940:62;70998:2;70987:9;70983:18;70974:6;70940:62;;;71013;71071:2;71060:9;71056:18;71047:6;71013:62;;;71086;71144:2;71133:9;71129:18;71120:6;71086:62;;;71159:63;71217:3;71206:9;71202:19;71193:6;71159:63;;;71233;71291:3;71280:9;71276:19;71267:6;71233:63;;71387:294;71523:2;71508:18;;71537:61;71512:9;71571:6;71537:61;;;71609:62;71667:2;71656:9;71652:18;71643:6;71609:62;;71688:256;71750:2;71744:9;71776:17;;;71851:18;71836:34;;71872:22;;;71833:62;71830:2;;;71908:1;71905;71898:12;71830:2;71924;71917:22;71728:216;;-1:-1;71728:216;71951:284;;72136:18;72128:6;72125:30;72122:2;;;72168:1;72165;72158:12;72122:2;-1:-1;72197:4;72185:17;;;72215:15;;72059:176;73098:258;;73241:18;73233:6;73230:30;73227:2;;;73273:1;73270;73263:12;73227:2;-1:-1;73346:4;73317;73294:17;;;;-1:-1;;73290:33;73336:15;;73164:192;73365:148;73501:4;73489:17;;73470:43;73782:134;73899:12;;73883:33;74755:128;-1:-1;;;;;74824:54;;74807:76;74890:92;74963:13;74956:21;;74939:43;75075:151;75154:66;75143:78;;75126:100;75725:88;75803:4;75792:16;;75775:38;75821:145;75902:6;75897:3;75892;75879:30;-1:-1;75958:1;75940:16;;75933:27;75872:94;75975:268;76040:1;76047:101;76061:6;76058:1;76055:13;76047:101;;;76128:11;;;76122:18;76109:11;;;76102:39;76083:2;76076:10;76047:101;;;76163:6;76160:1;76157:13;76154:2;;;-1:-1;;76228:1;76210:16;;76203:27;76024:219;76251:97;76339:2;76319:14;-1:-1;;76315:28;;76299:49

Swarm Source

bzzr://f2bc84465e5a52aaccfb3f929bfb7a3f77e3fb0269d9690d437f40b6eab310d6
Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Block Uncle Number Difficulty Gas Used Reward
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.