ETH Price: $3,555.31 (+7.83%)

Contract

0x103675510a219bd84CE91d1bcb82Ca194D665a09
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Token Holdings

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Execute212717482024-11-26 11:53:2327 hrs ago1732622003IN
Argent: Transfer Manager
0 ETH0.0042737220.06217566
Execute212714712024-11-26 10:57:2328 hrs ago1732618643IN
Argent: Transfer Manager
0 ETH0.0021761410.215
Execute212611782024-11-25 0:26:352 days ago1732494395IN
Argent: Transfer Manager
0 ETH0.001606917.543
Execute212609032024-11-24 23:31:232 days ago1732491083IN
Argent: Transfer Manager
0 ETH0.001658367.784
Execute212485022024-11-23 5:59:354 days ago1732341575IN
Argent: Transfer Manager
0 ETH0.002186429.644
Execute212038682024-11-17 0:32:5910 days ago1731803579IN
Argent: Transfer Manager
0 ETH0.002245110.564
Execute211455592024-11-08 21:18:1118 days ago1731100691IN
Argent: Transfer Manager
0 ETH0.0036988316.35271803
Execute211414492024-11-08 7:32:3519 days ago1731051155IN
Argent: Transfer Manager
0 ETH0.001717328.062
Execute211274722024-11-06 8:39:1121 days ago1730882351IN
Argent: Transfer Manager
0 ETH0.0051489224.229
Execute211098342024-11-03 21:34:3523 days ago1730669675IN
Argent: Transfer Manager
0 ETH0.000679223.196
Execute210733892024-10-29 19:29:1128 days ago1730230151IN
Argent: Transfer Manager
0 ETH0.0039507117.426
Execute210517032024-10-26 18:51:4731 days ago1729968707IN
Argent: Transfer Manager
0 ETH0.001601647.53675323
Execute210282042024-10-23 12:11:4735 days ago1729685507IN
Argent: Transfer Manager
0 ETH0.002822713.25
Execute210069972024-10-20 13:09:2338 days ago1729429763IN
Argent: Transfer Manager
0 ETH0.0030930213.675
Execute210011822024-10-19 17:42:5938 days ago1729359779IN
Argent: Transfer Manager
0 ETH0.0021905610.308
Execute209993272024-10-19 11:30:3539 days ago1729337435IN
Argent: Transfer Manager
0 ETH0.0023975611.25489597
Execute209921442024-10-18 11:27:1140 days ago1729250831IN
Argent: Transfer Manager
0 ETH0.00764635.891
Execute209409582024-10-11 7:42:1147 days ago1728632531IN
Argent: Transfer Manager
0 ETH0.0023408110.988
Execute209087812024-10-06 20:04:1151 days ago1728245051IN
Argent: Transfer Manager
0 ETH0.001046044.922
Execute208597422024-09-30 0:00:2358 days ago1727654423IN
Argent: Transfer Manager
0 ETH0.00121115.342
Execute208294632024-09-25 18:39:3562 days ago1727289575IN
Argent: Transfer Manager
0 ETH0.0051130822.553
Execute208102712024-09-23 2:22:3565 days ago1727058155IN
Argent: Transfer Manager
0 ETH0.001606277.54
Execute207702842024-09-17 12:18:5971 days ago1726575539IN
Argent: Transfer Manager
0 ETH0.000574332.696
Execute207585362024-09-15 20:53:4772 days ago1726433627IN
Argent: Transfer Manager
0 ETH0.000379541.786
Execute207572322024-09-15 16:32:2372 days ago1726417943IN
Argent: Transfer Manager
0 ETH0.00052931.688
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block From To
212717482024-11-26 11:53:2327 hrs ago1732622003
0x10367551...94D665a09
0 ETH
212717482024-11-26 11:53:2327 hrs ago1732622003
0x10367551...94D665a09
0 ETH
212717482024-11-26 11:53:2327 hrs ago1732622003
0x10367551...94D665a09
0x10367551...94D665a09
0 ETH
212717482024-11-26 11:53:2327 hrs ago1732622003
0x10367551...94D665a09
0 ETH
212717482024-11-26 11:53:2327 hrs ago1732622003
0x10367551...94D665a09
0 ETH
212714712024-11-26 10:57:2328 hrs ago1732618643
0x10367551...94D665a09
0 ETH
212714712024-11-26 10:57:2328 hrs ago1732618643
0x10367551...94D665a09
0 ETH
212714712024-11-26 10:57:2328 hrs ago1732618643
0x10367551...94D665a09
0x10367551...94D665a09
0 ETH
212714712024-11-26 10:57:2328 hrs ago1732618643
0x10367551...94D665a09
0 ETH
212714712024-11-26 10:57:2328 hrs ago1732618643
0x10367551...94D665a09
0 ETH
212611782024-11-25 0:26:352 days ago1732494395
0x10367551...94D665a09
0 ETH
212611782024-11-25 0:26:352 days ago1732494395
0x10367551...94D665a09
0 ETH
212611782024-11-25 0:26:352 days ago1732494395
0x10367551...94D665a09
0x10367551...94D665a09
0 ETH
212611782024-11-25 0:26:352 days ago1732494395
0x10367551...94D665a09
0 ETH
212611782024-11-25 0:26:352 days ago1732494395
0x10367551...94D665a09
0 ETH
212609032024-11-24 23:31:232 days ago1732491083
0x10367551...94D665a09
0 ETH
212609032024-11-24 23:31:232 days ago1732491083
0x10367551...94D665a09
0 ETH
212609032024-11-24 23:31:232 days ago1732491083
0x10367551...94D665a09
0x10367551...94D665a09
0 ETH
212609032024-11-24 23:31:232 days ago1732491083
0x10367551...94D665a09
0 ETH
212609032024-11-24 23:31:232 days ago1732491083
0x10367551...94D665a09
0 ETH
212485022024-11-23 5:59:354 days ago1732341575
0x10367551...94D665a09
0 ETH
212485022024-11-23 5:59:354 days ago1732341575
0x10367551...94D665a09
0 ETH
212485022024-11-23 5:59:354 days ago1732341575
0x10367551...94D665a09
0x10367551...94D665a09
0 ETH
212485022024-11-23 5:59:354 days ago1732341575
0x10367551...94D665a09
0 ETH
212485022024-11-23 5:59:354 days ago1732341575
0x10367551...94D665a09
0 ETH
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
TransferManager

Compiler Version
v0.5.4+commit.9549d8ff

Optimization Enabled:
Yes with 999 runs

Other Settings:
default evmVersion, GNU GPLv3 license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2020-05-08
*/

pragma solidity ^0.5.4;// Copyright (C) 2018  Argent Labs Ltd. <https://argent.xyz>

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.


/**
 * @title Module
 * @dev Interface for a module.
 * A module MUST implement the addModule() method to ensure that a wallet with at least one module
 * can never end up in a "frozen" state.
 * @author Julien Niset - <[email protected]>
 */
interface Module {

    /**
     * @dev Inits a module for a wallet by e.g. setting some wallet specific parameters in storage.
     * @param _wallet The wallet.
     */
    function init(BaseWallet _wallet) external;

    /**
     * @dev Adds a module to a wallet.
     * @param _wallet The target wallet.
     * @param _module The modules to authorise.
     */
    function addModule(BaseWallet _wallet, Module _module) external;

    /**
    * @dev Utility method to recover any ERC20 token that was sent to the
    * module by mistake.
    * @param _token The token to recover.
    */
    function recoverToken(address _token) external;
}// Copyright (C) 2018  Argent Labs Ltd. <https://argent.xyz>

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.


/**
 * @title BaseWallet
 * @dev Simple modular wallet that authorises modules to call its invoke() method.
 * @author Julien Niset - <[email protected]>
 */
contract BaseWallet {

    // The implementation of the proxy
    address public implementation;
    // The owner
    address public owner;
    // The authorised modules
    mapping (address => bool) public authorised;
    // The enabled static calls
    mapping (bytes4 => address) public enabled;
    // The number of modules
    uint public modules;

    event AuthorisedModule(address indexed module, bool value);
    event EnabledStaticCall(address indexed module, bytes4 indexed method);
    event Invoked(address indexed module, address indexed target, uint indexed value, bytes data);
    event Received(uint indexed value, address indexed sender, bytes data);
    event OwnerChanged(address owner);

    /**
     * @dev Throws if the sender is not an authorised module.
     */
    modifier moduleOnly {
        require(authorised[msg.sender], "BW: msg.sender not an authorized module");
        _;
    }

    /**
     * @dev Inits the wallet by setting the owner and authorising a list of modules.
     * @param _owner The owner.
     * @param _modules The modules to authorise.
     */
    function init(address _owner, address[] calldata _modules) external {
        require(owner == address(0) && modules == 0, "BW: wallet already initialised");
        require(_modules.length > 0, "BW: construction requires at least 1 module");
        owner = _owner;
        modules = _modules.length;
        for (uint256 i = 0; i < _modules.length; i++) {
            require(authorised[_modules[i]] == false, "BW: module is already added");
            authorised[_modules[i]] = true;
            Module(_modules[i]).init(this);
            emit AuthorisedModule(_modules[i], true);
        }
        if (address(this).balance > 0) {
            emit Received(address(this).balance, address(0), "");
        }
    }

    /**
     * @dev Enables/Disables a module.
     * @param _module The target module.
     * @param _value Set to true to authorise the module.
     */
    function authoriseModule(address _module, bool _value) external moduleOnly {
        if (authorised[_module] != _value) {
            emit AuthorisedModule(_module, _value);
            if (_value == true) {
                modules += 1;
                authorised[_module] = true;
                Module(_module).init(this);
            } else {
                modules -= 1;
                require(modules > 0, "BW: wallet must have at least one module");
                delete authorised[_module];
            }
        }
    }

    /**
    * @dev Enables a static method by specifying the target module to which the call
    * must be delegated.
    * @param _module The target module.
    * @param _method The static method signature.
    */
    function enableStaticCall(address _module, bytes4 _method) external moduleOnly {
        require(authorised[_module], "BW: must be an authorised module for static call");
        enabled[_method] = _module;
        emit EnabledStaticCall(_module, _method);
    }

    /**
     * @dev Sets a new owner for the wallet.
     * @param _newOwner The new owner.
     */
    function setOwner(address _newOwner) external moduleOnly {
        require(_newOwner != address(0), "BW: address cannot be null");
        owner = _newOwner;
        emit OwnerChanged(_newOwner);
    }

    /**
     * @dev Performs a generic transaction.
     * @param _target The address for the transaction.
     * @param _value The value of the transaction.
     * @param _data The data of the transaction.
     */
    function invoke(address _target, uint _value, bytes calldata _data) external moduleOnly returns (bytes memory _result) {
        bool success;
        // solium-disable-next-line security/no-call-value
        (success, _result) = _target.call.value(_value)(_data);
        if (!success) {
            // solium-disable-next-line security/no-inline-assembly
            assembly {
                returndatacopy(0, 0, returndatasize)
                revert(0, returndatasize)
            }
        }
        emit Invoked(msg.sender, _target, _value, _data);
    }

    /**
     * @dev This method makes it possible for the wallet to comply to interfaces expecting the wallet to
     * implement specific static methods. It delegates the static call to a target contract if the data corresponds
     * to an enabled method, or logs the call otherwise.
     */
    function() external payable {
        if (msg.data.length > 0) {
            address module = enabled[msg.sig];
            if (module == address(0)) {
                emit Received(msg.value, msg.sender, msg.data);
            } else {
                require(authorised[module], "BW: must be an authorised module for static call");
                // solium-disable-next-line security/no-inline-assembly
                assembly {
                    calldatacopy(0, 0, calldatasize())
                    let result := staticcall(gas, module, 0, calldatasize(), 0, 0)
                    returndatacopy(0, 0, returndatasize())
                    switch result
                    case 0 {revert(0, returndatasize())}
                    default {return (0, returndatasize())}
                }
            }
        }
    }
}// Copyright (C) 2018  Argent Labs Ltd. <https://argent.xyz>

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.



/**
 * @title Owned
 * @dev Basic contract to define an owner.
 * @author Julien Niset - <[email protected]>
 */
contract Owned {

    // The owner
    address public owner;

    event OwnerChanged(address indexed _newOwner);

    /**
     * @dev Throws if the sender is not the owner.
     */
    modifier onlyOwner {
        require(msg.sender == owner, "Must be owner");
        _;
    }

    constructor() public {
        owner = msg.sender;
    }

    /**
     * @dev Lets the owner transfer ownership of the contract to a new owner.
     * @param _newOwner The new owner.
     */
    function changeOwner(address _newOwner) external onlyOwner {
        require(_newOwner != address(0), "Address must not be null");
        owner = _newOwner;
        emit OwnerChanged(_newOwner);
    }
}

/**
 * ERC20 contract interface.
 */
contract ERC20 {
    function totalSupply() public view returns (uint);
    function decimals() public view returns (uint);
    function balanceOf(address tokenOwner) public view returns (uint balance);
    function allowance(address tokenOwner, address spender) public view returns (uint remaining);
    function transfer(address to, uint tokens) public returns (bool success);
    function approve(address spender, uint tokens) public returns (bool success);
    function transferFrom(address from, address to, uint tokens) public returns (bool success);
}// Copyright (C) 2018  Argent Labs Ltd. <https://argent.xyz>

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.



/**
 * @title ModuleRegistry
 * @dev Registry of authorised modules.
 * Modules must be registered before they can be authorised on a wallet.
 * @author Julien Niset - <[email protected]>
 */
contract ModuleRegistry is Owned {

    mapping (address => Info) internal modules;
    mapping (address => Info) internal upgraders;

    event ModuleRegistered(address indexed module, bytes32 name);
    event ModuleDeRegistered(address module);
    event UpgraderRegistered(address indexed upgrader, bytes32 name);
    event UpgraderDeRegistered(address upgrader);

    struct Info {
        bool exists;
        bytes32 name;
    }

    /**
     * @dev Registers a module.
     * @param _module The module.
     * @param _name The unique name of the module.
     */
    function registerModule(address _module, bytes32 _name) external onlyOwner {
        require(!modules[_module].exists, "MR: module already exists");
        modules[_module] = Info({exists: true, name: _name});
        emit ModuleRegistered(_module, _name);
    }

    /**
     * @dev Deregisters a module.
     * @param _module The module.
     */
    function deregisterModule(address _module) external onlyOwner {
        require(modules[_module].exists, "MR: module does not exist");
        delete modules[_module];
        emit ModuleDeRegistered(_module);
    }

        /**
     * @dev Registers an upgrader.
     * @param _upgrader The upgrader.
     * @param _name The unique name of the upgrader.
     */
    function registerUpgrader(address _upgrader, bytes32 _name) external onlyOwner {
        require(!upgraders[_upgrader].exists, "MR: upgrader already exists");
        upgraders[_upgrader] = Info({exists: true, name: _name});
        emit UpgraderRegistered(_upgrader, _name);
    }

    /**
     * @dev Deregisters an upgrader.
     * @param _upgrader The _upgrader.
     */
    function deregisterUpgrader(address _upgrader) external onlyOwner {
        require(upgraders[_upgrader].exists, "MR: upgrader does not exist");
        delete upgraders[_upgrader];
        emit UpgraderDeRegistered(_upgrader);
    }

    /**
    * @dev Utility method enbaling the owner of the registry to claim any ERC20 token that was sent to the
    * registry.
    * @param _token The token to recover.
    */
    function recoverToken(address _token) external onlyOwner {
        uint total = ERC20(_token).balanceOf(address(this));
        ERC20(_token).transfer(msg.sender, total);
    }

    /**
     * @dev Gets the name of a module from its address.
     * @param _module The module address.
     * @return the name.
     */
    function moduleInfo(address _module) external view returns (bytes32) {
        return modules[_module].name;
    }

    /**
     * @dev Gets the name of an upgrader from its address.
     * @param _upgrader The upgrader address.
     * @return the name.
     */
    function upgraderInfo(address _upgrader) external view returns (bytes32) {
        return upgraders[_upgrader].name;
    }

    /**
     * @dev Checks if a module is registered.
     * @param _module The module address.
     * @return true if the module is registered.
     */
    function isRegisteredModule(address _module) external view returns (bool) {
        return modules[_module].exists;
    }

    /**
     * @dev Checks if a list of modules are registered.
     * @param _modules The list of modules address.
     * @return true if all the modules are registered.
     */
    function isRegisteredModule(address[] calldata _modules) external view returns (bool) {
        for (uint i = 0; i < _modules.length; i++) {
            if (!modules[_modules[i]].exists) {
                return false;
            }
        }
        return true;
    }

    /**
     * @dev Checks if an upgrader is registered.
     * @param _upgrader The upgrader address.
     * @return true if the upgrader is registered.
     */
    function isRegisteredUpgrader(address _upgrader) external view returns (bool) {
        return upgraders[_upgrader].exists;
    }
}// Copyright (C) 2018  Argent Labs Ltd. <https://argent.xyz>

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.


/**
 * @title Storage
 * @dev Base contract for the storage of a wallet.
 * @author Julien Niset - <[email protected]>
 */
contract Storage {

    /**
     * @dev Throws if the caller is not an authorised module.
     */
    modifier onlyModule(BaseWallet _wallet) {
        require(_wallet.authorised(msg.sender), "TS: must be an authorized module to call this method");
        _;
    }
}// Copyright (C) 2018  Argent Labs Ltd. <https://argent.xyz>

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.


interface IGuardianStorage{

    /**
     * @dev Lets an authorised module add a guardian to a wallet.
     * @param _wallet The target wallet.
     * @param _guardian The guardian to add.
     */
    function addGuardian(BaseWallet _wallet, address _guardian) external;

    /**
     * @dev Lets an authorised module revoke a guardian from a wallet.
     * @param _wallet The target wallet.
     * @param _guardian The guardian to revoke.
     */
    function revokeGuardian(BaseWallet _wallet, address _guardian) external;

    /**
     * @dev Checks if an account is a guardian for a wallet.
     * @param _wallet The target wallet.
     * @param _guardian The account.
     * @return true if the account is a guardian for a wallet.
     */
    function isGuardian(BaseWallet _wallet, address _guardian) external view returns (bool);
}// Copyright (C) 2018  Argent Labs Ltd. <https://argent.xyz>

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.




/**
 * @title GuardianStorage
 * @dev Contract storing the state of wallets related to guardians and lock.
 * The contract only defines basic setters and getters with no logic. Only modules authorised
 * for a wallet can modify its state.
 * @author Julien Niset - <[email protected]>
 * @author Olivier Van Den Biggelaar - <[email protected]>
 */
contract GuardianStorage is IGuardianStorage, Storage {

    struct GuardianStorageConfig {
        // the list of guardians
        address[] guardians;
        // the info about guardians
        mapping (address => GuardianInfo) info;
        // the lock's release timestamp
        uint256 lock;
        // the module that set the last lock
        address locker;
    }

    struct GuardianInfo {
        bool exists;
        uint128 index;
    }

    // wallet specific storage
    mapping (address => GuardianStorageConfig) internal configs;

    // *************** External Functions ********************* //

    /**
     * @dev Lets an authorised module add a guardian to a wallet.
     * @param _wallet The target wallet.
     * @param _guardian The guardian to add.
     */
    function addGuardian(BaseWallet _wallet, address _guardian) external onlyModule(_wallet) {
        GuardianStorageConfig storage config = configs[address(_wallet)];
        config.info[_guardian].exists = true;
        config.info[_guardian].index = uint128(config.guardians.push(_guardian) - 1);
    }

    /**
     * @dev Lets an authorised module revoke a guardian from a wallet.
     * @param _wallet The target wallet.
     * @param _guardian The guardian to revoke.
     */
    function revokeGuardian(BaseWallet _wallet, address _guardian) external onlyModule(_wallet) {
        GuardianStorageConfig storage config = configs[address(_wallet)];
        address lastGuardian = config.guardians[config.guardians.length - 1];
        if (_guardian != lastGuardian) {
            uint128 targetIndex = config.info[_guardian].index;
            config.guardians[targetIndex] = lastGuardian;
            config.info[lastGuardian].index = targetIndex;
        }
        config.guardians.length--;
        delete config.info[_guardian];
    }

    /**
     * @dev Returns the number of guardians for a wallet.
     * @param _wallet The target wallet.
     * @return the number of guardians.
     */
    function guardianCount(BaseWallet _wallet) external view returns (uint256) {
        return configs[address(_wallet)].guardians.length;
    }

    /**
     * @dev Gets the list of guaridans for a wallet.
     * @param _wallet The target wallet.
     * @return the list of guardians.
     */
    function getGuardians(BaseWallet _wallet) external view returns (address[] memory) {
        GuardianStorageConfig storage config = configs[address(_wallet)];
        address[] memory guardians = new address[](config.guardians.length);
        for (uint256 i = 0; i < config.guardians.length; i++) {
            guardians[i] = config.guardians[i];
        }
        return guardians;
    }

    /**
     * @dev Checks if an account is a guardian for a wallet.
     * @param _wallet The target wallet.
     * @param _guardian The account.
     * @return true if the account is a guardian for a wallet.
     */
    function isGuardian(BaseWallet _wallet, address _guardian) external view returns (bool) {
        return configs[address(_wallet)].info[_guardian].exists;
    }

    /**
     * @dev Lets an authorised module set the lock for a wallet.
     * @param _wallet The target wallet.
     * @param _releaseAfter The epoch time at which the lock should automatically release.
     */
    function setLock(BaseWallet _wallet, uint256 _releaseAfter) external onlyModule(_wallet) {
        configs[address(_wallet)].lock = _releaseAfter;
        if (_releaseAfter != 0 && msg.sender != configs[address(_wallet)].locker) {
            configs[address(_wallet)].locker = msg.sender;
        }
    }

    /**
     * @dev Checks if the lock is set for a wallet.
     * @param _wallet The target wallet.
     * @return true if the lock is set for the wallet.
     */
    function isLocked(BaseWallet _wallet) external view returns (bool) {
        return configs[address(_wallet)].lock > now;
    }

    /**
     * @dev Gets the time at which the lock of a wallet will release.
     * @param _wallet The target wallet.
     * @return the time at which the lock of a wallet will release, or zero if there is no lock set.
     */
    function getLock(BaseWallet _wallet) external view returns (uint256) {
        return configs[address(_wallet)].lock;
    }

    /**
     * @dev Gets the address of the last module that modified the lock for a wallet.
     * @param _wallet The target wallet.
     * @return the address of the last module that modified the lock for a wallet.
     */
    function getLocker(BaseWallet _wallet) external view returns (address) {
        return configs[address(_wallet)].locker;
    }
}/* The MIT License (MIT)

Copyright (c) 2016 Smart Contract Solutions, Inc.

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */



/**
 * @title SafeMath
 * @dev Math operations with safety checks that throw 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;
    }

    /**
    * @dev Returns ceil(a / b).
    */
    function ceil(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a / b;
        if(a % b == 0) {
            return c;
        }
        else {
            return c + 1;
        }
    }

    // from DSMath - operations on fixed precision floats

    uint256 constant WAD = 10 ** 18;
    uint256 constant RAY = 10 ** 27;

    function wmul(uint256 x, uint256 y) internal pure returns (uint256 z) {
        z = add(mul(x, y), WAD / 2) / WAD;
    }
    function rmul(uint256 x, uint256 y) internal pure returns (uint256 z) {
        z = add(mul(x, y), RAY / 2) / RAY;
    }
    function wdiv(uint256 x, uint256 y) internal pure returns (uint256 z) {
        z = add(mul(x, WAD), y / 2) / y;
    }
    function rdiv(uint256 x, uint256 y) internal pure returns (uint256 z) {
        z = add(mul(x, RAY), y / 2) / y;
    }
}
// Copyright (C) 2018  Argent Labs Ltd. <https://argent.xyz>

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.







/**
 * @title BaseModule
 * @dev Basic module that contains some methods common to all modules.
 * @author Julien Niset - <[email protected]>
 */
contract BaseModule is Module {

    // Empty calldata
    bytes constant internal EMPTY_BYTES = "";

    // The adddress of the module registry.
    ModuleRegistry internal registry;
    // The address of the Guardian storage
    GuardianStorage internal guardianStorage;

    /**
     * @dev Throws if the wallet is locked.
     */
    modifier onlyWhenUnlocked(BaseWallet _wallet) {
        // solium-disable-next-line security/no-block-members
        require(!guardianStorage.isLocked(_wallet), "BM: wallet must be unlocked");
        _;
    }

    event ModuleCreated(bytes32 name);
    event ModuleInitialised(address wallet);

    constructor(ModuleRegistry _registry, GuardianStorage _guardianStorage, bytes32 _name) public {
        registry = _registry;
        guardianStorage = _guardianStorage;
        emit ModuleCreated(_name);
    }

    /**
     * @dev Throws if the sender is not the target wallet of the call.
     */
    modifier onlyWallet(BaseWallet _wallet) {
        require(msg.sender == address(_wallet), "BM: caller must be wallet");
        _;
    }

    /**
     * @dev Throws if the sender is not the owner of the target wallet or the module itself.
     */
    modifier onlyWalletOwner(BaseWallet _wallet) {
        require(msg.sender == address(this) || isOwner(_wallet, msg.sender), "BM: must be an owner for the wallet");
        _;
    }

    /**
     * @dev Throws if the sender is not the owner of the target wallet.
     */
    modifier strictOnlyWalletOwner(BaseWallet _wallet) {
        require(isOwner(_wallet, msg.sender), "BM: msg.sender must be an owner for the wallet");
        _;
    }

    /**
     * @dev Inits the module for a wallet by logging an event.
     * The method can only be called by the wallet itself.
     * @param _wallet The wallet.
     */
    function init(BaseWallet _wallet) public onlyWallet(_wallet) {
        emit ModuleInitialised(address(_wallet));
    }

    /**
     * @dev Adds a module to a wallet. First checks that the module is registered.
     * @param _wallet The target wallet.
     * @param _module The modules to authorise.
     */
    function addModule(BaseWallet _wallet, Module _module) external strictOnlyWalletOwner(_wallet) {
        require(registry.isRegisteredModule(address(_module)), "BM: module is not registered");
        _wallet.authoriseModule(address(_module), true);
    }

    /**
    * @dev Utility method enbaling anyone to recover ERC20 token sent to the
    * module by mistake and transfer them to the Module Registry.
    * @param _token The token to recover.
    */
    function recoverToken(address _token) external {
        uint total = ERC20(_token).balanceOf(address(this));
        ERC20(_token).transfer(address(registry), total);
    }

    /**
     * @dev Helper method to check if an address is the owner of a target wallet.
     * @param _wallet The target wallet.
     * @param _addr The address.
     */
    function isOwner(BaseWallet _wallet, address _addr) internal view returns (bool) {
        return _wallet.owner() == _addr;
    }

    /**
     * @dev Helper method to invoke a wallet.
     * @param _wallet The target wallet.
     * @param _to The target address for the transaction.
     * @param _value The value of the transaction.
     * @param _data The data of the transaction.
     */
    function invokeWallet(address _wallet, address _to, uint256 _value, bytes memory _data) internal returns (bytes memory _res) {
        bool success;
        // solium-disable-next-line security/no-call-value
        (success, _res) = _wallet.call(abi.encodeWithSignature("invoke(address,uint256,bytes)", _to, _value, _data));
        if (success && _res.length > 0) { //_res is empty if _wallet is an "old" BaseWallet that can't return output values
            (_res) = abi.decode(_res, (bytes));
        } else if (_res.length > 0) {
            // solium-disable-next-line security/no-inline-assembly
            assembly {
                returndatacopy(0, 0, returndatasize)
                revert(0, returndatasize)
            }
        } else if (!success) {
            revert("BM: wallet invoke reverted");
        }
    }
}// Copyright (C) 2018  Argent Labs Ltd. <https://argent.xyz>

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.



/**
 * @title RelayerModule
 * @dev Base module containing logic to execute transactions signed by eth-less accounts and sent by a relayer.
 * @author Julien Niset - <[email protected]>
 */
contract RelayerModule is BaseModule {

    uint256 constant internal BLOCKBOUND = 10000;

    mapping (address => RelayerConfig) public relayer;

    struct RelayerConfig {
        uint256 nonce;
        mapping (bytes32 => bool) executedTx;
    }

    event TransactionExecuted(address indexed wallet, bool indexed success, bytes32 signedHash);

    /**
     * @dev Throws if the call did not go through the execute() method.
     */
    modifier onlyExecute {
        require(msg.sender == address(this), "RM: must be called via execute()");
        _;
    }

    /* ***************** Abstract method ************************* */

    /**
    * @dev Gets the number of valid signatures that must be provided to execute a
    * specific relayed transaction.
    * @param _wallet The target wallet.
    * @param _data The data of the relayed transaction.
    * @return The number of required signatures.
    */
    function getRequiredSignatures(BaseWallet _wallet, bytes memory _data) internal view returns (uint256);

    /**
    * @dev Validates the signatures provided with a relayed transaction.
    * The method MUST throw if one or more signatures are not valid.
    * @param _wallet The target wallet.
    * @param _data The data of the relayed transaction.
    * @param _signHash The signed hash representing the relayed transaction.
    * @param _signatures The signatures as a concatenated byte array.
    */
    function validateSignatures(
        BaseWallet _wallet,
        bytes memory _data,
        bytes32 _signHash,
        bytes memory _signatures) internal view returns (bool);

    /* ************************************************************ */

    /**
    * @dev Executes a relayed transaction.
    * @param _wallet The target wallet.
    * @param _data The data for the relayed transaction
    * @param _nonce The nonce used to prevent replay attacks.
    * @param _signatures The signatures as a concatenated byte array.
    * @param _gasPrice The gas price to use for the gas refund.
    * @param _gasLimit The gas limit to use for the gas refund.
    */
    function execute(
        BaseWallet _wallet,
        bytes calldata _data,
        uint256 _nonce,
        bytes calldata _signatures,
        uint256 _gasPrice,
        uint256 _gasLimit
    )
        external
        returns (bool success)
    {
        uint startGas = gasleft();
        bytes32 signHash = getSignHash(address(this), address(_wallet), 0, _data, _nonce, _gasPrice, _gasLimit);
        require(checkAndUpdateUniqueness(_wallet, _nonce, signHash), "RM: Duplicate request");
        require(verifyData(address(_wallet), _data), "RM: the wallet authorized is different then the target of the relayed data");
        uint256 requiredSignatures = getRequiredSignatures(_wallet, _data);
        if ((requiredSignatures * 65) == _signatures.length) {
            if (verifyRefund(_wallet, _gasLimit, _gasPrice, requiredSignatures)) {
                if (requiredSignatures == 0 || validateSignatures(_wallet, _data, signHash, _signatures)) {
                    // solium-disable-next-line security/no-call-value
                    (success,) = address(this).call(_data);
                    refund(_wallet, startGas - gasleft(), _gasPrice, _gasLimit, requiredSignatures, msg.sender);
                }
            }
        }
        emit TransactionExecuted(address(_wallet), success, signHash);
    }

    /**
    * @dev Gets the current nonce for a wallet.
    * @param _wallet The target wallet.
    */
    function getNonce(BaseWallet _wallet) external view returns (uint256 nonce) {
        return relayer[address(_wallet)].nonce;
    }

    /**
    * @dev Generates the signed hash of a relayed transaction according to ERC 1077.
    * @param _from The starting address for the relayed transaction (should be the module)
    * @param _to The destination address for the relayed transaction (should be the wallet)
    * @param _value The value for the relayed transaction
    * @param _data The data for the relayed transaction
    * @param _nonce The nonce used to prevent replay attacks.
    * @param _gasPrice The gas price to use for the gas refund.
    * @param _gasLimit The gas limit to use for the gas refund.
    */
    function getSignHash(
        address _from,
        address _to,
        uint256 _value,
        bytes memory _data,
        uint256 _nonce,
        uint256 _gasPrice,
        uint256 _gasLimit
    )
        internal
        pure
        returns (bytes32)
    {
        return keccak256(
            abi.encodePacked(
                "\x19Ethereum Signed Message:\n32",
                keccak256(abi.encodePacked(byte(0x19), byte(0), _from, _to, _value, _data, _nonce, _gasPrice, _gasLimit))
        ));
    }

    /**
    * @dev Checks if the relayed transaction is unique.
    * @param _wallet The target wallet.
    * @param _signHash The signed hash of the transaction
    */
    function checkAndUpdateUniqueness(BaseWallet _wallet, uint256 /* _nonce */, bytes32 _signHash) internal returns (bool) {
        if (relayer[address(_wallet)].executedTx[_signHash] == true) {
            return false;
        }
        relayer[address(_wallet)].executedTx[_signHash] = true;
        return true;
    }

    /**
    * @dev Checks that a nonce has the correct format and is valid.
    * It must be constructed as nonce = {block number}{timestamp} where each component is 16 bytes.
    * @param _wallet The target wallet.
    * @param _nonce The nonce
    */
    function checkAndUpdateNonce(BaseWallet _wallet, uint256 _nonce) internal returns (bool) {
        if (_nonce <= relayer[address(_wallet)].nonce) {
            return false;
        }
        uint256 nonceBlock = (_nonce & 0xffffffffffffffffffffffffffffffff00000000000000000000000000000000) >> 128;
        if (nonceBlock > block.number + BLOCKBOUND) {
            return false;
        }
        relayer[address(_wallet)].nonce = _nonce;
        return true;
    }

    /**
    * @dev Recovers the signer at a given position from a list of concatenated signatures.
    * @param _signedHash The signed hash
    * @param _signatures The concatenated signatures.
    * @param _index The index of the signature to recover.
    */
    function recoverSigner(bytes32 _signedHash, bytes memory _signatures, uint _index) internal pure returns (address) {
        uint8 v;
        bytes32 r;
        bytes32 s;
        // we jump 32 (0x20) as the first slot of bytes contains the length
        // we jump 65 (0x41) per signature
        // for v we load 32 bytes ending with v (the first 31 come from s) then apply a mask
        // solium-disable-next-line security/no-inline-assembly
        assembly {
            r := mload(add(_signatures, add(0x20,mul(0x41,_index))))
            s := mload(add(_signatures, add(0x40,mul(0x41,_index))))
            v := and(mload(add(_signatures, add(0x41,mul(0x41,_index)))), 0xff)
        }
        require(v == 27 || v == 28); // solium-disable-line error-reason
        return ecrecover(_signedHash, v, r, s);
    }

    /**
    * @dev Refunds the gas used to the Relayer.
    * For security reasons the default behavior is to not refund calls with 0 or 1 signatures.
    * @param _wallet The target wallet.
    * @param _gasUsed The gas used.
    * @param _gasPrice The gas price for the refund.
    * @param _gasLimit The gas limit for the refund.
    * @param _signatures The number of signatures used in the call.
    * @param _relayer The address of the Relayer.
    */
    function refund(BaseWallet _wallet, uint _gasUsed, uint _gasPrice, uint _gasLimit, uint _signatures, address _relayer) internal {
        uint256 amount = 29292 + _gasUsed; // 21000 (transaction) + 7620 (execution of refund) + 672 to log the event + _gasUsed
        // only refund if gas price not null, more than 1 signatures, gas less than gasLimit
        if (_gasPrice > 0 && _signatures > 1 && amount <= _gasLimit) {
            if (_gasPrice > tx.gasprice) {
                amount = amount * tx.gasprice;
            } else {
                amount = amount * _gasPrice;
            }
            invokeWallet(address(_wallet), _relayer, amount, EMPTY_BYTES);
        }
    }

    /**
    * @dev Returns false if the refund is expected to fail.
    * @param _wallet The target wallet.
    * @param _gasUsed The expected gas used.
    * @param _gasPrice The expected gas price for the refund.
    */
    function verifyRefund(BaseWallet _wallet, uint _gasUsed, uint _gasPrice, uint _signatures) internal view returns (bool) {
        if (_gasPrice > 0 &&
            _signatures > 1 &&
            (address(_wallet).balance < _gasUsed * _gasPrice || _wallet.authorised(address(this)) == false)) {
            return false;
        }
        return true;
    }

    /**
    * @dev Checks that the wallet address provided as the first parameter of the relayed data is the same
    * as the wallet passed as the input of the execute() method.
    @return false if the addresses are different.
    */
    function verifyData(address _wallet, bytes memory _data) private pure returns (bool) {
        require(_data.length >= 36, "RM: Invalid dataWallet");
        address dataWallet;
        // solium-disable-next-line security/no-inline-assembly
        assembly {
            //_data = {length:32}{sig:4}{_wallet:32}{...}
            dataWallet := mload(add(_data, 0x24))
        }
        return dataWallet == _wallet;
    }

    /**
    * @dev Parses the data to extract the method signature.
    */
    function functionPrefix(bytes memory _data) internal pure returns (bytes4 prefix) {
        require(_data.length >= 4, "RM: Invalid functionPrefix");
        // solium-disable-next-line security/no-inline-assembly
        assembly {
            prefix := mload(add(_data, 0x20))
        }
    }
}// Copyright (C) 2018  Argent Labs Ltd. <https://argent.xyz>

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.




/**
 * @title OnlyOwnerModule
 * @dev Module that extends BaseModule and RelayerModule for modules where the execute() method
 * must be called with one signature frm the owner.
 * @author Julien Niset - <[email protected]>
 */
contract OnlyOwnerModule is BaseModule, RelayerModule {

    // bytes4 private constant IS_ONLY_OWNER_MODULE = bytes4(keccak256("isOnlyOwnerModule()"));

   /**
    * @dev Returns a constant that indicates that the module is an OnlyOwnerModule.
    * @return The constant bytes4(keccak256("isOnlyOwnerModule()"))
    */
    function isOnlyOwnerModule() external pure returns (bytes4) {
        // return IS_ONLY_OWNER_MODULE;
        return this.isOnlyOwnerModule.selector;
    }

    /**
     * @dev Adds a module to a wallet. First checks that the module is registered.
     * Unlike its overrided parent, this method can be called via the RelayerModule's execute()
     * @param _wallet The target wallet.
     * @param _module The modules to authorise.
     */
    function addModule(BaseWallet _wallet, Module _module) external onlyWalletOwner(_wallet) {
        require(registry.isRegisteredModule(address(_module)), "BM: module is not registered");
        _wallet.authoriseModule(address(_module), true);
    }

    // *************** Implementation of RelayerModule methods ********************* //

    // Overrides to use the incremental nonce and save some gas
    function checkAndUpdateUniqueness(BaseWallet _wallet, uint256 _nonce, bytes32 /* _signHash */) internal returns (bool) {
        return checkAndUpdateNonce(_wallet, _nonce);
    }

    function validateSignatures(
        BaseWallet _wallet,
        bytes memory /* _data */,
        bytes32 _signHash,
        bytes memory _signatures
    )
        internal
        view
        returns (bool)
    {
        address signer = recoverSigner(_signHash, _signatures, 0);
        return isOwner(_wallet, signer); // "OOM: signer must be owner"
    }

    function getRequiredSignatures(BaseWallet /* _wallet */, bytes memory /* _data */) internal view returns (uint256) {
        return 1;
    }
}// Copyright (C) 2018  Argent Labs Ltd. <https://argent.xyz>

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.


/**
 * @title BaseTransfer
 * @dev Module containing internal methods to execute or approve transfers
 * @author Olivier VDB - <[email protected]>
 */
contract BaseTransfer is BaseModule {

    // Mock token address for ETH
    address constant internal ETH_TOKEN = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;

    // *************** Events *************************** //

    event Transfer(address indexed wallet, address indexed token, uint256 indexed amount, address to, bytes data);
    event Approved(address indexed wallet, address indexed token, uint256 amount, address spender);
    event CalledContract(address indexed wallet, address indexed to, uint256 amount, bytes data);
    event ApprovedAndCalledContract(
        address indexed wallet,
        address indexed to,
        address spender,
        address indexed token,
        uint256 amountApproved,
        uint256 amountSpent,
        bytes data
    );
    // *************** Internal Functions ********************* //

    /**
    * @dev Helper method to transfer ETH or ERC20 for a wallet.
    * @param _wallet The target wallet.
    * @param _token The ERC20 address.
    * @param _to The recipient.
    * @param _value The amount of ETH to transfer
    * @param _data The data to *log* with the transfer.
    */
    function doTransfer(BaseWallet _wallet, address _token, address _to, uint256 _value, bytes memory _data) internal {
        if (_token == ETH_TOKEN) {
            invokeWallet(address(_wallet), _to, _value, EMPTY_BYTES);
        } else {
            bytes memory methodData = abi.encodeWithSignature("transfer(address,uint256)", _to, _value);
            invokeWallet(address(_wallet), _token, 0, methodData);
        }
        emit Transfer(address(_wallet), _token, _value, _to, _data);
    }

    /**
    * @dev Helper method to approve spending the ERC20 of a wallet.
    * @param _wallet The target wallet.
    * @param _token The ERC20 address.
    * @param _spender The spender address.
    * @param _value The amount of token to transfer.
    */
    function doApproveToken(BaseWallet _wallet, address _token, address _spender, uint256 _value) internal {
        bytes memory methodData = abi.encodeWithSignature("approve(address,uint256)", _spender, _value);
        invokeWallet(address(_wallet), _token, 0, methodData);
        emit Approved(address(_wallet), _token, _value, _spender);
    }

    /**
    * @dev Helper method to call an external contract.
    * @param _wallet The target wallet.
    * @param _contract The contract address.
    * @param _value The ETH value to transfer.
    * @param _data The method data.
    */
    function doCallContract(BaseWallet _wallet, address _contract, uint256 _value, bytes memory _data) internal {
        invokeWallet(address(_wallet), _contract, _value, _data);
        emit CalledContract(address(_wallet), _contract, _value, _data);
    }

    /**
    * @dev Helper method to approve a certain amount of token and call an external contract.
    * The address that spends the _token and the address that is called with _data can be different.
    * @param _wallet The target wallet.
    * @param _token The ERC20 address.
    * @param _spender The spender address.
    * @param _amount The amount of tokens to transfer.
    * @param _contract The contract address.
    * @param _data The method data.
    */
    function doApproveTokenAndCallContract(
        BaseWallet _wallet,
        address _token,
        address _spender,
        uint256 _amount,
        address _contract,
        bytes memory _data
    )
        internal
    {
        uint256 existingAllowance = ERC20(_token).allowance(address(_wallet), _spender);
        uint256 totalAllowance = SafeMath.add(existingAllowance, _amount);
        // Approve the desired amount plus existing amount. This logic allows for potential gas saving later
        // when restoring the original approved amount, in cases where the _spender uses the exact approved _amount.
        bytes memory methodData = abi.encodeWithSignature("approve(address,uint256)", _spender, totalAllowance);

        invokeWallet(address(_wallet), _token, 0, methodData);
        invokeWallet(address(_wallet), _contract, 0, _data);

        // Calculate the approved amount that was spent after the call
        uint256 unusedAllowance = ERC20(_token).allowance(address(_wallet), _spender);
        uint256 usedAllowance = SafeMath.sub(totalAllowance, unusedAllowance);
        // Ensure the amount spent does not exceed the amount approved for this call
        require(usedAllowance <= _amount, "BT: insufficient amount for call");

        if (unusedAllowance != existingAllowance) {
            // Restore the original allowance amount if the amount spent was different (can be lower).
            methodData = abi.encodeWithSignature("approve(address,uint256)", _spender, existingAllowance);
            invokeWallet(address(_wallet), _token, 0, methodData);
        }

        emit ApprovedAndCalledContract(
            address(_wallet),
            _contract,
            _spender,
            _token,
            _amount,
            usedAllowance,
            _data);
    }
}
// Copyright (C) 2018  Argent Labs Ltd. <https://argent.xyz>

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.



/**
 * @title LimitManager
 * @dev Module to manage a daily spending limit
 * @author Julien Niset - <[email protected]>
 */
contract LimitManager is BaseModule {

    // large limit when the limit can be considered disabled
    uint128 constant private LIMIT_DISABLED = uint128(-1); // 3.40282366920938463463374607431768211455e+38

    using SafeMath for uint256;

    struct LimitManagerConfig {
        // The daily limit
        Limit limit;
        // The current usage
        DailySpent dailySpent;
    }

    struct Limit {
        // the current limit
        uint128 current;
        // the pending limit if any
        uint128 pending;
        // when the pending limit becomes the current limit
        uint64 changeAfter;
    }

    struct DailySpent {
        // The amount already spent during the current period
        uint128 alreadySpent;
        // The end of the current period
        uint64 periodEnd;
    }

    // wallet specific storage
    mapping (address => LimitManagerConfig) internal limits;
    // The default limit
    uint256 public defaultLimit;

    // *************** Events *************************** //

    event LimitChanged(address indexed wallet, uint indexed newLimit, uint64 indexed startAfter);

    // *************** Constructor ********************** //

    constructor(uint256 _defaultLimit) public {
        defaultLimit = _defaultLimit;
    }

    // *************** External/Public Functions ********************* //

    /**
     * @dev Inits the module for a wallet by setting the limit to the default value.
     * @param _wallet The target wallet.
     */
    function init(BaseWallet _wallet) public onlyWallet(_wallet) {
        Limit storage limit = limits[address(_wallet)].limit;
        if (limit.current == 0 && limit.changeAfter == 0) {
            limit.current = uint128(defaultLimit);
        }
    }

    // *************** Internal Functions ********************* //

    /**
     * @dev Changes the daily limit.
     * The limit is expressed in ETH and the change is pending for the security period.
     * @param _wallet The target wallet.
     * @param _newLimit The new limit.
     * @param _securityPeriod The security period.
     */
    function changeLimit(BaseWallet _wallet, uint256 _newLimit, uint256 _securityPeriod) internal {
        Limit storage limit = limits[address(_wallet)].limit;
        // solium-disable-next-line security/no-block-members
        uint128 current = (limit.changeAfter > 0 && limit.changeAfter < now) ? limit.pending : limit.current;
        limit.current = current;
        limit.pending = uint128(_newLimit);
        // solium-disable-next-line security/no-block-members
        limit.changeAfter = uint64(now.add(_securityPeriod));
        // solium-disable-next-line security/no-block-members
        emit LimitChanged(address(_wallet), _newLimit, uint64(now.add(_securityPeriod)));
    }

     /**
     * @dev Disable the daily limit.
     * The change is pending for the security period.
     * @param _wallet The target wallet.
     * @param _securityPeriod The security period.
     */
    function disableLimit(BaseWallet _wallet, uint256 _securityPeriod) internal {
        changeLimit(_wallet, LIMIT_DISABLED, _securityPeriod);
    }

    /**
    * @dev Gets the current daily limit for a wallet.
    * @param _wallet The target wallet.
    * @return the current limit expressed in ETH.
    */
    function getCurrentLimit(BaseWallet _wallet) public view returns (uint256 _currentLimit) {
        Limit storage limit = limits[address(_wallet)].limit;
        _currentLimit = uint256(currentLimit(limit.current, limit.pending, limit.changeAfter));
    }

    /**
    * @dev Returns whether the daily limit is disabled for a wallet.
    * @param _wallet The target wallet.
    * @return true if the daily limit is disabled, false otherwise.
    */
    function isLimitDisabled(BaseWallet _wallet) public view returns (bool _limitDisabled) {
        uint256 currentLimit = getCurrentLimit(_wallet);
        _limitDisabled = currentLimit == LIMIT_DISABLED;
    }

    /**
    * @dev Gets a pending limit for a wallet if any.
    * @param _wallet The target wallet.
    * @return the pending limit (in ETH) and the time at chich it will become effective.
    */
    function getPendingLimit(BaseWallet _wallet) external view returns (uint256 _pendingLimit, uint64 _changeAfter) {
        Limit storage limit = limits[address(_wallet)].limit;
        // solium-disable-next-line security/no-block-members
        return ((now < limit.changeAfter)? (uint256(limit.pending), limit.changeAfter) : (0,0));
    }

    /**
    * @dev Gets the amount of tokens that has not yet been spent during the current period.
    * @param _wallet The target wallet.
    * @return the amount of tokens (in ETH) that has not been spent yet and the end of the period.
    */
    function getDailyUnspent(BaseWallet _wallet) external view returns (uint256 _unspent, uint64 _periodEnd) {
        uint256 limit = getCurrentLimit(_wallet);
        DailySpent storage expense = limits[address(_wallet)].dailySpent;
        // solium-disable-next-line security/no-block-members
        if (now > expense.periodEnd) {
            _unspent = limit;
            // solium-disable-next-line security/no-block-members
            _periodEnd = uint64(now + 24 hours);
        } else {
            _periodEnd = expense.periodEnd;
            if (expense.alreadySpent < limit) {
                _unspent = limit - expense.alreadySpent;
            }
        }
    }

    /**
    * @dev Helper method to check if a transfer is within the limit.
    * If yes the daily unspent for the current period is updated.
    * @param _wallet The target wallet.
    * @param _amount The amount for the transfer
    */
    function checkAndUpdateDailySpent(BaseWallet _wallet, uint _amount) internal returns (bool) {
        if (_amount == 0)
            return true;
        Limit storage limit = limits[address(_wallet)].limit;
        uint128 current = currentLimit(limit.current, limit.pending, limit.changeAfter);
        if (isWithinDailyLimit(_wallet, current, _amount)) {
            updateDailySpent(_wallet, current, _amount);
            return true;
        }
        return false;
    }

    /**
    * @dev Helper method to update the daily spent for the current period.
    * @param _wallet The target wallet.
    * @param _limit The current limit for the wallet.
    * @param _amount The amount to add to the daily spent.
    */
    function updateDailySpent(BaseWallet _wallet, uint128 _limit, uint _amount) internal {
        if (_limit != LIMIT_DISABLED) {
            DailySpent storage expense = limits[address(_wallet)].dailySpent;
            // solium-disable-next-line security/no-block-members
            if (expense.periodEnd < now) {
                // solium-disable-next-line security/no-block-members
                expense.periodEnd = uint64(now + 24 hours);
                expense.alreadySpent = uint128(_amount);
            } else {
                expense.alreadySpent += uint128(_amount);
            }
        }
    }

    /**
    * @dev Checks if a transfer amount is withing the daily limit for a wallet.
    * @param _wallet The target wallet.
    * @param _limit The current limit for the wallet.
    * @param _amount The transfer amount.
    * @return true if the transfer amount is withing the daily limit.
    */
    function isWithinDailyLimit(BaseWallet _wallet, uint _limit, uint _amount) internal view returns (bool) {
        if (_limit == LIMIT_DISABLED) {
            return true;
        }
        DailySpent storage expense = limits[address(_wallet)].dailySpent;
        // solium-disable-next-line security/no-block-members
        if (expense.periodEnd < now) {
            return (_amount <= _limit);
        } else {
            return (expense.alreadySpent + _amount <= _limit && expense.alreadySpent + _amount >= expense.alreadySpent);
        }
    }

    /**
    * @dev Helper method to get the current limit from a Limit struct.
    * @param _current The value of the current parameter
    * @param _pending The value of the pending parameter
    * @param _changeAfter The value of the changeAfter parameter
    */
    function currentLimit(uint128 _current, uint128 _pending, uint64 _changeAfter) internal view returns (uint128) {
        // solium-disable-next-line security/no-block-members
        if (_changeAfter > 0 && _changeAfter < now) {
            return _pending;
        }
        return _current;
    }

}// Copyright (C) 2018  Argent Labs Ltd. <https://argent.xyz>

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.



/**
 * @title TransferStorage
 * @dev Contract storing the state of wallets related to transfers (limit and whitelist).
 * The contract only defines basic setters and getters with no logic. Only modules authorised
 * for a wallet can modify its state.
 * @author Julien Niset - <[email protected]>
 */
contract TransferStorage is Storage {

    // wallet specific storage
    mapping (address => mapping (address => uint256)) internal whitelist;

    // *************** External Functions ********************* //

    /**
     * @dev Lets an authorised module add or remove an account from the whitelist of a wallet.
     * @param _wallet The target wallet.
     * @param _target The account to add/remove.
     * @param _value True for addition, false for revokation.
     */
    function setWhitelist(BaseWallet _wallet, address _target, uint256 _value) external onlyModule(_wallet) {
        whitelist[address(_wallet)][_target] = _value;
    }

    /**
     * @dev Gets the whitelist state of an account for a wallet.
     * @param _wallet The target wallet.
     * @param _target The account.
     * @return the epoch time at which an account strats to be whitelisted, or zero if the account is not whitelisted.
     */
    function getWhitelist(BaseWallet _wallet, address _target) external view returns (uint256) {
        return whitelist[address(_wallet)][_target];
    }
}// Copyright (C) 2018  Argent Labs Ltd. <https://argent.xyz>

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.


/**
 * @title Managed
 * @dev Basic contract that defines a set of managers. Only the owner can add/remove managers.
 * @author Julien Niset - <[email protected]>
 */
contract Managed is Owned {

    // The managers
    mapping (address => bool) public managers;

    /**
     * @dev Throws if the sender is not a manager.
     */
    modifier onlyManager {
        require(managers[msg.sender] == true, "M: Must be manager");
        _;
    }

    event ManagerAdded(address indexed _manager);
    event ManagerRevoked(address indexed _manager);

    /**
    * @dev Adds a manager.
    * @param _manager The address of the manager.
    */
    function addManager(address _manager) external onlyOwner {
        require(_manager != address(0), "M: Address must not be null");
        if (managers[_manager] == false) {
            managers[_manager] = true;
            emit ManagerAdded(_manager);
        }
    }

    /**
    * @dev Revokes a manager.
    * @param _manager The address of the manager.
    */
    function revokeManager(address _manager) external onlyOwner {
        require(managers[_manager] == true, "M: Target must be an existing manager");
        delete managers[_manager];
        emit ManagerRevoked(_manager);
    }
}

contract KyberNetwork {

    function getExpectedRate(
        ERC20 src,
        ERC20 dest,
        uint srcQty
    )
        public
        view
        returns (uint expectedRate, uint slippageRate);

    function trade(
        ERC20 src,
        uint srcAmount,
        ERC20 dest,
        address payable destAddress,
        uint maxDestAmount,
        uint minConversionRate,
        address walletId
    )
        public
        payable
        returns(uint);
}
// Copyright (C) 2018  Argent Labs Ltd. <https://argent.xyz>

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.





contract TokenPriceProvider is Managed {

    // Mock token address for ETH
    address constant internal ETH_TOKEN_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;

    using SafeMath for uint256;

    mapping(address => uint256) public cachedPrices;

    // Address of the KyberNetwork contract
    KyberNetwork public kyberNetwork;

    constructor(KyberNetwork _kyberNetwork) public {
        kyberNetwork = _kyberNetwork;
    }

    function setPrice(ERC20 _token, uint256 _price) public onlyManager {
        cachedPrices[address(_token)] = _price;
    }

    function setPriceForTokenList(ERC20[] calldata _tokens, uint256[] calldata _prices) external onlyManager {
        for (uint16 i = 0; i < _tokens.length; i++) {
            setPrice(_tokens[i], _prices[i]);
        }
    }

    /**
     * @dev Converts the value of _amount tokens in ether.
     * @param _amount the amount of tokens to convert (in 'token wei' twei)
     * @param _token the ERC20 token contract
     * @return the ether value (in wei) of _amount tokens with contract _token
     */
    function getEtherValue(uint256 _amount, address _token) external view returns (uint256) {
        uint256 decimals = ERC20(_token).decimals();
        uint256 price = cachedPrices[_token];
        return price.mul(_amount).div(10**decimals);
    }

    //
    // The following is added to be backward-compatible with Argent's old backend
    //

    function setKyberNetwork(KyberNetwork _kyberNetwork) external onlyManager {
        kyberNetwork = _kyberNetwork;
    }

    function syncPrice(ERC20 _token) external {
        require(address(kyberNetwork) != address(0), "Kyber sync is disabled");
        (uint256 expectedRate,) = kyberNetwork.getExpectedRate(_token, ERC20(ETH_TOKEN_ADDRESS), 10000);
        cachedPrices[address(_token)] = expectedRate;
    }

    function syncPriceForTokenList(ERC20[] calldata _tokens) external {
        require(address(kyberNetwork) != address(0), "Kyber sync is disabled");
        for (uint16 i = 0; i < _tokens.length; i++) {
            (uint256 expectedRate,) = kyberNetwork.getExpectedRate(_tokens[i], ERC20(ETH_TOKEN_ADDRESS), 10000);
            cachedPrices[address(_tokens[i])] = expectedRate;
        }
    }
}// Copyright (C) 2018  Argent Labs Ltd. <https://argent.xyz>

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.










/**
 * @title TransferManager
 * @dev Module to transfer and approve tokens (ETH or ERC20) or data (contract call) based on a security context (daily limit, whitelist, etc).
 * This module is the V2 of TokenTransfer.
 * @author Julien Niset - <[email protected]>
 */
contract TransferManager is BaseModule, RelayerModule, OnlyOwnerModule, BaseTransfer, LimitManager {

    bytes32 constant NAME = "TransferManager";

    bytes4 private constant ERC1271_ISVALIDSIGNATURE_BYTES = bytes4(keccak256("isValidSignature(bytes,bytes)"));
    bytes4 private constant ERC1271_ISVALIDSIGNATURE_BYTES32 = bytes4(keccak256("isValidSignature(bytes32,bytes)"));

    enum ActionType { Transfer }

    using SafeMath for uint256;

    struct TokenManagerConfig {
        // Mapping between pending action hash and their timestamp
        mapping (bytes32 => uint256) pendingActions;
    }

    // wallet specific storage
    mapping (address => TokenManagerConfig) internal configs;

    // The security period
    uint256 public securityPeriod;
    // The execution window
    uint256 public securityWindow;
    // The Token storage
    TransferStorage public transferStorage;
    // The Token price provider
    TokenPriceProvider public priceProvider;
    // The previous limit manager needed to migrate the limits
    LimitManager public oldLimitManager;

    // *************** Events *************************** //

    event AddedToWhitelist(address indexed wallet, address indexed target, uint64 whitelistAfter);
    event RemovedFromWhitelist(address indexed wallet, address indexed target);
    event PendingTransferCreated(address indexed wallet, bytes32 indexed id, uint256 indexed executeAfter,
    address token, address to, uint256 amount, bytes data);
    event PendingTransferExecuted(address indexed wallet, bytes32 indexed id);
    event PendingTransferCanceled(address indexed wallet, bytes32 indexed id);

    // *************** Constructor ********************** //

    constructor(
        ModuleRegistry _registry,
        TransferStorage _transferStorage,
        GuardianStorage _guardianStorage,
        address _priceProvider,
        uint256 _securityPeriod,
        uint256 _securityWindow,
        uint256 _defaultLimit,
        LimitManager _oldLimitManager
    )
        BaseModule(_registry, _guardianStorage, NAME)
        LimitManager(_defaultLimit)
        public
    {
        transferStorage = _transferStorage;
        priceProvider = TokenPriceProvider(_priceProvider);
        securityPeriod = _securityPeriod;
        securityWindow = _securityWindow;
        oldLimitManager = _oldLimitManager;
    }

    /**
     * @dev Inits the module for a wallet by setting up the isValidSignature (EIP 1271)
     * static call redirection from the wallet to the module and copying all the parameters
     * of the daily limit from the previous implementation of the LimitManager module.
     * @param _wallet The target wallet.
     */
    function init(BaseWallet _wallet) public onlyWallet(_wallet) {

        // setup static calls
        _wallet.enableStaticCall(address(this), ERC1271_ISVALIDSIGNATURE_BYTES);
        _wallet.enableStaticCall(address(this), ERC1271_ISVALIDSIGNATURE_BYTES32);

        // setup default limit for new deployment
        if (address(oldLimitManager) == address(0)) {
            super.init(_wallet);
            return;
        }
        // get limit from previous LimitManager
        uint256 current = oldLimitManager.getCurrentLimit(_wallet);
        (uint256 pending, uint64 changeAfter) = oldLimitManager.getPendingLimit(_wallet);
        // setup default limit for new wallets
        if (current == 0 && changeAfter == 0) {
            super.init(_wallet);
            return;
        }
        // migrate existing limit for existing wallets
        if (current == pending) {
            limits[address(_wallet)].limit.current = uint128(current);
        } else {
            limits[address(_wallet)].limit = Limit(uint128(current), uint128(pending), changeAfter);
        }
        // migrate daily pending if we are within a rolling period
        (uint256 unspent, uint64 periodEnd) = oldLimitManager.getDailyUnspent(_wallet);
        // solium-disable-next-line security/no-block-members
        if (periodEnd > now) {
            limits[address(_wallet)].dailySpent = DailySpent(uint128(current.sub(unspent)), periodEnd);
        }
    }

    // *************** External/Public Functions ********************* //

    /**
    * @dev lets the owner transfer tokens (ETH or ERC20) from a wallet.
    * @param _wallet The target wallet.
    * @param _token The address of the token to transfer.
    * @param _to The destination address
    * @param _amount The amoutn of token to transfer
    * @param _data The data for the transaction
    */
    function transferToken(
        BaseWallet _wallet,
        address _token,
        address _to,
        uint256 _amount,
        bytes calldata _data
    )
        external
        onlyWalletOwner(_wallet)
        onlyWhenUnlocked(_wallet)
    {
        if (isWhitelisted(_wallet, _to)) {
            // transfer to whitelist
            doTransfer(_wallet, _token, _to, _amount, _data);
        } else {
            uint256 etherAmount = (_token == ETH_TOKEN) ? _amount : priceProvider.getEtherValue(_amount, _token);
            if (checkAndUpdateDailySpent(_wallet, etherAmount)) {
                // transfer under the limit
                doTransfer(_wallet, _token, _to, _amount, _data);
            } else {
                // transfer above the limit
                (bytes32 id, uint256 executeAfter) = addPendingAction(ActionType.Transfer, _wallet, _token, _to, _amount, _data);
                emit PendingTransferCreated(address(_wallet), id, executeAfter, _token, _to, _amount, _data);
            }
        }
    }

    /**
    * @dev lets the owner approve an allowance of ERC20 tokens for a spender (dApp).
    * @param _wallet The target wallet.
    * @param _token The address of the token to transfer.
    * @param _spender The address of the spender
    * @param _amount The amount of tokens to approve
    */
    function approveToken(
        BaseWallet _wallet,
        address _token,
        address _spender,
        uint256 _amount
    )
        external
        onlyWalletOwner(_wallet)
        onlyWhenUnlocked(_wallet)
    {
        if (isWhitelisted(_wallet, _spender)) {
            // approve to whitelist
            doApproveToken(_wallet, _token, _spender, _amount);
        } else {
            // get current alowance
            uint256 currentAllowance = ERC20(_token).allowance(address(_wallet), _spender);
            if (_amount <= currentAllowance) {
                // approve if we reduce the allowance
                doApproveToken(_wallet, _token, _spender, _amount);
            } else {
                // check if delta is under the limit
                uint delta = _amount - currentAllowance;
                uint256 deltaInEth = priceProvider.getEtherValue(delta, _token);
                require(checkAndUpdateDailySpent(_wallet, deltaInEth), "TM: Approve above daily limit");
                // approve if under the limit
                doApproveToken(_wallet, _token, _spender, _amount);
            }
        }
    }

    /**
    * @dev lets the owner call a contract.
    * @param _wallet The target wallet.
    * @param _contract The address of the contract.
    * @param _value The amount of ETH to transfer as part of call
    * @param _data The encoded method data
    */
    function callContract(
        BaseWallet _wallet,
        address _contract,
        uint256 _value,
        bytes calldata _data
    )
        external
        onlyWalletOwner(_wallet)
        onlyWhenUnlocked(_wallet)
    {
        // Make sure we don't call a module, the wallet itself, or a supported ERC20
        authoriseContractCall(_wallet, _contract);

        if (isWhitelisted(_wallet, _contract)) {
            // call to whitelist
            doCallContract(_wallet, _contract, _value, _data);
        } else {
            require(checkAndUpdateDailySpent(_wallet, _value), "TM: Call contract above daily limit");
            // call under the limit
            doCallContract(_wallet, _contract, _value, _data);
        }
    }

    /**
    * @dev lets the owner do an ERC20 approve followed by a call to a contract.
    * We assume that the contract will pull the tokens and does not require ETH.
    * @param _wallet The target wallet.
    * @param _token The token to approve.
    * @param _spender The address to approve.
    * @param _amount The amount of ERC20 tokens to approve.
    * @param _contract The address of the contract.
    * @param _data The encoded method data
    */
    function approveTokenAndCallContract(
        BaseWallet _wallet,
        address _token,
        address _spender,
        uint256 _amount,
        address _contract,
        bytes calldata _data
    )
        external
        onlyWalletOwner(_wallet)
        onlyWhenUnlocked(_wallet)
    {
        // Make sure we don't call a module, the wallet itself, or a supported ERC20
        authoriseContractCall(_wallet, _contract);

        if (!isWhitelisted(_wallet, _spender)) {
            // check if the amount is under the daily limit
            // check the entire amount because the currently approved amount will be restored and should still count towards the daily limit
            uint256 valueInEth = priceProvider.getEtherValue(_amount, _token);
            require(checkAndUpdateDailySpent(_wallet, valueInEth), "TM: Approve above daily limit");
        }

        doApproveTokenAndCallContract(_wallet, _token, _spender, _amount, _contract, _data);
    }

    /**
     * @dev Adds an address to the whitelist of a wallet.
     * @param _wallet The target wallet.
     * @param _target The address to add.
     */
    function addToWhitelist(
        BaseWallet _wallet,
        address _target
    )
        external
        onlyWalletOwner(_wallet)
        onlyWhenUnlocked(_wallet)
    {
        require(!isWhitelisted(_wallet, _target), "TT: target already whitelisted");
        // solium-disable-next-line security/no-block-members
        uint256 whitelistAfter = now.add(securityPeriod);
        transferStorage.setWhitelist(_wallet, _target, whitelistAfter);
        emit AddedToWhitelist(address(_wallet), _target, uint64(whitelistAfter));
    }

    /**
     * @dev Removes an address from the whitelist of a wallet.
     * @param _wallet The target wallet.
     * @param _target The address to remove.
     */
    function removeFromWhitelist(
        BaseWallet _wallet,
        address _target
    )
        external
        onlyWalletOwner(_wallet)
        onlyWhenUnlocked(_wallet)
    {
        require(isWhitelisted(_wallet, _target), "TT: target not whitelisted");
        transferStorage.setWhitelist(_wallet, _target, 0);
        emit RemovedFromWhitelist(address(_wallet), _target);
    }

    /**
    * @dev Executes a pending transfer for a wallet.
    * The method can be called by anyone to enable orchestration.
    * @param _wallet The target wallet.
    * @param _token The token of the pending transfer.
    * @param _to The destination address of the pending transfer.
    * @param _amount The amount of token to transfer of the pending transfer.
    * @param _data The data associated to the pending transfer.
    * @param _block The block at which the pending transfer was created.
    */
    function executePendingTransfer(
        BaseWallet _wallet,
        address _token,
        address _to,
        uint _amount,
        bytes calldata _data,
        uint _block
    )
        external
        onlyWhenUnlocked(_wallet)
    {
        bytes32 id = keccak256(abi.encodePacked(ActionType.Transfer, _token, _to, _amount, _data, _block));
        uint executeAfter = configs[address(_wallet)].pendingActions[id];
        require(executeAfter > 0, "TT: unknown pending transfer");
        uint executeBefore = executeAfter.add(securityWindow);
        // solium-disable-next-line security/no-block-members
        require(executeAfter <= now && now <= executeBefore, "TT: transfer outside of the execution window");
        delete configs[address(_wallet)].pendingActions[id];
        doTransfer(_wallet, _token, _to, _amount, _data);
        emit PendingTransferExecuted(address(_wallet), id);
    }

    function cancelPendingTransfer(
        BaseWallet _wallet,
        bytes32 _id
    )
        external
        onlyWalletOwner(_wallet)
        onlyWhenUnlocked(_wallet)
    {
        require(configs[address(_wallet)].pendingActions[_id] > 0, "TT: unknown pending action");
        delete configs[address(_wallet)].pendingActions[_id];
        emit PendingTransferCanceled(address(_wallet), _id);
    }

    /**
     * @dev Lets the owner of a wallet change its daily limit.
     * The limit is expressed in ETH. Changes to the limit take 24 hours.
     * @param _wallet The target wallet.
     * @param _newLimit The new limit.
     */
    function changeLimit(BaseWallet _wallet, uint256 _newLimit) external onlyWalletOwner(_wallet) onlyWhenUnlocked(_wallet) {
        changeLimit(_wallet, _newLimit, securityPeriod);
    }

    /**
     * @dev Convenience method to disable the limit
     * The limit is disabled by setting it to an arbitrary large value.
     * @param _wallet The target wallet.
     */
    function disableLimit(BaseWallet _wallet) external onlyWalletOwner(_wallet) onlyWhenUnlocked(_wallet) {
        disableLimit(_wallet, securityPeriod);
    }

    /**
    * @dev Checks if an address is whitelisted for a wallet.
    * @param _wallet The target wallet.
    * @param _target The address.
    * @return true if the address is whitelisted.
    */
    function isWhitelisted(BaseWallet _wallet, address _target) public view returns (bool _isWhitelisted) {
        uint whitelistAfter = transferStorage.getWhitelist(_wallet, _target);
        // solium-disable-next-line security/no-block-members
        return whitelistAfter > 0 && whitelistAfter < now;
    }

    /**
    * @dev Gets the info of a pending transfer for a wallet.
    * @param _wallet The target wallet.
    * @param _id The pending transfer ID.
    * @return the epoch time at which the pending transfer can be executed.
    */
    function getPendingTransfer(BaseWallet _wallet, bytes32 _id) external view returns (uint64 _executeAfter) {
        _executeAfter = uint64(configs[address(_wallet)].pendingActions[_id]);
    }

    /**
    * @dev Implementation of EIP 1271.
    * Should return whether the signature provided is valid for the provided data.
    * @param _data Arbitrary length data signed on the behalf of address(this)
    * @param _signature Signature byte array associated with _data
    */
    function isValidSignature(bytes calldata _data, bytes calldata _signature) external view returns (bytes4) {
        bytes32 msgHash = keccak256(abi.encodePacked(_data));
        isValidSignature(msgHash, _signature);
        return ERC1271_ISVALIDSIGNATURE_BYTES;
    }

    /**
    * @dev Implementation of EIP 1271.
    * Should return whether the signature provided is valid for the provided data.
    * @param _msgHash Hash of a message signed on the behalf of address(this)
    * @param _signature Signature byte array associated with _msgHash
    */
    function isValidSignature(bytes32 _msgHash, bytes memory _signature) public view returns (bytes4) {
        require(_signature.length == 65, "TM: invalid signature length");
        address signer = recoverSigner(_msgHash, _signature, 0);
        require(isOwner(BaseWallet(msg.sender), signer), "TM: Invalid signer");
        return ERC1271_ISVALIDSIGNATURE_BYTES32;
    }

    // *************** Internal Functions ********************* //

    /**
     * @dev Creates a new pending action for a wallet.
     * @param _action The target action.
     * @param _wallet The target wallet.
     * @param _token The target token for the action.
     * @param _to The recipient of the action.
     * @param _amount The amount of token associated to the action.
     * @param _data The data associated to the action.
     * @return the identifier for the new pending action and the time when the action can be executed
     */
    function addPendingAction(
        ActionType _action,
        BaseWallet _wallet,
        address _token,
        address _to,
        uint _amount,
        bytes memory _data
    )
        internal
        returns (bytes32 id, uint256 executeAfter)
    {
        id = keccak256(abi.encodePacked(_action, _token, _to, _amount, _data, block.number));
        require(configs[address(_wallet)].pendingActions[id] == 0, "TM: duplicate pending action");
        // solium-disable-next-line security/no-block-members
        executeAfter = now.add(securityPeriod);
        configs[address(_wallet)].pendingActions[id] = executeAfter;
    }

    /**
    * @dev Make sure a contract call is not trying to call a module, the wallet itself, or a supported ERC20.
    * @param _wallet The target wallet.
    * @param _contract The address of the contract.
     */
    function authoriseContractCall(BaseWallet _wallet, address _contract) internal view {
        require(
            _contract != address(_wallet) && // not the wallet itself
            !_wallet.authorised(_contract) && // not an authorised module
            (priceProvider.cachedPrices(_contract) == 0 || isLimitDisabled(_wallet)), // not an ERC20 listed in the provider (or limit disabled)
            "TM: Forbidden contract");
    }

    // *************** Implementation of RelayerModule methods ********************* //

    // Overrides refund to add the refund in the daily limit.
    function refund(BaseWallet _wallet, uint _gasUsed, uint _gasPrice, uint _gasLimit, uint _signatures, address _relayer) internal {
        // 21000 (transaction) + 7620 (execution of refund) + 7324 (execution of updateDailySpent) + 672 to log the event + _gasUsed
        uint256 amount = 36616 + _gasUsed;
        if (_gasPrice > 0 && _signatures > 0 && amount <= _gasLimit) {
            if (_gasPrice > tx.gasprice) {
                amount = amount * tx.gasprice;
            } else {
                amount = amount * _gasPrice;
            }
            checkAndUpdateDailySpent(_wallet, amount);
            invokeWallet(address(_wallet), _relayer, amount, EMPTY_BYTES);
        }
    }

    // Overrides verifyRefund to add the refund in the daily limit.
    function verifyRefund(BaseWallet _wallet, uint _gasUsed, uint _gasPrice, uint _signatures) internal view returns (bool) {
        if (_gasPrice > 0 && _signatures > 0 && (
            address(_wallet).balance < _gasUsed * _gasPrice ||
            isWithinDailyLimit(_wallet, getCurrentLimit(_wallet), _gasUsed * _gasPrice) == false ||
            _wallet.authorised(address(this)) == false
        ))
        {
            return false;
        }
        return true;
    }
}

Contract Security Audit

Contract ABI

[{"constant":true,"inputs":[],"name":"securityWindow","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_wallet","type":"address"},{"name":"_token","type":"address"},{"name":"_spender","type":"address"},{"name":"_amount","type":"uint256"}],"name":"approveToken","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_msgHash","type":"bytes32"},{"name":"_signature","type":"bytes"}],"name":"isValidSignature","outputs":[{"name":"","type":"bytes4"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_wallet","type":"address"}],"name":"init","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_data","type":"bytes"},{"name":"_signature","type":"bytes"}],"name":"isValidSignature","outputs":[{"name":"","type":"bytes4"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_wallet","type":"address"}],"name":"getNonce","outputs":[{"name":"nonce","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_wallet","type":"address"},{"name":"_token","type":"address"},{"name":"_to","type":"address"},{"name":"_amount","type":"uint256"},{"name":"_data","type":"bytes"}],"name":"transferToken","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_wallet","type":"address"}],"name":"getCurrentLimit","outputs":[{"name":"_currentLimit","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_wallet","type":"address"},{"name":"_target","type":"address"}],"name":"addToWhitelist","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_wallet","type":"address"},{"name":"_module","type":"address"}],"name":"addModule","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_wallet","type":"address"},{"name":"_token","type":"address"},{"name":"_to","type":"address"},{"name":"_amount","type":"uint256"},{"name":"_data","type":"bytes"},{"name":"_block","type":"uint256"}],"name":"executePendingTransfer","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_wallet","type":"address"}],"name":"getDailyUnspent","outputs":[{"name":"_unspent","type":"uint256"},{"name":"_periodEnd","type":"uint64"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"securityPeriod","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"oldLimitManager","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"transferStorage","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_token","type":"address"}],"name":"recoverToken","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_wallet","type":"address"}],"name":"getPendingLimit","outputs":[{"name":"_pendingLimit","type":"uint256"},{"name":"_changeAfter","type":"uint64"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_wallet","type":"address"}],"name":"disableLimit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_wallet","type":"address"},{"name":"_data","type":"bytes"},{"name":"_nonce","type":"uint256"},{"name":"_signatures","type":"bytes"},{"name":"_gasPrice","type":"uint256"},{"name":"_gasLimit","type":"uint256"}],"name":"execute","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_wallet","type":"address"},{"name":"_newLimit","type":"uint256"}],"name":"changeLimit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_wallet","type":"address"},{"name":"_id","type":"bytes32"}],"name":"cancelPendingTransfer","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_wallet","type":"address"},{"name":"_target","type":"address"}],"name":"isWhitelisted","outputs":[{"name":"_isWhitelisted","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"priceProvider","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"relayer","outputs":[{"name":"nonce","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isOnlyOwnerModule","outputs":[{"name":"","type":"bytes4"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":false,"inputs":[{"name":"_wallet","type":"address"},{"name":"_token","type":"address"},{"name":"_spender","type":"address"},{"name":"_amount","type":"uint256"},{"name":"_contract","type":"address"},{"name":"_data","type":"bytes"}],"name":"approveTokenAndCallContract","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_wallet","type":"address"},{"name":"_id","type":"bytes32"}],"name":"getPendingTransfer","outputs":[{"name":"_executeAfter","type":"uint64"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"defaultLimit","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_wallet","type":"address"},{"name":"_target","type":"address"}],"name":"removeFromWhitelist","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_wallet","type":"address"}],"name":"isLimitDisabled","outputs":[{"name":"_limitDisabled","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_wallet","type":"address"},{"name":"_contract","type":"address"},{"name":"_value","type":"uint256"},{"name":"_data","type":"bytes"}],"name":"callContract","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_registry","type":"address"},{"name":"_transferStorage","type":"address"},{"name":"_guardianStorage","type":"address"},{"name":"_priceProvider","type":"address"},{"name":"_securityPeriod","type":"uint256"},{"name":"_securityWindow","type":"uint256"},{"name":"_defaultLimit","type":"uint256"},{"name":"_oldLimitManager","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"wallet","type":"address"},{"indexed":true,"name":"target","type":"address"},{"indexed":false,"name":"whitelistAfter","type":"uint64"}],"name":"AddedToWhitelist","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"wallet","type":"address"},{"indexed":true,"name":"target","type":"address"}],"name":"RemovedFromWhitelist","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"wallet","type":"address"},{"indexed":true,"name":"id","type":"bytes32"},{"indexed":true,"name":"executeAfter","type":"uint256"},{"indexed":false,"name":"token","type":"address"},{"indexed":false,"name":"to","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"data","type":"bytes"}],"name":"PendingTransferCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"wallet","type":"address"},{"indexed":true,"name":"id","type":"bytes32"}],"name":"PendingTransferExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"wallet","type":"address"},{"indexed":true,"name":"id","type":"bytes32"}],"name":"PendingTransferCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"wallet","type":"address"},{"indexed":true,"name":"newLimit","type":"uint256"},{"indexed":true,"name":"startAfter","type":"uint64"}],"name":"LimitChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"wallet","type":"address"},{"indexed":true,"name":"token","type":"address"},{"indexed":true,"name":"amount","type":"uint256"},{"indexed":false,"name":"to","type":"address"},{"indexed":false,"name":"data","type":"bytes"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"wallet","type":"address"},{"indexed":true,"name":"token","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"spender","type":"address"}],"name":"Approved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"wallet","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"data","type":"bytes"}],"name":"CalledContract","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"wallet","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"spender","type":"address"},{"indexed":true,"name":"token","type":"address"},{"indexed":false,"name":"amountApproved","type":"uint256"},{"indexed":false,"name":"amountSpent","type":"uint256"},{"indexed":false,"name":"data","type":"bytes"}],"name":"ApprovedAndCalledContract","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"wallet","type":"address"},{"indexed":true,"name":"success","type":"bool"},{"indexed":false,"name":"signedHash","type":"bytes32"}],"name":"TransactionExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"name","type":"bytes32"}],"name":"ModuleCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"wallet","type":"address"}],"name":"ModuleInitialised","type":"event"}]

608060405234801561001057600080fd5b506040516101008062004d5f833981018060405261010081101561003357600080fd5b5080516020808301516040808501516060860151608087015160a088015160c089015160e09099015160008054600160a060020a03808c16600160a060020a031992831617909255600180549288169290911691909117905585517f5472616e736665724d616e6167657200000000000000000000000000000000008082529651999a979995989497939692959394919385938c938b9391927f3019c8fc80239e3dff8f781212ae2004839c2cb61d6c70acd279ac65392145df9281900390910190a150505060045560088054600160a060020a03988916600160a060020a031991821617909155600980549689169682169690961790955560069390935550600755600a8054919094169116179091555050614c0980620001566000396000f3fe608060405234801561001057600080fd5b5060043610610201576000357c0100000000000000000000000000000000000000000000000000000000900480639be65a601161012c578063c9b5ef8e116100bf578063e26b013b1161008e578063e26b013b14610982578063f8d3277d1461098a578063f9f6499e146109b8578063fd6ac309146109de57610201565b8063c9b5ef8e1461086c578063d490da4d14610892578063d5e69ee91461089a578063e1ee38ec1461093957610201565b8063b20f3f37116100fb578063b20f3f37146107de578063b377a9d51461080a578063b6b3527214610836578063b888879e1461086457610201565b80639be65a601461067c578063a0aec105146106a2578063a3411c0a146106c8578063aacaaf88146106ee57610201565b806343cd5c7e116101a45780637cb8f8ba116101735780637cb8f8ba146106005780637cc0d9061461064857806395813db414610650578063961bfeee1461067457610201565b806343cd5c7e146104e6578063575182431461050c5780635a1db8c41461053a5780635ed4bf811461056857610201565b806319ab453c116101e057806319ab453c1461034057806320c13b0b146103665780632d0335ab146104285780632df546f41461044e57610201565b80626fda351461020657806312ef080d146102205780631626ba7e1461025e575b600080fd5b61020e610a6e565b60408051918252519081900360200190f35b61025c6004803603608081101561023657600080fd5b50600160a060020a03813581169160208101358216916040820135169060600135610a74565b005b61030b6004803603604081101561027457600080fd5b8135919081019060408101602082013564010000000081111561029657600080fd5b8201836020820111156102a857600080fd5b803590602001918460018302840111640100000000831117156102ca57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610d9d945050505050565b604080517fffffffff000000000000000000000000000000000000000000000000000000009092168252519081900360200190f35b61025c6004803603602081101561035657600080fd5b5035600160a060020a0316610ea4565b61030b6004803603604081101561037c57600080fd5b81019060208101813564010000000081111561039757600080fd5b8201836020820111156103a957600080fd5b803590602001918460018302840111640100000000831117156103cb57600080fd5b9193909290916020810190356401000000008111156103e957600080fd5b8201836020820111156103fb57600080fd5b8035906020019184600183028401116401000000008311171561041d57600080fd5b5090925090506114a0565b61020e6004803603602081101561043e57600080fd5b5035600160a060020a0316611554565b61025c600480360360a081101561046457600080fd5b600160a060020a03823581169260208101358216926040820135909216916060820135919081019060a0810160808201356401000000008111156104a757600080fd5b8201836020820111156104b957600080fd5b803590602001918460018302840111640100000000831117156104db57600080fd5b50909250905061156f565b61020e600480360360208110156104fc57600080fd5b5035600160a060020a0316611925565b61025c6004803603604081101561052257600080fd5b50600160a060020a038135811691602001351661199c565b61025c6004803603604081101561055057600080fd5b50600160a060020a0381358116916020013516611c33565b61025c600480360360c081101561057e57600080fd5b600160a060020a03823581169260208101358216926040820135909216916060820135919081019060a0810160808201356401000000008111156105c157600080fd5b8201836020820111156105d357600080fd5b803590602001918460018302840111640100000000831117156105f557600080fd5b919350915035611dee565b6106266004803603602081101561061657600080fd5b5035600160a060020a0316612153565b6040805192835267ffffffffffffffff90911660208301528051918290030190f35b61020e612212565b610658612218565b60408051600160a060020a039092168252519081900360200190f35b610658612227565b61025c6004803603602081101561069257600080fd5b5035600160a060020a0316612236565b610626600480360360208110156106b857600080fd5b5035600160a060020a0316612369565b61025c600480360360208110156106de57600080fd5b5035600160a060020a03166123e5565b6107ca600480360360c081101561070457600080fd5b600160a060020a03823516919081019060408101602082013564010000000081111561072f57600080fd5b82018360208201111561074157600080fd5b8035906020019184600183028401116401000000008311171561076357600080fd5b9193909282359260408101906020013564010000000081111561078557600080fd5b82018360208201111561079757600080fd5b803590602001918460018302840111640100000000831117156107b957600080fd5b919350915080359060200135612534565b604080519115158252519081900360200190f35b61025c600480360360408110156107f457600080fd5b50600160a060020a038135169060200135612812565b61025c6004803603604081101561082057600080fd5b50600160a060020a03813516906020013561295d565b6107ca6004803603604081101561084c57600080fd5b50600160a060020a0381358116916020013516612b68565b610658612c1a565b61020e6004803603602081101561088257600080fd5b5035600160a060020a0316612c29565b61030b612c3b565b61025c600480360360c08110156108b057600080fd5b600160a060020a0382358116926020810135821692604082013583169260608301359260808101359091169181019060c0810160a08201356401000000008111156108fa57600080fd5b82018360208201111561090c57600080fd5b8035906020019184600183028401116401000000008311171561092e57600080fd5b509092509050612c5f565b6109656004803603604081101561094f57600080fd5b50600160a060020a038135169060200135612efc565b6040805167ffffffffffffffff9092168252519081900360200190f35b61020e612f23565b61025c600480360360408110156109a057600080fd5b50600160a060020a0381358116916020013516612f29565b6107ca600480360360208110156109ce57600080fd5b5035600160a060020a0316613191565b61025c600480360360808110156109f457600080fd5b600160a060020a03823581169260208101359091169160408201359190810190608081016060820135640100000000811115610a2f57600080fd5b820183602082011115610a4157600080fd5b80359060200191846001830284011164010000000083111715610a6357600080fd5b5090925090506131b6565b60075481565b8333301480610a885750610a8881336133db565b1515610ac85760405160e560020a62461bcd028152600401808060200182810382526023815260200180614bbb6023913960400191505060405180910390fd5b600154604080517f4a4fbeec000000000000000000000000000000000000000000000000000000008152600160a060020a038089166004830152915188939290921691634a4fbeec91602480820192602092909190829003018186803b158015610b3157600080fd5b505afa158015610b45573d6000803e3d6000fd5b505050506040513d6020811015610b5b57600080fd5b505115610bb2576040805160e560020a62461bcd02815260206004820152601b60248201527f424d3a2077616c6c6574206d75737420626520756e6c6f636b65640000000000604482015290519081900360640190fd5b610bbc8685612b68565b15610bd257610bcd86868686613479565b610d95565b604080517fdd62ed3e000000000000000000000000000000000000000000000000000000008152600160a060020a0388811660048301528681166024830152915160009288169163dd62ed3e916044808301926020929190829003018186803b158015610c3e57600080fd5b505afa158015610c52573d6000803e3d6000fd5b505050506040513d6020811015610c6857600080fd5b50519050808411610c8457610c7f87878787613479565b610d93565b600954604080517fce55c85200000000000000000000000000000000000000000000000000000000815283870360048201819052600160a060020a038a8116602484015292519093600093169163ce55c852916044808301926020929190829003018186803b158015610cf657600080fd5b505afa158015610d0a573d6000803e3d6000fd5b505050506040513d6020811015610d2057600080fd5b50519050610d2e898261354d565b1515610d84576040805160e560020a62461bcd02815260206004820152601d60248201527f544d3a20417070726f76652061626f7665206461696c79206c696d6974000000604482015290519081900360640190fd5b610d9089898989613479565b50505b505b505050505050565b8051600090604114610df9576040805160e560020a62461bcd02815260206004820152601c60248201527f544d3a20696e76616c6964207369676e6174757265206c656e67746800000000604482015290519081900360640190fd5b6000610e0784846000613604565b9050610e1333826133db565b1515610e69576040805160e560020a62461bcd02815260206004820152601260248201527f544d3a20496e76616c6964207369676e65720000000000000000000000000000604482015290519081900360640190fd5b5050604080517f697356616c69645369676e617475726528627974657333322c627974657329008152905190819003601f0190205b92915050565b8033600160a060020a03821614610f05576040805160e560020a62461bcd02815260206004820152601960248201527f424d3a2063616c6c6572206d7573742062652077616c6c657400000000000000604482015290519081900360640190fd5b604080517f697356616c69645369676e61747572652862797465732c6279746573290000008152815190819003601d0181207f13da30b20000000000000000000000000000000000000000000000000000000082523060048301527fffffffff000000000000000000000000000000000000000000000000000000001660248201529051600160a060020a038416916313da30b291604480830192600092919082900301818387803b158015610fba57600080fd5b505af1158015610fce573d6000803e3d6000fd5b5050604080517f697356616c69645369676e617475726528627974657333322c627974657329008152815190819003601f0181207f13da30b20000000000000000000000000000000000000000000000000000000082523060048301527fffffffff000000000000000000000000000000000000000000000000000000001660248201529051600160a060020a03861693506313da30b29250604480830192600092919082900301818387803b15801561108757600080fd5b505af115801561109b573d6000803e3d6000fd5b5050600a54600160a060020a0316151591506110c19050576110bc826136af565b61149c565b600a54604080517f43cd5c7e000000000000000000000000000000000000000000000000000000008152600160a060020a038581166004830152915160009392909216916343cd5c7e91602480820192602092909190829003018186803b15801561112b57600080fd5b505afa15801561113f573d6000803e3d6000fd5b505050506040513d602081101561115557600080fd5b5051600a54604080517fa0aec105000000000000000000000000000000000000000000000000000000008152600160a060020a03878116600483015282519495506000948594919091169263a0aec1059260248082019391829003018186803b1580156111c157600080fd5b505afa1580156111d5573d6000803e3d6000fd5b505050506040513d60408110156111eb57600080fd5b50805160209091015190925090508215801561120f575067ffffffffffffffff8116155b156112255761121d856136af565b50505061149c565b8183141561127557600160a060020a038516600090815260036020526040902080546fffffffffffffffffffffffffffffffff19166fffffffffffffffffffffffffffffffff8516179055611325565b604080516060810182526fffffffffffffffffffffffffffffffff8086168252848116602080840191825267ffffffffffffffff808716858701908152600160a060020a038c1660009081526003909352959091209351845492518416700100000000000000000000000000000000029084166fffffffffffffffffffffffffffffffff19909316929092179092161782559151600190910180549190921667ffffffffffffffff199091161790555b600a54604080517f7cb8f8ba000000000000000000000000000000000000000000000000000000008152600160a060020a03888116600483015282516000948594921692637cb8f8ba926024808301939192829003018186803b15801561138b57600080fd5b505afa15801561139f573d6000803e3d6000fd5b505050506040513d60408110156113b557600080fd5b50805160209091015190925090504267ffffffffffffffff82161115610d935760408051808201909152806113f0878563ffffffff61378d16565b6fffffffffffffffffffffffffffffffff908116825267ffffffffffffffff938416602092830152600160a060020a038a166000908152600383526040902083516002909101805494909301516fffffffffffffffffffffffffffffffff199094169116177fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000009290931691909102919091179055505050505b5050565b60008085856040516020018083838082843780830192505050925050506040516020818303038152906040528051906020012090506115158185858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610d9d92505050565b5050604080517f697356616c69645369676e61747572652862797465732c6279746573290000008152905190819003601d01902090505b949350505050565b600160a060020a031660009081526002602052604090205490565b8533301480611583575061158381336133db565b15156115c35760405160e560020a62461bcd028152600401808060200182810382526023815260200180614bbb6023913960400191505060405180910390fd5b600154604080517f4a4fbeec000000000000000000000000000000000000000000000000000000008152600160a060020a03808b16600483015291518a939290921691634a4fbeec91602480820192602092909190829003018186803b15801561162c57600080fd5b505afa158015611640573d6000803e3d6000fd5b505050506040513d602081101561165657600080fd5b5051156116ad576040805160e560020a62461bcd02815260206004820152601b60248201527f424d3a2077616c6c6574206d75737420626520756e6c6f636b65640000000000604482015290519081900360640190fd5b6116b78887612b68565b15611704576116ff8888888888888080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506137a292505050565b61191b565b6000600160a060020a03881673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee146117c857600954604080517fce55c85200000000000000000000000000000000000000000000000000000000815260048101899052600160a060020a038b811660248301529151919092169163ce55c852916044808301926020929190829003018186803b15801561179757600080fd5b505afa1580156117ab573d6000803e3d6000fd5b505050506040513d60208110156117c157600080fd5b50516117ca565b855b90506117d6898261354d565b156118235761181e8989898989898080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506137a292505050565b610d90565b60008061186b60008c8c8c8c8c8c8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061393d92505050565b9150915080828c600160a060020a03167fc63146cfd39cd6097f6e314e8595c4554faf95175b45c6215517903c12e765d98d8d8d8d8d6040518086600160a060020a0316600160a060020a0316815260200185600160a060020a0316600160a060020a03168152602001848152602001806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039850909650505050505050a45050505b5050505050505050565b600160a060020a038116600090815260036020526040812080546001820154611983916fffffffffffffffffffffffffffffffff80821692700100000000000000000000000000000000909204169067ffffffffffffffff16613b23565b6fffffffffffffffffffffffffffffffff169392505050565b81333014806119b057506119b081336133db565b15156119f05760405160e560020a62461bcd028152600401808060200182810382526023815260200180614bbb6023913960400191505060405180910390fd5b600154604080517f4a4fbeec000000000000000000000000000000000000000000000000000000008152600160a060020a038087166004830152915186939290921691634a4fbeec91602480820192602092909190829003018186803b158015611a5957600080fd5b505afa158015611a6d573d6000803e3d6000fd5b505050506040513d6020811015611a8357600080fd5b505115611ada576040805160e560020a62461bcd02815260206004820152601b60248201527f424d3a2077616c6c6574206d75737420626520756e6c6f636b65640000000000604482015290519081900360640190fd5b611ae48484612b68565b15611b39576040805160e560020a62461bcd02815260206004820152601e60248201527f54543a2074617267657420616c72656164792077686974656c69737465640000604482015290519081900360640190fd5b6000611b5060065442613b5b90919063ffffffff16565b600854604080517f80bfbe68000000000000000000000000000000000000000000000000000000008152600160a060020a03898116600483015288811660248301526044820185905291519394509116916380bfbe689160648082019260009290919082900301818387803b158015611bc857600080fd5b505af1158015611bdc573d6000803e3d6000fd5b50506040805167ffffffffffffffff851681529051600160a060020a038089169450891692507f1f57f9641d3e8733ed672fef5ac85464bd7215ef2f21e83428e8408248b13dcd9181900360200190a35050505050565b8133301480611c475750611c4781336133db565b1515611c875760405160e560020a62461bcd028152600401808060200182810382526023815260200180614bbb6023913960400191505060405180910390fd5b600054604080517f0bcd4ebb000000000000000000000000000000000000000000000000000000008152600160a060020a03858116600483015291519190921691630bcd4ebb916024808301926020929190829003018186803b158015611ced57600080fd5b505afa158015611d01573d6000803e3d6000fd5b505050506040513d6020811015611d1757600080fd5b50511515611d6f576040805160e560020a62461bcd02815260206004820152601c60248201527f424d3a206d6f64756c65206973206e6f74207265676973746572656400000000604482015290519081900360640190fd5b604080517f1f17732d000000000000000000000000000000000000000000000000000000008152600160a060020a03848116600483015260016024830152915191851691631f17732d9160448082019260009290919082900301818387803b158015611dda57600080fd5b505af1158015610d93573d6000803e3d6000fd5b600154604080517f4a4fbeec000000000000000000000000000000000000000000000000000000008152600160a060020a03808b16600483015291518a939290921691634a4fbeec91602480820192602092909190829003018186803b158015611e5757600080fd5b505afa158015611e6b573d6000803e3d6000fd5b505050506040513d6020811015611e8157600080fd5b505115611ed8576040805160e560020a62461bcd02815260206004820152601b60248201527f424d3a2077616c6c6574206d75737420626520756e6c6f636b65640000000000604482015290519081900360640190fd5b60008088888888888860405160200180886000811115611ef457fe5b60ff167f010000000000000000000000000000000000000000000000000000000000000002815260010187600160a060020a0316600160a060020a03166c0100000000000000000000000002815260140186600160a060020a0316600160a060020a03166c01000000000000000000000000028152601401858152602001848480828437808301925050508281526020019750505050505050506040516020818303038152906040528051906020012090506000600560008b600160a060020a0316600160a060020a03168152602001908152602001600020600001600083815260200190815260200160002054905060008111151561203e576040805160e560020a62461bcd02815260206004820152601c60248201527f54543a20756e6b6e6f776e2070656e64696e67207472616e7366657200000000604482015290519081900360640190fd5b600061205560075483613b5b90919063ffffffff16565b90504282111580156120675750804211155b15156120a75760405160e560020a62461bcd02815260040180806020018281038252602c815260200180614b8f602c913960400191505060405180910390fd5b600160a060020a038b1660009081526005602090815260408083208684528252808320929092558151601f8901829004820281018201909252878252612110918d918d918d918d91908d908d90819084018382808284376000920191909152506137a292505050565b6040518390600160a060020a038d16907f53d984c4cd3917405bdcc3baabad7c1269dd3baf7c2c53ca571d8d7de9629bc990600090a35050505050505050505050565b600080600061216184611925565b600160a060020a0385166000908152600360205260409020600201805491925090700100000000000000000000000000000000900467ffffffffffffffff164211156121b757819350426201518001925061220b565b805467ffffffffffffffff70010000000000000000000000000000000082041693506fffffffffffffffffffffffffffffffff1682111561220b5780546fffffffffffffffffffffffffffffffff16820393505b5050915091565b60065481565b600a54600160a060020a031681565b600854600160a060020a031681565b604080517f70a082310000000000000000000000000000000000000000000000000000000081523060048201529051600091600160a060020a038416916370a0823191602480820192602092909190829003018186803b15801561229957600080fd5b505afa1580156122ad573d6000803e3d6000fd5b505050506040513d60208110156122c357600080fd5b505160008054604080517fa9059cbb000000000000000000000000000000000000000000000000000000008152600160a060020a0392831660048201526024810185905290519394509085169263a9059cbb92604480840193602093929083900390910190829087803b15801561233957600080fd5b505af115801561234d573d6000803e3d6000fd5b505050506040513d602081101561236357600080fd5b50505050565b600160a060020a0381166000908152600360205260408120600181015482919067ffffffffffffffff1642106123a1576000806123db565b805460018201547001000000000000000000000000000000009091046fffffffffffffffffffffffffffffffff169067ffffffffffffffff165b9250925050915091565b80333014806123f957506123f981336133db565b15156124395760405160e560020a62461bcd028152600401808060200182810382526023815260200180614bbb6023913960400191505060405180910390fd5b600154604080517f4a4fbeec000000000000000000000000000000000000000000000000000000008152600160a060020a038086166004830152915185939290921691634a4fbeec91602480820192602092909190829003018186803b1580156124a257600080fd5b505afa1580156124b6573d6000803e3d6000fd5b505050506040513d60208110156124cc57600080fd5b505115612523576040805160e560020a62461bcd02815260206004820152601b60248201527f424d3a2077616c6c6574206d75737420626520756e6c6f636b65640000000000604482015290519081900360640190fd5b61252f83600654613b6d565b505050565b6000805a90506000612584308c60008d8d8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508f92508c91508b9050613b88565b90506125918b8983613ccb565b15156125e7576040805160e560020a62461bcd02815260206004820152601560248201527f524d3a204475706c696361746520726571756573740000000000000000000000604482015290519081900360640190fd5b6126278b8b8b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250613cd792505050565b15156126675760405160e560020a62461bcd02815260040180806020018281038252604a815260200180614b22604a913960600191505060405180910390fd5b60006126a98c8c8c8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250613d4b92505050565b9050604181028714156127c1576126c28c868884613d53565b156127c15780158061274557506127458c8c8c8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8f018190048102820181019092528d815288935091508d908d9081908401838280828437600092019190915250613e4292505050565b156127c15730600160a060020a03168b8b604051808383808284376040519201945060009350909150508083038183865af19150503d80600081146127a6576040519150601f19603f3d011682016040523d82523d6000602084013e6127ab565b606091505b5050809450506127c18c5a850388888533613e67565b60408051838152905185151591600160a060020a038f16917f6bb0b384ce772133df63560651bc8c727c53306cec1d51e2cbf8ea35fb8f2ec19181900360200190a350505098975050505050505050565b8133301480612826575061282681336133db565b15156128665760405160e560020a62461bcd028152600401808060200182810382526023815260200180614bbb6023913960400191505060405180910390fd5b600154604080517f4a4fbeec000000000000000000000000000000000000000000000000000000008152600160a060020a038087166004830152915186939290921691634a4fbeec91602480820192602092909190829003018186803b1580156128cf57600080fd5b505afa1580156128e3573d6000803e3d6000fd5b505050506040513d60208110156128f957600080fd5b505115612950576040805160e560020a62461bcd02815260206004820152601b60248201527f424d3a2077616c6c6574206d75737420626520756e6c6f636b65640000000000604482015290519081900360640190fd5b6123638484600654613ec6565b8133301480612971575061297181336133db565b15156129b15760405160e560020a62461bcd028152600401808060200182810382526023815260200180614bbb6023913960400191505060405180910390fd5b600154604080517f4a4fbeec000000000000000000000000000000000000000000000000000000008152600160a060020a038087166004830152915186939290921691634a4fbeec91602480820192602092909190829003018186803b158015612a1a57600080fd5b505afa158015612a2e573d6000803e3d6000fd5b505050506040513d6020811015612a4457600080fd5b505115612a9b576040805160e560020a62461bcd02815260206004820152601b60248201527f424d3a2077616c6c6574206d75737420626520756e6c6f636b65640000000000604482015290519081900360640190fd5b600160a060020a038416600090815260056020908152604080832086845290915281205411612b14576040805160e560020a62461bcd02815260206004820152601a60248201527f54543a20756e6b6e6f776e2070656e64696e6720616374696f6e000000000000604482015290519081900360640190fd5b600160a060020a0384166000818152600560209081526040808320878452909152808220829055518592917f2914460f2e2359d06bcda666d815164a8e77d104644dfbe6360885abfa2da59c91a350505050565b600854604080517f13f4a0ea000000000000000000000000000000000000000000000000000000008152600160a060020a03858116600483015284811660248301529151600093849316916313f4a0ea916044808301926020929190829003018186803b158015612bd857600080fd5b505afa158015612bec573d6000803e3d6000fd5b505050506040513d6020811015612c0257600080fd5b5051905060008111801561154c575042119392505050565b600954600160a060020a031681565b60026020526000908152604090205481565b7fd490da4d0000000000000000000000000000000000000000000000000000000090565b8633301480612c735750612c7381336133db565b1515612cb35760405160e560020a62461bcd028152600401808060200182810382526023815260200180614bbb6023913960400191505060405180910390fd5b600154604080517f4a4fbeec000000000000000000000000000000000000000000000000000000008152600160a060020a03808c16600483015291518b939290921691634a4fbeec91602480820192602092909190829003018186803b158015612d1c57600080fd5b505afa158015612d30573d6000803e3d6000fd5b505050506040513d6020811015612d4657600080fd5b505115612d9d576040805160e560020a62461bcd02815260206004820152601b60248201527f424d3a2077616c6c6574206d75737420626520756e6c6f636b65640000000000604482015290519081900360640190fd5b612da78986614024565b612db18988612b68565b1515612eb857600954604080517fce55c85200000000000000000000000000000000000000000000000000000000815260048101899052600160a060020a038b811660248301529151600093929092169163ce55c85291604480820192602092909190829003018186803b158015612e2857600080fd5b505afa158015612e3c573d6000803e3d6000fd5b505050506040513d6020811015612e5257600080fd5b50519050612e608a8261354d565b1515612eb6576040805160e560020a62461bcd02815260206004820152601d60248201527f544d3a20417070726f76652061626f7665206461696c79206c696d6974000000604482015290519081900360640190fd5b505b610d90898989898989898080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506141e092505050565b600160a060020a039091166000908152600560209081526040808320938352929052205490565b60045481565b8133301480612f3d5750612f3d81336133db565b1515612f7d5760405160e560020a62461bcd028152600401808060200182810382526023815260200180614bbb6023913960400191505060405180910390fd5b600154604080517f4a4fbeec000000000000000000000000000000000000000000000000000000008152600160a060020a038087166004830152915186939290921691634a4fbeec91602480820192602092909190829003018186803b158015612fe657600080fd5b505afa158015612ffa573d6000803e3d6000fd5b505050506040513d602081101561301057600080fd5b505115613067576040805160e560020a62461bcd02815260206004820152601b60248201527f424d3a2077616c6c6574206d75737420626520756e6c6f636b65640000000000604482015290519081900360640190fd5b6130718484612b68565b15156130c7576040805160e560020a62461bcd02815260206004820152601a60248201527f54543a20746172676574206e6f742077686974656c6973746564000000000000604482015290519081900360640190fd5b600854604080517f80bfbe68000000000000000000000000000000000000000000000000000000008152600160a060020a038781166004830152868116602483015260006044830181905292519316926380bfbe689260648084019391929182900301818387803b15801561313b57600080fd5b505af115801561314f573d6000803e3d6000fd5b5050604051600160a060020a038087169350871691507fd288ab5da2e1f37cf384a1565a3f905ad289b092fbdd31950dbbfef148c04f8890600090a350505050565b60008061319d83611925565b6fffffffffffffffffffffffffffffffff149392505050565b84333014806131ca57506131ca81336133db565b151561320a5760405160e560020a62461bcd028152600401808060200182810382526023815260200180614bbb6023913960400191505060405180910390fd5b600154604080517f4a4fbeec000000000000000000000000000000000000000000000000000000008152600160a060020a03808a166004830152915189939290921691634a4fbeec91602480820192602092909190829003018186803b15801561327357600080fd5b505afa158015613287573d6000803e3d6000fd5b505050506040513d602081101561329d57600080fd5b5051156132f4576040805160e560020a62461bcd02815260206004820152601b60248201527f424d3a2077616c6c6574206d75737420626520756e6c6f636b65640000000000604482015290519081900360640190fd5b6132fe8787614024565b6133088787612b68565b1561334f57610c7f87878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061459592505050565b613359878661354d565b15156133995760405160e560020a62461bcd028152600401808060200182810382526023815260200180614b6c6023913960400191505060405180910390fd5b610d9387878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061459592505050565b600081600160a060020a031683600160a060020a0316638da5cb5b6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b15801561343c57600080fd5b505afa158015613450573d6000803e3d6000fd5b505050506040513d602081101561346657600080fd5b5051600160a060020a0316149392505050565b60408051600160a060020a038416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790526134fb858560008461465d565b5060408051838152600160a060020a038581166020830152825181881693918916927fdc47705473b4a899de6e16a740ecc86f2a65dc7dbb9eadd0a06ce5421a44e23092908290030190a35050505050565b600081151561355e57506001610e9e565b600160a060020a0383166000908152600360205260408120805460018201549192916135bf916fffffffffffffffffffffffffffffffff80821692700100000000000000000000000000000000909204169067ffffffffffffffff16613b23565b90506135de85826fffffffffffffffffffffffffffffffff16866148e0565b156135f9576135ee858286614992565b600192505050610e9e565b506000949350505050565b6041808202830160208101516040820151919092015160009260ff9190911691601b83148061363657508260ff16601c145b151561364157600080fd5b604080516000815260208082018084528a905260ff8616828401526060820185905260808201849052915160019260a0808401939192601f1981019281900390910190855afa158015613698573d6000803e3d6000fd5b5050506020604051035193505050505b9392505050565b8033600160a060020a03821614613710576040805160e560020a62461bcd02815260206004820152601960248201527f424d3a2063616c6c6572206d7573742062652077616c6c657400000000000000604482015290519081900360640190fd5b600160a060020a038216600090815260036020526040902080546fffffffffffffffffffffffffffffffff161580156137555750600181015467ffffffffffffffff16155b1561252f5760045481546fffffffffffffffffffffffffffffffff19166fffffffffffffffffffffffffffffffff9091161790555050565b60008282111561379c57600080fd5b50900390565b600160a060020a03841673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14156137e9576137e3858484602060405190810160405280600081525061465d565b5061386e565b60408051600160a060020a038516602482015260448082018590528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261386b868660008461465d565b50505b8184600160a060020a031686600160a060020a03167fd5c97f2e041b2046be3b4337472f05720760a198f4d7d84980b7155eec7cca6f86856040518083600160a060020a0316600160a060020a0316815260200180602001828103825283818151815260200191508051906020019080838360005b838110156138fb5781810151838201526020016138e3565b50505050905090810190601f1680156139285780820380516001836020036101000a031916815260200191505b50935050505060405180910390a45050505050565b6000808786868686436040516020018087600081111561395957fe5b60ff167f010000000000000000000000000000000000000000000000000000000000000002815260010186600160a060020a0316600160a060020a03166c0100000000000000000000000002815260140185600160a060020a0316600160a060020a03166c0100000000000000000000000002815260140184815260200183805190602001908083835b60208310613a025780518252601f1990920191602091820191016139e3565b6001836020036101000a03801982511681845116808217855250505050505090500182815260200196505050505050506040516020818303038152906040528051906020012091506005600088600160a060020a0316600160a060020a031681526020019081526020016000206000016000838152602001908152602001600020546000141515613add576040805160e560020a62461bcd02815260206004820152601c60248201527f544d3a206475706c69636174652070656e64696e6720616374696f6e00000000604482015290519081900360640190fd5b600654613af190429063ffffffff613b5b16565b600160a060020a0390971660009081526005602090815260408083208584529091529020879055509694955050505050565b6000808267ffffffffffffffff16118015613b475750428267ffffffffffffffff16105b15613b535750816136a8565b509192915050565b6000828201838110156136a857600080fd5b61149c826fffffffffffffffffffffffffffffffff83613ec6565b6040517f190000000000000000000000000000000000000000000000000000000000000060208083018281526000602185018190526c01000000000000000000000000600160a060020a03808e16820260228801528c16026036860152604a85018a90528851909485938d938d938d938d938d938d938d939192606a909201918701908083835b60208310613c2e5780518252601f199092019160209182019101613c0f565b51815160209384036101000a600019018019909216911617905292019586525084810193909352506040808401919091528051808403820181526060840182528051908301207f19457468657265756d205369676e6564204d6573736167653a0a3332000000006080850152609c808501919091528151808503909101815260bc909301905281519101209e9d5050505050505050505050505050565b600061154c8484614a9b565b60006024825110151515613d35576040805160e560020a62461bcd02815260206004820152601660248201527f524d3a20496e76616c6964206461746157616c6c657400000000000000000000604482015290519081900360640190fd5b5060240151600160a060020a0391821691161490565b600192915050565b60008083118015613d645750600082115b8015613e2a575082840285600160a060020a0316311080613d975750613d9585613d8d87611925565b8587026148e0565b155b80613e2a5750604080517fd6eb1bbf0000000000000000000000000000000000000000000000000000000081523060048201529051600160a060020a0387169163d6eb1bbf916024808301926020929190829003018186803b158015613dfc57600080fd5b505afa158015613e10573d6000803e3d6000fd5b505050506040513d6020811015613e2657600080fd5b5051155b15613e375750600061154c565b506001949350505050565b600080613e5184846000613604565b9050613e5d86826133db565b9695505050505050565b618f088501600085118015613e7c5750600083115b8015613e885750838111155b15610d93573a851115613e9c573a02613e9f565b84025b613ea9878261354d565b5061191b878383602060405190810160405280600081525061465d565b600160a060020a0383166000908152600360205260408120600181015490919067ffffffffffffffff1681108015613f0d575060018201544267ffffffffffffffff909116105b613f2a5781546fffffffffffffffffffffffffffffffff16613f53565b815470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff165b82546fffffffffffffffffffffffffffffffff868116700100000000000000000000000000000000028184166fffffffffffffffffffffffffffffffff1990931692909217161783559050613fae428463ffffffff613b5b16565b60018301805467ffffffffffffffff191667ffffffffffffffff92909216919091179055613fdc4284613b5b565b67ffffffffffffffff168486600160a060020a03167f8a747eae44b6307d1b112c127968367d02d9f52ffef8533b3e899983ff2b1d4a60405160405180910390a45050505050565b81600160a060020a031681600160a060020a0316141580156140e1575081600160a060020a031663d6eb1bbf826040518263ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018082600160a060020a0316600160a060020a0316815260200191505060206040518083038186803b1580156140b357600080fd5b505afa1580156140c7573d6000803e3d6000fd5b505050506040513d60208110156140dd57600080fd5b5051155b801561418a5750600954604080517f837479c9000000000000000000000000000000000000000000000000000000008152600160a060020a0384811660048301529151919092169163837479c9916024808301926020929190829003018186803b15801561414e57600080fd5b505afa158015614162573d6000803e3d6000fd5b505050506040513d602081101561417857600080fd5b5051158061418a575061418a82613191565b151561149c576040805160e560020a62461bcd02815260206004820152601660248201527f544d3a20466f7262696464656e20636f6e747261637400000000000000000000604482015290519081900360640190fd5b604080517fdd62ed3e000000000000000000000000000000000000000000000000000000008152600160a060020a0388811660048301528681166024830152915160009288169163dd62ed3e916044808301926020929190829003018186803b15801561424c57600080fd5b505afa158015614260573d6000803e3d6000fd5b505050506040513d602081101561427657600080fd5b5051905060006142868286613b5b565b60408051600160a060020a038916602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b30000000000000000000000000000000000000000000000000000000017905290915061430b898960008461465d565b50614319898660008761465d565b50604080517fdd62ed3e000000000000000000000000000000000000000000000000000000008152600160a060020a038b81166004830152898116602483015291516000928b169163dd62ed3e916044808301926020929190829003018186803b15801561438657600080fd5b505afa15801561439a573d6000803e3d6000fd5b505050506040513d60208110156143b057600080fd5b5051905060006143c0848361378d565b90508781111561441a576040805160e560020a62461bcd02815260206004820181905260248201527f42543a20696e73756666696369656e7420616d6f756e7420666f722063616c6c604482015290519081900360640190fd5b8185146144a75760408051600160a060020a038b16602482015260448082018890528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b30000000000000000000000000000000000000000000000000000000017905292506144a58b8b60008661465d565b505b89600160a060020a031687600160a060020a03168c600160a060020a03167fb99e2a91cdfde581196884f6b42392a5000200a43dd5726d92d9405616fdffb98c8c868c6040518085600160a060020a0316600160a060020a0316815260200184815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561454b578181015183820152602001614533565b50505050905090810190601f1680156145785780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a45050505050505050505050565b6145a18484848461465d565b5082600160a060020a031684600160a060020a03167fbfbd7fb6c6d7dd1ef01d18a7e98333f084363d82d5ce600328e8b941a53d665484846040518083815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561461c578181015183820152602001614604565b50505050905090810190601f1680156146495780820380516001836020036101000a031916815260200191505b50935050505060405180910390a350505050565b6060600085600160a060020a03168585856040516024018084600160a060020a0316600160a060020a0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b838110156146cc5781810151838201526020016146b4565b50505050905090810190601f1680156146f95780820380516001836020036101000a031916815260200191505b5060408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f8f6f033200000000000000000000000000000000000000000000000000000000178152905182519297509550859450925090508083835b602083106147855780518252601f199092019160209182019101614766565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146147e7576040519150601f19603f3d011682016040523d82523d6000602084013e6147ec565b606091505b50925090508080156147ff575060008251115b1561486c5781806020019051602081101561481957600080fd5b81019080805164010000000081111561483157600080fd5b8201602081018481111561484457600080fd5b815164010000000081118282018710171561485e57600080fd5b509095506148d79350505050565b600082511115614880573d6000803e3d6000fd5b8015156148d7576040805160e560020a62461bcd02815260206004820152601a60248201527f424d3a2077616c6c657420696e766f6b65207265766572746564000000000000604482015290519081900360640190fd5b50949350505050565b60006fffffffffffffffffffffffffffffffff831415614902575060016136a8565b600160a060020a038416600090815260036020526040902060020180544270010000000000000000000000000000000090910467ffffffffffffffff161015614950575050818111156136a8565b80546fffffffffffffffffffffffffffffffff168301841080159061498a575080546fffffffffffffffffffffffffffffffff1683810110155b9150506136a8565b6fffffffffffffffffffffffffffffffff8281161461252f57600160a060020a038316600090815260036020526040902060020180544270010000000000000000000000000000000090910467ffffffffffffffff161015614a645780547fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff1670010000000000000000000000000000000042620151800167ffffffffffffffff1602176fffffffffffffffffffffffffffffffff19166fffffffffffffffffffffffffffffffff8316178155612363565b80546fffffffffffffffffffffffffffffffff8082168401166fffffffffffffffffffffffffffffffff1990911617815550505050565b600160a060020a0382166000908152600260205260408120548211614ac257506000610e9e565b7001000000000000000000000000000000006fffffffffffffffffffffffffffffffff198316044361271001811115614aff576000915050610e9e565b5050600160a060020a039190911660009081526002602052604090205560019056fe524d3a207468652077616c6c657420617574686f72697a656420697320646966666572656e74207468656e2074686520746172676574206f66207468652072656c617965642064617461544d3a2043616c6c20636f6e74726163742061626f7665206461696c79206c696d697454543a207472616e73666572206f757473696465206f662074686520657865637574696f6e2077696e646f77424d3a206d75737420626520616e206f776e657220666f72207468652077616c6c6574a165627a7a72305820641e34e07437f1a08f3931f78ac4ac6e754cc21aa2278f474a6465f63e50f3560029000000000000000000000000c17d432bd8e8850fd7b32b0270f5afac65db0105000000000000000000000000391f0e86da951c03b1183c60b195090671adea8800000000000000000000000044da3a8051ba88eab0440db3779cab9d679ae76f000000000000000000000000e8a76d2f37fe50b6a95d27fb92291fe0b57407d30000000000000000000000000000000000000000000000000000000000015180000000000000000000000000000000000000000000000000000000000000a8c00000000000000000000000000000000000000000000000008ac7230489e800000000000000000000000000002b6d87f12b106e1d3fa7137494751566329d1045

Deployed Bytecode

0x608060405234801561001057600080fd5b5060043610610201576000357c0100000000000000000000000000000000000000000000000000000000900480639be65a601161012c578063c9b5ef8e116100bf578063e26b013b1161008e578063e26b013b14610982578063f8d3277d1461098a578063f9f6499e146109b8578063fd6ac309146109de57610201565b8063c9b5ef8e1461086c578063d490da4d14610892578063d5e69ee91461089a578063e1ee38ec1461093957610201565b8063b20f3f37116100fb578063b20f3f37146107de578063b377a9d51461080a578063b6b3527214610836578063b888879e1461086457610201565b80639be65a601461067c578063a0aec105146106a2578063a3411c0a146106c8578063aacaaf88146106ee57610201565b806343cd5c7e116101a45780637cb8f8ba116101735780637cb8f8ba146106005780637cc0d9061461064857806395813db414610650578063961bfeee1461067457610201565b806343cd5c7e146104e6578063575182431461050c5780635a1db8c41461053a5780635ed4bf811461056857610201565b806319ab453c116101e057806319ab453c1461034057806320c13b0b146103665780632d0335ab146104285780632df546f41461044e57610201565b80626fda351461020657806312ef080d146102205780631626ba7e1461025e575b600080fd5b61020e610a6e565b60408051918252519081900360200190f35b61025c6004803603608081101561023657600080fd5b50600160a060020a03813581169160208101358216916040820135169060600135610a74565b005b61030b6004803603604081101561027457600080fd5b8135919081019060408101602082013564010000000081111561029657600080fd5b8201836020820111156102a857600080fd5b803590602001918460018302840111640100000000831117156102ca57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610d9d945050505050565b604080517fffffffff000000000000000000000000000000000000000000000000000000009092168252519081900360200190f35b61025c6004803603602081101561035657600080fd5b5035600160a060020a0316610ea4565b61030b6004803603604081101561037c57600080fd5b81019060208101813564010000000081111561039757600080fd5b8201836020820111156103a957600080fd5b803590602001918460018302840111640100000000831117156103cb57600080fd5b9193909290916020810190356401000000008111156103e957600080fd5b8201836020820111156103fb57600080fd5b8035906020019184600183028401116401000000008311171561041d57600080fd5b5090925090506114a0565b61020e6004803603602081101561043e57600080fd5b5035600160a060020a0316611554565b61025c600480360360a081101561046457600080fd5b600160a060020a03823581169260208101358216926040820135909216916060820135919081019060a0810160808201356401000000008111156104a757600080fd5b8201836020820111156104b957600080fd5b803590602001918460018302840111640100000000831117156104db57600080fd5b50909250905061156f565b61020e600480360360208110156104fc57600080fd5b5035600160a060020a0316611925565b61025c6004803603604081101561052257600080fd5b50600160a060020a038135811691602001351661199c565b61025c6004803603604081101561055057600080fd5b50600160a060020a0381358116916020013516611c33565b61025c600480360360c081101561057e57600080fd5b600160a060020a03823581169260208101358216926040820135909216916060820135919081019060a0810160808201356401000000008111156105c157600080fd5b8201836020820111156105d357600080fd5b803590602001918460018302840111640100000000831117156105f557600080fd5b919350915035611dee565b6106266004803603602081101561061657600080fd5b5035600160a060020a0316612153565b6040805192835267ffffffffffffffff90911660208301528051918290030190f35b61020e612212565b610658612218565b60408051600160a060020a039092168252519081900360200190f35b610658612227565b61025c6004803603602081101561069257600080fd5b5035600160a060020a0316612236565b610626600480360360208110156106b857600080fd5b5035600160a060020a0316612369565b61025c600480360360208110156106de57600080fd5b5035600160a060020a03166123e5565b6107ca600480360360c081101561070457600080fd5b600160a060020a03823516919081019060408101602082013564010000000081111561072f57600080fd5b82018360208201111561074157600080fd5b8035906020019184600183028401116401000000008311171561076357600080fd5b9193909282359260408101906020013564010000000081111561078557600080fd5b82018360208201111561079757600080fd5b803590602001918460018302840111640100000000831117156107b957600080fd5b919350915080359060200135612534565b604080519115158252519081900360200190f35b61025c600480360360408110156107f457600080fd5b50600160a060020a038135169060200135612812565b61025c6004803603604081101561082057600080fd5b50600160a060020a03813516906020013561295d565b6107ca6004803603604081101561084c57600080fd5b50600160a060020a0381358116916020013516612b68565b610658612c1a565b61020e6004803603602081101561088257600080fd5b5035600160a060020a0316612c29565b61030b612c3b565b61025c600480360360c08110156108b057600080fd5b600160a060020a0382358116926020810135821692604082013583169260608301359260808101359091169181019060c0810160a08201356401000000008111156108fa57600080fd5b82018360208201111561090c57600080fd5b8035906020019184600183028401116401000000008311171561092e57600080fd5b509092509050612c5f565b6109656004803603604081101561094f57600080fd5b50600160a060020a038135169060200135612efc565b6040805167ffffffffffffffff9092168252519081900360200190f35b61020e612f23565b61025c600480360360408110156109a057600080fd5b50600160a060020a0381358116916020013516612f29565b6107ca600480360360208110156109ce57600080fd5b5035600160a060020a0316613191565b61025c600480360360808110156109f457600080fd5b600160a060020a03823581169260208101359091169160408201359190810190608081016060820135640100000000811115610a2f57600080fd5b820183602082011115610a4157600080fd5b80359060200191846001830284011164010000000083111715610a6357600080fd5b5090925090506131b6565b60075481565b8333301480610a885750610a8881336133db565b1515610ac85760405160e560020a62461bcd028152600401808060200182810382526023815260200180614bbb6023913960400191505060405180910390fd5b600154604080517f4a4fbeec000000000000000000000000000000000000000000000000000000008152600160a060020a038089166004830152915188939290921691634a4fbeec91602480820192602092909190829003018186803b158015610b3157600080fd5b505afa158015610b45573d6000803e3d6000fd5b505050506040513d6020811015610b5b57600080fd5b505115610bb2576040805160e560020a62461bcd02815260206004820152601b60248201527f424d3a2077616c6c6574206d75737420626520756e6c6f636b65640000000000604482015290519081900360640190fd5b610bbc8685612b68565b15610bd257610bcd86868686613479565b610d95565b604080517fdd62ed3e000000000000000000000000000000000000000000000000000000008152600160a060020a0388811660048301528681166024830152915160009288169163dd62ed3e916044808301926020929190829003018186803b158015610c3e57600080fd5b505afa158015610c52573d6000803e3d6000fd5b505050506040513d6020811015610c6857600080fd5b50519050808411610c8457610c7f87878787613479565b610d93565b600954604080517fce55c85200000000000000000000000000000000000000000000000000000000815283870360048201819052600160a060020a038a8116602484015292519093600093169163ce55c852916044808301926020929190829003018186803b158015610cf657600080fd5b505afa158015610d0a573d6000803e3d6000fd5b505050506040513d6020811015610d2057600080fd5b50519050610d2e898261354d565b1515610d84576040805160e560020a62461bcd02815260206004820152601d60248201527f544d3a20417070726f76652061626f7665206461696c79206c696d6974000000604482015290519081900360640190fd5b610d9089898989613479565b50505b505b505050505050565b8051600090604114610df9576040805160e560020a62461bcd02815260206004820152601c60248201527f544d3a20696e76616c6964207369676e6174757265206c656e67746800000000604482015290519081900360640190fd5b6000610e0784846000613604565b9050610e1333826133db565b1515610e69576040805160e560020a62461bcd02815260206004820152601260248201527f544d3a20496e76616c6964207369676e65720000000000000000000000000000604482015290519081900360640190fd5b5050604080517f697356616c69645369676e617475726528627974657333322c627974657329008152905190819003601f0190205b92915050565b8033600160a060020a03821614610f05576040805160e560020a62461bcd02815260206004820152601960248201527f424d3a2063616c6c6572206d7573742062652077616c6c657400000000000000604482015290519081900360640190fd5b604080517f697356616c69645369676e61747572652862797465732c6279746573290000008152815190819003601d0181207f13da30b20000000000000000000000000000000000000000000000000000000082523060048301527fffffffff000000000000000000000000000000000000000000000000000000001660248201529051600160a060020a038416916313da30b291604480830192600092919082900301818387803b158015610fba57600080fd5b505af1158015610fce573d6000803e3d6000fd5b5050604080517f697356616c69645369676e617475726528627974657333322c627974657329008152815190819003601f0181207f13da30b20000000000000000000000000000000000000000000000000000000082523060048301527fffffffff000000000000000000000000000000000000000000000000000000001660248201529051600160a060020a03861693506313da30b29250604480830192600092919082900301818387803b15801561108757600080fd5b505af115801561109b573d6000803e3d6000fd5b5050600a54600160a060020a0316151591506110c19050576110bc826136af565b61149c565b600a54604080517f43cd5c7e000000000000000000000000000000000000000000000000000000008152600160a060020a038581166004830152915160009392909216916343cd5c7e91602480820192602092909190829003018186803b15801561112b57600080fd5b505afa15801561113f573d6000803e3d6000fd5b505050506040513d602081101561115557600080fd5b5051600a54604080517fa0aec105000000000000000000000000000000000000000000000000000000008152600160a060020a03878116600483015282519495506000948594919091169263a0aec1059260248082019391829003018186803b1580156111c157600080fd5b505afa1580156111d5573d6000803e3d6000fd5b505050506040513d60408110156111eb57600080fd5b50805160209091015190925090508215801561120f575067ffffffffffffffff8116155b156112255761121d856136af565b50505061149c565b8183141561127557600160a060020a038516600090815260036020526040902080546fffffffffffffffffffffffffffffffff19166fffffffffffffffffffffffffffffffff8516179055611325565b604080516060810182526fffffffffffffffffffffffffffffffff8086168252848116602080840191825267ffffffffffffffff808716858701908152600160a060020a038c1660009081526003909352959091209351845492518416700100000000000000000000000000000000029084166fffffffffffffffffffffffffffffffff19909316929092179092161782559151600190910180549190921667ffffffffffffffff199091161790555b600a54604080517f7cb8f8ba000000000000000000000000000000000000000000000000000000008152600160a060020a03888116600483015282516000948594921692637cb8f8ba926024808301939192829003018186803b15801561138b57600080fd5b505afa15801561139f573d6000803e3d6000fd5b505050506040513d60408110156113b557600080fd5b50805160209091015190925090504267ffffffffffffffff82161115610d935760408051808201909152806113f0878563ffffffff61378d16565b6fffffffffffffffffffffffffffffffff908116825267ffffffffffffffff938416602092830152600160a060020a038a166000908152600383526040902083516002909101805494909301516fffffffffffffffffffffffffffffffff199094169116177fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000009290931691909102919091179055505050505b5050565b60008085856040516020018083838082843780830192505050925050506040516020818303038152906040528051906020012090506115158185858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610d9d92505050565b5050604080517f697356616c69645369676e61747572652862797465732c6279746573290000008152905190819003601d01902090505b949350505050565b600160a060020a031660009081526002602052604090205490565b8533301480611583575061158381336133db565b15156115c35760405160e560020a62461bcd028152600401808060200182810382526023815260200180614bbb6023913960400191505060405180910390fd5b600154604080517f4a4fbeec000000000000000000000000000000000000000000000000000000008152600160a060020a03808b16600483015291518a939290921691634a4fbeec91602480820192602092909190829003018186803b15801561162c57600080fd5b505afa158015611640573d6000803e3d6000fd5b505050506040513d602081101561165657600080fd5b5051156116ad576040805160e560020a62461bcd02815260206004820152601b60248201527f424d3a2077616c6c6574206d75737420626520756e6c6f636b65640000000000604482015290519081900360640190fd5b6116b78887612b68565b15611704576116ff8888888888888080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506137a292505050565b61191b565b6000600160a060020a03881673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee146117c857600954604080517fce55c85200000000000000000000000000000000000000000000000000000000815260048101899052600160a060020a038b811660248301529151919092169163ce55c852916044808301926020929190829003018186803b15801561179757600080fd5b505afa1580156117ab573d6000803e3d6000fd5b505050506040513d60208110156117c157600080fd5b50516117ca565b855b90506117d6898261354d565b156118235761181e8989898989898080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506137a292505050565b610d90565b60008061186b60008c8c8c8c8c8c8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061393d92505050565b9150915080828c600160a060020a03167fc63146cfd39cd6097f6e314e8595c4554faf95175b45c6215517903c12e765d98d8d8d8d8d6040518086600160a060020a0316600160a060020a0316815260200185600160a060020a0316600160a060020a03168152602001848152602001806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039850909650505050505050a45050505b5050505050505050565b600160a060020a038116600090815260036020526040812080546001820154611983916fffffffffffffffffffffffffffffffff80821692700100000000000000000000000000000000909204169067ffffffffffffffff16613b23565b6fffffffffffffffffffffffffffffffff169392505050565b81333014806119b057506119b081336133db565b15156119f05760405160e560020a62461bcd028152600401808060200182810382526023815260200180614bbb6023913960400191505060405180910390fd5b600154604080517f4a4fbeec000000000000000000000000000000000000000000000000000000008152600160a060020a038087166004830152915186939290921691634a4fbeec91602480820192602092909190829003018186803b158015611a5957600080fd5b505afa158015611a6d573d6000803e3d6000fd5b505050506040513d6020811015611a8357600080fd5b505115611ada576040805160e560020a62461bcd02815260206004820152601b60248201527f424d3a2077616c6c6574206d75737420626520756e6c6f636b65640000000000604482015290519081900360640190fd5b611ae48484612b68565b15611b39576040805160e560020a62461bcd02815260206004820152601e60248201527f54543a2074617267657420616c72656164792077686974656c69737465640000604482015290519081900360640190fd5b6000611b5060065442613b5b90919063ffffffff16565b600854604080517f80bfbe68000000000000000000000000000000000000000000000000000000008152600160a060020a03898116600483015288811660248301526044820185905291519394509116916380bfbe689160648082019260009290919082900301818387803b158015611bc857600080fd5b505af1158015611bdc573d6000803e3d6000fd5b50506040805167ffffffffffffffff851681529051600160a060020a038089169450891692507f1f57f9641d3e8733ed672fef5ac85464bd7215ef2f21e83428e8408248b13dcd9181900360200190a35050505050565b8133301480611c475750611c4781336133db565b1515611c875760405160e560020a62461bcd028152600401808060200182810382526023815260200180614bbb6023913960400191505060405180910390fd5b600054604080517f0bcd4ebb000000000000000000000000000000000000000000000000000000008152600160a060020a03858116600483015291519190921691630bcd4ebb916024808301926020929190829003018186803b158015611ced57600080fd5b505afa158015611d01573d6000803e3d6000fd5b505050506040513d6020811015611d1757600080fd5b50511515611d6f576040805160e560020a62461bcd02815260206004820152601c60248201527f424d3a206d6f64756c65206973206e6f74207265676973746572656400000000604482015290519081900360640190fd5b604080517f1f17732d000000000000000000000000000000000000000000000000000000008152600160a060020a03848116600483015260016024830152915191851691631f17732d9160448082019260009290919082900301818387803b158015611dda57600080fd5b505af1158015610d93573d6000803e3d6000fd5b600154604080517f4a4fbeec000000000000000000000000000000000000000000000000000000008152600160a060020a03808b16600483015291518a939290921691634a4fbeec91602480820192602092909190829003018186803b158015611e5757600080fd5b505afa158015611e6b573d6000803e3d6000fd5b505050506040513d6020811015611e8157600080fd5b505115611ed8576040805160e560020a62461bcd02815260206004820152601b60248201527f424d3a2077616c6c6574206d75737420626520756e6c6f636b65640000000000604482015290519081900360640190fd5b60008088888888888860405160200180886000811115611ef457fe5b60ff167f010000000000000000000000000000000000000000000000000000000000000002815260010187600160a060020a0316600160a060020a03166c0100000000000000000000000002815260140186600160a060020a0316600160a060020a03166c01000000000000000000000000028152601401858152602001848480828437808301925050508281526020019750505050505050506040516020818303038152906040528051906020012090506000600560008b600160a060020a0316600160a060020a03168152602001908152602001600020600001600083815260200190815260200160002054905060008111151561203e576040805160e560020a62461bcd02815260206004820152601c60248201527f54543a20756e6b6e6f776e2070656e64696e67207472616e7366657200000000604482015290519081900360640190fd5b600061205560075483613b5b90919063ffffffff16565b90504282111580156120675750804211155b15156120a75760405160e560020a62461bcd02815260040180806020018281038252602c815260200180614b8f602c913960400191505060405180910390fd5b600160a060020a038b1660009081526005602090815260408083208684528252808320929092558151601f8901829004820281018201909252878252612110918d918d918d918d91908d908d90819084018382808284376000920191909152506137a292505050565b6040518390600160a060020a038d16907f53d984c4cd3917405bdcc3baabad7c1269dd3baf7c2c53ca571d8d7de9629bc990600090a35050505050505050505050565b600080600061216184611925565b600160a060020a0385166000908152600360205260409020600201805491925090700100000000000000000000000000000000900467ffffffffffffffff164211156121b757819350426201518001925061220b565b805467ffffffffffffffff70010000000000000000000000000000000082041693506fffffffffffffffffffffffffffffffff1682111561220b5780546fffffffffffffffffffffffffffffffff16820393505b5050915091565b60065481565b600a54600160a060020a031681565b600854600160a060020a031681565b604080517f70a082310000000000000000000000000000000000000000000000000000000081523060048201529051600091600160a060020a038416916370a0823191602480820192602092909190829003018186803b15801561229957600080fd5b505afa1580156122ad573d6000803e3d6000fd5b505050506040513d60208110156122c357600080fd5b505160008054604080517fa9059cbb000000000000000000000000000000000000000000000000000000008152600160a060020a0392831660048201526024810185905290519394509085169263a9059cbb92604480840193602093929083900390910190829087803b15801561233957600080fd5b505af115801561234d573d6000803e3d6000fd5b505050506040513d602081101561236357600080fd5b50505050565b600160a060020a0381166000908152600360205260408120600181015482919067ffffffffffffffff1642106123a1576000806123db565b805460018201547001000000000000000000000000000000009091046fffffffffffffffffffffffffffffffff169067ffffffffffffffff165b9250925050915091565b80333014806123f957506123f981336133db565b15156124395760405160e560020a62461bcd028152600401808060200182810382526023815260200180614bbb6023913960400191505060405180910390fd5b600154604080517f4a4fbeec000000000000000000000000000000000000000000000000000000008152600160a060020a038086166004830152915185939290921691634a4fbeec91602480820192602092909190829003018186803b1580156124a257600080fd5b505afa1580156124b6573d6000803e3d6000fd5b505050506040513d60208110156124cc57600080fd5b505115612523576040805160e560020a62461bcd02815260206004820152601b60248201527f424d3a2077616c6c6574206d75737420626520756e6c6f636b65640000000000604482015290519081900360640190fd5b61252f83600654613b6d565b505050565b6000805a90506000612584308c60008d8d8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508f92508c91508b9050613b88565b90506125918b8983613ccb565b15156125e7576040805160e560020a62461bcd02815260206004820152601560248201527f524d3a204475706c696361746520726571756573740000000000000000000000604482015290519081900360640190fd5b6126278b8b8b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250613cd792505050565b15156126675760405160e560020a62461bcd02815260040180806020018281038252604a815260200180614b22604a913960600191505060405180910390fd5b60006126a98c8c8c8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250613d4b92505050565b9050604181028714156127c1576126c28c868884613d53565b156127c15780158061274557506127458c8c8c8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8f018190048102820181019092528d815288935091508d908d9081908401838280828437600092019190915250613e4292505050565b156127c15730600160a060020a03168b8b604051808383808284376040519201945060009350909150508083038183865af19150503d80600081146127a6576040519150601f19603f3d011682016040523d82523d6000602084013e6127ab565b606091505b5050809450506127c18c5a850388888533613e67565b60408051838152905185151591600160a060020a038f16917f6bb0b384ce772133df63560651bc8c727c53306cec1d51e2cbf8ea35fb8f2ec19181900360200190a350505098975050505050505050565b8133301480612826575061282681336133db565b15156128665760405160e560020a62461bcd028152600401808060200182810382526023815260200180614bbb6023913960400191505060405180910390fd5b600154604080517f4a4fbeec000000000000000000000000000000000000000000000000000000008152600160a060020a038087166004830152915186939290921691634a4fbeec91602480820192602092909190829003018186803b1580156128cf57600080fd5b505afa1580156128e3573d6000803e3d6000fd5b505050506040513d60208110156128f957600080fd5b505115612950576040805160e560020a62461bcd02815260206004820152601b60248201527f424d3a2077616c6c6574206d75737420626520756e6c6f636b65640000000000604482015290519081900360640190fd5b6123638484600654613ec6565b8133301480612971575061297181336133db565b15156129b15760405160e560020a62461bcd028152600401808060200182810382526023815260200180614bbb6023913960400191505060405180910390fd5b600154604080517f4a4fbeec000000000000000000000000000000000000000000000000000000008152600160a060020a038087166004830152915186939290921691634a4fbeec91602480820192602092909190829003018186803b158015612a1a57600080fd5b505afa158015612a2e573d6000803e3d6000fd5b505050506040513d6020811015612a4457600080fd5b505115612a9b576040805160e560020a62461bcd02815260206004820152601b60248201527f424d3a2077616c6c6574206d75737420626520756e6c6f636b65640000000000604482015290519081900360640190fd5b600160a060020a038416600090815260056020908152604080832086845290915281205411612b14576040805160e560020a62461bcd02815260206004820152601a60248201527f54543a20756e6b6e6f776e2070656e64696e6720616374696f6e000000000000604482015290519081900360640190fd5b600160a060020a0384166000818152600560209081526040808320878452909152808220829055518592917f2914460f2e2359d06bcda666d815164a8e77d104644dfbe6360885abfa2da59c91a350505050565b600854604080517f13f4a0ea000000000000000000000000000000000000000000000000000000008152600160a060020a03858116600483015284811660248301529151600093849316916313f4a0ea916044808301926020929190829003018186803b158015612bd857600080fd5b505afa158015612bec573d6000803e3d6000fd5b505050506040513d6020811015612c0257600080fd5b5051905060008111801561154c575042119392505050565b600954600160a060020a031681565b60026020526000908152604090205481565b7fd490da4d0000000000000000000000000000000000000000000000000000000090565b8633301480612c735750612c7381336133db565b1515612cb35760405160e560020a62461bcd028152600401808060200182810382526023815260200180614bbb6023913960400191505060405180910390fd5b600154604080517f4a4fbeec000000000000000000000000000000000000000000000000000000008152600160a060020a03808c16600483015291518b939290921691634a4fbeec91602480820192602092909190829003018186803b158015612d1c57600080fd5b505afa158015612d30573d6000803e3d6000fd5b505050506040513d6020811015612d4657600080fd5b505115612d9d576040805160e560020a62461bcd02815260206004820152601b60248201527f424d3a2077616c6c6574206d75737420626520756e6c6f636b65640000000000604482015290519081900360640190fd5b612da78986614024565b612db18988612b68565b1515612eb857600954604080517fce55c85200000000000000000000000000000000000000000000000000000000815260048101899052600160a060020a038b811660248301529151600093929092169163ce55c85291604480820192602092909190829003018186803b158015612e2857600080fd5b505afa158015612e3c573d6000803e3d6000fd5b505050506040513d6020811015612e5257600080fd5b50519050612e608a8261354d565b1515612eb6576040805160e560020a62461bcd02815260206004820152601d60248201527f544d3a20417070726f76652061626f7665206461696c79206c696d6974000000604482015290519081900360640190fd5b505b610d90898989898989898080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506141e092505050565b600160a060020a039091166000908152600560209081526040808320938352929052205490565b60045481565b8133301480612f3d5750612f3d81336133db565b1515612f7d5760405160e560020a62461bcd028152600401808060200182810382526023815260200180614bbb6023913960400191505060405180910390fd5b600154604080517f4a4fbeec000000000000000000000000000000000000000000000000000000008152600160a060020a038087166004830152915186939290921691634a4fbeec91602480820192602092909190829003018186803b158015612fe657600080fd5b505afa158015612ffa573d6000803e3d6000fd5b505050506040513d602081101561301057600080fd5b505115613067576040805160e560020a62461bcd02815260206004820152601b60248201527f424d3a2077616c6c6574206d75737420626520756e6c6f636b65640000000000604482015290519081900360640190fd5b6130718484612b68565b15156130c7576040805160e560020a62461bcd02815260206004820152601a60248201527f54543a20746172676574206e6f742077686974656c6973746564000000000000604482015290519081900360640190fd5b600854604080517f80bfbe68000000000000000000000000000000000000000000000000000000008152600160a060020a038781166004830152868116602483015260006044830181905292519316926380bfbe689260648084019391929182900301818387803b15801561313b57600080fd5b505af115801561314f573d6000803e3d6000fd5b5050604051600160a060020a038087169350871691507fd288ab5da2e1f37cf384a1565a3f905ad289b092fbdd31950dbbfef148c04f8890600090a350505050565b60008061319d83611925565b6fffffffffffffffffffffffffffffffff149392505050565b84333014806131ca57506131ca81336133db565b151561320a5760405160e560020a62461bcd028152600401808060200182810382526023815260200180614bbb6023913960400191505060405180910390fd5b600154604080517f4a4fbeec000000000000000000000000000000000000000000000000000000008152600160a060020a03808a166004830152915189939290921691634a4fbeec91602480820192602092909190829003018186803b15801561327357600080fd5b505afa158015613287573d6000803e3d6000fd5b505050506040513d602081101561329d57600080fd5b5051156132f4576040805160e560020a62461bcd02815260206004820152601b60248201527f424d3a2077616c6c6574206d75737420626520756e6c6f636b65640000000000604482015290519081900360640190fd5b6132fe8787614024565b6133088787612b68565b1561334f57610c7f87878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061459592505050565b613359878661354d565b15156133995760405160e560020a62461bcd028152600401808060200182810382526023815260200180614b6c6023913960400191505060405180910390fd5b610d9387878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061459592505050565b600081600160a060020a031683600160a060020a0316638da5cb5b6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b15801561343c57600080fd5b505afa158015613450573d6000803e3d6000fd5b505050506040513d602081101561346657600080fd5b5051600160a060020a0316149392505050565b60408051600160a060020a038416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790526134fb858560008461465d565b5060408051838152600160a060020a038581166020830152825181881693918916927fdc47705473b4a899de6e16a740ecc86f2a65dc7dbb9eadd0a06ce5421a44e23092908290030190a35050505050565b600081151561355e57506001610e9e565b600160a060020a0383166000908152600360205260408120805460018201549192916135bf916fffffffffffffffffffffffffffffffff80821692700100000000000000000000000000000000909204169067ffffffffffffffff16613b23565b90506135de85826fffffffffffffffffffffffffffffffff16866148e0565b156135f9576135ee858286614992565b600192505050610e9e565b506000949350505050565b6041808202830160208101516040820151919092015160009260ff9190911691601b83148061363657508260ff16601c145b151561364157600080fd5b604080516000815260208082018084528a905260ff8616828401526060820185905260808201849052915160019260a0808401939192601f1981019281900390910190855afa158015613698573d6000803e3d6000fd5b5050506020604051035193505050505b9392505050565b8033600160a060020a03821614613710576040805160e560020a62461bcd02815260206004820152601960248201527f424d3a2063616c6c6572206d7573742062652077616c6c657400000000000000604482015290519081900360640190fd5b600160a060020a038216600090815260036020526040902080546fffffffffffffffffffffffffffffffff161580156137555750600181015467ffffffffffffffff16155b1561252f5760045481546fffffffffffffffffffffffffffffffff19166fffffffffffffffffffffffffffffffff9091161790555050565b60008282111561379c57600080fd5b50900390565b600160a060020a03841673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14156137e9576137e3858484602060405190810160405280600081525061465d565b5061386e565b60408051600160a060020a038516602482015260448082018590528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261386b868660008461465d565b50505b8184600160a060020a031686600160a060020a03167fd5c97f2e041b2046be3b4337472f05720760a198f4d7d84980b7155eec7cca6f86856040518083600160a060020a0316600160a060020a0316815260200180602001828103825283818151815260200191508051906020019080838360005b838110156138fb5781810151838201526020016138e3565b50505050905090810190601f1680156139285780820380516001836020036101000a031916815260200191505b50935050505060405180910390a45050505050565b6000808786868686436040516020018087600081111561395957fe5b60ff167f010000000000000000000000000000000000000000000000000000000000000002815260010186600160a060020a0316600160a060020a03166c0100000000000000000000000002815260140185600160a060020a0316600160a060020a03166c0100000000000000000000000002815260140184815260200183805190602001908083835b60208310613a025780518252601f1990920191602091820191016139e3565b6001836020036101000a03801982511681845116808217855250505050505090500182815260200196505050505050506040516020818303038152906040528051906020012091506005600088600160a060020a0316600160a060020a031681526020019081526020016000206000016000838152602001908152602001600020546000141515613add576040805160e560020a62461bcd02815260206004820152601c60248201527f544d3a206475706c69636174652070656e64696e6720616374696f6e00000000604482015290519081900360640190fd5b600654613af190429063ffffffff613b5b16565b600160a060020a0390971660009081526005602090815260408083208584529091529020879055509694955050505050565b6000808267ffffffffffffffff16118015613b475750428267ffffffffffffffff16105b15613b535750816136a8565b509192915050565b6000828201838110156136a857600080fd5b61149c826fffffffffffffffffffffffffffffffff83613ec6565b6040517f190000000000000000000000000000000000000000000000000000000000000060208083018281526000602185018190526c01000000000000000000000000600160a060020a03808e16820260228801528c16026036860152604a85018a90528851909485938d938d938d938d938d938d938d939192606a909201918701908083835b60208310613c2e5780518252601f199092019160209182019101613c0f565b51815160209384036101000a600019018019909216911617905292019586525084810193909352506040808401919091528051808403820181526060840182528051908301207f19457468657265756d205369676e6564204d6573736167653a0a3332000000006080850152609c808501919091528151808503909101815260bc909301905281519101209e9d5050505050505050505050505050565b600061154c8484614a9b565b60006024825110151515613d35576040805160e560020a62461bcd02815260206004820152601660248201527f524d3a20496e76616c6964206461746157616c6c657400000000000000000000604482015290519081900360640190fd5b5060240151600160a060020a0391821691161490565b600192915050565b60008083118015613d645750600082115b8015613e2a575082840285600160a060020a0316311080613d975750613d9585613d8d87611925565b8587026148e0565b155b80613e2a5750604080517fd6eb1bbf0000000000000000000000000000000000000000000000000000000081523060048201529051600160a060020a0387169163d6eb1bbf916024808301926020929190829003018186803b158015613dfc57600080fd5b505afa158015613e10573d6000803e3d6000fd5b505050506040513d6020811015613e2657600080fd5b5051155b15613e375750600061154c565b506001949350505050565b600080613e5184846000613604565b9050613e5d86826133db565b9695505050505050565b618f088501600085118015613e7c5750600083115b8015613e885750838111155b15610d93573a851115613e9c573a02613e9f565b84025b613ea9878261354d565b5061191b878383602060405190810160405280600081525061465d565b600160a060020a0383166000908152600360205260408120600181015490919067ffffffffffffffff1681108015613f0d575060018201544267ffffffffffffffff909116105b613f2a5781546fffffffffffffffffffffffffffffffff16613f53565b815470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff165b82546fffffffffffffffffffffffffffffffff868116700100000000000000000000000000000000028184166fffffffffffffffffffffffffffffffff1990931692909217161783559050613fae428463ffffffff613b5b16565b60018301805467ffffffffffffffff191667ffffffffffffffff92909216919091179055613fdc4284613b5b565b67ffffffffffffffff168486600160a060020a03167f8a747eae44b6307d1b112c127968367d02d9f52ffef8533b3e899983ff2b1d4a60405160405180910390a45050505050565b81600160a060020a031681600160a060020a0316141580156140e1575081600160a060020a031663d6eb1bbf826040518263ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018082600160a060020a0316600160a060020a0316815260200191505060206040518083038186803b1580156140b357600080fd5b505afa1580156140c7573d6000803e3d6000fd5b505050506040513d60208110156140dd57600080fd5b5051155b801561418a5750600954604080517f837479c9000000000000000000000000000000000000000000000000000000008152600160a060020a0384811660048301529151919092169163837479c9916024808301926020929190829003018186803b15801561414e57600080fd5b505afa158015614162573d6000803e3d6000fd5b505050506040513d602081101561417857600080fd5b5051158061418a575061418a82613191565b151561149c576040805160e560020a62461bcd02815260206004820152601660248201527f544d3a20466f7262696464656e20636f6e747261637400000000000000000000604482015290519081900360640190fd5b604080517fdd62ed3e000000000000000000000000000000000000000000000000000000008152600160a060020a0388811660048301528681166024830152915160009288169163dd62ed3e916044808301926020929190829003018186803b15801561424c57600080fd5b505afa158015614260573d6000803e3d6000fd5b505050506040513d602081101561427657600080fd5b5051905060006142868286613b5b565b60408051600160a060020a038916602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b30000000000000000000000000000000000000000000000000000000017905290915061430b898960008461465d565b50614319898660008761465d565b50604080517fdd62ed3e000000000000000000000000000000000000000000000000000000008152600160a060020a038b81166004830152898116602483015291516000928b169163dd62ed3e916044808301926020929190829003018186803b15801561438657600080fd5b505afa15801561439a573d6000803e3d6000fd5b505050506040513d60208110156143b057600080fd5b5051905060006143c0848361378d565b90508781111561441a576040805160e560020a62461bcd02815260206004820181905260248201527f42543a20696e73756666696369656e7420616d6f756e7420666f722063616c6c604482015290519081900360640190fd5b8185146144a75760408051600160a060020a038b16602482015260448082018890528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b30000000000000000000000000000000000000000000000000000000017905292506144a58b8b60008661465d565b505b89600160a060020a031687600160a060020a03168c600160a060020a03167fb99e2a91cdfde581196884f6b42392a5000200a43dd5726d92d9405616fdffb98c8c868c6040518085600160a060020a0316600160a060020a0316815260200184815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561454b578181015183820152602001614533565b50505050905090810190601f1680156145785780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a45050505050505050505050565b6145a18484848461465d565b5082600160a060020a031684600160a060020a03167fbfbd7fb6c6d7dd1ef01d18a7e98333f084363d82d5ce600328e8b941a53d665484846040518083815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561461c578181015183820152602001614604565b50505050905090810190601f1680156146495780820380516001836020036101000a031916815260200191505b50935050505060405180910390a350505050565b6060600085600160a060020a03168585856040516024018084600160a060020a0316600160a060020a0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b838110156146cc5781810151838201526020016146b4565b50505050905090810190601f1680156146f95780820380516001836020036101000a031916815260200191505b5060408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f8f6f033200000000000000000000000000000000000000000000000000000000178152905182519297509550859450925090508083835b602083106147855780518252601f199092019160209182019101614766565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146147e7576040519150601f19603f3d011682016040523d82523d6000602084013e6147ec565b606091505b50925090508080156147ff575060008251115b1561486c5781806020019051602081101561481957600080fd5b81019080805164010000000081111561483157600080fd5b8201602081018481111561484457600080fd5b815164010000000081118282018710171561485e57600080fd5b509095506148d79350505050565b600082511115614880573d6000803e3d6000fd5b8015156148d7576040805160e560020a62461bcd02815260206004820152601a60248201527f424d3a2077616c6c657420696e766f6b65207265766572746564000000000000604482015290519081900360640190fd5b50949350505050565b60006fffffffffffffffffffffffffffffffff831415614902575060016136a8565b600160a060020a038416600090815260036020526040902060020180544270010000000000000000000000000000000090910467ffffffffffffffff161015614950575050818111156136a8565b80546fffffffffffffffffffffffffffffffff168301841080159061498a575080546fffffffffffffffffffffffffffffffff1683810110155b9150506136a8565b6fffffffffffffffffffffffffffffffff8281161461252f57600160a060020a038316600090815260036020526040902060020180544270010000000000000000000000000000000090910467ffffffffffffffff161015614a645780547fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff1670010000000000000000000000000000000042620151800167ffffffffffffffff1602176fffffffffffffffffffffffffffffffff19166fffffffffffffffffffffffffffffffff8316178155612363565b80546fffffffffffffffffffffffffffffffff8082168401166fffffffffffffffffffffffffffffffff1990911617815550505050565b600160a060020a0382166000908152600260205260408120548211614ac257506000610e9e565b7001000000000000000000000000000000006fffffffffffffffffffffffffffffffff198316044361271001811115614aff576000915050610e9e565b5050600160a060020a039190911660009081526002602052604090205560019056fe524d3a207468652077616c6c657420617574686f72697a656420697320646966666572656e74207468656e2074686520746172676574206f66207468652072656c617965642064617461544d3a2043616c6c20636f6e74726163742061626f7665206461696c79206c696d697454543a207472616e73666572206f757473696465206f662074686520657865637574696f6e2077696e646f77424d3a206d75737420626520616e206f776e657220666f72207468652077616c6c6574a165627a7a72305820641e34e07437f1a08f3931f78ac4ac6e754cc21aa2278f474a6465f63e50f3560029

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

000000000000000000000000c17d432bd8e8850fd7b32b0270f5afac65db0105000000000000000000000000391f0e86da951c03b1183c60b195090671adea8800000000000000000000000044da3a8051ba88eab0440db3779cab9d679ae76f000000000000000000000000e8a76d2f37fe50b6a95d27fb92291fe0b57407d30000000000000000000000000000000000000000000000000000000000015180000000000000000000000000000000000000000000000000000000000000a8c00000000000000000000000000000000000000000000000008ac7230489e800000000000000000000000000002b6d87f12b106e1d3fa7137494751566329d1045

-----Decoded View---------------
Arg [0] : _registry (address): 0xc17D432Bd8e8850Fd7b32B0270f5AfAc65DB0105
Arg [1] : _transferStorage (address): 0x391f0e86dA951C03b1183C60b195090671ADea88
Arg [2] : _guardianStorage (address): 0x44DA3A8051bA88EAB0440DB3779cAB9D679ae76f
Arg [3] : _priceProvider (address): 0xE8a76D2f37Fe50B6A95d27FB92291Fe0B57407d3
Arg [4] : _securityPeriod (uint256): 86400
Arg [5] : _securityWindow (uint256): 43200
Arg [6] : _defaultLimit (uint256): 10000000000000000000
Arg [7] : _oldLimitManager (address): 0x2B6D87F12B106E1D3fA7137494751566329d1045

-----Encoded View---------------
8 Constructor Arguments found :
Arg [0] : 000000000000000000000000c17d432bd8e8850fd7b32b0270f5afac65db0105
Arg [1] : 000000000000000000000000391f0e86da951c03b1183c60b195090671adea88
Arg [2] : 00000000000000000000000044da3a8051ba88eab0440db3779cab9d679ae76f
Arg [3] : 000000000000000000000000e8a76d2f37fe50b6a95d27fb92291fe0b57407d3
Arg [4] : 0000000000000000000000000000000000000000000000000000000000015180
Arg [5] : 000000000000000000000000000000000000000000000000000000000000a8c0
Arg [6] : 0000000000000000000000000000000000000000000000008ac7230489e80000
Arg [7] : 0000000000000000000000002b6d87f12b106e1d3fa7137494751566329d1045


Deployed Bytecode Sourcemap

70528:19195:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;70528:19195:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;71345:29;;;:::i;:::-;;;;;;;;;;;;;;;;76554:1171;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;;76554:1171:0;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;86025:378;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;86025:378:0;;;;;;;;;;;;;;21:11:-1;5:28;;2:2;;;46:1;43;36:12;2:2;86025:378:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;86025:378:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;86025:378:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;86025:378:0;;-1:-1:-1;86025:378:0;;-1:-1:-1;;;;;86025:378:0:i;:::-;;;;;;;;;;;;;;;;;;;73288:1476;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;73288:1476:0;-1:-1:-1;;;;;73288:1476:0;;:::i;85453:273::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;85453:273:0;;;;;;;;21:11:-1;5:28;;2:2;;;46:1;43;36:12;2:2;85453:273:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;85453:273:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;85453:273:0;;;;;;;;;;;21:11:-1;5:28;;2:2;;;46:1;43;36:12;2:2;85453:273:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;85453:273:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;-1:-1;85453:273:0;;-1:-1:-1;85453:273:0;-1:-1:-1;85453:273:0;:::i;36993:133::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;36993:133:0;-1:-1:-1;;;;;36993:133:0;;:::i;75184:1055::-;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;75184:1055:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21:11:-1;5:28;;2:2;;;46:1;43;36:12;2:2;75184:1055:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;75184:1055:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;-1:-1;75184:1055:0;;-1:-1:-1;75184:1055:0;-1:-1:-1;75184:1055:0;:::i;56594:257::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;56594:257:0;-1:-1:-1;;;;;56594:257:0;;:::i;80402:550::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;80402:550:0;;;;;;;;;;:::i;45201:252::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;45201:252:0;;;;;;;;;;:::i;82053:929::-;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;82053:929:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21:11:-1;5:28;;2:2;;;46:1;43;36:12;2:2;82053:929:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;82053:929:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;82053:929:0;;-1:-1:-1;82053:929:0;-1:-1:-1;82053:929:0;;:::i;58080:686::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;58080:686:0;-1:-1:-1;;;;;58080:686:0;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;71280:29;;;:::i;71595:35::-;;;:::i;:::-;;;;-1:-1:-1;;;;;71595:35:0;;;;;;;;;;;;;;71407:38;;;:::i;30851:176::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;30851:176:0;-1:-1:-1;;;;;30851:176:0;;:::i;57477:344::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;57477:344:0;-1:-1:-1;;;;;57477:344:0;;:::i;84030:158::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;84030:158:0;-1:-1:-1;;;;;84030:158:0;;:::i;35536:1342::-;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;35536:1342:0;;;;;;;;;;;;;;;21:11:-1;5:28;;2:2;;;46:1;43;36:12;2:2;35536:1342:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;35536:1342:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;35536:1342:0;;;;;;;;;;;;;;21:11:-1;5:28;;2:2;;;46:1;43;36:12;2:2;35536:1342:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;35536:1342:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;35536:1342:0;;-1:-1:-1;35536:1342:0;-1:-1:-1;35536:1342:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;83650:186;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;83650:186:0;;;;;;;;:::i;82990:413::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;82990:413:0;;;;;;;;:::i;84402:312::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;84402:312:0;;;;;;;;;;:::i;71485:39::-;;;:::i;33486:49::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;33486:49:0;-1:-1:-1;;;;;33486:49:0;;:::i;44745:158::-;;;:::i;79240:992::-;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;79240:992:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21:11:-1;5:28;;2:2;;;46:1;43;36:12;2:2;79240:992:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;79240:992:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;-1:-1;79240:992:0;;-1:-1:-1;79240:992:0;-1:-1:-1;79240:992:0;:::i;84962:194::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;84962:194:0;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;54164:27;;;:::i;81130:395::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;81130:395:0;;;;;;;;;;:::i;57056:211::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;57056:211:0;-1:-1:-1;;;;;57056:211:0;;:::i;77999:764::-;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;77999:764:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21:11:-1;5:28;;2:2;;;46:1;43;36:12;2:2;77999:764:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;77999:764:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;-1:-1;77999:764:0;;-1:-1:-1;77999:764:0;-1:-1:-1;77999:764:0;:::i;71345:29::-;;;;:::o;76554:1171::-;76733:7;29487:10;29509:4;29487:27;;:59;;;29518:28;29526:7;29535:10;29518:7;:28::i;:::-;29479:107;;;;;;-1:-1:-1;;;;;29479:107:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28671:15;;:33;;;;;;-1:-1:-1;;;;;28671:33:0;;;;;;;;;76768:7;;28671:15;;;;;:24;;:33;;;;;;;;;;;;;;;:15;:33;;;5:2:-1;;;;30:1;27;20:12;5:2;28671:33:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;28671:33:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;28671:33:0;28670:34;28662:74;;;;;-1:-1:-1;;;;;28662:74:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;76797:32;76811:7;76820:8;76797:13;:32::i;:::-;76793:925;;;76883:50;76898:7;76907:6;76915:8;76925:7;76883:14;:50::i;:::-;76793:925;;;77030:51;;;;;;-1:-1:-1;;;;;77030:51:0;;;;;;;;;;;;;;;;77003:24;;77030:23;;;;;:51;;;;;;;;;;;;;;:23;:51;;;5:2:-1;;;;30:1;27;20:12;5:2;77030:51:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;77030:51:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;77030:51:0;;-1:-1:-1;77100:27:0;;;77096:611;;77203:50;77218:7;77227:6;77235:8;77245:7;77203:14;:50::i;:::-;77096:611;;;77427:13;;:42;;;;;;77361:26;;;77427:42;;;;;;-1:-1:-1;;;;;77427:42:0;;;;;;;;;77361:26;;77348:10;;77427:13;;:27;;:42;;;;;;;;;;;;;;:13;:42;;;5:2:-1;;;;30:1;27;20:12;5:2;77427:42:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;77427:42:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;77427:42:0;;-1:-1:-1;77496:45:0;77521:7;77427:42;77496:24;:45::i;:::-;77488:87;;;;;;;-1:-1:-1;;;;;77488:87:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;77641:50;77656:7;77665:6;77673:8;77683:7;77641:14;:50::i;:::-;77096:611;;;76793:925;;29597:1;76554:1171;;;;;:::o;86025:378::-;86142:17;;86115:6;;86163:2;86142:23;86134:64;;;;;-1:-1:-1;;;;;86134:64:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;86209:14;86226:38;86240:8;86250:10;86262:1;86226:13;:38::i;:::-;86209:55;;86283:39;86302:10;86315:6;86283:7;:39::i;:::-;86275:70;;;;;;;-1:-1:-1;;;;;86275:70:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;70866:44:0;;;;;;;;;;;;;;;;86025:378;;;;;:::o;73288:1476::-;73340:7;29223:10;-1:-1:-1;;;;;29223:30:0;;;29215:68;;;;;-1:-1:-1;;;;;29215:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;70750:42;;;;;;;;;;;;;;;;73393:71;;;73426:4;73393:71;;;;;;;;;;;;-1:-1:-1;;;;;73393:24:0;;;;;:71;;;;;-1:-1:-1;;73393:71:0;;;;;;;-1:-1:-1;73393:24:0;:71;;;5:2:-1;;;;30:1;27;20:12;5:2;73393:71:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;70866:44:0;;;;;;;;;;;;;;;;73475:73;;;73508:4;73475:73;;;;;;;;;;;;-1:-1:-1;;;;;73475:24:0;;;-1:-1:-1;73475:24:0;;-1:-1:-1;73475:73:0;;;;;-1:-1:-1;;73475:73:0;;;;;;;-1:-1:-1;73475:24:0;:73;;;5:2:-1;;;;30:1;27;20:12;5:2;73475:73:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;73624:15:0;;-1:-1:-1;;;;;73624:15:0;73616:38;73612:111;;-1:-1:-1;73612:111:0;;-1:-1:-1;73612:111:0;73671:19;73682:7;73671:10;:19::i;:::-;73705:7;;73612:111;73800:15;;:40;;;;;;-1:-1:-1;;;;;73800:40:0;;;;;;;;;73782:15;;73800;;;;;:31;;:40;;;;;;;;;;;;;;;:15;:40;;;5:2:-1;;;;30:1;27;20:12;5:2;73800:40:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;73800:40:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;73800:40:0;73891:15;;:40;;;;;;-1:-1:-1;;;;;73891:40:0;;;;;;;;;73800;;-1:-1:-1;73852:15:0;;;;73891;;;;;:31;;:40;;;;;;;;;;;:15;:40;;;5:2:-1;;;;30:1;27;20:12;5:2;73891:40:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;73891:40:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;73891:40:0;;;;;;;;;-1:-1:-1;73891:40:0;-1:-1:-1;73994:12:0;;:32;;;;-1:-1:-1;74010:16:0;;;;73994:32;73990:105;;;74043:19;74054:7;74043:10;:19::i;:::-;74077:7;;;;;73990:105;74176:7;74165;:18;74161:228;;;-1:-1:-1;;;;;74200:24:0;;;;;;:6;:24;;;;;:57;;-1:-1:-1;;74200:57:0;;;;;;;74161:228;;;74323:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;74290:24:0;;-1:-1:-1;74290:24:0;;;:6;:24;;;;;;;:87;;;;;;;;;;;;;-1:-1:-1;;74290:87:0;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;74290:87:0;;;;;;74161:228;74505:15;;:40;;;;;;-1:-1:-1;;;;;74505:40:0;;;;;;;;;74468:15;;;;74505;;;:31;;:40;;;;;;;;;;;;:15;:40;;;5:2:-1;;;;30:1;27;20:12;5:2;74505:40:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;74505:40:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;74505:40:0;;;;;;;;;-1:-1:-1;74505:40:0;-1:-1:-1;74635:3:0;74623:15;;;;74619:138;;;74693:52;;;;;;;;;;74712:20;:7;74724;74712:20;:11;:20;:::i;:::-;74693:52;;;;;;;;;;;;;;;-1:-1:-1;;;;;74655:24:0;;-1:-1:-1;74655:24:0;;;:6;:24;;;;;:90;;:35;;;;:90;;;;;;;-1:-1:-1;;74655:90:0;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;29294:1:0;73288:1476;;:::o;85453:273::-;85551:6;85570:15;85615:5;;85598:23;;;;;;;30:3:-1;22:6;14;1:33;57:3;49:6;45:16;35:26;;85598:23:0;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;85598:23:0;;;85588:34;;;;;;85570:52;;85633:37;85650:7;85659:10;;85633:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;85633:16:0;;-1:-1:-1;;;85633:37:0:i;:::-;-1:-1:-1;;70750:42:0;;;;;;;;;;;;;;;;;-1:-1:-1;85453:273:0;;;;;;;:::o;36993:133::-;-1:-1:-1;;;;;37087:25:0;37054:13;37087:25;;;:7;:25;;;;;:31;;36993:133::o;75184:1055::-;75390:7;29487:10;29509:4;29487:27;;:59;;;29518:28;29526:7;29535:10;29518:7;:28::i;:::-;29479:107;;;;;;-1:-1:-1;;;;;29479:107:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28671:15;;:33;;;;;;-1:-1:-1;;;;;28671:33:0;;;;;;;;;75425:7;;28671:15;;;;;:24;;:33;;;;;;;;;;;;;;;:15;:33;;;5:2:-1;;;;30:1;27;20:12;5:2;28671:33:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;28671:33:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;28671:33:0;28670:34;28662:74;;;;;-1:-1:-1;;;;;28662:74:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;75454:27;75468:7;75477:3;75454:13;:27::i;:::-;75450:782;;;75536:48;75547:7;75556:6;75564:3;75569:7;75578:5;;75536:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;75536:10:0;;-1:-1:-1;;;75536:48:0:i;:::-;75450:782;;;75617:19;-1:-1:-1;;;;;75640:19:0;;47328:42;75640:19;75639:78;;75673:13;;:44;;;;;;;;;;;;-1:-1:-1;;;;;75673:44:0;;;;;;;;;:13;;;;;:27;;:44;;;;;;;;;;;;;;:13;:44;;;5:2:-1;;;;30:1;27;20:12;5:2;75673:44:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;75673:44:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;75673:44:0;75639:78;;;75663:7;75639:78;75617:100;;75736:46;75761:7;75770:11;75736:24;:46::i;:::-;75732:489;;;75848:48;75859:7;75868:6;75876:3;75881:7;75890:5;;75848:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;75848:10:0;;-1:-1:-1;;;75848:48:0:i;:::-;75732:489;;;75983:10;75995:20;76019:75;76036:19;76057:7;76066:6;76074:3;76079:7;76088:5;;76019:75;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;76019:16:0;;-1:-1:-1;;;76019:75:0:i;:::-;75982:112;;;;76163:12;76159:2;76149:7;-1:-1:-1;;;;;76118:87:0;;76177:6;76185:3;76190:7;76199:5;;76118:87;;;;-1:-1:-1;;;;;76118:87:0;-1:-1:-1;;;;;76118:87:0;;;;;;-1:-1:-1;;;;;76118:87:0;-1:-1:-1;;;;;76118:87:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;;74:27;76118:87:0;;137:4:-1;117:14;;;-1:-1;;113:30;157:16;;;76118:87:0;;;;-1:-1:-1;76118:87:0;;-1:-1:-1;;;;;;;76118:87:0;75732:489;;75450:782;;29597:1;75184:1055;;;;;;;:::o;56594:257::-;-1:-1:-1;;;;;56716:24:0;;56660:21;56716:24;;;:6;:24;;;;;56794:13;;;56824:17;;;56781:61;;56794:13;;;;;56809;;;;;;56824:17;;56781:12;:61::i;:::-;56773:70;;;56594:257;-1:-1:-1;;;56594:257:0:o;80402:550::-;80531:7;29487:10;29509:4;29487:27;;:59;;;29518:28;29526:7;29535:10;29518:7;:28::i;:::-;29479:107;;;;;;-1:-1:-1;;;;;29479:107:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28671:15;;:33;;;;;;-1:-1:-1;;;;;28671:33:0;;;;;;;;;80566:7;;28671:15;;;;;:24;;:33;;;;;;;;;;;;;;;:15;:33;;;5:2:-1;;;;30:1;27;20:12;5:2;28671:33:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;28671:33:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;28671:33:0;28670:34;28662:74;;;;;-1:-1:-1;;;;;28662:74:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;80600:31;80614:7;80623;80600:13;:31::i;:::-;80599:32;80591:75;;;;;-1:-1:-1;;;;;80591:75:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;80740:22;80765:23;80773:14;;80765:3;:7;;:23;;;;:::i;:::-;80799:15;;:62;;;;;;-1:-1:-1;;;;;80799:62:0;;;;;;;;;;;;;;;;;;;;;;80740:48;;-1:-1:-1;80799:15:0;;;:28;;:62;;;;;:15;;:62;;;;;;;;:15;;:62;;;5:2:-1;;;;30:1;27;20:12;5:2;80799:62:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;80877:67:0;;;;;;;;;;-1:-1:-1;;;;;80877:67:0;;;;-1:-1:-1;80877:67:0;;;-1:-1:-1;80877:67:0;;;;;;;;;28747:1;29597;80402:550;;;:::o;45201:252::-;45281:7;29487:10;29509:4;29487:27;;:59;;;29518:28;29526:7;29535:10;29518:7;:28::i;:::-;29479:107;;;;;;-1:-1:-1;;;;;29479:107:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45309:8;;:45;;;;;;-1:-1:-1;;;;;45309:45:0;;;;;;;;;:8;;;;;:27;;:45;;;;;;;;;;;;;;:8;:45;;;5:2:-1;;;;30:1;27;20:12;5:2;45309:45:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;45309:45:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;45309:45:0;45301:86;;;;;;;-1:-1:-1;;;;;45301:86:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;45398:47;;;;;;-1:-1:-1;;;;;45398:47:0;;;;;;;45440:4;45398:47;;;;;;:23;;;;;;:47;;;;;-1:-1:-1;;45398:47:0;;;;;;;;-1:-1:-1;45398:23:0;:47;;;5:2:-1;;;;30:1;27;20:12;5:2;45398:47:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;82053:929:0;28671:15;;:33;;;;;;-1:-1:-1;;;;;28671:33:0;;;;;;;;;82288:7;;28671:15;;;;;:24;;:33;;;;;;;;;;;;;;;:15;:33;;;5:2:-1;;;;30:1;27;20:12;5:2;28671:33:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;28671:33:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;28671:33:0;28670:34;28662:74;;;;;-1:-1:-1;;;;;28662:74:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;82313:10;82353:19;82374:6;82382:3;82387:7;82396:5;;82403:6;82336:74;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;82336:74:0;-1:-1:-1;;;;;82336:74:0;;;;;;;;-1:-1:-1;;;;;82336:74:0;-1:-1:-1;;;;;82336:74:0;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;57:3;49:6;45:16;35:26;;82336:74:0;;;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;82336:74:0;;;82326:85;;;;;;82313:98;;82422:17;82442:7;:25;82458:7;-1:-1:-1;;;;;82442:25:0;-1:-1:-1;;;;;82442:25:0;;;;;;;;;;;;:40;;:44;82483:2;82442:44;;;;;;;;;;;;82422:64;;82520:1;82505:12;:16;82497:57;;;;;;;-1:-1:-1;;;;;82497:57:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;82565:18;82586:32;82603:14;;82586:12;:16;;:32;;;;:::i;:::-;82565:53;;82716:3;82700:12;:19;;:43;;;;;82730:13;82723:3;:20;;82700:43;82692:100;;;;;;-1:-1:-1;;;;;82692:100:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;82810:25:0;;;;;;:7;:25;;;;;;;;:44;;;;;;;;82803:51;;;;82865:48;;;;;;;;;;;;;;;;;;;;;;82826:7;;82885:6;;82893:3;;82898:7;;82865:48;82907:5;;;;;;82865:48;;82907:5;;;;82865:48;1:33:-1;99:1;81:16;;74:27;;;;-1:-1;82865:10:0;;-1:-1:-1;;;82865:48:0:i;:::-;82929:45;;82971:2;;-1:-1:-1;;;;;82929:45:0;;;;;;;;28747:1;;;82053:929;;;;;;;;:::o;58080:686::-;58148:16;58166:17;58196:13;58212:24;58228:7;58212:15;:24::i;:::-;-1:-1:-1;;;;;58276:24:0;;58247:26;58276:24;;;:6;:24;;;;;:35;;58395:17;;58196:40;;-1:-1:-1;58276:35:0;58395:17;;;;;58389:3;:23;58385:374;;;58440:5;58429:16;;58547:3;58553:8;58547:14;58527:35;;58385:374;;;58608:17;;;;;;;;-1:-1:-1;58644:20:0;;:28;-1:-1:-1;58640:108:0;;;58712:20;;;;58704:28;;;-1:-1:-1;58640:108:0;58080:686;;;;;:::o;71280:29::-;;;;:::o;71595:35::-;;;-1:-1:-1;;;;;71595:35:0;;:::o;71407:38::-;;;-1:-1:-1;;;;;71407:38:0;;:::o;30851:176::-;30922:38;;;;;;30954:4;30922:38;;;;;;30909:10;;-1:-1:-1;;;;;30922:23:0;;;;;:38;;;;;;;;;;;;;;;:23;:38;;;5:2:-1;;;;30:1;27;20:12;5:2;30922:38:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;30922:38:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;30922:38:0;31002:8;;;30971:48;;;;;;-1:-1:-1;;;;;31002:8:0;;;30971:48;;;;;;;;;;;;30922:38;;-1:-1:-1;30971:22:0;;;;;;:48;;;;;30922:38;;30971:48;;;;;;;;;;;:22;:48;;;5:2:-1;;;;30:1;27;20:12;5:2;30971:48:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;30971:48:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;30851:176:0:o;57477:344::-;-1:-1:-1;;;;;57622:24:0;;57545:21;57622:24;;;:6;:24;;;;;57741:17;;;;57545:21;;57622:24;57741:17;;57735:3;:23;57734:78;;57808:1;;57734:78;;;57770:13;;57786:17;;;;57770:13;;;;;;;57786:17;;57734:78;57726:87;;;;;57477:344;;;:::o;84030:158::-;84097:7;29487:10;29509:4;29487:27;;:59;;;29518:28;29526:7;29535:10;29518:7;:28::i;:::-;29479:107;;;;;;-1:-1:-1;;;;;29479:107:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28671:15;;:33;;;;;;-1:-1:-1;;;;;28671:33:0;;;;;;;;;84123:7;;28671:15;;;;;:24;;:33;;;;;;;;;;;;;;;:15;:33;;;5:2:-1;;;;30:1;27;20:12;5:2;28671:33:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;28671:33:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;28671:33:0;28670:34;28662:74;;;;;-1:-1:-1;;;;;28662:74:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;84143:37;84156:7;84165:14;;84143:12;:37::i;:::-;29597:1;84030:158;;:::o;35536:1342::-;35774:12;35804:13;35820:9;35804:25;;35840:16;35859:84;35879:4;35894:7;35904:1;35907:5;;35859:84;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;35914:6:0;;-1:-1:-1;35922:9:0;;-1:-1:-1;35933:9:0;;-1:-1:-1;35859:11:0;:84::i;:::-;35840:103;;35962:51;35987:7;35996:6;36004:8;35962:24;:51::i;:::-;35954:85;;;;;;;-1:-1:-1;;;;;35954:85:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;36058:35;36077:7;36087:5;;36058:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;36058:10:0;;-1:-1:-1;;;36058:35:0:i;:::-;36050:122;;;;;;-1:-1:-1;;;;;36050:122:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36183:26;36212:37;36234:7;36243:5;;36212:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;36212:21:0;;-1:-1:-1;;;36212:37:0:i;:::-;36183:66;-1:-1:-1;36286:2:0;36265:23;;36264:47;;36260:539;;;36332:63;36345:7;36354:9;36365;36376:18;36332:12;:63::i;:::-;36328:460;;;36420:23;;;:84;;;36447:57;36466:7;36475:5;;36447:57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;;36447:57:0;;;;137:4:-1;36447:57:0;;;;;;;;;;;;;;;;;36482:8;;-1:-1:-1;36447:57:0;-1:-1:-1;36492:11:0;;;;;;36447:57;;36492:11;;;;36447:57;1:33:-1;99:1;81:16;;74:27;;;;-1:-1;36447:18:0;;-1:-1:-1;;;36447:57:0:i;:::-;36416:357;;;36622:4;-1:-1:-1;;;;;36614:18:0;36633:5;;36614:25;;;;;30:3:-1;22:6;14;1:33;36614:25:0;;45:16:-1;;;-1:-1;36614:25:0;;-1:-1:-1;36614:25:0;;-1:-1:-1;;36614:25:0;;;;;;;;;;;;14:1:-1;21;16:31;;;;75:4;69:11;64:16;;144:4;140:9;133:4;115:16;111:27;107:43;104:1;100:51;94:4;87:65;169:16;166:1;159:27;225:16;222:1;215:4;212:1;208:12;193:49;7:242;;16:31;36:4;31:9;;7:242;;36601:38:0;;;;;36662:91;36669:7;36689:9;36678:8;:20;36700:9;36711;36722:18;36742:10;36662:6;:91::i;:::-;36814:56;;;;;;;;;;;;-1:-1:-1;;;;;36814:56:0;;;;;;;;;;;;35536:1342;;;;;;;;;;;;;:::o;83650:186::-;83735:7;29487:10;29509:4;29487:27;;:59;;;29518:28;29526:7;29535:10;29518:7;:28::i;:::-;29479:107;;;;;;-1:-1:-1;;;;;29479:107:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28671:15;;:33;;;;;;-1:-1:-1;;;;;28671:33:0;;;;;;;;;83761:7;;28671:15;;;;;:24;;:33;;;;;;;;;;;;;;;:15;:33;;;5:2:-1;;;;30:1;27;20:12;5:2;28671:33:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;28671:33:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;28671:33:0;28670:34;28662:74;;;;;-1:-1:-1;;;;;28662:74:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;83781:47;83793:7;83802:9;83813:14;;83781:11;:47::i;82990:413::-;83122:7;29487:10;29509:4;29487:27;;:59;;;29518:28;29526:7;29535:10;29518:7;:28::i;:::-;29479:107;;;;;;-1:-1:-1;;;;;29479:107:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28671:15;;:33;;;;;;-1:-1:-1;;;;;28671:33:0;;;;;;;;;83157:7;;28671:15;;;;;:24;;:33;;;;;;;;;;;;;;;:15;:33;;;5:2:-1;;;;30:1;27;20:12;5:2;28671:33:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;28671:33:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;28671:33:0;28670:34;28662:74;;;;;-1:-1:-1;;;;;28662:74:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;83190:25:0;;83238:1;83190:25;;;:7;:25;;;;;;;;:45;;;;;;;;;:49;83182:88;;;;;-1:-1:-1;;;;;83182:88:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;83288:25:0;;;;;;:7;:25;;;;;;;;:45;;;;;;;;;83281:52;;;83349:46;83329:3;;83288:25;83349:46;;;29597:1;82990:413;;;:::o;84402:312::-;84537:15;;:46;;;;;;-1:-1:-1;;;;;84537:46:0;;;;;;;;;;;;;;;;84483:19;;;;84537:15;;:28;;:46;;;;;;;;;;;;;;:15;:46;;;5:2:-1;;;;30:1;27;20:12;5:2;84537:46:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;84537:46:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;84537:46:0;;-1:-1:-1;84681:1:0;84664:18;;:42;;;;-1:-1:-1;84703:3:0;-1:-1:-1;84686:20:0;84657:49;-1:-1:-1;;;84402:312:0:o;71485:39::-;;;-1:-1:-1;;;;;71485:39:0;;:::o;33486:49::-;;;;;;;;;;;;;:::o;44745:158::-;44864:31;44745:158;:::o;79240:992::-;79493:7;29487:10;29509:4;29487:27;;:59;;;29518:28;29526:7;29535:10;29518:7;:28::i;:::-;29479:107;;;;;;-1:-1:-1;;;;;29479:107:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28671:15;;:33;;;;;;-1:-1:-1;;;;;28671:33:0;;;;;;;;;79528:7;;28671:15;;;;;:24;;:33;;;;;;;;;;;;;;;:15;:33;;;5:2:-1;;;;30:1;27;20:12;5:2;28671:33:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;28671:33:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;28671:33:0;28670:34;28662:74;;;;;-1:-1:-1;;;;;28662:74:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;79639:41;79661:7;79670:9;79639:21;:41::i;:::-;79698:32;79712:7;79721:8;79698:13;:32::i;:::-;79697:33;79693:436;;;79971:13;;:44;;;;;;;;;;;;-1:-1:-1;;;;;79971:44:0;;;;;;;;;79950:18;;79971:13;;;;;:27;;:44;;;;;;;;;;;;;;;:13;:44;;;5:2:-1;;;;30:1;27;20:12;5:2;79971:44:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;79971:44:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;79971:44:0;;-1:-1:-1;80038:45:0;80063:7;79971:44;80038:24;:45::i;:::-;80030:87;;;;;;;-1:-1:-1;;;;;80030:87:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;79693:436;;80141:83;80171:7;80180:6;80188:8;80198:7;80207:9;80218:5;;80141:83;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;80141:29:0;;-1:-1:-1;;;80141:83:0:i;84962:194::-;-1:-1:-1;;;;;85102:25:0;;;85046:20;85102:25;;;:7;:25;;;;;;;;:45;;;;;;;;;84962:194::o;54164:27::-;;;;:::o;81130:395::-;81264:7;29487:10;29509:4;29487:27;;:59;;;29518:28;29526:7;29535:10;29518:7;:28::i;:::-;29479:107;;;;;;-1:-1:-1;;;;;29479:107:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28671:15;;:33;;;;;;-1:-1:-1;;;;;28671:33:0;;;;;;;;;81299:7;;28671:15;;;;;:24;;:33;;;;;;;;;;;;;;;:15;:33;;;5:2:-1;;;;30:1;27;20:12;5:2;28671:33:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;28671:33:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;28671:33:0;28670:34;28662:74;;;;;-1:-1:-1;;;;;28662:74:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;81332:31;81346:7;81355;81332:13;:31::i;:::-;81324:70;;;;;;;-1:-1:-1;;;;;81324:70:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;81405:15;;:49;;;;;;-1:-1:-1;;;;;81405:49:0;;;;;;;;;;;;;;:15;:49;;;;;;;;:15;;;:28;;:49;;;;;:15;;:49;;;;;;:15;;:49;;;5:2:-1;;;;30:1;27;20:12;5:2;81405:49:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;81470:47:0;;-1:-1:-1;;;;;81470:47:0;;;;-1:-1:-1;81470:47:0;;;-1:-1:-1;81470:47:0;;;;;29597:1;81130:395;;;:::o;57056:211::-;57122:19;57154:20;57177:24;57193:7;57177:15;:24::i;:::-;57229:30;;;57056:211;-1:-1:-1;;;57056:211:0:o;77999:764::-;78184:7;29487:10;29509:4;29487:27;;:59;;;29518:28;29526:7;29535:10;29518:7;:28::i;:::-;29479:107;;;;;;-1:-1:-1;;;;;29479:107:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28671:15;;:33;;;;;;-1:-1:-1;;;;;28671:33:0;;;;;;;;;78219:7;;28671:15;;;;;:24;;:33;;;;;;;;;;;;;;;:15;:33;;;5:2:-1;;;;30:1;27;20:12;5:2;28671:33:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;28671:33:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;28671:33:0;28670:34;28662:74;;;;;-1:-1:-1;;;;;28662:74:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;78330:41;78352:7;78361:9;78330:21;:41::i;:::-;78388:33;78402:7;78411:9;78388:13;:33::i;:::-;78384:372;;;78472:49;78487:7;78496:9;78507:6;78515:5;;78472:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;78472:14:0;;-1:-1:-1;;;78472:49:0:i;78384:372::-;78562:41;78587:7;78596:6;78562:24;:41::i;:::-;78554:89;;;;;;-1:-1:-1;;;;;78554:89:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;78695:49;78710:7;78719:9;78730:6;78738:5;;78695:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;78695:14:0;;-1:-1:-1;;;78695:49:0:i;31212:131::-;31287:4;31330:5;-1:-1:-1;;;;;31311:24:0;:7;-1:-1:-1;;;;;31311:13:0;;:15;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;31311:15:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;31311:15:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;31311:15:0;-1:-1:-1;;;;;31311:24:0;;;31212:131;-1:-1:-1;;;31212:131:0:o;49157:349::-;49297:69;;;-1:-1:-1;;;;;49297:69:0;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;49297:69:0;;;;;;;;25:18:-1;;61:17;;49297:69:0;182:15:-1;49297:69:0;179:29:-1;160:49;;49377:53:0;49398:7;49408:6;-1:-1:-1;49297:69:0;49377:12;:53::i;:::-;-1:-1:-1;49446:52:0;;;;;;-1:-1:-1;;;;;49446:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;49157:349;;;;;:::o;59019:486::-;59105:4;59126:12;;59122:42;;;-1:-1:-1;59160:4:0;59153:11;;59122:42;-1:-1:-1;;;;;59197:24:0;;59175:19;59197:24;;;:6;:24;;;;;59269:13;;;59299:17;;;59197:24;;59175:19;59256:61;;59269:13;;;;;59284;;;;;;59299:17;;59256:12;:61::i;:::-;59238:79;;59332:45;59351:7;59360;59332:45;;59369:7;59332:18;:45::i;:::-;59328:147;;;59394:43;59411:7;59420;59429;59394:16;:43::i;:::-;59459:4;59452:11;;;;;;59328:147;-1:-1:-1;59492:5:0;;59019:486;-1:-1:-1;;;;59019:486:0:o;39781:836::-;40310:4;40306:16;;;40280:44;;40301:4;40280:44;;40274:51;40371:4;40350:44;;40344:51;40424:44;;;;40418:51;39887:7;;40471:4;40414:62;;;;;40510:2;40505:7;;;:18;;;40516:1;:7;;40521:2;40516:7;40505:18;40497:27;;;;;;;;40578:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;40578:31:0;;;;;;;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;40578:31:0;;;;;;;;40571:38;;;;;39781:836;;;;;;:::o;54749:256::-;54801:7;29223:10;-1:-1:-1;;;;;29223:30:0;;;29215:68;;;;;-1:-1:-1;;;;;29215:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;54843:24:0;;54821:19;54843:24;;;:6;:24;;;;;54888:13;;;;:18;:44;;;;-1:-1:-1;54910:17:0;;;;;;:22;54888:44;54884:114;;;54973:12;;54949:37;;-1:-1:-1;;54949:37:0;;;;;;;;-1:-1:-1;;54749:256:0:o;25731:150::-;25789:7;25817:6;;;;25809:15;;;;;;-1:-1:-1;25847:5:0;;;25731:150::o;48382:502::-;-1:-1:-1;;;;;48511:19:0;;47328:42;48511:19;48507:300;;;48547:56;48568:7;48578:3;48583:6;48591:11;;;;;;;;;;;;;48547:12;:56::i;:::-;;48507:300;;;48662:65;;;-1:-1:-1;;;;;48662:65:0;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;48662:65:0;;;;;;;;25:18:-1;;61:17;;48662:65:0;182:15:-1;48662:65:0;179:29:-1;160:49;;48742:53:0;48763:7;48773:6;-1:-1:-1;48662:65:0;48742:12;:53::i;:::-;;48507:300;;48857:6;48849;-1:-1:-1;;;;;48822:54:0;48839:7;-1:-1:-1;;;;;48822:54:0;;48865:3;48870:5;48822:54;;;;-1:-1:-1;;;;;48822:54:0;-1:-1:-1;;;;;48822:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;48822:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;48382:502;;;;;:::o;86970:651::-;87196:10;87208:20;87278:7;87287:6;87295:3;87300:7;87309:5;87316:12;87261:68;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;87261:68:0;-1:-1:-1;;;;;87261:68:0;;;;;;;;-1:-1:-1;;;;;87261:68:0;-1:-1:-1;;;;;87261:68:0;;;;;;;;;;;;;;;;;;;;;;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;87261:68:0;;;;;;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;87261:68:0;;;87251:79;;;;;;87246:84;;87349:7;:25;87365:7;-1:-1:-1;;;;;87349:25:0;-1:-1:-1;;;;;87349:25:0;;;;;;;;;;;;:40;;:44;87390:2;87349:44;;;;;;;;;;;;87397:1;87349:49;87341:90;;;;;;;-1:-1:-1;;;;;87341:90:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;87528:14;;87520:23;;:3;;:23;:7;:23;:::i;:::-;-1:-1:-1;;;;;87554:25:0;;;;;;;:7;:25;;;;;;;;:44;;;;;;;;:59;;;-1:-1:-1;87595:2:0;87505:38;;-1:-1:-1;;;;;86970:651:0:o;61538:304::-;61640:7;61742:1;61727:12;:16;;;:38;;;;;61762:3;61747:12;:18;;;61727:38;61723:86;;;-1:-1:-1;61789:8:0;61782:15;;61723:86;-1:-1:-1;61826:8:0;;61538:304;-1:-1:-1;;61538:304:0:o;25957:150::-;26015:7;26047:5;;;26071:6;;;;26063:15;;;;;56274:148;56361:53;56373:7;56361:53;56398:15;56361:11;:53::i;37731:528::-;38144:94;;38161:10;38144:94;;;;;;;37990:7;38144:94;;;;;;;-1:-1:-1;;;;;38144:94:0;;;;;;;;;;;;;;;;;;;;;;;;37990:7;;;;38182:5;;38189:3;;38194:6;;38202:5;;38209:6;;38217:9;;38228;;38144:94;;;;;;;;;;;;;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;;38144:94:0;;;;;-1:-1:-1;38144:94:0;;;;;;;-1:-1:-1;38144:94:0;;;;;;;;;;26:21:-1;;;22:32;;6:49;;38144:94:0;;;;;38134:105;;;;;;38046:204;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;38046:204:0;;;;;;38022:229;;;;;;37731:528;-1:-1:-1;;;;;;;;;;;;;;37731:528:0:o;45617:181::-;45730:4;45754:36;45774:7;45783:6;45754:19;:36::i;42634:431::-;42713:4;42754:2;42738:5;:12;:18;;42730:53;;;;;;;-1:-1:-1;;;;;42730:53:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;43002:4:0;42991:16;42985:23;-1:-1:-1;;;;;43036:21:0;;;;;;;42634:431::o;46186:142::-;46319:1;46186:142;;;;:::o;89237:483::-;89351:4;89384:1;89372:9;:13;:32;;;;;89403:1;89389:11;:15;89372:32;:269;;;;;89461:9;89450:8;:20;89431:7;-1:-1:-1;;;;;89423:24:0;;:47;:148;;;;89487:75;89506:7;89515:24;89531:7;89515:15;:24::i;:::-;89552:9;89541:8;:20;89487:18;:75::i;:::-;:84;89423:148;:207;;;-1:-1:-1;89588:33:0;;;;;;89615:4;89588:33;;;;;;-1:-1:-1;;;;;89588:18:0;;;;;:33;;;;;;;;;;;;;;:18;:33;;;5:2:-1;;;;30:1;27;20:12;5:2;89588:33:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;89588:33:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;89588:33:0;:42;89423:207;89368:323;;;-1:-1:-1;89674:5:0;89667:12;;89368:323;-1:-1:-1;89708:4:0;89237:483;;;;;;:::o;45806:372::-;46018:4;46040:14;46057:40;46071:9;46082:11;46095:1;46057:13;:40::i;:::-;46040:57;;46115:24;46123:7;46132:6;46115:7;:24::i;:::-;46108:31;45806:372;-1:-1:-1;;;;;;45806:372:0:o;88456:704::-;88746:5;:16;;88729:14;88777:13;;:32;;;;;88808:1;88794:11;:15;88777:32;:55;;;;;88823:9;88813:6;:19;;88777:55;88773:380;;;88865:11;88853:9;:23;88849:161;;;88915:11;88906:20;88849:161;;;88976:18;;88849:161;89024:41;89049:7;89058:6;89024:24;:41::i;:::-;;89080:61;89101:7;89111:8;89121:6;89129:11;;;;;;;;;;;;;89080:12;:61::i;55362:698::-;-1:-1:-1;;;;;55489:24:0;;55467:19;55489:24;;;:6;:24;;;;;55612:17;;;;55489:24;;55467:19;55612:17;;:21;-1:-1:-1;55612:48:0;;;;-1:-1:-1;55637:17:0;;;;55657:3;55637:17;;;;:23;55612:48;55611:82;;55680:13;;;;55611:82;;;55664:13;;;;;;;55611:82;55704:23;;;55738:34;;;;;55704:23;;;-1:-1:-1;;55704:23:0;;;;;;;55738:34;;;;55593:100;-1:-1:-1;55873:24:0;:3;55881:15;55873:24;:7;:24;:::i;:::-;55846:17;;;:52;;-1:-1:-1;;55846:52:0;;;;;;;;;;;;56026:24;:3;56034:15;56026:7;:24::i;:::-;55977:75;;56008:9;55998:7;-1:-1:-1;;;;;55977:75:0;;;;;;;;;;;55362:698;;;;;:::o;87852:442::-;87990:7;-1:-1:-1;;;;;87969:29:0;:9;-1:-1:-1;;;;;87969:29:0;;;:101;;;;;88041:7;-1:-1:-1;;;;;88041:18:0;;88060:9;88041:29;;;;;;;;;;;;;-1:-1:-1;;;;;88041:29:0;-1:-1:-1;;;;;88041:29:0;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;88041:29:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;88041:29:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;88041:29:0;88040:30;87969:101;:218;;;;-1:-1:-1;88116:13:0;;:37;;;;;;-1:-1:-1;;;;;88116:37:0;;;;;;;;;:13;;;;;:26;;:37;;;;;;;;;;;;;;:13;:37;;;5:2:-1;;;;30:1;27;20:12;5:2;88116:37:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;88116:37:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;88116:37:0;:42;;:70;;;88162:24;88178:7;88162:15;:24::i;:::-;87947:339;;;;;;;-1:-1:-1;;;;;87947:339:0;;;;;;;;;;;;;;;;;;;;;;;;;;;50501:1844;50773:51;;;;;;-1:-1:-1;;;;;50773:51:0;;;;;;;;;;;;;;;;50745:25;;50773:23;;;;;:51;;;;;;;;;;;;;;:23;:51;;;5:2:-1;;;;30:1;27;20:12;5:2;50773:51:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;50773:51:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;50773:51:0;;-1:-1:-1;50835:22:0;50860:40;50773:51;50892:7;50860:12;:40::i;:::-;51165:77;;;-1:-1:-1;;;;;51165:77:0;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;51165:77:0;;;;;;;;25:18:-1;;61:17;;51165:77:0;182:15:-1;51165:77:0;179:29:-1;160:49;;50835:65:0;;-1:-1:-1;51255:53:0;51276:7;51286:6;-1:-1:-1;51165:77:0;51255:12;:53::i;:::-;;51319:51;51340:7;51350:9;51361:1;51364:5;51319:12;:51::i;:::-;-1:-1:-1;51481:51:0;;;;;;-1:-1:-1;;;;;51481:51:0;;;;;;;;;;;;;;;;51455:23;;51481;;;;;:51;;;;;;;;;;;;;;:23;:51;;;5:2:-1;;;;30:1;27;20:12;5:2;51481:51:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;51481:51:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;51481:51:0;;-1:-1:-1;51543:21:0;51567:45;51580:14;51481:51;51567:12;:45::i;:::-;51543:69;-1:-1:-1;51717:24:0;;;;51709:69;;;;;-1:-1:-1;;;;;51709:69:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51795:36;;;51791:334;;51965:80;;;-1:-1:-1;;;;;51965:80:0;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;51965:80:0;;;;;;;;25:18:-1;;61:17;;51965:80:0;182:15:-1;51965:80:0;179:29:-1;160:49;;51965:80:0;-1:-1:-1;52060:53:0;52081:7;52091:6;-1:-1:-1;51965:80:0;52060:12;:53::i;:::-;;51791:334;52260:6;-1:-1:-1;;;;;52142:195:0;52213:9;-1:-1:-1;;;;;52142:195:0;52190:7;-1:-1:-1;;;;;52142:195:0;;52237:8;52281:7;52303:13;52331:5;52142:195;;;;-1:-1:-1;;;;;52142:195:0;-1:-1:-1;;;;;52142:195:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;52142:195:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50501:1844;;;;;;;;;;;:::o;49759:257::-;49878:56;49899:7;49909:9;49920:6;49928:5;49878:12;:56::i;:::-;;49983:9;-1:-1:-1;;;;;49950:58:0;49973:7;-1:-1:-1;;;;;49950:58:0;;49994:6;50002:5;49950:58;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;49950:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49759:257;;;;:::o;31619:847::-;31725:17;31755:12;31856:7;-1:-1:-1;;;;;31856:12:0;31926:3;31931:6;31939:5;31869:76;;;;;;-1:-1:-1;;;;;31869:76:0;-1:-1:-1;;;;;31869:76:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;31869:76:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;31869:76:0;;;-1:-1:-1;;26:21;;;22:32;6:49;;31869:76:0;;;49:4:-1;25:18;;61:17;;31869:76:0;182:15:-1;31869:76:0;179:29:-1;160:49;;31856:90:0;;;;31869:76;;-1:-1:-1;31856:90:0;-1:-1:-1;31856:90:0;;-1:-1:-1;25:18;-1:-1;31856:90:0;-1:-1:-1;31856:90:0;;25:18:-1;36:153;66:2;58:11;;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;31856:90:0;;;;;;;;;;;;;;;;;;;;;;;;14:1:-1;21;16:31;;;;75:4;69:11;64:16;;144:4;140:9;133:4;115:16;111:27;107:43;104:1;100:51;94:4;87:65;169:16;166:1;159:27;225:16;222:1;215:4;212:1;208:12;193:49;7:242;;16:31;36:4;31:9;;7:242;-1:-1;31838:108:0;-1:-1:-1;31838:108:0;-1:-1:-1;31838:108:0;31961:26;;;;;31986:1;31972:4;:11;:15;31961:26;31957:502;;;32106:4;32095:25;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;32095:25:0;;;;;;19:11:-1;14:3;11:20;8:2;;;44:1;41;34:12;8:2;62:21;;123:4;114:14;;138:31;;;135:2;;;182:1;179;172:12;135:2;213:10;;261:11;244:29;;285:43;;;282:58;-1:-1;233:115;230:2;;;361:1;358;351:12;230:2;-1:-1;32095:25:0;;-1:-1:-1;31957:502:0;;-1:-1:-1;;;;31957:502:0;;32156:1;32142:4;:11;:15;32138:321;;;32292:14;32289:1;32286;32271:36;32335:14;32332:1;32325:25;32252:113;32387:7;32386:8;32382:77;;;32411:36;;;-1:-1:-1;;;;;32411:36:0;;;;;;;;;;;;;;;;;;;;;;;;;;;32382:77;31619:847;;;;;;;:::o;60699:560::-;60797:4;60818:24;;;60814:68;;;-1:-1:-1;60866:4:0;60859:11;;60814:68;-1:-1:-1;;;;;60921:24:0;;60892:26;60921:24;;;:6;:24;;;;;:35;;61034:17;;61054:3;61034:17;;;;;;:23;61030:222;;;-1:-1:-1;;61082:17:0;;;;61074:26;;61030:222;61141:20;;;;:30;;:40;-1:-1:-1;61141:40:0;;;:98;;-1:-1:-1;61219:20:0;;;;61185:30;;;:54;;61141:98;61133:107;;;;;59762:621;59862:24;;;;;59858:518;;-1:-1:-1;;;;;59932:24:0;;59903:26;59932:24;;;:6;:24;;;;;:35;;60053:17;;60073:3;60053:17;;;;;;:23;60049:316;;;60168:42;;;;;60195:3;60201:8;60195:14;60168:42;;;;-1:-1:-1;;60229:39:0;;;;;;;60049:316;;;60309:40;;;;;;;;;-1:-1:-1;;60309:40:0;;;;;;59858:518;59762:621;;;:::o;39032:475::-;-1:-1:-1;;;;;39146:25:0;;39115:4;39146:25;;;:7;:25;;;;;:31;39136:41;;39132:86;;-1:-1:-1;39201:5:0;39194:12;;39132:86;45:20:-1;-1:-1;;39250:75:0;;25:41:-1;39361:12:0;33472:5;39361:25;39348:38;;39344:83;;;39410:5;39403:12;;;;;39344:83;-1:-1:-1;;;;;;;39437:25:0;;;;;;;;:7;:25;;;;;:40;39495:4;;39032:475::o

Swarm Source

bzzr://641e34e07437f1a08f3931f78ac4ac6e754cc21aa2278f474a6465f63e50f356

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

OVERVIEW

Contract of Argent's Transfer Manager

Validator Index Block Amount
View All Withdrawals

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

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