Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 7 from a total of 7 transactions
| Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Add Proof Batch | 23620875 | 17 days ago | IN | 0 ETH | 0.00187347 | ||||
| Mark Session End | 23607019 | 19 days ago | IN | 0 ETH | 0.00010195 | ||||
| Add Memo | 23385149 | 50 days ago | IN | 0 ETH | 0.00021775 | ||||
| Add Memo | 23385129 | 50 days ago | IN | 0 ETH | 0.00009188 | ||||
| Add Proof Batch | 23385057 | 50 days ago | IN | 0 ETH | 0.00236587 | ||||
| Add Memo | 23377756 | 51 days ago | IN | 0 ETH | 0.0001493 | ||||
| Mark Session End | 23371470 | 52 days ago | IN | 0 ETH | 0.0001071 |
Latest 2 internal transactions
Advanced mode:
| Parent Transaction Hash | Method | Block |
From
|
To
|
|||
|---|---|---|---|---|---|---|---|
| 0x60806040 | 23361861 | 53 days ago | Contract Creation | 0 ETH | |||
| 0x60806040 | 23361861 | 53 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
ProofOfBurn
Compiler Version
v0.8.28+commit.7893614a
Contract Source Code (Solidity Multiple files format)
// SPDX-License-Identifier: MIT
/*
( (
( )\ ) )\ )
( )\ ( (()/((()/(
)((_) )\ /(_))/(_))
((_)_ _ ((_)(_)) (_))_
| _ )| | | |/ __| | \
| _ \| |_| |\__ \ | |) |
|___/ \___/ |___/ |___/
by steviep.eth
2025
*/
import "./Dependencies.sol";
import "./BUSD.sol";
pragma solidity ^0.8.28;
/// @title Proof of Burn (bUSD)
/// @author steviep.eth
/// @notice Archival NFTs representing the proof that specific bills were burned in an official bUSD Burn Ceremony
contract ProofOfBurn is ERC721, Ownable {
BUSD public busd;
uint256 public billsBurned;
uint256 public proofsBurned;
ProofOfBurnURI public uri;
/// @notice Mapping of tokenIds to serial numbers of burnt bills
mapping(uint256 => string) public serials;
/// @notice Mapping of tokenIds to denominations of burnt bills
mapping(uint256 => uint8) public denominations;
/// @notice Mapping of tokenIds to metadata
mapping(uint256 => string) public proofs;
/// @notice Timestamp of the completion of the bill's Burn Ceremony
mapping(uint256 => uint256) public timestamps;
/// @notice Notes regarding the bill's Burn Ceremony
mapping(uint256 => string) public memos;
/// @notice A record of which Proofs of Burn were burned by which addresses
mapping(uint256 => address) public burnedBy;
/// @notice A log of serial numbers alreay burned
mapping(string => bool) public serialUsed;
uint256[] public sessionEnds;
event MetadataUpdate(uint256 _tokenId);
event BatchMetadataUpdate(uint256 _fromTokenId, uint256 _toTokenId);
event Burn(address burner, uint256 tokenId, uint256 amount);
constructor() ERC721('Proof of Burn (bUSD)', 'POB') {
busd = BUSD(msg.sender);
uri = new ProofOfBurnURI();
transferOwnership(tx.origin);
}
/// @notice Checks if given token ID exists
/// @param tokenId Token to run existence check on
/// @return True if token exists
function exists(uint256 tokenId) external view returns (bool) {
return _exists(tokenId);
}
/// @notice Total circulating supply of Proof of Burn tokens
function totalSupply() external view returns (uint256) {
return billsBurned - proofsBurned;
}
modifier onlyAgent {
address burnAgent = busd.ceremony().burnAgent();
require(msg.sender == burnAgent, 'Caller is not Burn Agent');
_;
}
/// @notice Total unique burn sessions completed
function totalSessions() public view returns (uint256) {
return sessionEnds.length;
}
/// @notice Finds the burn session a specific bill
function tokenIdToSessionId(uint256 tokenId) public view returns (uint256) {
uint256 ts = timestamps[tokenId];
for (uint256 i; i < sessionEnds.length; ++i) {
if (ts < sessionEnds[i]) return i;
}
return sessionEnds.length;
}
/// @notice Mark the end of a "session" (i.e. a series of Burn Ceremonies)
function markSessionEnd() external onlyAgent {
sessionEnds.push(block.timestamp);
}
/// @notice Add the metadata to a specific Proof of Burn token
function addProof(uint256 tokenId, string calldata proof) external onlyAgent {
proofs[tokenId] = proof;
emit MetadataUpdate(tokenId);
}
/// @notice Add the metadata to a batch of Proof of Burn tokens
function addProofBatch(uint256[] calldata tokenIds, string calldata baseURI, string calldata ext) external onlyAgent {
for (uint256 i; i < tokenIds.length; ++i) {
proofs[tokenIds[i]] = string.concat(baseURI, Strings.toString(tokenIds[i]), ext);
}
emit BatchMetadataUpdate(0, billsBurned);
}
/// @notice Add a memo to
function addMemo(uint256 tokenId, string calldata memo) external onlyAgent {
memos[tokenId] = memo;
}
/// @notice Mint a new Proof of Burn token
/// @dev This can only be called by the BurnCeremony contract
/// @param account Address to send the POB token to
/// @param denomination Denomination of the burnt bill
/// @param serial Serial number of the bunt bill
function mint(
address account,
uint256 denomination,
string calldata serial
) external {
require(msg.sender == address(busd.ceremony()), 'Invalid minter');
require(!serialUsed[serial], 'Serial already used');
denominations[billsBurned] = uint8(denomination);
serials[billsBurned] = serial;
serialUsed[serial] = true;
timestamps[billsBurned] = block.timestamp;
_safeMint(account, billsBurned);
billsBurned += 1;
}
/// @notice Burn a specific Proof of Burn token. This will also burn a an amount of the owner's bUSD corresponding to the bill's denomination
/// @dev This can be delegated to an operator
function burn(uint256 tokenId) public virtual {
require(_isApprovedOrOwner(msg.sender, tokenId), 'ERC721: caller is not token owner or approved');
uint256 amount = uint256(denominations[tokenId]) * 1 ether;
busd.burnFrom(ownerOf(tokenId), amount);
burnedBy[tokenId] = ownerOf(tokenId);
proofsBurned += 1;
_burn(tokenId);
emit Burn(burnedBy[tokenId], tokenId, amount);
}
function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
return uri.tokenURI(tokenId);
}
function setURI(address newURI) external {
require(msg.sender == busd.owner(), 'Caller is not BUSD Owner');
uri = ProofOfBurnURI(newURI);
}
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721) returns (bool) {
return interfaceId == bytes4(0x49064906) || super.supportsInterface(interfaceId);
}
string private _contractURI = 'data:application/json;utf8,{"name":"Proof of Burn (bUSD)"}';
event ContractURIUpdated();
function contractURI() external view returns (string memory) {
return _contractURI;
}
function updateContractURI(string calldata newURI) external onlyOwner {
_contractURI = newURI;
emit ContractURIUpdated();
}
}
contract ProofOfBurnURI {
ProofOfBurn public pob;
constructor() {
pob = ProofOfBurn(msg.sender);
}
function tokenURI(uint256 tokenId) external view returns (string memory) {
string memory denomination = Strings.toString(pob.denominations(tokenId));
string memory timestampString = Strings.toString(pob.timestamps(tokenId));
string memory serial = pob.serials(tokenId);
string memory memo = pob.memos(tokenId);
string memory sessionId = Strings.toString(pob.tokenIdToSessionId(tokenId));
string memory tokenIdStr = Strings.toString(tokenId);
bool hasMemo = bytes(memo).length > 0;
string memory description = string.concat('Proof of Burn #', tokenIdStr, ' for bill: ', serial, ', issuing ', denomination, ' bUSD at timestamp ', timestampString, hasMemo ? string.concat('. Included Memo: ', memo) : '.');
bytes memory proof = bytes(pob.proofs(tokenId));
if (proof.length == 0) {
proof = abi.encodePacked(
'data:image/svg+xml;base64,',
Base64.encode(abi.encodePacked(
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 180">'
'<rect x="0" y="0" width="100%" height="100%" fill="#000"></rect>'
'<text x="50%" y="43%" font-size="20px" fill="#fff" font-family="monospace" dominant-baseline="middle" text-anchor="middle">Proof of Burn #', tokenIdStr,'</text>'
'<text x="50%" y="57%" font-size="20px" fill="#fff" font-family="monospace" dominant-baseline="middle" text-anchor="middle">',
serial, ' $', denomination,
'</text>'
'</svg>'
))
);
}
string memory attrs = string.concat(
'[',
string.concat('{ "trait_type": "Serial", "value": "', serial, '" },'),
string.concat('{ "trait_type": "Denomination", "value": "', denomination, '" },'),
string.concat('{ "trait_type": "Burned at", "value": "', timestampString, '" },'),
string.concat('{ "trait_type": "Session ID", "value": "', sessionId, '" }'),
hasMemo ? string.concat(',{ "trait_type": "Burn Memo", "value": "', memo, '" }') : '',
']'
);
return string(abi.encodePacked(
'data:application/json;utf8,'
'{"name": "Proof of Burn #', string.concat(tokenIdStr, ' (', serial, ', $', denomination, ')'),
'", "description": "', description,
'", "image": "', proof,
'", "animation_url": "', proof,
'", "attributes":', attrs,
'}'
));
}
}// SPDX-License-Identifier: MIT
/*
( (
( )\ ) )\ )
( )\ ( (()/((()/(
)((_) )\ /(_))/(_))
((_)_ _ ((_)(_)) (_))_
| _ )| | | |/ __| | \
| _ \| |_| |\__ \ | |) |
|___/ \___/ |___/ |___/
by steviep.eth
2025
*/
import "./Dependencies.sol";
pragma solidity ^0.8.28;
/// @title Burn Agreement (bUSD)
/// @author steviep.eth
/// @notice Terms and conditions for engaging with the bUSD project. Owning a Burn Agreement token can be used to streamline the bUSD issuance process. Ownership of this NFT does not guarantee participation in a Burn Ceremony
contract BurnAgreement is ERC721, Ownable {
uint256 public totalSupply = 1;
string public activeAgreementVersion = '1.0.0';
address public burnCeremony;
BurnAgreementURI public uri;
BurnAgreementMinter public minter;
/// @notice Map a Burn Agreement token to the agreement version
mapping(uint256 => string) public tokenIdToAgreementVersion;
/// @notice Map an agreement version to the agreement content uri
mapping(string => string) public agreementVersionToMetadata;
/// @notice Keeps track of whether an agreement token has been used in a Ceremony
mapping(uint256 => bool) public agreementUsed;
event MetadataUpdate(uint256 _tokenId);
event BatchMetadataUpdate(uint256 _fromTokenId, uint256 _toTokenId);
/// @dev Mints #0 to the contract deployer
constructor(address ceremony) ERC721('Burn Agreement', 'BA') {
burnCeremony = ceremony;
uri = new BurnAgreementURI();
minter = new BurnAgreementMinter();
_safeMint(msg.sender, 0);
tokenIdToAgreementVersion[0] = activeAgreementVersion;
}
/// @notice Checks if given token ID exists
/// @param tokenId Token to run existence check on
/// @return True if token exists
function exists(uint256 tokenId) external view returns (bool) {
return _exists(tokenId);
}
/// @notice Mints a Burn Agreement token to the recipient
/// @param recipient Address to sent token to
/// @dev Can only be called by the BurnAgreementMinter
function mint(address recipient) external payable {
require(msg.sender == address(minter), 'Only minting address can mint');
tokenIdToAgreementVersion[totalSupply] = activeAgreementVersion;
_safeMint(recipient, totalSupply);
totalSupply++;
}
/// @notice Marks an Agreement as "used" as part of a burn ceremony
/// @dev Can only be called by the BurnCeremony
function markAgreementUsed(uint256 tokenId) external {
require(msg.sender == burnCeremony, 'Only burn ceremony can use agreement');
require(!agreementUsed[tokenId], 'Agreement already used');
agreementUsed[tokenId] = true;
emit MetadataUpdate(tokenId);
}
function setMinter(BurnAgreementMinter newMinter) external onlyOwner {
minter = newMinter;
}
function setBurnCeremony(address _burnCeremony) external onlyOwner {
burnCeremony = _burnCeremony;
}
function setActiveAgreement(string calldata _activeAgreementVersion) external onlyOwner {
activeAgreementVersion = _activeAgreementVersion;
}
function setAgreementMetadata(string calldata agreementVersion, string calldata metadata) external onlyOwner {
agreementVersionToMetadata[agreementVersion] = metadata;
}
function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
return uri.tokenURI(tokenId);
}
function setURI(address newURI) external onlyOwner {
uri = BurnAgreementURI(newURI);
}
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721) returns (bool) {
return interfaceId == bytes4(0x49064906) || super.supportsInterface(interfaceId);
}
}
/// @title Burn Agreement Minter (bUSD)
/// @author steviep.eth
/// @notice Interface for minting bUSD Burn Agreement NFTs
contract BurnAgreementMinter {
uint256 public price = 0.01 ether;
BurnAgreement public burnAgreement;
constructor() {
burnAgreement = BurnAgreement(msg.sender);
}
modifier onlyOwner {
require(msg.sender == burnAgreement.owner(), "Ownable: caller is not the owner");
_;
}
function mint() external payable {
require(msg.value >= price, 'Invalid value');
burnAgreement.mint(msg.sender);
}
function withdraw(uint256 balance) external onlyOwner {
payable(burnAgreement.owner()).call{value: balance}('');
}
function setPrice(uint256 _price) external onlyOwner {
price = _price;
}
}
contract BurnAgreementURI {
BurnAgreement public agreement;
constructor() {
agreement = BurnAgreement(msg.sender);
}
function tokenURI(uint256 tokenId) public view returns (string memory) {
bool agreementUsed = agreement.agreementUsed(tokenId);
string memory agreementVersion = agreement.tokenIdToAgreementVersion(tokenId);
string memory bg = agreementUsed ? '#000' : '#fff';
string memory text = agreementUsed ? '#ef791f' : '#000';
bytes memory thumbnail = abi.encodePacked(
'data:image/svg+xml;base64,',
Base64.encode(abi.encodePacked(
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 850 1100">'
'<style>text{font:bold 50px sans-serif;fill:', text, ';text-anchor: middle}</style>'
'<rect width="850" height="1100" x="0" y="0" fill="', bg,'" stroke="none"/>'
'<rect x="150" y="150" width="550" height="800" style="fill:none;stroke:', text,';stroke-width:7.5px"/>'
'<text x="425" y="450">BURN</text>'
'<text x="425" y="550">AGREEMENT</text>'
'<text x="425" y="650">v', agreementVersion, '</text>'
'</svg>'
))
);
string memory attrs = string.concat(
'[',
string.concat('{ "trait_type": "Agreement Version", "value": "', agreementVersion, '" },'),
string.concat('{ "trait_type": "Agreement Used", "value": "', agreementUsed ? 'True' : 'False', '" }'),
']'
);
return string(abi.encodePacked(
'data:application/json;utf8,'
'{"name": "Burn Agreement v', agreementVersion,
'", "description": "By purchasing this token you implicitly agree to the terms of this agreement. Ownership of this NFT does not guarantee participation in a Burn Ceremony. Participation shall be left to the full discretion of the Burn Agent.'
'", "image": "', thumbnail,
'", "animation_url": "', agreement.agreementVersionToMetadata(agreementVersion),
'", "attributes":', attrs,
'}'
));
}
}// SPDX-License-Identifier: MIT
/*
( (
( )\ ) )\ )
( )\ ( (()/((()/(
)((_) )\ /(_))/(_))
((_)_ _ ((_)(_)) (_))_
| _ )| | | |/ __| | \
| _ \| |_| |\__ \ | |) |
|___/ \___/ |___/ |___/
by steviep.eth
2025
*/
import "./BUSD.sol";
import "./ProofOfBurn.sol";
pragma solidity ^0.8.28;
/// @title Burn Ceremony (bUSD)
/// @author steviep.eth
/// @notice Interface for issuing new bUSD and Proofs of Burn
contract BurnCeremony {
BUSD public busd;
ProofOfBurn public proofOfBurn;
IBurnAgreement public burnAgreement;
address public burnAgent;
event Issuance(address indexed account, uint256 indexed denomination, string indexed serial);
constructor() {
busd = BUSD(msg.sender);
}
/// @dev This is necessary due to some weird solidity quirk during instantiation. Should only be called once
function init(address owner, ProofOfBurn pob) external {
require(burnAgent == address(0));
burnAgent = owner;
proofOfBurn = pob;
}
modifier onlyAgent {
require(msg.sender == burnAgent, 'Caller is not Burn Agent');
_;
}
/// @notice Set the Burn Agent role
function setBurnAgent(address _agent) external {
require(msg.sender == busd.owner(), 'Ownable: caller is not BUSD owner');
burnAgent = _agent;
}
/// @notice Designate the Burn Agreement contract
function setBurnAgreement(address agreement) external {
require(msg.sender == busd.owner(), 'Ownable: caller is not BUSD owner');
burnAgreement = IBurnAgreement(agreement);
}
/// @notice Issue new bUSD. This may only be called during the completion of an official Burn Ceremony
/// @param account Address to send the POB token to
/// @param denomination Denomination of the burnt bill
/// @param serial Serial number of the bunt bill
function issue(
address account,
uint256 denomination,
string calldata serial
) external onlyAgent {
busd.issue(account, denomination * 1 ether);
proofOfBurn.mint(account, denomination, serial);
emit Issuance(account, denomination, serial);
}
/// @notice Issue new bUSD using a Burn Agreement NFT. This may only be called during the completion of an official Burn Ceremony
/// @param agreementTokenId Issue bUSD to the owner of this token
/// @param denomination Denomination of the burnt bill
/// @param serial Serial number of the bunt bill
function issueWithAgreement(
uint256 agreementTokenId,
uint256 denomination,
string calldata serial
) external onlyAgent {
address account = burnAgreement.ownerOf(agreementTokenId);
burnAgreement.markAgreementUsed(agreementTokenId);
busd.issue(account, denomination * 1 ether);
proofOfBurn.mint(account, denomination, serial);
emit Issuance(account, denomination, serial);
}
}
// SPDX-License-Identifier: MIT
/*
( (
( )\ ) )\ )
( )\ ( (()/((()/(
)((_) )\ /(_))/(_))
((_)_ _ ((_)(_)) (_))_
| _ )| | | |/ __| | \
| _ \| |_| |\__ \ | |) |
|___/ \___/ |___/ |___/
by steviep.eth
2025
*/
import "./Dependencies.sol";
import "./BurnCeremony.sol";
import "./ProofOfBurn.sol";
pragma solidity ^0.8.28;
interface IBurnAgreement {
function ownerOf(uint256) external view returns (address);
function markAgreementUsed(uint256) external;
}
/// @title Burnt US Dollars (bUSD)
/// @author steviep.eth
/// @notice Burnt US Dollars ($bUSD) is a coin that represents the value of burned US Dollars.
contract BUSD is ERC20, Ownable {
BurnCeremony public ceremony;
ProofOfBurn public proofOfBurn;
/// @notice BUSD can no longer be issued once the contract is locked
bool public isLocked;
/// @notice Keeps track of which addresses burned the most bUSD
mapping(address => uint256) public busdBurnedBy;
constructor() ERC20('Burnt US Dollars', 'bUSD') {
ceremony = new BurnCeremony();
proofOfBurn = new ProofOfBurn();
ceremony.init(owner(), proofOfBurn);
}
/// @notice Issue new bUSD
/// @param account Address to issue bUSD to
/// @param amount Amount of bUSD to issue
/// @dev This can only be called by the BurnCeremony address
function issue(address account, uint256 amount) external {
require(!isLocked, 'New issuance is locked');
require(msg.sender == address(ceremony), 'Can only issue through official Burn Ceremony');
_mint(account, amount);
}
/// @notice Burn bUSD along with a Proof of Burn token
/// @param account Address to burn bUSD from
/// @param amount Amount of bUSD to burn
/// @dev This can only be called by the ProofOfBurn contract
function burnFrom(address account, uint256 amount) external {
require(msg.sender == address(proofOfBurn));
busdBurnedBy[account] += amount;
_burn(account, amount);
}
/// @notice Change the BurnCeremony contract
/// @param newCeremony New BurnCeremony contract address
function modifyCeremony(address newCeremony) external onlyOwner {
ceremony = BurnCeremony(newCeremony);
}
/// @notice Lock new bUSD issuance
/// @dev This is one way. Issuance cnanot be unlocked
function lockIssuance() external onlyOwner {
isLocked = true;
}
string private _contractURI = 'data:application/json;utf8,{"name":"Burnt US Dollars"}';
event ContractURIUpdated();
function contractURI() external view returns (string memory) {
return _contractURI;
}
function updateContractURI(string calldata newURI) external onlyOwner {
_contractURI = newURI;
emit ContractURIUpdated();
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
/**
* @dev Required interface of an ERC721 compliant contract.
*/
interface IERC721 is IERC165 {
/**
* @dev Emitted when `tokenId` token is transferred from `from` to `to`.
*/
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
/**
* @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
*/
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
/**
* @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
*/
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
/**
* @dev Returns the number of tokens in ``owner``'s account.
*/
function balanceOf(address owner) external view returns (uint256 balance);
/**
* @dev Returns the owner of the `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function ownerOf(uint256 tokenId) external view returns (address owner);
/**
* @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
* are aware of the ERC721 protocol to prevent tokens from being forever locked.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) external;
/**
* @dev Transfers `tokenId` token from `from` to `to`.
*
* WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must be owned by `from`.
* - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
*
* Emits a {Transfer} event.
*/
function transferFrom(
address from,
address to,
uint256 tokenId
) external;
/**
* @dev Gives permission to `to` to transfer `tokenId` token to another account.
* The approval is cleared when the token is transferred.
*
* Only a single account can be approved at a time, so approving the zero address clears previous approvals.
*
* Requirements:
*
* - The caller must own the token or be an approved operator.
* - `tokenId` must exist.
*
* Emits an {Approval} event.
*/
function approve(address to, uint256 tokenId) external;
/**
* @dev Returns the account approved for `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function getApproved(uint256 tokenId) external view returns (address operator);
/**
* @dev Approve or remove `operator` as an operator for the caller.
* Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
*
* Requirements:
*
* - The `operator` cannot be the caller.
*
* Emits an {ApprovalForAll} event.
*/
function setApprovalForAll(address operator, bool _approved) external;
/**
* @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
*
* See {setApprovalForAll}
*/
function isApprovedForAll(address owner, address operator) external view returns (bool);
/**
* @dev Safely transfers `tokenId` token from `from` to `to`.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes calldata data
) external;
}
/**
* @title ERC721 token receiver interface
* @dev Interface for any contract that wants to support safeTransfers
* from ERC721 asset contracts.
*/
interface IERC721Receiver {
/**
* @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
* by `operator` from `from`, this function is called.
*
* It must return its Solidity selector to confirm the token transfer.
* If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
*
* The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`.
*/
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes calldata data
) external returns (bytes4);
}
/**
* @title ERC-721 Non-Fungible Token Standard, optional metadata extension
* @dev See https://eips.ethereum.org/EIPS/eip-721
*/
interface IERC721Metadata is IERC721 {
/**
* @dev Returns the token collection name.
*/
function name() external view returns (string memory);
/**
* @dev Returns the token collection symbol.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
*/
function tokenURI(uint256 tokenId) external view returns (string memory);
}
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize, which returns 0 for contracts in
// construction, since the code is only stored at the end of the
// constructor execution.
uint256 size;
assembly {
size := extcodesize(account)
}
return size > 0;
}
// /**
// * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
// * `recipient`, forwarding all available gas and reverting on errors.
// *
// * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
// * of certain opcodes, possibly making contracts go over the 2300 gas limit
// * imposed by `transfer`, making them unable to receive funds via
// * `transfer`. {sendValue} removes this limitation.
// *
// * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
// *
// * IMPORTANT: because control is transferred to `recipient`, care must be
// * taken to not create reentrancy vulnerabilities. Consider using
// * {ReentrancyGuard} or the
// * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
// */
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
// /**
// * @dev Performs a Solidity function call using a low level `call`. A
// * plain `call` is an unsafe replacement for a function call: use this
// * function instead.
// *
// * If `target` reverts with a revert reason, it is bubbled up by this
// * function (like regular Solidity function calls).
// *
// * Returns the raw returned data. To convert to the expected return value,
// * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
// *
// * Requirements:
// *
// * - `target` must be a contract.
// * - calling `target` with `data` must not revert.
// *
// * _Available since v3.1._
// */
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
// /**
// * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
// * `errorMessage` as a fallback revert reason when `target` reverts.
// *
// * _Available since v3.1._
// */
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
// /**
// * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
// * but also transferring `value` wei to `target`.
// *
// * Requirements:
// *
// * - the calling contract must have an ETH balance of at least `value`.
// * - the called Solidity function must be `payable`.
// *
// * _Available since v3.1._
// */
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
// *
// * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
// * with `errorMessage` as a fallback revert reason when `target` reverts.
// *
// * _Available since v3.1._
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResult(success, returndata, errorMessage);
}
// /**
// * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
// * but performing a static call.
// *
// * _Available since v3.3._
// */
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
// /**
// * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
// * but performing a static call.
// *
// * _Available since v3.3._
// */
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResult(success, returndata, errorMessage);
}
// /**
// * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
// * but performing a delegate call.
// *
// * _Available since v3.4._
// */
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
// /**
// * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
// * but performing a delegate call.
// *
// * _Available since v3.4._
// */
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResult(success, returndata, errorMessage);
}
// /**
// * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
// * revert reason using the provided one.
// *
// * _Available since v4.3._
// */
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
/**
* @dev String operations.
*/
library Strings {
bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";
/**
* @dev Converts a `uint256` to its ASCII `string` decimal representation.
*/
function toString(uint256 value) internal pure returns (string memory) {
// Inspired by OraclizeAPI's implementation - MIT licence
// https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol
if (value == 0) {
return "0";
}
uint256 temp = value;
uint256 digits;
while (temp != 0) {
digits++;
temp /= 10;
}
bytes memory buffer = new bytes(digits);
while (value != 0) {
digits -= 1;
buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
value /= 10;
}
return string(buffer);
}
// Don't need these
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
*/
function toHexString(uint256 value) internal pure returns (string memory) {
if (value == 0) {
return "0x00";
}
uint256 temp = value;
uint256 length = 0;
while (temp != 0) {
length++;
temp >>= 8;
}
return toHexString(value, length);
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
*/
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = "0";
buffer[1] = "x";
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = _HEX_SYMBOLS[value & 0xf];
value >>= 4;
}
require(value == 0, "Strings: hex length insufficient");
return string(buffer);
}
}
/// [MIT License]
/// @title Base64
/// @notice Provides a function for encoding some bytes in base64
/// @author Brecht Devos <[email protected]>
library Base64 {
bytes internal constant TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
/// @notice Encodes some bytes to the base64 representation
function encode(bytes memory data) internal pure returns (string memory) {
uint256 len = data.length;
if (len == 0) return "";
// multiply by 4/3 rounded up
uint256 encodedLen = 4 * ((len + 2) / 3);
// Add some extra buffer at the end
bytes memory result = new bytes(encodedLen + 32);
bytes memory table = TABLE;
assembly {
let tablePtr := add(table, 1)
let resultPtr := add(result, 32)
for {
let i := 0
} lt(i, len) {
} {
i := add(i, 3)
let input := and(mload(add(data, i)), 0xffffff)
let out := mload(add(tablePtr, and(shr(18, input), 0x3F)))
out := shl(8, out)
out := add(out, and(mload(add(tablePtr, and(shr(12, input), 0x3F))), 0xFF))
out := shl(8, out)
out := add(out, and(mload(add(tablePtr, and(shr(6, input), 0x3F))), 0xFF))
out := shl(8, out)
out := add(out, and(mload(add(tablePtr, and(input, 0x3F))), 0xFF))
out := shl(224, out)
mstore(resultPtr, out)
resultPtr := add(resultPtr, 4)
}
switch mod(len, 3)
case 1 {
mstore(sub(resultPtr, 2), shl(240, 0x3d3d))
}
case 2 {
mstore(sub(resultPtr, 1), shl(248, 0x3d))
}
mstore(result, encodedLen)
}
return string(result);
}
}
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
* for the additional interface id that will be supported. For example:
*
* ```solidity
* function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
* return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
* }
* ```
*
* Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
*/
abstract contract ERC165 is IERC165 {
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() {
_setOwner(_msgSender());
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
_;
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_setOwner(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_setOwner(newOwner);
}
function _setOwner(address newOwner) private {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
/**
* @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
* the Metadata extension, but not including the Enumerable extension, which is available separately as
* {ERC721Enumerable}.
*/
contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
using Address for address;
using Strings for uint256;
// Token name
string private _name;
// Token symbol
string private _symbol;
// Mapping from token ID to owner address
mapping(uint256 => address) private _owners;
// Mapping owner address to token count
mapping(address => uint256) private _balances;
// Mapping from token ID to approved address
mapping(uint256 => address) private _tokenApprovals;
// Mapping from owner to operator approvals
mapping(address => mapping(address => bool)) private _operatorApprovals;
/**
* @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.
*/
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
return
interfaceId == type(IERC721).interfaceId ||
interfaceId == type(IERC721Metadata).interfaceId ||
super.supportsInterface(interfaceId);
}
/**
* @dev See {IERC721-balanceOf}.
*/
function balanceOf(address owner) public view virtual override returns (uint256) {
require(owner != address(0), "ERC721: balance query for the zero address");
return _balances[owner];
}
/**
* @dev See {IERC721-ownerOf}.
*/
function ownerOf(uint256 tokenId) public view virtual override returns (address) {
address owner = _owners[tokenId];
require(owner != address(0), "ERC721: owner query for nonexistent token");
return owner;
}
/**
* @dev See {IERC721Metadata-name}.
*/
function name() public view virtual override returns (string memory) {
return _name;
}
/**
* @dev See {IERC721Metadata-symbol}.
*/
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
/**
* @dev See {IERC721Metadata-tokenURI}.
*/
function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");
string memory baseURI = _baseURI();
return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : "";
}
/**
* @dev Base URI for computing {tokenURI}. If set, the resulting URI for each
* token will be the concatenation of the `baseURI` and the `tokenId`. Empty
* by default, can be overriden in child contracts.
*/
function _baseURI() internal view virtual returns (string memory) {
return "";
}
/**
* @dev See {IERC721-approve}.
*/
function approve(address to, uint256 tokenId) public virtual override {
address owner = ERC721.ownerOf(tokenId);
require(to != owner, "ERC721: approval to current owner");
require(
_msgSender() == owner || isApprovedForAll(owner, _msgSender()),
"ERC721: approve caller is not owner nor approved for all"
);
_approve(to, tokenId);
}
/**
* @dev See {IERC721-getApproved}.
*/
function getApproved(uint256 tokenId) public view virtual override returns (address) {
require(_exists(tokenId), "ERC721: approved query for nonexistent token");
return _tokenApprovals[tokenId];
}
/**
* @dev See {IERC721-setApprovalForAll}.
*/
function setApprovalForAll(address operator, bool approved) public virtual override {
require(operator != _msgSender(), "ERC721: approve to caller");
_operatorApprovals[_msgSender()][operator] = approved;
emit ApprovalForAll(_msgSender(), operator, approved);
}
/**
* @dev See {IERC721-isApprovedForAll}.
*/
function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
return _operatorApprovals[owner][operator];
}
/**
* @dev See {IERC721-transferFrom}.
*/
function transferFrom(
address from,
address to,
uint256 tokenId
) public virtual override {
//solhint-disable-next-line max-line-length
require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
_transfer(from, to, tokenId);
}
/**
* @dev See {IERC721-safeTransferFrom}.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) public virtual override {
safeTransferFrom(from, to, tokenId, "");
}
/**
* @dev See {IERC721-safeTransferFrom}.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes memory _data
) public virtual override {
require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
_safeTransfer(from, to, tokenId, _data);
}
/**
* @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
* are aware of the ERC721 protocol to prevent tokens from being forever locked.
*
* `_data` is additional data, it has no specified format and it is sent in call to `to`.
*
* This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.
* implement alternative mechanisms to perform token transfer, such as signature-based.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function _safeTransfer(
address from,
address to,
uint256 tokenId,
bytes memory _data
) internal virtual {
_transfer(from, to, tokenId);
require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
}
/**
* @dev Returns whether `tokenId` exists.
*
* Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
*
* Tokens start existing when they are minted (`_mint`),
* and stop existing when they are burned (`_burn`).
*/
function _exists(uint256 tokenId) internal view virtual returns (bool) {
return _owners[tokenId] != address(0);
}
/**
* @dev Returns whether `spender` is allowed to manage `tokenId`.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {
require(_exists(tokenId), "ERC721: operator query for nonexistent token");
address owner = ERC721.ownerOf(tokenId);
return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));
}
/**
* @dev Safely mints `tokenId` and transfers it to `to`.
*
* Requirements:
*
* - `tokenId` must not exist.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function _safeMint(address to, uint256 tokenId) internal virtual {
_safeMint(to, tokenId, "");
}
/**
* @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is
* forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
*/
function _safeMint(
address to,
uint256 tokenId,
bytes memory _data
) internal virtual {
_mint(to, tokenId);
require(
_checkOnERC721Received(address(0), to, tokenId, _data),
"ERC721: transfer to non ERC721Receiver implementer"
);
}
/**
* @dev Mints `tokenId` and transfers it to `to`.
*
* WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible
*
* Requirements:
*
* - `tokenId` must not exist.
* - `to` cannot be the zero address.
*
* Emits a {Transfer} event.
*/
function _mint(address to, uint256 tokenId) internal virtual {
require(to != address(0), "ERC721: mint to the zero address");
require(!_exists(tokenId), "ERC721: token already minted");
_beforeTokenTransfer(address(0), to, tokenId);
_balances[to] += 1;
_owners[tokenId] = to;
emit Transfer(address(0), to, tokenId);
}
/**
* @dev Destroys `tokenId`.
* The approval is cleared when the token is burned.
*
* Requirements:
*
* - `tokenId` must exist.
*
* Emits a {Transfer} event.
*/
function _burn(uint256 tokenId) internal virtual {
address owner = ERC721.ownerOf(tokenId);
_beforeTokenTransfer(owner, address(0), tokenId);
// Clear approvals
_approve(address(0), tokenId);
_balances[owner] -= 1;
delete _owners[tokenId];
emit Transfer(owner, address(0), tokenId);
}
/**
* @dev Transfers `tokenId` from `from` to `to`.
* As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - `tokenId` token must be owned by `from`.
*
* Emits a {Transfer} event.
*/
function _transfer(
address from,
address to,
uint256 tokenId
) internal virtual {
require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer of token that is not own");
require(to != address(0), "ERC721: transfer to the zero address");
_beforeTokenTransfer(from, to, tokenId);
// Clear approvals from the previous owner
_approve(address(0), tokenId);
_balances[from] -= 1;
_balances[to] += 1;
_owners[tokenId] = to;
emit Transfer(from, to, tokenId);
}
/**
* @dev Approve `to` to operate on `tokenId`
*
* Emits a {Approval} event.
*/
function _approve(address to, uint256 tokenId) internal virtual {
_tokenApprovals[tokenId] = to;
emit Approval(ERC721.ownerOf(tokenId), to, tokenId);
}
/**
* @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.
* The call is not executed if the target address is not a contract.
*
* @param from address representing the previous owner of the given token ID
* @param to target address that will receive the tokens
* @param tokenId uint256 ID of the token to be transferred
* @param _data bytes optional data to send along with the call
* @return bool whether the call correctly returned the expected magic value
*/
function _checkOnERC721Received(
address from,
address to,
uint256 tokenId,
bytes memory _data
) private returns (bool) {
if (to.isContract()) {
try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) {
return retval == IERC721Receiver(to).onERC721Received.selector;
} catch (bytes memory reason) {
if (reason.length == 0) {
revert("ERC721: transfer to non ERC721Receiver implementer");
} else {
assembly {
revert(add(32, reason), mload(reason))
}
}
}
} else {
return true;
}
}
/**
* @dev Hook that is called before any token transfer. This includes minting
* and burning.
*
* Calling conditions:
*
* - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be
* transferred to `to`.
* - When `from` is zero, `tokenId` will be minted for `to`.
* - When `to` is zero, ``from``'s `tokenId` will be burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _beforeTokenTransfer(
address from,
address to,
uint256 tokenId
) internal virtual {}
}
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `from` to `to` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 amount) external returns (bool);
}
/**
* @dev Interface for the optional metadata functions from the ERC20 standard.
*
* _Available since v4.1._
*/
interface IERC20Metadata is IERC20 {
/**
* @dev Returns the name of the token.
*/
function name() external view returns (string memory);
/**
* @dev Returns the symbol of the token.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the decimals places of the token.
*/
function decimals() external view returns (uint8);
}
/**
* @dev Implementation of the {IERC20} interface.
*
* This implementation is agnostic to the way tokens are created. This means
* that a supply mechanism has to be added in a derived contract using {_mint}.
* For a generic mechanism see {ERC20PresetMinterPauser}.
*
* TIP: For a detailed writeup see our guide
* https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How
* to implement supply mechanisms].
*
* The default value of {decimals} is 18. To change this, you should override
* this function so it returns a different value.
*
* We have followed general OpenZeppelin Contracts guidelines: functions revert
* instead returning `false` on failure. This behavior is nonetheless
* conventional and does not conflict with the expectations of ERC20
* applications.
*
* Additionally, an {Approval} event is emitted on calls to {transferFrom}.
* This allows applications to reconstruct the allowance for all accounts just
* by listening to said events. Other implementations of the EIP may not emit
* these events, as it isn't required by the specification.
*
* Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
* functions have been added to mitigate the well-known issues around setting
* allowances. See {IERC20-approve}.
*/
contract ERC20 is Context, IERC20, IERC20Metadata {
mapping(address => uint256) private _balances;
mapping(address => mapping(address => uint256)) private _allowances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
/**
* @dev Sets the values for {name} and {symbol}.
*
* All two of these values are immutable: they can only be set once during
* construction.
*/
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
/**
* @dev Returns the name of the token.
*/
function name() public view virtual override returns (string memory) {
return _name;
}
/**
* @dev Returns the symbol of the token, usually a shorter version of the
* name.
*/
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
/**
* @dev Returns the number of decimals used to get its user representation.
* For example, if `decimals` equals `2`, a balance of `505` tokens should
* be displayed to a user as `5.05` (`505 / 10 ** 2`).
*
* Tokens usually opt for a value of 18, imitating the relationship between
* Ether and Wei. This is the default value returned by this function, unless
* it's overridden.
*
* NOTE: This information is only used for _display_ purposes: it in
* no way affects any of the arithmetic of the contract, including
* {IERC20-balanceOf} and {IERC20-transfer}.
*/
function decimals() public view virtual override returns (uint8) {
return 18;
}
/**
* @dev See {IERC20-totalSupply}.
*/
function totalSupply() public view virtual override returns (uint256) {
return _totalSupply;
}
/**
* @dev See {IERC20-balanceOf}.
*/
function balanceOf(address account) public view virtual override returns (uint256) {
return _balances[account];
}
/**
* @dev See {IERC20-transfer}.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - the caller must have a balance of at least `amount`.
*/
function transfer(address to, uint256 amount) public virtual override returns (bool) {
address owner = _msgSender();
_transfer(owner, to, amount);
return true;
}
/**
* @dev See {IERC20-allowance}.
*/
function allowance(address owner, address spender) public view virtual override returns (uint256) {
return _allowances[owner][spender];
}
/**
* @dev See {IERC20-approve}.
*
* NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on
* `transferFrom`. This is semantically equivalent to an infinite approval.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function approve(address spender, uint256 amount) public virtual override returns (bool) {
address owner = _msgSender();
_approve(owner, spender, amount);
return true;
}
/**
* @dev See {IERC20-transferFrom}.
*
* Emits an {Approval} event indicating the updated allowance. This is not
* required by the EIP. See the note at the beginning of {ERC20}.
*
* NOTE: Does not update the allowance if the current allowance
* is the maximum `uint256`.
*
* Requirements:
*
* - `from` and `to` cannot be the zero address.
* - `from` must have a balance of at least `amount`.
* - the caller must have allowance for ``from``'s tokens of at least
* `amount`.
*/
function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {
address spender = _msgSender();
_spendAllowance(from, spender, amount);
_transfer(from, to, amount);
return true;
}
/**
* @dev Atomically increases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
address owner = _msgSender();
_approve(owner, spender, allowance(owner, spender) + addedValue);
return true;
}
/**
* @dev Atomically decreases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `spender` must have allowance for the caller of at least
* `subtractedValue`.
*/
function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
address owner = _msgSender();
uint256 currentAllowance = allowance(owner, spender);
require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
unchecked {
_approve(owner, spender, currentAllowance - subtractedValue);
}
return true;
}
/**
* @dev Moves `amount` of tokens from `from` to `to`.
*
* This internal function is equivalent to {transfer}, and can be used to
* e.g. implement automatic token fees, slashing mechanisms, etc.
*
* Emits a {Transfer} event.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `from` must have a balance of at least `amount`.
*/
function _transfer(address from, address to, uint256 amount) internal virtual {
require(from != address(0), "ERC20: transfer from the zero address");
require(to != address(0), "ERC20: transfer to the zero address");
_beforeTokenTransfer(from, to, amount);
uint256 fromBalance = _balances[from];
require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
unchecked {
_balances[from] = fromBalance - amount;
// Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by
// decrementing then incrementing.
_balances[to] += amount;
}
emit Transfer(from, to, amount);
_afterTokenTransfer(from, to, amount);
}
/** @dev Creates `amount` tokens and assigns them to `account`, increasing
* the total supply.
*
* Emits a {Transfer} event with `from` set to the zero address.
*
* Requirements:
*
* - `account` cannot be the zero address.
*/
function _mint(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: mint to the zero address");
_beforeTokenTransfer(address(0), account, amount);
_totalSupply += amount;
unchecked {
// Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.
_balances[account] += amount;
}
emit Transfer(address(0), account, amount);
_afterTokenTransfer(address(0), account, amount);
}
/**
* @dev Destroys `amount` tokens from `account`, reducing the
* total supply.
*
* Emits a {Transfer} event with `to` set to the zero address.
*
* Requirements:
*
* - `account` cannot be the zero address.
* - `account` must have at least `amount` tokens.
*/
function _burn(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: burn from the zero address");
_beforeTokenTransfer(account, address(0), amount);
uint256 accountBalance = _balances[account];
require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
unchecked {
_balances[account] = accountBalance - amount;
// Overflow not possible: amount <= accountBalance <= totalSupply.
_totalSupply -= amount;
}
emit Transfer(account, address(0), amount);
_afterTokenTransfer(account, address(0), amount);
}
/**
* @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
*
* This internal function is equivalent to `approve`, and can be used to
* e.g. set automatic allowances for certain subsystems, etc.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `owner` cannot be the zero address.
* - `spender` cannot be the zero address.
*/
function _approve(address owner, address spender, uint256 amount) internal virtual {
require(owner != address(0), "ERC20: approve from the zero address");
require(spender != address(0), "ERC20: approve to the zero address");
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
/**
* @dev Updates `owner` s allowance for `spender` based on spent `amount`.
*
* Does not update the allowance amount in case of infinite allowance.
* Revert if not enough allowance is available.
*
* Might emit an {Approval} event.
*/
function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {
uint256 currentAllowance = allowance(owner, spender);
if (currentAllowance != type(uint256).max) {
require(currentAllowance >= amount, "ERC20: insufficient allowance");
unchecked {
_approve(owner, spender, currentAllowance - amount);
}
}
}
/**
* @dev Hook that is called before any transfer of tokens. This includes
* minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* will be transferred to `to`.
* - when `from` is zero, `amount` tokens will be minted for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens will be burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}
/**
* @dev Hook that is called after any transfer of tokens. This includes
* minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* has been transferred to `to`.
* - when `from` is zero, `amount` tokens have been minted for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens have been burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}
}
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_toTokenId","type":"uint256"}],"name":"BatchMetadataUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"burner","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Burn","type":"event"},{"anonymous":false,"inputs":[],"name":"ContractURIUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"MetadataUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"memo","type":"string"}],"name":"addMemo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"proof","type":"string"}],"name":"addProof","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"string","name":"baseURI","type":"string"},{"internalType":"string","name":"ext","type":"string"}],"name":"addProofBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"billsBurned","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"burnedBy","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"busd","outputs":[{"internalType":"contract BUSD","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"denominations","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"exists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"markSessionEnd","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"memos","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"denomination","type":"uint256"},{"internalType":"string","name":"serial","type":"string"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"proofs","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proofsBurned","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"","type":"string"}],"name":"serialUsed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"serials","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"sessionEnds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newURI","type":"address"}],"name":"setURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"timestamps","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenIdToSessionId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSessions","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newURI","type":"string"}],"name":"updateContractURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"uri","outputs":[{"internalType":"contract ProofOfBurnURI","name":"","type":"address"}],"stateMutability":"view","type":"function"}]Contract Creation Code
60806040526040518060600160405280603a8152602001617182603a91396013908161002b91906105de565b50348015610037575f5ffd5b506040518060400160405280601481526020017f50726f6f66206f66204275726e202862555344290000000000000000000000008152506040518060400160405280600381526020017f504f420000000000000000000000000000000000000000000000000000000000815250815f90816100b291906105de565b5080600190816100c291906105de565b5050506100e16100d661019a60201b60201c565b6101a160201b60201c565b3360075f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060405161012d90610394565b604051809103905ff080158015610146573d5f5f3e3d5ffd5b50600a5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506101953261026460201b60201c565b6107b3565b5f33905090565b5f60065f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160065f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b61027261019a60201b60201c565b73ffffffffffffffffffffffffffffffffffffffff1661029661036c60201b60201c565b73ffffffffffffffffffffffffffffffffffffffff16146102ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102e390610707565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361035a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161035190610795565b60405180910390fd5b610369816101a160201b60201c565b50565b5f60065f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b611cee8061549483390190565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061041c57607f821691505b60208210810361042f5761042e6103d8565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026104917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82610456565b61049b8683610456565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f6104df6104da6104d5846104b3565b6104bc565b6104b3565b9050919050565b5f819050919050565b6104f8836104c5565b61050c610504826104e6565b848454610462565b825550505050565b5f5f905090565b610523610514565b61052e8184846104ef565b505050565b5b81811015610551576105465f8261051b565b600181019050610534565b5050565b601f8211156105965761056781610435565b61057084610447565b8101602085101561057f578190505b61059361058b85610447565b830182610533565b50505b505050565b5f82821c905092915050565b5f6105b65f198460080261059b565b1980831691505092915050565b5f6105ce83836105a7565b9150826002028217905092915050565b6105e7826103a1565b67ffffffffffffffff811115610600576105ff6103ab565b5b61060a8254610405565b610615828285610555565b5f60209050601f831160018114610646575f8415610634578287015190505b61063e85826105c3565b8655506106a5565b601f19841661065486610435565b5f5b8281101561067b57848901518255600182019150602085019450602081019050610656565b868310156106985784890151610694601f8916826105a7565b8355505b6001600288020188555050505b505050505050565b5f82825260208201905092915050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65725f82015250565b5f6106f16020836106ad565b91506106fc826106bd565b602082019050919050565b5f6020820190508181035f83015261071e816106e5565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f20615f8201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b5f61077f6026836106ad565b915061078a82610725565b604082019050919050565b5f6020820190508181035f8301526107ac81610773565b9050919050565b614cd4806107c05f395ff3fe608060405234801561000f575f5ffd5b5060043610610251575f3560e01c80637e5b1e2411610144578063c3062ce7116100c1578063e985e9c511610085578063e985e9c51461072f578063eac989f81461075f578063f2fde38b1461077d578063f3ce61ad14610799578063f93e4ec8146107c9578063f9f3d0d9146107e557610251565b8063c3062ce714610665578063c87b56dd14610695578063d3fc9864146106c5578063e8a3d485146106e1578063e8dfdf04146106ff57610251565b8063997fe50711610108578063997fe507146105d75780639ddaf5aa146105f3578063a22cb46514610623578063a547b48e1461063f578063b88d4fde1461064957610251565b80637e5b1e241461051f5780638bc33af31461053b5780638da5cb5b1461056b57806395d89b411461058957806398cd96af146105a757610251565b806342966c68116101d25780636c1a1779116101965780636c1a17791461047b5780636dbf6e3b146104975780636f5db0b5146104c757806370a08231146104e5578063715018a61461051557610251565b806342966c68146103b157806343470a89146103cd5780634f558e79146103fd5780635213f7211461042d5780636352211e1461044b57610251565b806323b872dd1161021957806323b872dd1461030d5780632583f5361461032957806339920528146103595780633ca5b2341461037757806342842e0e1461039557610251565b806301ffc9a71461025557806306fdde0314610285578063081812fc146102a3578063095ea7b3146102d357806318160ddd146102ef575b5f5ffd5b61026f600480360381019061026a919061306a565b610801565b60405161027c91906130af565b60405180910390f35b61028d610861565b60405161029a9190613138565b60405180910390f35b6102bd60048036038101906102b8919061318b565b6108f0565b6040516102ca91906131f5565b60405180910390f35b6102ed60048036038101906102e89190613238565b610971565b005b6102f7610a87565b6040516103049190613285565b60405180910390f35b6103276004803603810190610322919061329e565b610a9d565b005b610343600480360381019061033e919061341a565b610afd565b60405161035091906130af565b60405180910390f35b610361610b32565b60405161036e9190613285565b60405180910390f35b61037f610b38565b60405161038c91906134bc565b60405180910390f35b6103af60048036038101906103aa919061329e565b610b5d565b005b6103cb60048036038101906103c6919061318b565b610b7c565b005b6103e760048036038101906103e2919061318b565b610d75565b6040516103f491906131f5565b60405180910390f35b6104176004803603810190610412919061318b565b610da5565b60405161042491906130af565b60405180910390f35b610435610db6565b6040516104429190613285565b60405180910390f35b6104656004803603810190610460919061318b565b610dbc565b60405161047291906131f5565b60405180910390f35b610495600480360381019061049091906134d5565b610e68565b005b6104b160048036038101906104ac919061318b565b610fa6565b6040516104be9190613285565b60405180910390f35b6104cf610fc6565b6040516104dc9190613285565b60405180910390f35b6104ff60048036038101906104fa91906134d5565b610fd2565b60405161050c9190613285565b60405180910390f35b61051d611086565b005b6105396004803603810190610534919061355d565b61110d565b005b6105556004803603810190610550919061318b565b6111cb565b6040516105629190613285565b60405180910390f35b6105736111e0565b60405161058091906131f5565b60405180910390f35b610591611208565b60405161059e9190613138565b60405180910390f35b6105c160048036038101906105bc919061318b565b611298565b6040516105ce9190613138565b60405180910390f35b6105f160048036038101906105ec91906135fd565b611333565b005b61060d6004803603810190610608919061318b565b61157b565b60405161061a9190613138565b60405180910390f35b61063d600480360381019061063891906136d7565b611616565b005b610647611791565b005b610663600480360381019061065e91906137b3565b611925565b005b61067f600480360381019061067a919061318b565b611987565b60405161068c9190613285565b60405180910390f35b6106af60048036038101906106aa919061318b565b6119f5565b6040516106bc9190613138565b60405180910390f35b6106df60048036038101906106da9190613833565b611a9a565b005b6106e9611ccb565b6040516106f69190613138565b60405180910390f35b6107196004803603810190610714919061318b565b611d5b565b6040516107269190613138565b60405180910390f35b610749600480360381019061074491906138a4565b611df6565b60405161075691906130af565b60405180910390f35b610767611e84565b6040516107749190613902565b60405180910390f35b610797600480360381019061079291906134d5565b611ea9565b005b6107b360048036038101906107ae919061318b565b611f9f565b6040516107c09190613936565b60405180910390f35b6107e360048036038101906107de919061394f565b611fbc565b005b6107ff60048036038101906107fa919061394f565b61214e565b005b5f634906490660e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061085a575061085982612317565b5b9050919050565b60605f805461086f906139d9565b80601f016020809104026020016040519081016040528092919081815260200182805461089b906139d9565b80156108e65780601f106108bd576101008083540402835291602001916108e6565b820191905f5260205f20905b8154815290600101906020018083116108c957829003601f168201915b5050505050905090565b5f6108fa826123f8565b610939576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161093090613a79565b60405180910390fd5b60045f8381526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b5f61097b82610dbc565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036109eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109e290613b07565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610a0a612460565b73ffffffffffffffffffffffffffffffffffffffff161480610a395750610a3881610a33612460565b611df6565b5b610a78576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a6f90613b95565b60405180910390fd5b610a828383612467565b505050565b5f600954600854610a989190613be0565b905090565b610aae610aa8612460565b8261251d565b610aed576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ae490613c83565b60405180910390fd5b610af88383836125f9565b505050565b6011818051602081018201805184825260208301602085012081835280955050505050505f915054906101000a900460ff1681565b60085481565b60075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610b7783838360405180602001604052805f815250611925565b505050565b610b86338261251d565b610bc5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bbc90613d11565b60405180910390fd5b5f670de0b6b3a7640000600c5f8481526020019081526020015f205f9054906101000a900460ff1660ff16610bfa9190613d2f565b905060075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166379cc6790610c4284610dbc565b836040518363ffffffff1660e01b8152600401610c60929190613d70565b5f604051808303815f87803b158015610c77575f5ffd5b505af1158015610c89573d5f5f3e3d5ffd5b50505050610c9682610dbc565b60105f8481526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600160095f828254610cf69190613d97565b92505081905550610d0682612849565b7f49995e5dd6158cf69ad3e9777c46755a1a826a446c6416992167462dad033b2a60105f8481526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff168383604051610d6993929190613dca565b60405180910390a15050565b6010602052805f5260405f205f915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f610daf826123f8565b9050919050565b60095481565b5f5f60025f8481526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610e5f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e5690613e6f565b60405180910390fd5b80915050919050565b60075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ed2573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ef69190613ea1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610f63576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f5a90613f16565b60405180910390fd5b80600a5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60128181548110610fb5575f80fd5b905f5260205f20015f915090505481565b5f601280549050905090565b5f5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611041576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161103890613fa4565b60405180910390fd5b60035f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b61108e612460565b73ffffffffffffffffffffffffffffffffffffffff166110ac6111e0565b73ffffffffffffffffffffffffffffffffffffffff1614611102576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110f99061400c565b60405180910390fd5b61110b5f612950565b565b611115612460565b73ffffffffffffffffffffffffffffffffffffffff166111336111e0565b73ffffffffffffffffffffffffffffffffffffffff1614611189576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111809061400c565b60405180910390fd5b81816013918261119a9291906141cb565b507fa5d4097edda6d87cb9329af83fb3712ef77eeb13738ffe43cc35a4ce305ad96260405160405180910390a15050565b600e602052805f5260405f205f915090505481565b5f60065f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060018054611217906139d9565b80601f0160208091040260200160405190810160405280929190818152602001828054611243906139d9565b801561128e5780601f106112655761010080835404028352916020019161128e565b820191905f5260205f20905b81548152906001019060200180831161127157829003601f168201915b5050505050905090565b600b602052805f5260405f205f9150905080546112b4906139d9565b80601f01602080910402602001604051908101604052809291908181526020018280546112e0906139d9565b801561132b5780601f106113025761010080835404028352916020019161132b565b820191905f5260205f20905b81548152906001019060200180831161130e57829003601f168201915b505050505081565b5f60075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166306133c656040518163ffffffff1660e01b8152600401602060405180830381865afa15801561139e573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113c291906142d3565b73ffffffffffffffffffffffffffffffffffffffff1663c365f4af6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561140a573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061142e9190613ea1565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461149e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161149590614348565b60405180910390fd5b5f5b878790508110156115365785856114cf8a8a858181106114c3576114c2614366565b5b90506020020135612a13565b86866040516020016114e59594939291906143f1565b604051602081830303815290604052600d5f8a8a8581811061150a57611509614366565b5b9050602002013581526020019081526020015f20908161152a9190614425565b508060010190506114a0565b507f6bd5c950a8d8df17f772f5af37cb3655737899cbf903264b9795592da439661c5f60085460405161156a92919061452d565b60405180910390a150505050505050565b600d602052805f5260405f205f915090508054611597906139d9565b80601f01602080910402602001604051908101604052809291908181526020018280546115c3906139d9565b801561160e5780601f106115e55761010080835404028352916020019161160e565b820191905f5260205f20905b8154815290600101906020018083116115f157829003601f168201915b505050505081565b61161e612460565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361168b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116829061459e565b60405180910390fd5b8060055f611697612460565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16611740612460565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161178591906130af565b60405180910390a35050565b5f60075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166306133c656040518163ffffffff1660e01b8152600401602060405180830381865afa1580156117fc573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061182091906142d3565b73ffffffffffffffffffffffffffffffffffffffff1663c365f4af6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611868573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061188c9190613ea1565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146118fc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118f390614348565b60405180910390fd5b601242908060018154018082558091505060019003905f5260205f20015f909190919091505550565b611936611930612460565b8361251d565b611975576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161196c90613c83565b60405180910390fd5b61198184848484612b6c565b50505050565b5f5f600e5f8481526020019081526020015f205490505f5b6012805490508110156119e557601281815481106119c0576119bf614366565b5b905f5260205f2001548210156119da5780925050506119f0565b80600101905061199f565b506012805490509150505b919050565b6060600a5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c87b56dd836040518263ffffffff1660e01b8152600401611a519190613285565b5f60405180830381865afa158015611a6b573d5f5f3e3d5ffd5b505050506040513d5f823e3d601f19601f82011682018060405250810190611a93919061462a565b9050919050565b60075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166306133c656040518163ffffffff1660e01b8152600401602060405180830381865afa158015611b04573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611b2891906142d3565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611b95576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b8c906146bb565b60405180910390fd5b60118282604051611ba79291906146d9565b90815260200160405180910390205f9054906101000a900460ff1615611c02576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bf99061473b565b60405180910390fd5b82600c5f60085481526020019081526020015f205f6101000a81548160ff021916908360ff1602179055508181600b5f60085481526020019081526020015f209182611c4f9291906141cb565b50600160118383604051611c649291906146d9565b90815260200160405180910390205f6101000a81548160ff02191690831515021790555042600e5f60085481526020019081526020015f2081905550611cac84600854612bc8565b600160085f828254611cbe9190613d97565b9250508190555050505050565b606060138054611cda906139d9565b80601f0160208091040260200160405190810160405280929190818152602001828054611d06906139d9565b8015611d515780601f10611d2857610100808354040283529160200191611d51565b820191905f5260205f20905b815481529060010190602001808311611d3457829003601f168201915b5050505050905090565b600f602052805f5260405f205f915090508054611d77906139d9565b80601f0160208091040260200160405190810160405280929190818152602001828054611da3906139d9565b8015611dee5780601f10611dc557610100808354040283529160200191611dee565b820191905f5260205f20905b815481529060010190602001808311611dd157829003601f168201915b505050505081565b5f60055f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b600a5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b611eb1612460565b73ffffffffffffffffffffffffffffffffffffffff16611ecf6111e0565b73ffffffffffffffffffffffffffffffffffffffff1614611f25576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f1c9061400c565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611f93576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f8a906147c9565b60405180910390fd5b611f9c81612950565b50565b600c602052805f5260405f205f915054906101000a900460ff1681565b5f60075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166306133c656040518163ffffffff1660e01b8152600401602060405180830381865afa158015612027573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061204b91906142d3565b73ffffffffffffffffffffffffffffffffffffffff1663c365f4af6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612093573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906120b79190613ea1565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612127576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161211e90614348565b60405180910390fd5b8282600f5f8781526020019081526020015f2091826121479291906141cb565b5050505050565b5f60075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166306133c656040518163ffffffff1660e01b8152600401602060405180830381865afa1580156121b9573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121dd91906142d3565b73ffffffffffffffffffffffffffffffffffffffff1663c365f4af6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612225573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906122499190613ea1565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146122b9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122b090614348565b60405180910390fd5b8282600d5f8781526020019081526020015f2091826122d99291906141cb565b507ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce7846040516123099190613285565b60405180910390a150505050565b5f7f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806123e157507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806123f157506123f082612be5565b5b9050919050565b5f5f73ffffffffffffffffffffffffffffffffffffffff1660025f8481526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b5f33905090565b8160045f8381526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff166124d783610dbc565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b5f612527826123f8565b612566576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161255d90614857565b60405180910390fd5b5f61257083610dbc565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614806125df57508373ffffffffffffffffffffffffffffffffffffffff166125c7846108f0565b73ffffffffffffffffffffffffffffffffffffffff16145b806125f057506125ef8185611df6565b5b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff1661261982610dbc565b73ffffffffffffffffffffffffffffffffffffffff161461266f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612666906148e5565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036126dd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126d490614973565b60405180910390fd5b6126e8838383612c4e565b6126f25f82612467565b600160035f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461273f9190613be0565b92505081905550600160035f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546127939190613d97565b925050819055508160025f8381526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b5f61285382610dbc565b9050612860815f84612c4e565b61286a5f83612467565b600160035f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546128b79190613be0565b9250508190555060025f8381526020019081526020015f205f6101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055815f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b5f60065f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160065f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60605f8203612a59576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050612b67565b5f8290505f5b5f8214612a88578080612a7190614991565b915050600a82612a819190614a05565b9150612a5f565b5f8167ffffffffffffffff811115612aa357612aa26132f6565b5b6040519080825280601f01601f191660200182016040528015612ad55781602001600182028036833780820191505090505b5090505b5f8514612b6057600182612aed9190613be0565b9150600a85612afc9190614a35565b6030612b089190613d97565b60f81b818381518110612b1e57612b1d614366565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a905350600a85612b599190614a05565b9450612ad9565b8093505050505b919050565b612b778484846125f9565b612b8384848484612c53565b612bc2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612bb990614ad5565b60405180910390fd5b50505050565b612be1828260405180602001604052805f815250612dd5565b5050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b505050565b5f612c738473ffffffffffffffffffffffffffffffffffffffff16612e2f565b15612dc8578373ffffffffffffffffffffffffffffffffffffffff1663150b7a02612c9c612460565b8786866040518563ffffffff1660e01b8152600401612cbe9493929190614b45565b6020604051808303815f875af1925050508015612cf957506040513d601f19601f82011682018060405250810190612cf69190614ba3565b60015b612d78573d805f8114612d27576040519150601f19603f3d011682016040523d82523d5f602084013e612d2c565b606091505b505f815103612d70576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d6790614ad5565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050612dcd565b600190505b949350505050565b612ddf8383612e40565b612deb5f848484612c53565b612e2a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e2190614ad5565b60405180910390fd5b505050565b5f5f823b90505f8111915050919050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612eae576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ea590614c18565b60405180910390fd5b612eb7816123f8565b15612ef7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612eee90614c80565b60405180910390fd5b612f025f8383612c4e565b600160035f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612f4f9190613d97565b925050819055508160025f8381526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff165f73ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b5f604051905090565b5f5ffd5b5f5ffd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61304981613015565b8114613053575f5ffd5b50565b5f8135905061306481613040565b92915050565b5f6020828403121561307f5761307e61300d565b5b5f61308c84828501613056565b91505092915050565b5f8115159050919050565b6130a981613095565b82525050565b5f6020820190506130c25f8301846130a0565b92915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f61310a826130c8565b61311481856130d2565b93506131248185602086016130e2565b61312d816130f0565b840191505092915050565b5f6020820190508181035f8301526131508184613100565b905092915050565b5f819050919050565b61316a81613158565b8114613174575f5ffd5b50565b5f8135905061318581613161565b92915050565b5f602082840312156131a05761319f61300d565b5b5f6131ad84828501613177565b91505092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6131df826131b6565b9050919050565b6131ef816131d5565b82525050565b5f6020820190506132085f8301846131e6565b92915050565b613217816131d5565b8114613221575f5ffd5b50565b5f813590506132328161320e565b92915050565b5f5f6040838503121561324e5761324d61300d565b5b5f61325b85828601613224565b925050602061326c85828601613177565b9150509250929050565b61327f81613158565b82525050565b5f6020820190506132985f830184613276565b92915050565b5f5f5f606084860312156132b5576132b461300d565b5b5f6132c286828701613224565b93505060206132d386828701613224565b92505060406132e486828701613177565b9150509250925092565b5f5ffd5b5f5ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61332c826130f0565b810181811067ffffffffffffffff8211171561334b5761334a6132f6565b5b80604052505050565b5f61335d613004565b90506133698282613323565b919050565b5f67ffffffffffffffff821115613388576133876132f6565b5b613391826130f0565b9050602081019050919050565b828183375f83830152505050565b5f6133be6133b98461336e565b613354565b9050828152602081018484840111156133da576133d96132f2565b5b6133e584828561339e565b509392505050565b5f82601f830112613401576134006132ee565b5b81356134118482602086016133ac565b91505092915050565b5f6020828403121561342f5761342e61300d565b5b5f82013567ffffffffffffffff81111561344c5761344b613011565b5b613458848285016133ed565b91505092915050565b5f819050919050565b5f61348461347f61347a846131b6565b613461565b6131b6565b9050919050565b5f6134958261346a565b9050919050565b5f6134a68261348b565b9050919050565b6134b68161349c565b82525050565b5f6020820190506134cf5f8301846134ad565b92915050565b5f602082840312156134ea576134e961300d565b5b5f6134f784828501613224565b91505092915050565b5f5ffd5b5f5ffd5b5f5f83601f84011261351d5761351c6132ee565b5b8235905067ffffffffffffffff81111561353a57613539613500565b5b60208301915083600182028301111561355657613555613504565b5b9250929050565b5f5f602083850312156135735761357261300d565b5b5f83013567ffffffffffffffff8111156135905761358f613011565b5b61359c85828601613508565b92509250509250929050565b5f5f83601f8401126135bd576135bc6132ee565b5b8235905067ffffffffffffffff8111156135da576135d9613500565b5b6020830191508360208202830111156135f6576135f5613504565b5b9250929050565b5f5f5f5f5f5f606087890312156136175761361661300d565b5b5f87013567ffffffffffffffff81111561363457613633613011565b5b61364089828a016135a8565b9650965050602087013567ffffffffffffffff81111561366357613662613011565b5b61366f89828a01613508565b9450945050604087013567ffffffffffffffff81111561369257613691613011565b5b61369e89828a01613508565b92509250509295509295509295565b6136b681613095565b81146136c0575f5ffd5b50565b5f813590506136d1816136ad565b92915050565b5f5f604083850312156136ed576136ec61300d565b5b5f6136fa85828601613224565b925050602061370b858286016136c3565b9150509250929050565b5f67ffffffffffffffff82111561372f5761372e6132f6565b5b613738826130f0565b9050602081019050919050565b5f61375761375284613715565b613354565b905082815260208101848484011115613773576137726132f2565b5b61377e84828561339e565b509392505050565b5f82601f83011261379a576137996132ee565b5b81356137aa848260208601613745565b91505092915050565b5f5f5f5f608085870312156137cb576137ca61300d565b5b5f6137d887828801613224565b94505060206137e987828801613224565b93505060406137fa87828801613177565b925050606085013567ffffffffffffffff81111561381b5761381a613011565b5b61382787828801613786565b91505092959194509250565b5f5f5f5f6060858703121561384b5761384a61300d565b5b5f61385887828801613224565b945050602061386987828801613177565b935050604085013567ffffffffffffffff81111561388a57613889613011565b5b61389687828801613508565b925092505092959194509250565b5f5f604083850312156138ba576138b961300d565b5b5f6138c785828601613224565b92505060206138d885828601613224565b9150509250929050565b5f6138ec8261348b565b9050919050565b6138fc816138e2565b82525050565b5f6020820190506139155f8301846138f3565b92915050565b5f60ff82169050919050565b6139308161391b565b82525050565b5f6020820190506139495f830184613927565b92915050565b5f5f5f604084860312156139665761396561300d565b5b5f61397386828701613177565b935050602084013567ffffffffffffffff81111561399457613993613011565b5b6139a086828701613508565b92509250509250925092565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806139f057607f821691505b602082108103613a0357613a026139ac565b5b50919050565b7f4552433732313a20617070726f76656420717565727920666f72206e6f6e65785f8201527f697374656e7420746f6b656e0000000000000000000000000000000000000000602082015250565b5f613a63602c836130d2565b9150613a6e82613a09565b604082019050919050565b5f6020820190508181035f830152613a9081613a57565b9050919050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e655f8201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b5f613af16021836130d2565b9150613afc82613a97565b604082019050919050565b5f6020820190508181035f830152613b1e81613ae5565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f775f8201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000602082015250565b5f613b7f6038836130d2565b9150613b8a82613b25565b604082019050919050565b5f6020820190508181035f830152613bac81613b73565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f613bea82613158565b9150613bf583613158565b9250828203905081811115613c0d57613c0c613bb3565b5b92915050565b7f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f5f8201527f776e6572206e6f7220617070726f766564000000000000000000000000000000602082015250565b5f613c6d6031836130d2565b9150613c7882613c13565b604082019050919050565b5f6020820190508181035f830152613c9a81613c61565b9050919050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e655f8201527f72206f7220617070726f76656400000000000000000000000000000000000000602082015250565b5f613cfb602d836130d2565b9150613d0682613ca1565b604082019050919050565b5f6020820190508181035f830152613d2881613cef565b9050919050565b5f613d3982613158565b9150613d4483613158565b9250828202613d5281613158565b91508282048414831517613d6957613d68613bb3565b5b5092915050565b5f604082019050613d835f8301856131e6565b613d906020830184613276565b9392505050565b5f613da182613158565b9150613dac83613158565b9250828201905080821115613dc457613dc3613bb3565b5b92915050565b5f606082019050613ddd5f8301866131e6565b613dea6020830185613276565b613df76040830184613276565b949350505050565b7f4552433732313a206f776e657220717565727920666f72206e6f6e65786973745f8201527f656e7420746f6b656e0000000000000000000000000000000000000000000000602082015250565b5f613e596029836130d2565b9150613e6482613dff565b604082019050919050565b5f6020820190508181035f830152613e8681613e4d565b9050919050565b5f81519050613e9b8161320e565b92915050565b5f60208284031215613eb657613eb561300d565b5b5f613ec384828501613e8d565b91505092915050565b7f43616c6c6572206973206e6f742042555344204f776e657200000000000000005f82015250565b5f613f006018836130d2565b9150613f0b82613ecc565b602082019050919050565b5f6020820190508181035f830152613f2d81613ef4565b9050919050565b7f4552433732313a2062616c616e636520717565727920666f7220746865207a655f8201527f726f206164647265737300000000000000000000000000000000000000000000602082015250565b5f613f8e602a836130d2565b9150613f9982613f34565b604082019050919050565b5f6020820190508181035f830152613fbb81613f82565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65725f82015250565b5f613ff66020836130d2565b915061400182613fc2565b602082019050919050565b5f6020820190508181035f83015261402381613fea565b9050919050565b5f82905092915050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026140907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82614055565b61409a8683614055565b95508019841693508086168417925050509392505050565b5f6140cc6140c76140c284613158565b613461565b613158565b9050919050565b5f819050919050565b6140e5836140b2565b6140f96140f1826140d3565b848454614061565b825550505050565b5f5f905090565b614110614101565b61411b8184846140dc565b505050565b5b8181101561413e576141335f82614108565b600181019050614121565b5050565b601f8211156141835761415481614034565b61415d84614046565b8101602085101561416c578190505b61418061417885614046565b830182614120565b50505b505050565b5f82821c905092915050565b5f6141a35f1984600802614188565b1980831691505092915050565b5f6141bb8383614194565b9150826002028217905092915050565b6141d5838361402a565b67ffffffffffffffff8111156141ee576141ed6132f6565b5b6141f882546139d9565b614203828285614142565b5f601f831160018114614230575f841561421e578287013590505b61422885826141b0565b86555061428f565b601f19841661423e86614034565b5f5b8281101561426557848901358255600182019150602085019450602081019050614240565b86831015614282578489013561427e601f891682614194565b8355505b6001600288020188555050505b50505050505050565b5f6142a2826131d5565b9050919050565b6142b281614298565b81146142bc575f5ffd5b50565b5f815190506142cd816142a9565b92915050565b5f602082840312156142e8576142e761300d565b5b5f6142f5848285016142bf565b91505092915050565b7f43616c6c6572206973206e6f74204275726e204167656e7400000000000000005f82015250565b5f6143326018836130d2565b915061433d826142fe565b602082019050919050565b5f6020820190508181035f83015261435f81614326565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f81905092915050565b5f6143a88385614393565b93506143b583858461339e565b82840190509392505050565b5f6143cb826130c8565b6143d58185614393565b93506143e58185602086016130e2565b80840191505092915050565b5f6143fd82878961439d565b915061440982866143c1565b915061441682848661439d565b91508190509695505050505050565b61442e826130c8565b67ffffffffffffffff811115614447576144466132f6565b5b61445182546139d9565b61445c828285614142565b5f60209050601f83116001811461448d575f841561447b578287015190505b61448585826141b0565b8655506144ec565b601f19841661449b86614034565b5f5b828110156144c25784890151825560018201915060208501945060208101905061449d565b868310156144df57848901516144db601f891682614194565b8355505b6001600288020188555050505b505050505050565b5f819050919050565b5f61451761451261450d846144f4565b613461565b613158565b9050919050565b614527816144fd565b82525050565b5f6040820190506145405f83018561451e565b61454d6020830184613276565b9392505050565b7f4552433732313a20617070726f766520746f2063616c6c6572000000000000005f82015250565b5f6145886019836130d2565b915061459382614554565b602082019050919050565b5f6020820190508181035f8301526145b58161457c565b9050919050565b5f6145ce6145c98461336e565b613354565b9050828152602081018484840111156145ea576145e96132f2565b5b6145f58482856130e2565b509392505050565b5f82601f830112614611576146106132ee565b5b81516146218482602086016145bc565b91505092915050565b5f6020828403121561463f5761463e61300d565b5b5f82015167ffffffffffffffff81111561465c5761465b613011565b5b614668848285016145fd565b91505092915050565b7f496e76616c6964206d696e7465720000000000000000000000000000000000005f82015250565b5f6146a5600e836130d2565b91506146b082614671565b602082019050919050565b5f6020820190508181035f8301526146d281614699565b9050919050565b5f6146e582848661439d565b91508190509392505050565b7f53657269616c20616c72656164792075736564000000000000000000000000005f82015250565b5f6147256013836130d2565b9150614730826146f1565b602082019050919050565b5f6020820190508181035f83015261475281614719565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f20615f8201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b5f6147b36026836130d2565b91506147be82614759565b604082019050919050565b5f6020820190508181035f8301526147e0816147a7565b9050919050565b7f4552433732313a206f70657261746f7220717565727920666f72206e6f6e65785f8201527f697374656e7420746f6b656e0000000000000000000000000000000000000000602082015250565b5f614841602c836130d2565b915061484c826147e7565b604082019050919050565b5f6020820190508181035f83015261486e81614835565b9050919050565b7f4552433732313a207472616e73666572206f6620746f6b656e207468617420695f8201527f73206e6f74206f776e0000000000000000000000000000000000000000000000602082015250565b5f6148cf6029836130d2565b91506148da82614875565b604082019050919050565b5f6020820190508181035f8301526148fc816148c3565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f206164645f8201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b5f61495d6024836130d2565b915061496882614903565b604082019050919050565b5f6020820190508181035f83015261498a81614951565b9050919050565b5f61499b82613158565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036149cd576149cc613bb3565b5b600182019050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f614a0f82613158565b9150614a1a83613158565b925082614a2a57614a296149d8565b5b828204905092915050565b5f614a3f82613158565b9150614a4a83613158565b925082614a5a57614a596149d8565b5b828206905092915050565b7f4552433732313a207472616e7366657220746f206e6f6e2045524337323152655f8201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b5f614abf6032836130d2565b9150614aca82614a65565b604082019050919050565b5f6020820190508181035f830152614aec81614ab3565b9050919050565b5f81519050919050565b5f82825260208201905092915050565b5f614b1782614af3565b614b218185614afd565b9350614b318185602086016130e2565b614b3a816130f0565b840191505092915050565b5f608082019050614b585f8301876131e6565b614b6560208301866131e6565b614b726040830185613276565b8181036060830152614b848184614b0d565b905095945050505050565b5f81519050614b9d81613040565b92915050565b5f60208284031215614bb857614bb761300d565b5b5f614bc584828501614b8f565b91505092915050565b7f4552433732313a206d696e7420746f20746865207a65726f20616464726573735f82015250565b5f614c026020836130d2565b9150614c0d82614bce565b602082019050919050565b5f6020820190508181035f830152614c2f81614bf6565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e746564000000005f82015250565b5f614c6a601c836130d2565b9150614c7582614c36565b602082019050919050565b5f6020820190508181035f830152614c9781614c5e565b905091905056fea26469706673582212203a459bb8f390945aad17b6c4b2d99984329d09f9a01b219d9b6066e912294cee64736f6c634300081c00336080604052348015600e575f5ffd5b50335f5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550611c938061005b5f395ff3fe608060405234801561000f575f5ffd5b5060043610610034575f3560e01c80632b4ef78214610038578063c87b56dd14610056575b5f5ffd5b610040610086565b60405161004d9190610a05565b60405180910390f35b610070600480360381019061006b9190610a62565b6100aa565b60405161007d9190610afd565b60405180910390f35b5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60605f6101505f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f3ce61ad856040518263ffffffff1660e01b81526004016101099190610b2c565b602060405180830381865afa158015610124573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906101489190610b7b565b60ff166106a2565b90505f6101f35f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638bc33af3866040518263ffffffff1660e01b81526004016101af9190610b2c565b602060405180830381865afa1580156101ca573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906101ee9190610bba565b6106a2565b90505f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166398cd96af866040518263ffffffff1660e01b815260040161024f9190610b2c565b5f60405180830381865afa158015610269573d5f5f3e3d5ffd5b505050506040513d5f823e3d601f19601f820116820180604052508101906102919190610d03565b90505f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e8dfdf04876040518263ffffffff1660e01b81526004016102ed9190610b2c565b5f60405180830381865afa158015610307573d5f5f3e3d5ffd5b505050506040513d5f823e3d601f19601f8201168201806040525081019061032f9190610d03565b90505f6103d25f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c3062ce7896040518263ffffffff1660e01b815260040161038e9190610b2c565b602060405180830381865afa1580156103a9573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103cd9190610bba565b6106a2565b90505f6103de886106a2565b90505f5f84511190505f828689898561042c576040518060400160405280600181526020017f2e0000000000000000000000000000000000000000000000000000000000000081525061044d565b8860405160200161043d9190610daa565b6040516020818303038152906040525b604051602001610461959493929190610e67565b60405160208183030381529060405290505f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639ddaf5aa8c6040518263ffffffff1660e01b81526004016104cc9190610b2c565b5f60405180830381865afa1580156104e6573d5f5f3e3d5ffd5b505050506040513d5f823e3d601f19601f8201168201806040525081019061050e9190610d03565b90505f8151036105665761054484888b604051602001610530939291906111e0565b6040516020818303038152906040526107fb565b6040516020016105549190611286565b60405160208183030381529060405290505b5f87604051602001610578919061133d565b6040516020818303038152906040528a60405160200161059891906113dd565b6040516020818303038152906040528a6040516020016105b8919061147d565b604051602081830303815290604052886040516020016105d89190611543565b604051602081830303815290604052876106005760405180602001604052805f815250610621565b8a60405160200161061191906115e3565b6040516020818303038152906040525b60405160200161063595949392919061165f565b604051602081830303815290604052905084888b60405160200161065b93929190611739565b604051602081830303815290604052838384846040516020016106829594939291906119bc565b6040516020818303038152906040529a5050505050505050505050919050565b60605f82036106e8576040518060400160405280600181526020017f300000000000000000000000000000000000000000000000000000000000000081525090506107f6565b5f8290505f5b5f821461071757808061070090611a75565b915050600a826107109190611ae9565b91506106ee565b5f8167ffffffffffffffff81111561073257610731610bed565b5b6040519080825280601f01601f1916602001820160405280156107645781602001600182028036833780820191505090505b5090505b5f85146107ef5760018261077c9190611b19565b9150600a8561078b9190611b4c565b60306107979190611b7c565b60f81b8183815181106107ad576107ac611baf565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a905350600a856107e89190611ae9565b9450610768565b8093505050505b919050565b60605f825190505f81036108205760405180602001604052805f815250915050610986565b5f60036002836108309190611b7c565b61083a9190611ae9565b60046108469190611bdc565b90505f6020826108569190611b7c565b67ffffffffffffffff81111561086f5761086e610bed565b5b6040519080825280601f01601f1916602001820160405280156108a15781602001600182028036833780820191505090505b5090505f604051806060016040528060408152602001611c1e60409139905060018101602083015f5b868110156109435760038101905062ffffff818a015116603f8160121c168401518060081b905060ff603f83600c1c1686015116810190508060081b905060ff603f8360061c1686015116810190508060081b905060ff603f831686015116810190508060e01b905080845260048401935050506108ca565b50600386066001811461095d576002811461096d57610978565b613d3d60f01b6002830352610978565b603d60f81b60018303525b508484525050819450505050505b919050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f819050919050565b5f6109cd6109c86109c38461098b565b6109aa565b61098b565b9050919050565b5f6109de826109b3565b9050919050565b5f6109ef826109d4565b9050919050565b6109ff816109e5565b82525050565b5f602082019050610a185f8301846109f6565b92915050565b5f604051905090565b5f5ffd5b5f5ffd5b5f819050919050565b610a4181610a2f565b8114610a4b575f5ffd5b50565b5f81359050610a5c81610a38565b92915050565b5f60208284031215610a7757610a76610a27565b5b5f610a8484828501610a4e565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f610acf82610a8d565b610ad98185610a97565b9350610ae9818560208601610aa7565b610af281610ab5565b840191505092915050565b5f6020820190508181035f830152610b158184610ac5565b905092915050565b610b2681610a2f565b82525050565b5f602082019050610b3f5f830184610b1d565b92915050565b5f60ff82169050919050565b610b5a81610b45565b8114610b64575f5ffd5b50565b5f81519050610b7581610b51565b92915050565b5f60208284031215610b9057610b8f610a27565b5b5f610b9d84828501610b67565b91505092915050565b5f81519050610bb481610a38565b92915050565b5f60208284031215610bcf57610bce610a27565b5b5f610bdc84828501610ba6565b91505092915050565b5f5ffd5b5f5ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b610c2382610ab5565b810181811067ffffffffffffffff82111715610c4257610c41610bed565b5b80604052505050565b5f610c54610a1e565b9050610c608282610c1a565b919050565b5f67ffffffffffffffff821115610c7f57610c7e610bed565b5b610c8882610ab5565b9050602081019050919050565b5f610ca7610ca284610c65565b610c4b565b905082815260208101848484011115610cc357610cc2610be9565b5b610cce848285610aa7565b509392505050565b5f82601f830112610cea57610ce9610be5565b5b8151610cfa848260208601610c95565b91505092915050565b5f60208284031215610d1857610d17610a27565b5b5f82015167ffffffffffffffff811115610d3557610d34610a2b565b5b610d4184828501610cd6565b91505092915050565b7f2e20496e636c75646564204d656d6f3a20000000000000000000000000000000815250565b5f81905092915050565b5f610d8482610a8d565b610d8e8185610d70565b9350610d9e818560208601610aa7565b80840191505092915050565b5f610db482610d4a565b601182019150610dc48284610d7a565b915081905092915050565b7f50726f6f66206f66204275726e20230000000000000000000000000000000000815250565b7f20666f722062696c6c3a20000000000000000000000000000000000000000000815250565b7f2c2069737375696e672000000000000000000000000000000000000000000000815250565b7f20625553442061742074696d657374616d702000000000000000000000000000815250565b5f610e7182610dcf565b600f82019150610e818288610d7a565b9150610e8c82610df5565b600b82019150610e9c8287610d7a565b9150610ea782610e1b565b600a82019150610eb78286610d7a565b9150610ec282610e41565b601382019150610ed28285610d7a565b9150610ede8284610d7a565b91508190509695505050505050565b7f3c73766720786d6c6e733d22687474703a2f2f7777772e77332e6f72672f32305f8201527f30302f737667222076696577426f783d223020302033323020313830223e3c7260208201527f65637420783d22302220793d2230222077696474683d2231303025222068656960408201527f6768743d2231303025222066696c6c3d2223303030223e3c2f726563743e3c7460608201527f65787420783d223530252220793d223433252220666f6e742d73697a653d223260808201527f307078222066696c6c3d22236666662220666f6e742d66616d696c793d226d6f60a08201527f6e6f73706163652220646f6d696e616e742d626173656c696e653d226d69646460c08201527f6c652220746578742d616e63686f723d226d6964646c65223e50726f6f66206f60e08201527f66204275726e202300000000000000000000000000000000000000000000000061010082015250565b5f61105361010883610d70565b915061105e82610eed565b61010882019050919050565b7f3c2f746578743e3c7465787420783d223530252220793d223537252220666f6e5f8201527f742d73697a653d2232307078222066696c6c3d22236666662220666f6e742d6660208201527f616d696c793d226d6f6e6f73706163652220646f6d696e616e742d626173656c60408201527f696e653d226d6964646c652220746578742d616e63686f723d226d6964646c6560608201527f223e000000000000000000000000000000000000000000000000000000000000608082015250565b5f611136608283610d70565b91506111418261106a565b608282019050919050565b7f20240000000000000000000000000000000000000000000000000000000000005f82015250565b5f611180600283610d70565b915061118b8261114c565b600282019050919050565b7f3c2f746578743e3c2f7376673e000000000000000000000000000000000000005f82015250565b5f6111ca600d83610d70565b91506111d582611196565b600d82019050919050565b5f6111ea82611046565b91506111f68286610d7a565b91506112018261112a565b915061120d8285610d7a565b915061121882611174565b91506112248284610d7a565b915061122f826111be565b9150819050949350505050565b7f646174613a696d6167652f7376672b786d6c3b6261736536342c0000000000005f82015250565b5f611270601a83610d70565b915061127b8261123c565b601a82019050919050565b5f61129082611264565b915061129c8284610d7a565b915081905092915050565b7f7b202274726169745f74797065223a202253657269616c222c202276616c75655f8201527f223a202200000000000000000000000000000000000000000000000000000000602082015250565b5f611301602483610d70565b915061130c826112a7565b602482019050919050565b7f22207d2c00000000000000000000000000000000000000000000000000000000815250565b5f611347826112f5565b91506113538284610d7a565b915061135e82611317565b60048201915081905092915050565b7f7b202274726169745f74797065223a202244656e6f6d696e6174696f6e222c205f8201527f2276616c7565223a202200000000000000000000000000000000000000000000602082015250565b5f6113c7602a83610d70565b91506113d28261136d565b602a82019050919050565b5f6113e7826113bb565b91506113f38284610d7a565b91506113fe82611317565b60048201915081905092915050565b7f7b202274726169745f74797065223a20224275726e6564206174222c202276615f8201527f6c7565223a202200000000000000000000000000000000000000000000000000602082015250565b5f611467602783610d70565b91506114728261140d565b602782019050919050565b5f6114878261145b565b91506114938284610d7a565b915061149e82611317565b60048201915081905092915050565b7f7b202274726169745f74797065223a202253657373696f6e204944222c2022765f8201527f616c7565223a2022000000000000000000000000000000000000000000000000602082015250565b5f611507602883610d70565b9150611512826114ad565b602882019050919050565b7f22207d0000000000000000000000000000000000000000000000000000000000815250565b5f61154d826114fb565b91506115598284610d7a565b91506115648261151d565b60038201915081905092915050565b7f2c7b202274726169745f74797065223a20224275726e204d656d6f222c2022765f8201527f616c7565223a2022000000000000000000000000000000000000000000000000602082015250565b5f6115cd602883610d70565b91506115d882611573565b602882019050919050565b5f6115ed826115c1565b91506115f98284610d7a565b91506116048261151d565b60038201915081905092915050565b7f5b00000000000000000000000000000000000000000000000000000000000000815250565b7f5d00000000000000000000000000000000000000000000000000000000000000815250565b5f61166982611613565b6001820191506116798288610d7a565b91506116858287610d7a565b91506116918286610d7a565b915061169d8285610d7a565b91506116a98284610d7a565b91506116b482611639565b6001820191508190509695505050505050565b7f2028000000000000000000000000000000000000000000000000000000000000815250565b7f2c20240000000000000000000000000000000000000000000000000000000000815250565b7f2900000000000000000000000000000000000000000000000000000000000000815250565b5f6117448286610d7a565b915061174f826116c7565b60028201915061175f8285610d7a565b915061176a826116ed565b60038201915061177a8284610d7a565b915061178582611713565b600182019150819050949350505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b757466382c7b226e616d5f8201527f65223a202250726f6f66206f66204275726e2023000000000000000000000000602082015250565b5f6117f0603483610d70565b91506117fb82611796565b603482019050919050565b7f222c20226465736372697074696f6e223a2022000000000000000000000000005f82015250565b5f61183a601383610d70565b915061184582611806565b601382019050919050565b7f222c2022696d616765223a2022000000000000000000000000000000000000005f82015250565b5f611884600d83610d70565b915061188f82611850565b600d82019050919050565b5f81519050919050565b5f81905092915050565b5f6118b88261189a565b6118c281856118a4565b93506118d2818560208601610aa7565b80840191505092915050565b7f222c2022616e696d6174696f6e5f75726c223a202200000000000000000000005f82015250565b5f611912601583610d70565b915061191d826118de565b601582019050919050565b7f222c202261747472696275746573223a000000000000000000000000000000005f82015250565b5f61195c601083610d70565b915061196782611928565b601082019050919050565b7f7d000000000000000000000000000000000000000000000000000000000000005f82015250565b5f6119a6600183610d70565b91506119b182611972565b600182019050919050565b5f6119c6826117e4565b91506119d28288610d7a565b91506119dd8261182e565b91506119e98287610d7a565b91506119f482611878565b9150611a0082866118ae565b9150611a0b82611906565b9150611a1782856118ae565b9150611a2282611950565b9150611a2e8284610d7a565b9150611a398261199a565b91508190509695505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f611a7f82610a2f565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611ab157611ab0611a48565b5b600182019050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f611af382610a2f565b9150611afe83610a2f565b925082611b0e57611b0d611abc565b5b828204905092915050565b5f611b2382610a2f565b9150611b2e83610a2f565b9250828203905081811115611b4657611b45611a48565b5b92915050565b5f611b5682610a2f565b9150611b6183610a2f565b925082611b7157611b70611abc565b5b828206905092915050565b5f611b8682610a2f565b9150611b9183610a2f565b9250828201905080821115611ba957611ba8611a48565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f611be682610a2f565b9150611bf183610a2f565b9250828202611bff81610a2f565b91508282048414831517611c1657611c15611a48565b5b509291505056fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa2646970667358221220069c705c4a98c772316bc62943a1577edaff35f6adc002d0f96e3763e337967764736f6c634300081c0033646174613a6170706c69636174696f6e2f6a736f6e3b757466382c7b226e616d65223a2250726f6f66206f66204275726e20286255534429227d
Deployed Bytecode
0x608060405234801561000f575f5ffd5b5060043610610251575f3560e01c80637e5b1e2411610144578063c3062ce7116100c1578063e985e9c511610085578063e985e9c51461072f578063eac989f81461075f578063f2fde38b1461077d578063f3ce61ad14610799578063f93e4ec8146107c9578063f9f3d0d9146107e557610251565b8063c3062ce714610665578063c87b56dd14610695578063d3fc9864146106c5578063e8a3d485146106e1578063e8dfdf04146106ff57610251565b8063997fe50711610108578063997fe507146105d75780639ddaf5aa146105f3578063a22cb46514610623578063a547b48e1461063f578063b88d4fde1461064957610251565b80637e5b1e241461051f5780638bc33af31461053b5780638da5cb5b1461056b57806395d89b411461058957806398cd96af146105a757610251565b806342966c68116101d25780636c1a1779116101965780636c1a17791461047b5780636dbf6e3b146104975780636f5db0b5146104c757806370a08231146104e5578063715018a61461051557610251565b806342966c68146103b157806343470a89146103cd5780634f558e79146103fd5780635213f7211461042d5780636352211e1461044b57610251565b806323b872dd1161021957806323b872dd1461030d5780632583f5361461032957806339920528146103595780633ca5b2341461037757806342842e0e1461039557610251565b806301ffc9a71461025557806306fdde0314610285578063081812fc146102a3578063095ea7b3146102d357806318160ddd146102ef575b5f5ffd5b61026f600480360381019061026a919061306a565b610801565b60405161027c91906130af565b60405180910390f35b61028d610861565b60405161029a9190613138565b60405180910390f35b6102bd60048036038101906102b8919061318b565b6108f0565b6040516102ca91906131f5565b60405180910390f35b6102ed60048036038101906102e89190613238565b610971565b005b6102f7610a87565b6040516103049190613285565b60405180910390f35b6103276004803603810190610322919061329e565b610a9d565b005b610343600480360381019061033e919061341a565b610afd565b60405161035091906130af565b60405180910390f35b610361610b32565b60405161036e9190613285565b60405180910390f35b61037f610b38565b60405161038c91906134bc565b60405180910390f35b6103af60048036038101906103aa919061329e565b610b5d565b005b6103cb60048036038101906103c6919061318b565b610b7c565b005b6103e760048036038101906103e2919061318b565b610d75565b6040516103f491906131f5565b60405180910390f35b6104176004803603810190610412919061318b565b610da5565b60405161042491906130af565b60405180910390f35b610435610db6565b6040516104429190613285565b60405180910390f35b6104656004803603810190610460919061318b565b610dbc565b60405161047291906131f5565b60405180910390f35b610495600480360381019061049091906134d5565b610e68565b005b6104b160048036038101906104ac919061318b565b610fa6565b6040516104be9190613285565b60405180910390f35b6104cf610fc6565b6040516104dc9190613285565b60405180910390f35b6104ff60048036038101906104fa91906134d5565b610fd2565b60405161050c9190613285565b60405180910390f35b61051d611086565b005b6105396004803603810190610534919061355d565b61110d565b005b6105556004803603810190610550919061318b565b6111cb565b6040516105629190613285565b60405180910390f35b6105736111e0565b60405161058091906131f5565b60405180910390f35b610591611208565b60405161059e9190613138565b60405180910390f35b6105c160048036038101906105bc919061318b565b611298565b6040516105ce9190613138565b60405180910390f35b6105f160048036038101906105ec91906135fd565b611333565b005b61060d6004803603810190610608919061318b565b61157b565b60405161061a9190613138565b60405180910390f35b61063d600480360381019061063891906136d7565b611616565b005b610647611791565b005b610663600480360381019061065e91906137b3565b611925565b005b61067f600480360381019061067a919061318b565b611987565b60405161068c9190613285565b60405180910390f35b6106af60048036038101906106aa919061318b565b6119f5565b6040516106bc9190613138565b60405180910390f35b6106df60048036038101906106da9190613833565b611a9a565b005b6106e9611ccb565b6040516106f69190613138565b60405180910390f35b6107196004803603810190610714919061318b565b611d5b565b6040516107269190613138565b60405180910390f35b610749600480360381019061074491906138a4565b611df6565b60405161075691906130af565b60405180910390f35b610767611e84565b6040516107749190613902565b60405180910390f35b610797600480360381019061079291906134d5565b611ea9565b005b6107b360048036038101906107ae919061318b565b611f9f565b6040516107c09190613936565b60405180910390f35b6107e360048036038101906107de919061394f565b611fbc565b005b6107ff60048036038101906107fa919061394f565b61214e565b005b5f634906490660e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061085a575061085982612317565b5b9050919050565b60605f805461086f906139d9565b80601f016020809104026020016040519081016040528092919081815260200182805461089b906139d9565b80156108e65780601f106108bd576101008083540402835291602001916108e6565b820191905f5260205f20905b8154815290600101906020018083116108c957829003601f168201915b5050505050905090565b5f6108fa826123f8565b610939576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161093090613a79565b60405180910390fd5b60045f8381526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b5f61097b82610dbc565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036109eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109e290613b07565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610a0a612460565b73ffffffffffffffffffffffffffffffffffffffff161480610a395750610a3881610a33612460565b611df6565b5b610a78576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a6f90613b95565b60405180910390fd5b610a828383612467565b505050565b5f600954600854610a989190613be0565b905090565b610aae610aa8612460565b8261251d565b610aed576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ae490613c83565b60405180910390fd5b610af88383836125f9565b505050565b6011818051602081018201805184825260208301602085012081835280955050505050505f915054906101000a900460ff1681565b60085481565b60075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610b7783838360405180602001604052805f815250611925565b505050565b610b86338261251d565b610bc5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bbc90613d11565b60405180910390fd5b5f670de0b6b3a7640000600c5f8481526020019081526020015f205f9054906101000a900460ff1660ff16610bfa9190613d2f565b905060075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166379cc6790610c4284610dbc565b836040518363ffffffff1660e01b8152600401610c60929190613d70565b5f604051808303815f87803b158015610c77575f5ffd5b505af1158015610c89573d5f5f3e3d5ffd5b50505050610c9682610dbc565b60105f8481526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600160095f828254610cf69190613d97565b92505081905550610d0682612849565b7f49995e5dd6158cf69ad3e9777c46755a1a826a446c6416992167462dad033b2a60105f8481526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff168383604051610d6993929190613dca565b60405180910390a15050565b6010602052805f5260405f205f915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f610daf826123f8565b9050919050565b60095481565b5f5f60025f8481526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610e5f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e5690613e6f565b60405180910390fd5b80915050919050565b60075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ed2573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ef69190613ea1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610f63576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f5a90613f16565b60405180910390fd5b80600a5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60128181548110610fb5575f80fd5b905f5260205f20015f915090505481565b5f601280549050905090565b5f5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611041576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161103890613fa4565b60405180910390fd5b60035f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b61108e612460565b73ffffffffffffffffffffffffffffffffffffffff166110ac6111e0565b73ffffffffffffffffffffffffffffffffffffffff1614611102576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110f99061400c565b60405180910390fd5b61110b5f612950565b565b611115612460565b73ffffffffffffffffffffffffffffffffffffffff166111336111e0565b73ffffffffffffffffffffffffffffffffffffffff1614611189576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111809061400c565b60405180910390fd5b81816013918261119a9291906141cb565b507fa5d4097edda6d87cb9329af83fb3712ef77eeb13738ffe43cc35a4ce305ad96260405160405180910390a15050565b600e602052805f5260405f205f915090505481565b5f60065f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060018054611217906139d9565b80601f0160208091040260200160405190810160405280929190818152602001828054611243906139d9565b801561128e5780601f106112655761010080835404028352916020019161128e565b820191905f5260205f20905b81548152906001019060200180831161127157829003601f168201915b5050505050905090565b600b602052805f5260405f205f9150905080546112b4906139d9565b80601f01602080910402602001604051908101604052809291908181526020018280546112e0906139d9565b801561132b5780601f106113025761010080835404028352916020019161132b565b820191905f5260205f20905b81548152906001019060200180831161130e57829003601f168201915b505050505081565b5f60075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166306133c656040518163ffffffff1660e01b8152600401602060405180830381865afa15801561139e573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113c291906142d3565b73ffffffffffffffffffffffffffffffffffffffff1663c365f4af6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561140a573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061142e9190613ea1565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461149e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161149590614348565b60405180910390fd5b5f5b878790508110156115365785856114cf8a8a858181106114c3576114c2614366565b5b90506020020135612a13565b86866040516020016114e59594939291906143f1565b604051602081830303815290604052600d5f8a8a8581811061150a57611509614366565b5b9050602002013581526020019081526020015f20908161152a9190614425565b508060010190506114a0565b507f6bd5c950a8d8df17f772f5af37cb3655737899cbf903264b9795592da439661c5f60085460405161156a92919061452d565b60405180910390a150505050505050565b600d602052805f5260405f205f915090508054611597906139d9565b80601f01602080910402602001604051908101604052809291908181526020018280546115c3906139d9565b801561160e5780601f106115e55761010080835404028352916020019161160e565b820191905f5260205f20905b8154815290600101906020018083116115f157829003601f168201915b505050505081565b61161e612460565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361168b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116829061459e565b60405180910390fd5b8060055f611697612460565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16611740612460565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161178591906130af565b60405180910390a35050565b5f60075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166306133c656040518163ffffffff1660e01b8152600401602060405180830381865afa1580156117fc573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061182091906142d3565b73ffffffffffffffffffffffffffffffffffffffff1663c365f4af6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611868573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061188c9190613ea1565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146118fc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118f390614348565b60405180910390fd5b601242908060018154018082558091505060019003905f5260205f20015f909190919091505550565b611936611930612460565b8361251d565b611975576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161196c90613c83565b60405180910390fd5b61198184848484612b6c565b50505050565b5f5f600e5f8481526020019081526020015f205490505f5b6012805490508110156119e557601281815481106119c0576119bf614366565b5b905f5260205f2001548210156119da5780925050506119f0565b80600101905061199f565b506012805490509150505b919050565b6060600a5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c87b56dd836040518263ffffffff1660e01b8152600401611a519190613285565b5f60405180830381865afa158015611a6b573d5f5f3e3d5ffd5b505050506040513d5f823e3d601f19601f82011682018060405250810190611a93919061462a565b9050919050565b60075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166306133c656040518163ffffffff1660e01b8152600401602060405180830381865afa158015611b04573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611b2891906142d3565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611b95576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b8c906146bb565b60405180910390fd5b60118282604051611ba79291906146d9565b90815260200160405180910390205f9054906101000a900460ff1615611c02576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bf99061473b565b60405180910390fd5b82600c5f60085481526020019081526020015f205f6101000a81548160ff021916908360ff1602179055508181600b5f60085481526020019081526020015f209182611c4f9291906141cb565b50600160118383604051611c649291906146d9565b90815260200160405180910390205f6101000a81548160ff02191690831515021790555042600e5f60085481526020019081526020015f2081905550611cac84600854612bc8565b600160085f828254611cbe9190613d97565b9250508190555050505050565b606060138054611cda906139d9565b80601f0160208091040260200160405190810160405280929190818152602001828054611d06906139d9565b8015611d515780601f10611d2857610100808354040283529160200191611d51565b820191905f5260205f20905b815481529060010190602001808311611d3457829003601f168201915b5050505050905090565b600f602052805f5260405f205f915090508054611d77906139d9565b80601f0160208091040260200160405190810160405280929190818152602001828054611da3906139d9565b8015611dee5780601f10611dc557610100808354040283529160200191611dee565b820191905f5260205f20905b815481529060010190602001808311611dd157829003601f168201915b505050505081565b5f60055f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b600a5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b611eb1612460565b73ffffffffffffffffffffffffffffffffffffffff16611ecf6111e0565b73ffffffffffffffffffffffffffffffffffffffff1614611f25576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f1c9061400c565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611f93576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f8a906147c9565b60405180910390fd5b611f9c81612950565b50565b600c602052805f5260405f205f915054906101000a900460ff1681565b5f60075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166306133c656040518163ffffffff1660e01b8152600401602060405180830381865afa158015612027573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061204b91906142d3565b73ffffffffffffffffffffffffffffffffffffffff1663c365f4af6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612093573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906120b79190613ea1565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612127576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161211e90614348565b60405180910390fd5b8282600f5f8781526020019081526020015f2091826121479291906141cb565b5050505050565b5f60075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166306133c656040518163ffffffff1660e01b8152600401602060405180830381865afa1580156121b9573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121dd91906142d3565b73ffffffffffffffffffffffffffffffffffffffff1663c365f4af6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612225573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906122499190613ea1565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146122b9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122b090614348565b60405180910390fd5b8282600d5f8781526020019081526020015f2091826122d99291906141cb565b507ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce7846040516123099190613285565b60405180910390a150505050565b5f7f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806123e157507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806123f157506123f082612be5565b5b9050919050565b5f5f73ffffffffffffffffffffffffffffffffffffffff1660025f8481526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b5f33905090565b8160045f8381526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff166124d783610dbc565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b5f612527826123f8565b612566576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161255d90614857565b60405180910390fd5b5f61257083610dbc565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614806125df57508373ffffffffffffffffffffffffffffffffffffffff166125c7846108f0565b73ffffffffffffffffffffffffffffffffffffffff16145b806125f057506125ef8185611df6565b5b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff1661261982610dbc565b73ffffffffffffffffffffffffffffffffffffffff161461266f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612666906148e5565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036126dd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126d490614973565b60405180910390fd5b6126e8838383612c4e565b6126f25f82612467565b600160035f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461273f9190613be0565b92505081905550600160035f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546127939190613d97565b925050819055508160025f8381526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b5f61285382610dbc565b9050612860815f84612c4e565b61286a5f83612467565b600160035f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546128b79190613be0565b9250508190555060025f8381526020019081526020015f205f6101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055815f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b5f60065f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160065f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60605f8203612a59576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050612b67565b5f8290505f5b5f8214612a88578080612a7190614991565b915050600a82612a819190614a05565b9150612a5f565b5f8167ffffffffffffffff811115612aa357612aa26132f6565b5b6040519080825280601f01601f191660200182016040528015612ad55781602001600182028036833780820191505090505b5090505b5f8514612b6057600182612aed9190613be0565b9150600a85612afc9190614a35565b6030612b089190613d97565b60f81b818381518110612b1e57612b1d614366565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a905350600a85612b599190614a05565b9450612ad9565b8093505050505b919050565b612b778484846125f9565b612b8384848484612c53565b612bc2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612bb990614ad5565b60405180910390fd5b50505050565b612be1828260405180602001604052805f815250612dd5565b5050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b505050565b5f612c738473ffffffffffffffffffffffffffffffffffffffff16612e2f565b15612dc8578373ffffffffffffffffffffffffffffffffffffffff1663150b7a02612c9c612460565b8786866040518563ffffffff1660e01b8152600401612cbe9493929190614b45565b6020604051808303815f875af1925050508015612cf957506040513d601f19601f82011682018060405250810190612cf69190614ba3565b60015b612d78573d805f8114612d27576040519150601f19603f3d011682016040523d82523d5f602084013e612d2c565b606091505b505f815103612d70576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d6790614ad5565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050612dcd565b600190505b949350505050565b612ddf8383612e40565b612deb5f848484612c53565b612e2a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e2190614ad5565b60405180910390fd5b505050565b5f5f823b90505f8111915050919050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612eae576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ea590614c18565b60405180910390fd5b612eb7816123f8565b15612ef7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612eee90614c80565b60405180910390fd5b612f025f8383612c4e565b600160035f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612f4f9190613d97565b925050819055508160025f8381526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff165f73ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b5f604051905090565b5f5ffd5b5f5ffd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61304981613015565b8114613053575f5ffd5b50565b5f8135905061306481613040565b92915050565b5f6020828403121561307f5761307e61300d565b5b5f61308c84828501613056565b91505092915050565b5f8115159050919050565b6130a981613095565b82525050565b5f6020820190506130c25f8301846130a0565b92915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f61310a826130c8565b61311481856130d2565b93506131248185602086016130e2565b61312d816130f0565b840191505092915050565b5f6020820190508181035f8301526131508184613100565b905092915050565b5f819050919050565b61316a81613158565b8114613174575f5ffd5b50565b5f8135905061318581613161565b92915050565b5f602082840312156131a05761319f61300d565b5b5f6131ad84828501613177565b91505092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6131df826131b6565b9050919050565b6131ef816131d5565b82525050565b5f6020820190506132085f8301846131e6565b92915050565b613217816131d5565b8114613221575f5ffd5b50565b5f813590506132328161320e565b92915050565b5f5f6040838503121561324e5761324d61300d565b5b5f61325b85828601613224565b925050602061326c85828601613177565b9150509250929050565b61327f81613158565b82525050565b5f6020820190506132985f830184613276565b92915050565b5f5f5f606084860312156132b5576132b461300d565b5b5f6132c286828701613224565b93505060206132d386828701613224565b92505060406132e486828701613177565b9150509250925092565b5f5ffd5b5f5ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61332c826130f0565b810181811067ffffffffffffffff8211171561334b5761334a6132f6565b5b80604052505050565b5f61335d613004565b90506133698282613323565b919050565b5f67ffffffffffffffff821115613388576133876132f6565b5b613391826130f0565b9050602081019050919050565b828183375f83830152505050565b5f6133be6133b98461336e565b613354565b9050828152602081018484840111156133da576133d96132f2565b5b6133e584828561339e565b509392505050565b5f82601f830112613401576134006132ee565b5b81356134118482602086016133ac565b91505092915050565b5f6020828403121561342f5761342e61300d565b5b5f82013567ffffffffffffffff81111561344c5761344b613011565b5b613458848285016133ed565b91505092915050565b5f819050919050565b5f61348461347f61347a846131b6565b613461565b6131b6565b9050919050565b5f6134958261346a565b9050919050565b5f6134a68261348b565b9050919050565b6134b68161349c565b82525050565b5f6020820190506134cf5f8301846134ad565b92915050565b5f602082840312156134ea576134e961300d565b5b5f6134f784828501613224565b91505092915050565b5f5ffd5b5f5ffd5b5f5f83601f84011261351d5761351c6132ee565b5b8235905067ffffffffffffffff81111561353a57613539613500565b5b60208301915083600182028301111561355657613555613504565b5b9250929050565b5f5f602083850312156135735761357261300d565b5b5f83013567ffffffffffffffff8111156135905761358f613011565b5b61359c85828601613508565b92509250509250929050565b5f5f83601f8401126135bd576135bc6132ee565b5b8235905067ffffffffffffffff8111156135da576135d9613500565b5b6020830191508360208202830111156135f6576135f5613504565b5b9250929050565b5f5f5f5f5f5f606087890312156136175761361661300d565b5b5f87013567ffffffffffffffff81111561363457613633613011565b5b61364089828a016135a8565b9650965050602087013567ffffffffffffffff81111561366357613662613011565b5b61366f89828a01613508565b9450945050604087013567ffffffffffffffff81111561369257613691613011565b5b61369e89828a01613508565b92509250509295509295509295565b6136b681613095565b81146136c0575f5ffd5b50565b5f813590506136d1816136ad565b92915050565b5f5f604083850312156136ed576136ec61300d565b5b5f6136fa85828601613224565b925050602061370b858286016136c3565b9150509250929050565b5f67ffffffffffffffff82111561372f5761372e6132f6565b5b613738826130f0565b9050602081019050919050565b5f61375761375284613715565b613354565b905082815260208101848484011115613773576137726132f2565b5b61377e84828561339e565b509392505050565b5f82601f83011261379a576137996132ee565b5b81356137aa848260208601613745565b91505092915050565b5f5f5f5f608085870312156137cb576137ca61300d565b5b5f6137d887828801613224565b94505060206137e987828801613224565b93505060406137fa87828801613177565b925050606085013567ffffffffffffffff81111561381b5761381a613011565b5b61382787828801613786565b91505092959194509250565b5f5f5f5f6060858703121561384b5761384a61300d565b5b5f61385887828801613224565b945050602061386987828801613177565b935050604085013567ffffffffffffffff81111561388a57613889613011565b5b61389687828801613508565b925092505092959194509250565b5f5f604083850312156138ba576138b961300d565b5b5f6138c785828601613224565b92505060206138d885828601613224565b9150509250929050565b5f6138ec8261348b565b9050919050565b6138fc816138e2565b82525050565b5f6020820190506139155f8301846138f3565b92915050565b5f60ff82169050919050565b6139308161391b565b82525050565b5f6020820190506139495f830184613927565b92915050565b5f5f5f604084860312156139665761396561300d565b5b5f61397386828701613177565b935050602084013567ffffffffffffffff81111561399457613993613011565b5b6139a086828701613508565b92509250509250925092565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806139f057607f821691505b602082108103613a0357613a026139ac565b5b50919050565b7f4552433732313a20617070726f76656420717565727920666f72206e6f6e65785f8201527f697374656e7420746f6b656e0000000000000000000000000000000000000000602082015250565b5f613a63602c836130d2565b9150613a6e82613a09565b604082019050919050565b5f6020820190508181035f830152613a9081613a57565b9050919050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e655f8201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b5f613af16021836130d2565b9150613afc82613a97565b604082019050919050565b5f6020820190508181035f830152613b1e81613ae5565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f775f8201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000602082015250565b5f613b7f6038836130d2565b9150613b8a82613b25565b604082019050919050565b5f6020820190508181035f830152613bac81613b73565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f613bea82613158565b9150613bf583613158565b9250828203905081811115613c0d57613c0c613bb3565b5b92915050565b7f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f5f8201527f776e6572206e6f7220617070726f766564000000000000000000000000000000602082015250565b5f613c6d6031836130d2565b9150613c7882613c13565b604082019050919050565b5f6020820190508181035f830152613c9a81613c61565b9050919050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e655f8201527f72206f7220617070726f76656400000000000000000000000000000000000000602082015250565b5f613cfb602d836130d2565b9150613d0682613ca1565b604082019050919050565b5f6020820190508181035f830152613d2881613cef565b9050919050565b5f613d3982613158565b9150613d4483613158565b9250828202613d5281613158565b91508282048414831517613d6957613d68613bb3565b5b5092915050565b5f604082019050613d835f8301856131e6565b613d906020830184613276565b9392505050565b5f613da182613158565b9150613dac83613158565b9250828201905080821115613dc457613dc3613bb3565b5b92915050565b5f606082019050613ddd5f8301866131e6565b613dea6020830185613276565b613df76040830184613276565b949350505050565b7f4552433732313a206f776e657220717565727920666f72206e6f6e65786973745f8201527f656e7420746f6b656e0000000000000000000000000000000000000000000000602082015250565b5f613e596029836130d2565b9150613e6482613dff565b604082019050919050565b5f6020820190508181035f830152613e8681613e4d565b9050919050565b5f81519050613e9b8161320e565b92915050565b5f60208284031215613eb657613eb561300d565b5b5f613ec384828501613e8d565b91505092915050565b7f43616c6c6572206973206e6f742042555344204f776e657200000000000000005f82015250565b5f613f006018836130d2565b9150613f0b82613ecc565b602082019050919050565b5f6020820190508181035f830152613f2d81613ef4565b9050919050565b7f4552433732313a2062616c616e636520717565727920666f7220746865207a655f8201527f726f206164647265737300000000000000000000000000000000000000000000602082015250565b5f613f8e602a836130d2565b9150613f9982613f34565b604082019050919050565b5f6020820190508181035f830152613fbb81613f82565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65725f82015250565b5f613ff66020836130d2565b915061400182613fc2565b602082019050919050565b5f6020820190508181035f83015261402381613fea565b9050919050565b5f82905092915050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026140907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82614055565b61409a8683614055565b95508019841693508086168417925050509392505050565b5f6140cc6140c76140c284613158565b613461565b613158565b9050919050565b5f819050919050565b6140e5836140b2565b6140f96140f1826140d3565b848454614061565b825550505050565b5f5f905090565b614110614101565b61411b8184846140dc565b505050565b5b8181101561413e576141335f82614108565b600181019050614121565b5050565b601f8211156141835761415481614034565b61415d84614046565b8101602085101561416c578190505b61418061417885614046565b830182614120565b50505b505050565b5f82821c905092915050565b5f6141a35f1984600802614188565b1980831691505092915050565b5f6141bb8383614194565b9150826002028217905092915050565b6141d5838361402a565b67ffffffffffffffff8111156141ee576141ed6132f6565b5b6141f882546139d9565b614203828285614142565b5f601f831160018114614230575f841561421e578287013590505b61422885826141b0565b86555061428f565b601f19841661423e86614034565b5f5b8281101561426557848901358255600182019150602085019450602081019050614240565b86831015614282578489013561427e601f891682614194565b8355505b6001600288020188555050505b50505050505050565b5f6142a2826131d5565b9050919050565b6142b281614298565b81146142bc575f5ffd5b50565b5f815190506142cd816142a9565b92915050565b5f602082840312156142e8576142e761300d565b5b5f6142f5848285016142bf565b91505092915050565b7f43616c6c6572206973206e6f74204275726e204167656e7400000000000000005f82015250565b5f6143326018836130d2565b915061433d826142fe565b602082019050919050565b5f6020820190508181035f83015261435f81614326565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f81905092915050565b5f6143a88385614393565b93506143b583858461339e565b82840190509392505050565b5f6143cb826130c8565b6143d58185614393565b93506143e58185602086016130e2565b80840191505092915050565b5f6143fd82878961439d565b915061440982866143c1565b915061441682848661439d565b91508190509695505050505050565b61442e826130c8565b67ffffffffffffffff811115614447576144466132f6565b5b61445182546139d9565b61445c828285614142565b5f60209050601f83116001811461448d575f841561447b578287015190505b61448585826141b0565b8655506144ec565b601f19841661449b86614034565b5f5b828110156144c25784890151825560018201915060208501945060208101905061449d565b868310156144df57848901516144db601f891682614194565b8355505b6001600288020188555050505b505050505050565b5f819050919050565b5f61451761451261450d846144f4565b613461565b613158565b9050919050565b614527816144fd565b82525050565b5f6040820190506145405f83018561451e565b61454d6020830184613276565b9392505050565b7f4552433732313a20617070726f766520746f2063616c6c6572000000000000005f82015250565b5f6145886019836130d2565b915061459382614554565b602082019050919050565b5f6020820190508181035f8301526145b58161457c565b9050919050565b5f6145ce6145c98461336e565b613354565b9050828152602081018484840111156145ea576145e96132f2565b5b6145f58482856130e2565b509392505050565b5f82601f830112614611576146106132ee565b5b81516146218482602086016145bc565b91505092915050565b5f6020828403121561463f5761463e61300d565b5b5f82015167ffffffffffffffff81111561465c5761465b613011565b5b614668848285016145fd565b91505092915050565b7f496e76616c6964206d696e7465720000000000000000000000000000000000005f82015250565b5f6146a5600e836130d2565b91506146b082614671565b602082019050919050565b5f6020820190508181035f8301526146d281614699565b9050919050565b5f6146e582848661439d565b91508190509392505050565b7f53657269616c20616c72656164792075736564000000000000000000000000005f82015250565b5f6147256013836130d2565b9150614730826146f1565b602082019050919050565b5f6020820190508181035f83015261475281614719565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f20615f8201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b5f6147b36026836130d2565b91506147be82614759565b604082019050919050565b5f6020820190508181035f8301526147e0816147a7565b9050919050565b7f4552433732313a206f70657261746f7220717565727920666f72206e6f6e65785f8201527f697374656e7420746f6b656e0000000000000000000000000000000000000000602082015250565b5f614841602c836130d2565b915061484c826147e7565b604082019050919050565b5f6020820190508181035f83015261486e81614835565b9050919050565b7f4552433732313a207472616e73666572206f6620746f6b656e207468617420695f8201527f73206e6f74206f776e0000000000000000000000000000000000000000000000602082015250565b5f6148cf6029836130d2565b91506148da82614875565b604082019050919050565b5f6020820190508181035f8301526148fc816148c3565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f206164645f8201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b5f61495d6024836130d2565b915061496882614903565b604082019050919050565b5f6020820190508181035f83015261498a81614951565b9050919050565b5f61499b82613158565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036149cd576149cc613bb3565b5b600182019050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f614a0f82613158565b9150614a1a83613158565b925082614a2a57614a296149d8565b5b828204905092915050565b5f614a3f82613158565b9150614a4a83613158565b925082614a5a57614a596149d8565b5b828206905092915050565b7f4552433732313a207472616e7366657220746f206e6f6e2045524337323152655f8201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b5f614abf6032836130d2565b9150614aca82614a65565b604082019050919050565b5f6020820190508181035f830152614aec81614ab3565b9050919050565b5f81519050919050565b5f82825260208201905092915050565b5f614b1782614af3565b614b218185614afd565b9350614b318185602086016130e2565b614b3a816130f0565b840191505092915050565b5f608082019050614b585f8301876131e6565b614b6560208301866131e6565b614b726040830185613276565b8181036060830152614b848184614b0d565b905095945050505050565b5f81519050614b9d81613040565b92915050565b5f60208284031215614bb857614bb761300d565b5b5f614bc584828501614b8f565b91505092915050565b7f4552433732313a206d696e7420746f20746865207a65726f20616464726573735f82015250565b5f614c026020836130d2565b9150614c0d82614bce565b602082019050919050565b5f6020820190508181035f830152614c2f81614bf6565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e746564000000005f82015250565b5f614c6a601c836130d2565b9150614c7582614c36565b602082019050919050565b5f6020820190508181035f830152614c9781614c5e565b905091905056fea26469706673582212203a459bb8f390945aad17b6c4b2d99984329d09f9a01b219d9b6066e912294cee64736f6c634300081c0033
Deployed Bytecode Sourcemap
508:5371:4:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5329:190;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;24508:98:3;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;26019:217;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;25557:401;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;2090:99:4;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;26883:330:3;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;1381:41:4;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;572:26;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;552:16;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;27279:179:3;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;4637:402:4;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;1281:43;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1927:96;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;602:27;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;24211:235:3;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;5175:149:4;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;1427:28;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2399:91;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;23949:205:3;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;21789:92;;;:::i;:::-;;5744:133:4;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;1054:45;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;21157:85:3;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;24670:102;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;730:41:4;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3251:310;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;939:40;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;26303:290:3;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;2878:89:4;;;:::i;:::-;;27524:320:3;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;2547:249:4;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;5044:127;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3976:464;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;5649:91;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1159:39;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;26659:162:3;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;633:25:4;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;22030:189:3;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;842:46:4;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3593:107;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;3036:145;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;5329:190;5422:4;5463:10;5456:18;;5441:33;;;:11;:33;;;;:73;;;;5478:36;5502:11;5478:23;:36::i;:::-;5441:73;5434:80;;5329:190;;;:::o;24508:98:3:-;24562:13;24594:5;24587:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24508:98;:::o;26019:217::-;26095:7;26122:16;26130:7;26122;:16::i;:::-;26114:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;26205:15;:24;26221:7;26205:24;;;;;;;;;;;;;;;;;;;;;26198:31;;26019:217;;;:::o;25557:401::-;25637:13;25653:23;25668:7;25653:14;:23::i;:::-;25637:39;;25700:5;25694:11;;:2;:11;;;25686:57;;;;;;;;;;;;:::i;:::-;;;;;;;;;25791:5;25775:21;;:12;:10;:12::i;:::-;:21;;;:62;;;;25800:37;25817:5;25824:12;:10;:12::i;:::-;25800:16;:37::i;:::-;25775:62;25754:165;;;;;;;;;;;;:::i;:::-;;;;;;;;;25930:21;25939:2;25943:7;25930:8;:21::i;:::-;25627:331;25557:401;;:::o;2090:99:4:-;2136:7;2172:12;;2158:11;;:26;;;;:::i;:::-;2151:33;;2090:99;:::o;26883:330:3:-;27072:41;27091:12;:10;:12::i;:::-;27105:7;27072:18;:41::i;:::-;27064:103;;;;;;;;;;;;:::i;:::-;;;;;;;;;27178:28;27188:4;27194:2;27198:7;27178:9;:28::i;:::-;26883:330;;;:::o;1381:41:4:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;572:26::-;;;;:::o;552:16::-;;;;;;;;;;;;;:::o;27279:179:3:-;27412:39;27429:4;27435:2;27439:7;27412:39;;;;;;;;;;;;:16;:39::i;:::-;27279:179;;;:::o;4637:402:4:-;4697:39;4716:10;4728:7;4697:18;:39::i;:::-;4689:97;;;;;;;;;;;;:::i;:::-;;;;;;;;;4793:14;4844:7;4818:13;:22;4832:7;4818:22;;;;;;;;;;;;;;;;;;;;;4810:31;;:41;;;;:::i;:::-;4793:58;;4857:4;;;;;;;;;;;:13;;;4871:16;4879:7;4871;:16::i;:::-;4889:6;4857:39;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4922:16;4930:7;4922;:16::i;:::-;4902:8;:17;4911:7;4902:17;;;;;;;;;;;;:36;;;;;;;;;;;;;;;;;;4961:1;4945:12;;:17;;;;;;;:::i;:::-;;;;;;;;4968:14;4974:7;4968:5;:14::i;:::-;4994:40;4999:8;:17;5008:7;4999:17;;;;;;;;;;;;;;;;;;;;;5018:7;5027:6;4994:40;;;;;;;;:::i;:::-;;;;;;;;4683:356;4637:402;:::o;1281:43::-;;;;;;;;;;;;;;;;;;;;;;:::o;1927:96::-;1983:4;2002:16;2010:7;2002;:16::i;:::-;1995:23;;1927:96;;;:::o;602:27::-;;;;:::o;24211:235:3:-;24283:7;24302:13;24318:7;:16;24326:7;24318:16;;;;;;;;;;;;;;;;;;;;;24302:32;;24369:1;24352:19;;:5;:19;;;24344:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;24434:5;24427:12;;;24211:235;;;:::o;5175:149:4:-;5244:4;;;;;;;;;;;:10;;;:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5230:26;;:10;:26;;;5222:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;5312:6;5291:3;;:28;;;;;;;;;;;;;;;;;;5175:149;:::o;1427:28::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;2399:91::-;2445:7;2467:11;:18;;;;2460:25;;2399:91;:::o;23949:205:3:-;24021:7;24065:1;24048:19;;:5;:19;;;24040:74;;;;;;;;;;;;:::i;:::-;;;;;;;;;24131:9;:16;24141:5;24131:16;;;;;;;;;;;;;;;;24124:23;;23949:205;;;:::o;21789:92::-;21380:12;:10;:12::i;:::-;21369:23;;:7;:5;:7::i;:::-;:23;;;21361:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;21853:21:::1;21871:1;21853:9;:21::i;:::-;21789:92::o:0;5744:133:4:-;21380:12:3;:10;:12::i;:::-;21369:23;;:7;:5;:7::i;:::-;:23;;;21361:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;5835:6:4::1;;5820:12;:21;;;;;;;:::i;:::-;;5852:20;;;;;;;;;;5744:133:::0;;:::o;1054:45::-;;;;;;;;;;;;;;;;;:::o;21157:85:3:-;21203:7;21229:6;;;;;;;;;;;21222:13;;21157:85;:::o;24670:102::-;24726:13;24758:7;24751:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24670:102;:::o;730:41:4:-;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;3251:310::-;2219:17;2239:4;;;;;;;;;;;:13;;;:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:25;;;:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2219:47;;2294:9;2280:23;;:10;:23;;;2272:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;3379:9:::1;3374:137;3394:8;;:15;;3390:1;:19;3374:137;;;3460:7;;3469:29;3486:8;;3495:1;3486:11;;;;;;;:::i;:::-;;;;;;;;3469:16;:29::i;:::-;3500:3;;3446:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;3424:6;:19;3431:8;;3440:1;3431:11;;;;;;;:::i;:::-;;;;;;;;3424:19;;;;;;;;;;;:80;;;;;;:::i;:::-;;3411:3;;;;;3374:137;;;;3521:35;3541:1;3544:11;;3521:35;;;;;;;:::i;:::-;;;;;;;;2213:131:::0;3251:310;;;;;;:::o;939:40::-;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;26303:290:3:-;26417:12;:10;:12::i;:::-;26405:24;;:8;:24;;;26397:62;;;;;;;;;;;;:::i;:::-;;;;;;;;;26515:8;26470:18;:32;26489:12;:10;:12::i;:::-;26470:32;;;;;;;;;;;;;;;:42;26503:8;26470:42;;;;;;;;;;;;;;;;:53;;;;;;;;;;;;;;;;;;26567:8;26538:48;;26553:12;:10;:12::i;:::-;26538:48;;;26577:8;26538:48;;;;;;:::i;:::-;;;;;;;;26303:290;;:::o;2878:89:4:-;2219:17;2239:4;;;;;;;;;;;:13;;;:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:25;;;:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2219:47;;2294:9;2280:23;;:10;:23;;;2272:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;2929:11:::1;2946:15;2929:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2213:131:::0;2878:89::o;27524:320:3:-;27693:41;27712:12;:10;:12::i;:::-;27726:7;27693:18;:41::i;:::-;27685:103;;;;;;;;;;;;:::i;:::-;;;;;;;;;27798:39;27812:4;27818:2;27822:7;27831:5;27798:13;:39::i;:::-;27524:320;;;;:::o;2547:249:4:-;2613:7;2628:10;2641;:19;2652:7;2641:19;;;;;;;;;;;;2628:32;;2672:9;2667:93;2687:11;:18;;;;2683:1;:22;2667:93;;;2729:11;2741:1;2729:14;;;;;;;;:::i;:::-;;;;;;;;;;2724:2;:19;2720:33;;;2752:1;2745:8;;;;;;2720:33;2707:3;;;;;2667:93;;;;2773:11;:18;;;;2766:25;;;2547:249;;;;:::o;5044:127::-;5117:13;5145:3;;;;;;;;;;;:12;;;5158:7;5145:21;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5138:28;;5044:127;;;:::o;3976:464::-;4114:4;;;;;;;;;;;:13;;;:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4092:38;;:10;:38;;;4084:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;4164:10;4175:6;;4164:18;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;4163:19;4155:51;;;;;;;;;;;;:::i;:::-;;;;;;;;;4248:12;4213:13;:26;4227:11;;4213:26;;;;;;;;;;;;:48;;;;;;;;;;;;;;;;;;4290:6;;4267:7;:20;4275:11;;4267:20;;;;;;;;;;;:29;;;;;;;:::i;:::-;;4323:4;4302:10;4313:6;;4302:18;;;;;;;:::i;:::-;;;;;;;;;;;;;;:25;;;;;;;;;;;;;;;;;;4359:15;4333:10;:23;4344:11;;4333:23;;;;;;;;;;;:41;;;;4381:31;4391:7;4400:11;;4381:9;:31::i;:::-;4434:1;4419:11;;:16;;;;;;;:::i;:::-;;;;;;;;3976:464;;;;:::o;5649:91::-;5695:13;5723:12;5716:19;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5649:91;:::o;1159:39::-;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;26659:162:3:-;26756:4;26779:18;:25;26798:5;26779:25;;;;;;;;;;;;;;;:35;26805:8;26779:35;;;;;;;;;;;;;;;;;;;;;;;;;26772:42;;26659:162;;;;:::o;633:25:4:-;;;;;;;;;;;;;:::o;22030:189:3:-;21380:12;:10;:12::i;:::-;21369:23;;:7;:5;:7::i;:::-;:23;;;21361:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;22138:1:::1;22118:22;;:8;:22;;::::0;22110:73:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;22193:19;22203:8;22193:9;:19::i;:::-;22030:189:::0;:::o;842:46:4:-;;;;;;;;;;;;;;;;;;;;;;:::o;3593:107::-;2219:17;2239:4;;;;;;;;;;;:13;;;:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:25;;;:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2219:47;;2294:9;2280:23;;:10;:23;;;2272:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;3691:4:::1;;3674:5;:14;3680:7;3674:14;;;;;;;;;;;:21;;;;;;;:::i;:::-;;2213:131:::0;3593:107;;;:::o;3036:145::-;2219:17;2239:4;;;;;;;;;;;:13;;;:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:25;;;:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2219:47;;2294:9;2280:23;;:10;:23;;;2272:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;3137:5:::1;;3119:6;:15;3126:7;3119:15;;;;;;;;;;;:23;;;;;;;:::i;:::-;;3153;3168:7;3153:23;;;;;;:::i;:::-;;;;;;;;2213:131:::0;3036:145;;;:::o;23590:300:3:-;23692:4;23742:25;23727:40;;;:11;:40;;;;:104;;;;23798:33;23783:48;;;:11;:48;;;;23727:104;:156;;;;23847:36;23871:11;23847:23;:36::i;:::-;23727:156;23708:175;;23590:300;;;:::o;29316:125::-;29381:4;29432:1;29404:30;;:7;:16;29412:7;29404:16;;;;;;;;;;;;;;;;;;;;;:30;;;;29397:37;;29316:125;;;:::o;15379:96::-;15432:7;15458:10;15451:17;;15379:96;:::o;33167:171::-;33268:2;33241:15;:24;33257:7;33241:24;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;33323:7;33319:2;33285:46;;33294:23;33309:7;33294:14;:23::i;:::-;33285:46;;;;;;;;;;;;33167:171;;:::o;29599:344::-;29692:4;29716:16;29724:7;29716;:16::i;:::-;29708:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;29791:13;29807:23;29822:7;29807:14;:23::i;:::-;29791:39;;29859:5;29848:16;;:7;:16;;;:51;;;;29892:7;29868:31;;:20;29880:7;29868:11;:20::i;:::-;:31;;;29848:51;:87;;;;29903:32;29920:5;29927:7;29903:16;:32::i;:::-;29848:87;29840:96;;;29599:344;;;;:::o;32496:560::-;32650:4;32623:31;;:23;32638:7;32623:14;:23::i;:::-;:31;;;32615:85;;;;;;;;;;;;:::i;:::-;;;;;;;;;32732:1;32718:16;;:2;:16;;;32710:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;32786:39;32807:4;32813:2;32817:7;32786:20;:39::i;:::-;32887:29;32904:1;32908:7;32887:8;:29::i;:::-;32946:1;32927:9;:15;32937:4;32927:15;;;;;;;;;;;;;;;;:20;;;;;;;:::i;:::-;;;;;;;;32974:1;32957:9;:13;32967:2;32957:13;;;;;;;;;;;;;;;;:18;;;;;;;:::i;:::-;;;;;;;;33004:2;32985:7;:16;32993:7;32985:16;;;;;;;;;;;;:21;;;;;;;;;;;;;;;;;;33041:7;33037:2;33022:27;;33031:4;33022:27;;;;;;;;;;;;32496:560;;;:::o;31824:348::-;31883:13;31899:23;31914:7;31899:14;:23::i;:::-;31883:39;;31933:48;31954:5;31969:1;31973:7;31933:20;:48::i;:::-;32019:29;32036:1;32040:7;32019:8;:29::i;:::-;32079:1;32059:9;:16;32069:5;32059:16;;;;;;;;;;;;;;;;:21;;;;;;;:::i;:::-;;;;;;;;32097:7;:16;32105:7;32097:16;;;;;;;;;;;;32090:23;;;;;;;;;;;32157:7;32153:1;32129:36;;32138:5;32129:36;;;;;;;;;;;;31873:299;31824:348;:::o;22225:169::-;22280:16;22299:6;;;;;;;;;;;22280:25;;22324:8;22315:6;;:17;;;;;;;;;;;;;;;;;;22378:8;22347:40;;22368:8;22347:40;;;;;;;;;;;;22270:124;22225:169;:::o;15802:703::-;15858:13;16084:1;16075:5;:10;16071:51;;16101:10;;;;;;;;;;;;;;;;;;;;;16071:51;16131:12;16146:5;16131:20;;16161:14;16185:75;16200:1;16192:4;:9;16185:75;;16217:8;;;;;:::i;:::-;;;;16247:2;16239:10;;;;;:::i;:::-;;;16185:75;;;16269:19;16301:6;16291:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16269:39;;16318:150;16334:1;16325:5;:10;16318:150;;16361:1;16351:11;;;;;:::i;:::-;;;16427:2;16419:5;:10;;;;:::i;:::-;16406:2;:24;;;;:::i;:::-;16393:39;;16376:6;16383;16376:14;;;;;;;;:::i;:::-;;;;;:56;;;;;;;;;;;16455:2;16446:11;;;;;:::i;:::-;;;16318:150;;;16491:6;16477:21;;;;;15802:703;;;;:::o;28706:307::-;28857:28;28867:4;28873:2;28877:7;28857:9;:28::i;:::-;28903:48;28926:4;28932:2;28936:7;28945:5;28903:22;:48::i;:::-;28895:111;;;;;;;;;;;;:::i;:::-;;;;;;;;;28706:307;;;;:::o;30273:108::-;30348:26;30358:2;30362:7;30348:26;;;;;;;;;;;;:9;:26::i;:::-;30273:108;;:::o;20113:155::-;20198:4;20236:25;20221:40;;;:11;:40;;;;20214:47;;20113:155;;;:::o;35229:122::-;;;;:::o;33891:782::-;34041:4;34061:15;:2;:13;;;:15::i;:::-;34057:610;;;34112:2;34096:36;;;34133:12;:10;:12::i;:::-;34147:4;34153:7;34162:5;34096:72;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;34092:523;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34356:1;34339:6;:13;:18;34335:266;;34381:60;;;;;;;;;;:::i;:::-;;;;;;;;34335:266;34553:6;34547:13;34538:6;34534:2;34530:15;34523:38;34092:523;34228:45;;;34218:55;;;:6;:55;;;;34211:62;;;;;34057:610;34652:4;34645:11;;33891:782;;;;;;;:::o;30602:311::-;30727:18;30733:2;30737:7;30727:5;:18::i;:::-;30776:54;30807:1;30811:2;30815:7;30824:5;30776:22;:54::i;:::-;30755:151;;;;;;;;;;;;:::i;:::-;;;;;;;;;30602:311;;;:::o;7462:377::-;7522:4;7725:12;7790:7;7778:20;7770:28;;7831:1;7824:4;:8;7817:15;;;7462:377;;;:::o;31235:372::-;31328:1;31314:16;;:2;:16;;;31306:61;;;;;;;;;;;;:::i;:::-;;;;;;;;;31386:16;31394:7;31386;:16::i;:::-;31385:17;31377:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;31446:45;31475:1;31479:2;31483:7;31446:20;:45::i;:::-;31519:1;31502:9;:13;31512:2;31502:13;;;;;;;;;;;;;;;;:18;;;;;;;:::i;:::-;;;;;;;;31549:2;31530:7;:16;31538:7;31530:16;;;;;;;;;;;;:21;;;;;;;;;;;;;;;;;;31592:7;31588:2;31567:33;;31584:1;31567:33;;;;;;;;;;;;31235:372;;:::o;7:75:5:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:149;370:7;410:66;403:5;399:78;388:89;;334:149;;;:::o;489:120::-;561:23;578:5;561:23;:::i;:::-;554:5;551:34;541:62;;599:1;596;589:12;541:62;489:120;:::o;615:137::-;660:5;698:6;685:20;676:29;;714:32;740:5;714:32;:::i;:::-;615:137;;;;:::o;758:327::-;816:6;865:2;853:9;844:7;840:23;836:32;833:119;;;871:79;;:::i;:::-;833:119;991:1;1016:52;1060:7;1051:6;1040:9;1036:22;1016:52;:::i;:::-;1006:62;;962:116;758:327;;;;:::o;1091:90::-;1125:7;1168:5;1161:13;1154:21;1143:32;;1091:90;;;:::o;1187:109::-;1268:21;1283:5;1268:21;:::i;:::-;1263:3;1256:34;1187:109;;:::o;1302:210::-;1389:4;1427:2;1416:9;1412:18;1404:26;;1440:65;1502:1;1491:9;1487:17;1478:6;1440:65;:::i;:::-;1302:210;;;;:::o;1518:99::-;1570:6;1604:5;1598:12;1588:22;;1518:99;;;:::o;1623:169::-;1707:11;1741:6;1736:3;1729:19;1781:4;1776:3;1772:14;1757:29;;1623:169;;;;:::o;1798:139::-;1887:6;1882:3;1877;1871:23;1928:1;1919:6;1914:3;1910:16;1903:27;1798:139;;;:::o;1943:102::-;1984:6;2035:2;2031:7;2026:2;2019:5;2015:14;2011:28;2001:38;;1943:102;;;:::o;2051:377::-;2139:3;2167:39;2200:5;2167:39;:::i;:::-;2222:71;2286:6;2281:3;2222:71;:::i;:::-;2215:78;;2302:65;2360:6;2355:3;2348:4;2341:5;2337:16;2302:65;:::i;:::-;2392:29;2414:6;2392:29;:::i;:::-;2387:3;2383:39;2376:46;;2143:285;2051:377;;;;:::o;2434:313::-;2547:4;2585:2;2574:9;2570:18;2562:26;;2634:9;2628:4;2624:20;2620:1;2609:9;2605:17;2598:47;2662:78;2735:4;2726:6;2662:78;:::i;:::-;2654:86;;2434:313;;;;:::o;2753:77::-;2790:7;2819:5;2808:16;;2753:77;;;:::o;2836:122::-;2909:24;2927:5;2909:24;:::i;:::-;2902:5;2899:35;2889:63;;2948:1;2945;2938:12;2889:63;2836:122;:::o;2964:139::-;3010:5;3048:6;3035:20;3026:29;;3064:33;3091:5;3064:33;:::i;:::-;2964:139;;;;:::o;3109:329::-;3168:6;3217:2;3205:9;3196:7;3192:23;3188:32;3185:119;;;3223:79;;:::i;:::-;3185:119;3343:1;3368:53;3413:7;3404:6;3393:9;3389:22;3368:53;:::i;:::-;3358:63;;3314:117;3109:329;;;;:::o;3444:126::-;3481:7;3521:42;3514:5;3510:54;3499:65;;3444:126;;;:::o;3576:96::-;3613:7;3642:24;3660:5;3642:24;:::i;:::-;3631:35;;3576:96;;;:::o;3678:118::-;3765:24;3783:5;3765:24;:::i;:::-;3760:3;3753:37;3678:118;;:::o;3802:222::-;3895:4;3933:2;3922:9;3918:18;3910:26;;3946:71;4014:1;4003:9;3999:17;3990:6;3946:71;:::i;:::-;3802:222;;;;:::o;4030:122::-;4103:24;4121:5;4103:24;:::i;:::-;4096:5;4093:35;4083:63;;4142:1;4139;4132:12;4083:63;4030:122;:::o;4158:139::-;4204:5;4242:6;4229:20;4220:29;;4258:33;4285:5;4258:33;:::i;:::-;4158:139;;;;:::o;4303:474::-;4371:6;4379;4428:2;4416:9;4407:7;4403:23;4399:32;4396:119;;;4434:79;;:::i;:::-;4396:119;4554:1;4579:53;4624:7;4615:6;4604:9;4600:22;4579:53;:::i;:::-;4569:63;;4525:117;4681:2;4707:53;4752:7;4743:6;4732:9;4728:22;4707:53;:::i;:::-;4697:63;;4652:118;4303:474;;;;;:::o;4783:118::-;4870:24;4888:5;4870:24;:::i;:::-;4865:3;4858:37;4783:118;;:::o;4907:222::-;5000:4;5038:2;5027:9;5023:18;5015:26;;5051:71;5119:1;5108:9;5104:17;5095:6;5051:71;:::i;:::-;4907:222;;;;:::o;5135:619::-;5212:6;5220;5228;5277:2;5265:9;5256:7;5252:23;5248:32;5245:119;;;5283:79;;:::i;:::-;5245:119;5403:1;5428:53;5473:7;5464:6;5453:9;5449:22;5428:53;:::i;:::-;5418:63;;5374:117;5530:2;5556:53;5601:7;5592:6;5581:9;5577:22;5556:53;:::i;:::-;5546:63;;5501:118;5658:2;5684:53;5729:7;5720:6;5709:9;5705:22;5684:53;:::i;:::-;5674:63;;5629:118;5135:619;;;;;:::o;5760:117::-;5869:1;5866;5859:12;5883:117;5992:1;5989;5982:12;6006:180;6054:77;6051:1;6044:88;6151:4;6148:1;6141:15;6175:4;6172:1;6165:15;6192:281;6275:27;6297:4;6275:27;:::i;:::-;6267:6;6263:40;6405:6;6393:10;6390:22;6369:18;6357:10;6354:34;6351:62;6348:88;;;6416:18;;:::i;:::-;6348:88;6456:10;6452:2;6445:22;6235:238;6192:281;;:::o;6479:129::-;6513:6;6540:20;;:::i;:::-;6530:30;;6569:33;6597:4;6589:6;6569:33;:::i;:::-;6479:129;;;:::o;6614:308::-;6676:4;6766:18;6758:6;6755:30;6752:56;;;6788:18;;:::i;:::-;6752:56;6826:29;6848:6;6826:29;:::i;:::-;6818:37;;6910:4;6904;6900:15;6892:23;;6614:308;;;:::o;6928:148::-;7026:6;7021:3;7016;7003:30;7067:1;7058:6;7053:3;7049:16;7042:27;6928:148;;;:::o;7082:425::-;7160:5;7185:66;7201:49;7243:6;7201:49;:::i;:::-;7185:66;:::i;:::-;7176:75;;7274:6;7267:5;7260:21;7312:4;7305:5;7301:16;7350:3;7341:6;7336:3;7332:16;7329:25;7326:112;;;7357:79;;:::i;:::-;7326:112;7447:54;7494:6;7489:3;7484;7447:54;:::i;:::-;7166:341;7082:425;;;;;:::o;7527:340::-;7583:5;7632:3;7625:4;7617:6;7613:17;7609:27;7599:122;;7640:79;;:::i;:::-;7599:122;7757:6;7744:20;7782:79;7857:3;7849:6;7842:4;7834:6;7830:17;7782:79;:::i;:::-;7773:88;;7589:278;7527:340;;;;:::o;7873:509::-;7942:6;7991:2;7979:9;7970:7;7966:23;7962:32;7959:119;;;7997:79;;:::i;:::-;7959:119;8145:1;8134:9;8130:17;8117:31;8175:18;8167:6;8164:30;8161:117;;;8197:79;;:::i;:::-;8161:117;8302:63;8357:7;8348:6;8337:9;8333:22;8302:63;:::i;:::-;8292:73;;8088:287;7873:509;;;;:::o;8388:60::-;8416:3;8437:5;8430:12;;8388:60;;;:::o;8454:142::-;8504:9;8537:53;8555:34;8564:24;8582:5;8564:24;:::i;:::-;8555:34;:::i;:::-;8537:53;:::i;:::-;8524:66;;8454:142;;;:::o;8602:126::-;8652:9;8685:37;8716:5;8685:37;:::i;:::-;8672:50;;8602:126;;;:::o;8734:138::-;8796:9;8829:37;8860:5;8829:37;:::i;:::-;8816:50;;8734:138;;;:::o;8878:155::-;8977:49;9020:5;8977:49;:::i;:::-;8972:3;8965:62;8878:155;;:::o;9039:246::-;9144:4;9182:2;9171:9;9167:18;9159:26;;9195:83;9275:1;9264:9;9260:17;9251:6;9195:83;:::i;:::-;9039:246;;;;:::o;9291:329::-;9350:6;9399:2;9387:9;9378:7;9374:23;9370:32;9367:119;;;9405:79;;:::i;:::-;9367:119;9525:1;9550:53;9595:7;9586:6;9575:9;9571:22;9550:53;:::i;:::-;9540:63;;9496:117;9291:329;;;;:::o;9626:117::-;9735:1;9732;9725:12;9749:117;9858:1;9855;9848:12;9886:553;9944:8;9954:6;10004:3;9997:4;9989:6;9985:17;9981:27;9971:122;;10012:79;;:::i;:::-;9971:122;10125:6;10112:20;10102:30;;10155:18;10147:6;10144:30;10141:117;;;10177:79;;:::i;:::-;10141:117;10291:4;10283:6;10279:17;10267:29;;10345:3;10337:4;10329:6;10325:17;10315:8;10311:32;10308:41;10305:128;;;10352:79;;:::i;:::-;10305:128;9886:553;;;;;:::o;10445:529::-;10516:6;10524;10573:2;10561:9;10552:7;10548:23;10544:32;10541:119;;;10579:79;;:::i;:::-;10541:119;10727:1;10716:9;10712:17;10699:31;10757:18;10749:6;10746:30;10743:117;;;10779:79;;:::i;:::-;10743:117;10892:65;10949:7;10940:6;10929:9;10925:22;10892:65;:::i;:::-;10874:83;;;;10670:297;10445:529;;;;;:::o;10997:568::-;11070:8;11080:6;11130:3;11123:4;11115:6;11111:17;11107:27;11097:122;;11138:79;;:::i;:::-;11097:122;11251:6;11238:20;11228:30;;11281:18;11273:6;11270:30;11267:117;;;11303:79;;:::i;:::-;11267:117;11417:4;11409:6;11405:17;11393:29;;11471:3;11463:4;11455:6;11451:17;11441:8;11437:32;11434:41;11431:128;;;11478:79;;:::i;:::-;11431:128;10997:568;;;;;:::o;11571:1249::-;11699:6;11707;11715;11723;11731;11739;11788:2;11776:9;11767:7;11763:23;11759:32;11756:119;;;11794:79;;:::i;:::-;11756:119;11942:1;11931:9;11927:17;11914:31;11972:18;11964:6;11961:30;11958:117;;;11994:79;;:::i;:::-;11958:117;12107:80;12179:7;12170:6;12159:9;12155:22;12107:80;:::i;:::-;12089:98;;;;11885:312;12264:2;12253:9;12249:18;12236:32;12295:18;12287:6;12284:30;12281:117;;;12317:79;;:::i;:::-;12281:117;12430:65;12487:7;12478:6;12467:9;12463:22;12430:65;:::i;:::-;12412:83;;;;12207:298;12572:2;12561:9;12557:18;12544:32;12603:18;12595:6;12592:30;12589:117;;;12625:79;;:::i;:::-;12589:117;12738:65;12795:7;12786:6;12775:9;12771:22;12738:65;:::i;:::-;12720:83;;;;12515:298;11571:1249;;;;;;;;:::o;12826:116::-;12896:21;12911:5;12896:21;:::i;:::-;12889:5;12886:32;12876:60;;12932:1;12929;12922:12;12876:60;12826:116;:::o;12948:133::-;12991:5;13029:6;13016:20;13007:29;;13045:30;13069:5;13045:30;:::i;:::-;12948:133;;;;:::o;13087:468::-;13152:6;13160;13209:2;13197:9;13188:7;13184:23;13180:32;13177:119;;;13215:79;;:::i;:::-;13177:119;13335:1;13360:53;13405:7;13396:6;13385:9;13381:22;13360:53;:::i;:::-;13350:63;;13306:117;13462:2;13488:50;13530:7;13521:6;13510:9;13506:22;13488:50;:::i;:::-;13478:60;;13433:115;13087:468;;;;;:::o;13561:307::-;13622:4;13712:18;13704:6;13701:30;13698:56;;;13734:18;;:::i;:::-;13698:56;13772:29;13794:6;13772:29;:::i;:::-;13764:37;;13856:4;13850;13846:15;13838:23;;13561:307;;;:::o;13874:423::-;13951:5;13976:65;13992:48;14033:6;13992:48;:::i;:::-;13976:65;:::i;:::-;13967:74;;14064:6;14057:5;14050:21;14102:4;14095:5;14091:16;14140:3;14131:6;14126:3;14122:16;14119:25;14116:112;;;14147:79;;:::i;:::-;14116:112;14237:54;14284:6;14279:3;14274;14237:54;:::i;:::-;13957:340;13874:423;;;;;:::o;14316:338::-;14371:5;14420:3;14413:4;14405:6;14401:17;14397:27;14387:122;;14428:79;;:::i;:::-;14387:122;14545:6;14532:20;14570:78;14644:3;14636:6;14629:4;14621:6;14617:17;14570:78;:::i;:::-;14561:87;;14377:277;14316:338;;;;:::o;14660:943::-;14755:6;14763;14771;14779;14828:3;14816:9;14807:7;14803:23;14799:33;14796:120;;;14835:79;;:::i;:::-;14796:120;14955:1;14980:53;15025:7;15016:6;15005:9;15001:22;14980:53;:::i;:::-;14970:63;;14926:117;15082:2;15108:53;15153:7;15144:6;15133:9;15129:22;15108:53;:::i;:::-;15098:63;;15053:118;15210:2;15236:53;15281:7;15272:6;15261:9;15257:22;15236:53;:::i;:::-;15226:63;;15181:118;15366:2;15355:9;15351:18;15338:32;15397:18;15389:6;15386:30;15383:117;;;15419:79;;:::i;:::-;15383:117;15524:62;15578:7;15569:6;15558:9;15554:22;15524:62;:::i;:::-;15514:72;;15309:287;14660:943;;;;;;;:::o;15609:819::-;15698:6;15706;15714;15722;15771:2;15759:9;15750:7;15746:23;15742:32;15739:119;;;15777:79;;:::i;:::-;15739:119;15897:1;15922:53;15967:7;15958:6;15947:9;15943:22;15922:53;:::i;:::-;15912:63;;15868:117;16024:2;16050:53;16095:7;16086:6;16075:9;16071:22;16050:53;:::i;:::-;16040:63;;15995:118;16180:2;16169:9;16165:18;16152:32;16211:18;16203:6;16200:30;16197:117;;;16233:79;;:::i;:::-;16197:117;16346:65;16403:7;16394:6;16383:9;16379:22;16346:65;:::i;:::-;16328:83;;;;16123:298;15609:819;;;;;;;:::o;16434:474::-;16502:6;16510;16559:2;16547:9;16538:7;16534:23;16530:32;16527:119;;;16565:79;;:::i;:::-;16527:119;16685:1;16710:53;16755:7;16746:6;16735:9;16731:22;16710:53;:::i;:::-;16700:63;;16656:117;16812:2;16838:53;16883:7;16874:6;16863:9;16859:22;16838:53;:::i;:::-;16828:63;;16783:118;16434:474;;;;;:::o;16914:149::-;16987:9;17020:37;17051:5;17020:37;:::i;:::-;17007:50;;16914:149;;;:::o;17069:177::-;17179:60;17233:5;17179:60;:::i;:::-;17174:3;17167:73;17069:177;;:::o;17252:268::-;17368:4;17406:2;17395:9;17391:18;17383:26;;17419:94;17510:1;17499:9;17495:17;17486:6;17419:94;:::i;:::-;17252:268;;;;:::o;17526:86::-;17561:7;17601:4;17594:5;17590:16;17579:27;;17526:86;;;:::o;17618:112::-;17701:22;17717:5;17701:22;:::i;:::-;17696:3;17689:35;17618:112;;:::o;17736:214::-;17825:4;17863:2;17852:9;17848:18;17840:26;;17876:67;17940:1;17929:9;17925:17;17916:6;17876:67;:::i;:::-;17736:214;;;;:::o;17956:674::-;18036:6;18044;18052;18101:2;18089:9;18080:7;18076:23;18072:32;18069:119;;;18107:79;;:::i;:::-;18069:119;18227:1;18252:53;18297:7;18288:6;18277:9;18273:22;18252:53;:::i;:::-;18242:63;;18198:117;18382:2;18371:9;18367:18;18354:32;18413:18;18405:6;18402:30;18399:117;;;18435:79;;:::i;:::-;18399:117;18548:65;18605:7;18596:6;18585:9;18581:22;18548:65;:::i;:::-;18530:83;;;;18325:298;17956:674;;;;;:::o;18636:180::-;18684:77;18681:1;18674:88;18781:4;18778:1;18771:15;18805:4;18802:1;18795:15;18822:320;18866:6;18903:1;18897:4;18893:12;18883:22;;18950:1;18944:4;18940:12;18971:18;18961:81;;19027:4;19019:6;19015:17;19005:27;;18961:81;19089:2;19081:6;19078:14;19058:18;19055:38;19052:84;;19108:18;;:::i;:::-;19052:84;18873:269;18822:320;;;:::o;19148:231::-;19288:34;19284:1;19276:6;19272:14;19265:58;19357:14;19352:2;19344:6;19340:15;19333:39;19148:231;:::o;19385:366::-;19527:3;19548:67;19612:2;19607:3;19548:67;:::i;:::-;19541:74;;19624:93;19713:3;19624:93;:::i;:::-;19742:2;19737:3;19733:12;19726:19;;19385:366;;;:::o;19757:419::-;19923:4;19961:2;19950:9;19946:18;19938:26;;20010:9;20004:4;20000:20;19996:1;19985:9;19981:17;19974:47;20038:131;20164:4;20038:131;:::i;:::-;20030:139;;19757:419;;;:::o;20182:220::-;20322:34;20318:1;20310:6;20306:14;20299:58;20391:3;20386:2;20378:6;20374:15;20367:28;20182:220;:::o;20408:366::-;20550:3;20571:67;20635:2;20630:3;20571:67;:::i;:::-;20564:74;;20647:93;20736:3;20647:93;:::i;:::-;20765:2;20760:3;20756:12;20749:19;;20408:366;;;:::o;20780:419::-;20946:4;20984:2;20973:9;20969:18;20961:26;;21033:9;21027:4;21023:20;21019:1;21008:9;21004:17;20997:47;21061:131;21187:4;21061:131;:::i;:::-;21053:139;;20780:419;;;:::o;21205:243::-;21345:34;21341:1;21333:6;21329:14;21322:58;21414:26;21409:2;21401:6;21397:15;21390:51;21205:243;:::o;21454:366::-;21596:3;21617:67;21681:2;21676:3;21617:67;:::i;:::-;21610:74;;21693:93;21782:3;21693:93;:::i;:::-;21811:2;21806:3;21802:12;21795:19;;21454:366;;;:::o;21826:419::-;21992:4;22030:2;22019:9;22015:18;22007:26;;22079:9;22073:4;22069:20;22065:1;22054:9;22050:17;22043:47;22107:131;22233:4;22107:131;:::i;:::-;22099:139;;21826:419;;;:::o;22251:180::-;22299:77;22296:1;22289:88;22396:4;22393:1;22386:15;22420:4;22417:1;22410:15;22437:194;22477:4;22497:20;22515:1;22497:20;:::i;:::-;22492:25;;22531:20;22549:1;22531:20;:::i;:::-;22526:25;;22575:1;22572;22568:9;22560:17;;22599:1;22593:4;22590:11;22587:37;;;22604:18;;:::i;:::-;22587:37;22437:194;;;;:::o;22637:236::-;22777:34;22773:1;22765:6;22761:14;22754:58;22846:19;22841:2;22833:6;22829:15;22822:44;22637:236;:::o;22879:366::-;23021:3;23042:67;23106:2;23101:3;23042:67;:::i;:::-;23035:74;;23118:93;23207:3;23118:93;:::i;:::-;23236:2;23231:3;23227:12;23220:19;;22879:366;;;:::o;23251:419::-;23417:4;23455:2;23444:9;23440:18;23432:26;;23504:9;23498:4;23494:20;23490:1;23479:9;23475:17;23468:47;23532:131;23658:4;23532:131;:::i;:::-;23524:139;;23251:419;;;:::o;23676:232::-;23816:34;23812:1;23804:6;23800:14;23793:58;23885:15;23880:2;23872:6;23868:15;23861:40;23676:232;:::o;23914:366::-;24056:3;24077:67;24141:2;24136:3;24077:67;:::i;:::-;24070:74;;24153:93;24242:3;24153:93;:::i;:::-;24271:2;24266:3;24262:12;24255:19;;23914:366;;;:::o;24286:419::-;24452:4;24490:2;24479:9;24475:18;24467:26;;24539:9;24533:4;24529:20;24525:1;24514:9;24510:17;24503:47;24567:131;24693:4;24567:131;:::i;:::-;24559:139;;24286:419;;;:::o;24711:410::-;24751:7;24774:20;24792:1;24774:20;:::i;:::-;24769:25;;24808:20;24826:1;24808:20;:::i;:::-;24803:25;;24863:1;24860;24856:9;24885:30;24903:11;24885:30;:::i;:::-;24874:41;;25064:1;25055:7;25051:15;25048:1;25045:22;25025:1;25018:9;24998:83;24975:139;;25094:18;;:::i;:::-;24975:139;24759:362;24711:410;;;;:::o;25127:332::-;25248:4;25286:2;25275:9;25271:18;25263:26;;25299:71;25367:1;25356:9;25352:17;25343:6;25299:71;:::i;:::-;25380:72;25448:2;25437:9;25433:18;25424:6;25380:72;:::i;:::-;25127:332;;;;;:::o;25465:191::-;25505:3;25524:20;25542:1;25524:20;:::i;:::-;25519:25;;25558:20;25576:1;25558:20;:::i;:::-;25553:25;;25601:1;25598;25594:9;25587:16;;25622:3;25619:1;25616:10;25613:36;;;25629:18;;:::i;:::-;25613:36;25465:191;;;;:::o;25662:442::-;25811:4;25849:2;25838:9;25834:18;25826:26;;25862:71;25930:1;25919:9;25915:17;25906:6;25862:71;:::i;:::-;25943:72;26011:2;26000:9;25996:18;25987:6;25943:72;:::i;:::-;26025;26093:2;26082:9;26078:18;26069:6;26025:72;:::i;:::-;25662:442;;;;;;:::o;26110:228::-;26250:34;26246:1;26238:6;26234:14;26227:58;26319:11;26314:2;26306:6;26302:15;26295:36;26110:228;:::o;26344:366::-;26486:3;26507:67;26571:2;26566:3;26507:67;:::i;:::-;26500:74;;26583:93;26672:3;26583:93;:::i;:::-;26701:2;26696:3;26692:12;26685:19;;26344:366;;;:::o;26716:419::-;26882:4;26920:2;26909:9;26905:18;26897:26;;26969:9;26963:4;26959:20;26955:1;26944:9;26940:17;26933:47;26997:131;27123:4;26997:131;:::i;:::-;26989:139;;26716:419;;;:::o;27141:143::-;27198:5;27229:6;27223:13;27214:22;;27245:33;27272:5;27245:33;:::i;:::-;27141:143;;;;:::o;27290:351::-;27360:6;27409:2;27397:9;27388:7;27384:23;27380:32;27377:119;;;27415:79;;:::i;:::-;27377:119;27535:1;27560:64;27616:7;27607:6;27596:9;27592:22;27560:64;:::i;:::-;27550:74;;27506:128;27290:351;;;;:::o;27647:174::-;27787:26;27783:1;27775:6;27771:14;27764:50;27647:174;:::o;27827:366::-;27969:3;27990:67;28054:2;28049:3;27990:67;:::i;:::-;27983:74;;28066:93;28155:3;28066:93;:::i;:::-;28184:2;28179:3;28175:12;28168:19;;27827:366;;;:::o;28199:419::-;28365:4;28403:2;28392:9;28388:18;28380:26;;28452:9;28446:4;28442:20;28438:1;28427:9;28423:17;28416:47;28480:131;28606:4;28480:131;:::i;:::-;28472:139;;28199:419;;;:::o;28624:229::-;28764:34;28760:1;28752:6;28748:14;28741:58;28833:12;28828:2;28820:6;28816:15;28809:37;28624:229;:::o;28859:366::-;29001:3;29022:67;29086:2;29081:3;29022:67;:::i;:::-;29015:74;;29098:93;29187:3;29098:93;:::i;:::-;29216:2;29211:3;29207:12;29200:19;;28859:366;;;:::o;29231:419::-;29397:4;29435:2;29424:9;29420:18;29412:26;;29484:9;29478:4;29474:20;29470:1;29459:9;29455:17;29448:47;29512:131;29638:4;29512:131;:::i;:::-;29504:139;;29231:419;;;:::o;29656:182::-;29796:34;29792:1;29784:6;29780:14;29773:58;29656:182;:::o;29844:366::-;29986:3;30007:67;30071:2;30066:3;30007:67;:::i;:::-;30000:74;;30083:93;30172:3;30083:93;:::i;:::-;30201:2;30196:3;30192:12;30185:19;;29844:366;;;:::o;30216:419::-;30382:4;30420:2;30409:9;30405:18;30397:26;;30469:9;30463:4;30459:20;30455:1;30444:9;30440:17;30433:47;30497:131;30623:4;30497:131;:::i;:::-;30489:139;;30216:419;;;:::o;30641:97::-;30700:6;30728:3;30718:13;;30641:97;;;;:::o;30744:141::-;30793:4;30816:3;30808:11;;30839:3;30836:1;30829:14;30873:4;30870:1;30860:18;30852:26;;30744:141;;;:::o;30891:93::-;30928:6;30975:2;30970;30963:5;30959:14;30955:23;30945:33;;30891:93;;;:::o;30990:107::-;31034:8;31084:5;31078:4;31074:16;31053:37;;30990:107;;;;:::o;31103:393::-;31172:6;31222:1;31210:10;31206:18;31245:97;31275:66;31264:9;31245:97;:::i;:::-;31363:39;31393:8;31382:9;31363:39;:::i;:::-;31351:51;;31435:4;31431:9;31424:5;31420:21;31411:30;;31484:4;31474:8;31470:19;31463:5;31460:30;31450:40;;31179:317;;31103:393;;;;;:::o;31502:142::-;31552:9;31585:53;31603:34;31612:24;31630:5;31612:24;:::i;:::-;31603:34;:::i;:::-;31585:53;:::i;:::-;31572:66;;31502:142;;;:::o;31650:75::-;31693:3;31714:5;31707:12;;31650:75;;;:::o;31731:269::-;31841:39;31872:7;31841:39;:::i;:::-;31902:91;31951:41;31975:16;31951:41;:::i;:::-;31943:6;31936:4;31930:11;31902:91;:::i;:::-;31896:4;31889:105;31807:193;31731:269;;;:::o;32006:73::-;32051:3;32072:1;32065:8;;32006:73;:::o;32085:189::-;32162:32;;:::i;:::-;32203:65;32261:6;32253;32247:4;32203:65;:::i;:::-;32138:136;32085:189;;:::o;32280:186::-;32340:120;32357:3;32350:5;32347:14;32340:120;;;32411:39;32448:1;32441:5;32411:39;:::i;:::-;32384:1;32377:5;32373:13;32364:22;;32340:120;;;32280:186;;:::o;32472:543::-;32573:2;32568:3;32565:11;32562:446;;;32607:38;32639:5;32607:38;:::i;:::-;32691:29;32709:10;32691:29;:::i;:::-;32681:8;32677:44;32874:2;32862:10;32859:18;32856:49;;;32895:8;32880:23;;32856:49;32918:80;32974:22;32992:3;32974:22;:::i;:::-;32964:8;32960:37;32947:11;32918:80;:::i;:::-;32577:431;;32562:446;32472:543;;;:::o;33021:117::-;33075:8;33125:5;33119:4;33115:16;33094:37;;33021:117;;;;:::o;33144:169::-;33188:6;33221:51;33269:1;33265:6;33257:5;33254:1;33250:13;33221:51;:::i;:::-;33217:56;33302:4;33296;33292:15;33282:25;;33195:118;33144:169;;;;:::o;33318:295::-;33394:4;33540:29;33565:3;33559:4;33540:29;:::i;:::-;33532:37;;33602:3;33599:1;33595:11;33589:4;33586:21;33578:29;;33318:295;;;;:::o;33618:1403::-;33742:44;33782:3;33777;33742:44;:::i;:::-;33851:18;33843:6;33840:30;33837:56;;;33873:18;;:::i;:::-;33837:56;33917:38;33949:4;33943:11;33917:38;:::i;:::-;34002:67;34062:6;34054;34048:4;34002:67;:::i;:::-;34096:1;34125:2;34117:6;34114:14;34142:1;34137:632;;;;34813:1;34830:6;34827:84;;;34886:9;34881:3;34877:19;34864:33;34855:42;;34827:84;34937:67;34997:6;34990:5;34937:67;:::i;:::-;34931:4;34924:81;34786:229;34107:908;;34137:632;34189:4;34185:9;34177:6;34173:22;34223:37;34255:4;34223:37;:::i;:::-;34282:1;34296:215;34310:7;34307:1;34304:14;34296:215;;;34396:9;34391:3;34387:19;34374:33;34366:6;34359:49;34447:1;34439:6;34435:14;34425:24;;34494:2;34483:9;34479:18;34466:31;;34333:4;34330:1;34326:12;34321:17;;34296:215;;;34539:6;34530:7;34527:19;34524:186;;;34604:9;34599:3;34595:19;34582:33;34647:48;34689:4;34681:6;34677:17;34666:9;34647:48;:::i;:::-;34639:6;34632:64;34547:163;34524:186;34756:1;34752;34744:6;34740:14;34736:22;34730:4;34723:36;34144:625;;;34107:908;;33717:1304;;;33618:1403;;;:::o;35027:116::-;35084:7;35113:24;35131:5;35113:24;:::i;:::-;35102:35;;35027:116;;;:::o;35149:162::-;35242:44;35280:5;35242:44;:::i;:::-;35235:5;35232:55;35222:83;;35301:1;35298;35291:12;35222:83;35149:162;:::o;35317:183::-;35394:5;35425:6;35419:13;35410:22;;35441:53;35488:5;35441:53;:::i;:::-;35317:183;;;;:::o;35506:391::-;35596:6;35645:2;35633:9;35624:7;35620:23;35616:32;35613:119;;;35651:79;;:::i;:::-;35613:119;35771:1;35796:84;35872:7;35863:6;35852:9;35848:22;35796:84;:::i;:::-;35786:94;;35742:148;35506:391;;;;:::o;35903:174::-;36043:26;36039:1;36031:6;36027:14;36020:50;35903:174;:::o;36083:366::-;36225:3;36246:67;36310:2;36305:3;36246:67;:::i;:::-;36239:74;;36322:93;36411:3;36322:93;:::i;:::-;36440:2;36435:3;36431:12;36424:19;;36083:366;;;:::o;36455:419::-;36621:4;36659:2;36648:9;36644:18;36636:26;;36708:9;36702:4;36698:20;36694:1;36683:9;36679:17;36672:47;36736:131;36862:4;36736:131;:::i;:::-;36728:139;;36455:419;;;:::o;36880:180::-;36928:77;36925:1;36918:88;37025:4;37022:1;37015:15;37049:4;37046:1;37039:15;37066:148;37168:11;37205:3;37190:18;;37066:148;;;;:::o;37244:330::-;37360:3;37381:89;37463:6;37458:3;37381:89;:::i;:::-;37374:96;;37480:56;37529:6;37524:3;37517:5;37480:56;:::i;:::-;37561:6;37556:3;37552:16;37545:23;;37244:330;;;;;:::o;37580:390::-;37686:3;37714:39;37747:5;37714:39;:::i;:::-;37769:89;37851:6;37846:3;37769:89;:::i;:::-;37762:96;;37867:65;37925:6;37920:3;37913:4;37906:5;37902:16;37867:65;:::i;:::-;37957:6;37952:3;37948:16;37941:23;;37690:280;37580:390;;;;:::o;37976:635::-;38224:3;38246:105;38347:3;38338:6;38330;38246:105;:::i;:::-;38239:112;;38368:95;38459:3;38450:6;38368:95;:::i;:::-;38361:102;;38480:105;38581:3;38572:6;38564;38480:105;:::i;:::-;38473:112;;38602:3;38595:10;;37976:635;;;;;;;;:::o;38617:1395::-;38734:37;38767:3;38734:37;:::i;:::-;38836:18;38828:6;38825:30;38822:56;;;38858:18;;:::i;:::-;38822:56;38902:38;38934:4;38928:11;38902:38;:::i;:::-;38987:67;39047:6;39039;39033:4;38987:67;:::i;:::-;39081:1;39105:4;39092:17;;39137:2;39129:6;39126:14;39154:1;39149:618;;;;39811:1;39828:6;39825:77;;;39877:9;39872:3;39868:19;39862:26;39853:35;;39825:77;39928:67;39988:6;39981:5;39928:67;:::i;:::-;39922:4;39915:81;39784:222;39119:887;;39149:618;39201:4;39197:9;39189:6;39185:22;39235:37;39267:4;39235:37;:::i;:::-;39294:1;39308:208;39322:7;39319:1;39316:14;39308:208;;;39401:9;39396:3;39392:19;39386:26;39378:6;39371:42;39452:1;39444:6;39440:14;39430:24;;39499:2;39488:9;39484:18;39471:31;;39345:4;39342:1;39338:12;39333:17;;39308:208;;;39544:6;39535:7;39532:19;39529:179;;;39602:9;39597:3;39593:19;39587:26;39645:48;39687:4;39679:6;39675:17;39664:9;39645:48;:::i;:::-;39637:6;39630:64;39552:156;39529:179;39754:1;39750;39742:6;39738:14;39734:22;39728:4;39721:36;39156:611;;;39119:887;;38709:1303;;;38617:1395;;:::o;40018:85::-;40063:7;40092:5;40081:16;;40018:85;;;:::o;40109:158::-;40167:9;40200:61;40218:42;40227:32;40253:5;40227:32;:::i;:::-;40218:42;:::i;:::-;40200:61;:::i;:::-;40187:74;;40109:158;;;:::o;40273:147::-;40368:45;40407:5;40368:45;:::i;:::-;40363:3;40356:58;40273:147;;:::o;40426:348::-;40555:4;40593:2;40582:9;40578:18;40570:26;;40606:79;40682:1;40671:9;40667:17;40658:6;40606:79;:::i;:::-;40695:72;40763:2;40752:9;40748:18;40739:6;40695:72;:::i;:::-;40426:348;;;;;:::o;40780:175::-;40920:27;40916:1;40908:6;40904:14;40897:51;40780:175;:::o;40961:366::-;41103:3;41124:67;41188:2;41183:3;41124:67;:::i;:::-;41117:74;;41200:93;41289:3;41200:93;:::i;:::-;41318:2;41313:3;41309:12;41302:19;;40961:366;;;:::o;41333:419::-;41499:4;41537:2;41526:9;41522:18;41514:26;;41586:9;41580:4;41576:20;41572:1;41561:9;41557:17;41550:47;41614:131;41740:4;41614:131;:::i;:::-;41606:139;;41333:419;;;:::o;41758:434::-;41847:5;41872:66;41888:49;41930:6;41888:49;:::i;:::-;41872:66;:::i;:::-;41863:75;;41961:6;41954:5;41947:21;41999:4;41992:5;41988:16;42037:3;42028:6;42023:3;42019:16;42016:25;42013:112;;;42044:79;;:::i;:::-;42013:112;42134:52;42179:6;42174:3;42169;42134:52;:::i;:::-;41853:339;41758:434;;;;;:::o;42212:355::-;42279:5;42328:3;42321:4;42313:6;42309:17;42305:27;42295:122;;42336:79;;:::i;:::-;42295:122;42446:6;42440:13;42471:90;42557:3;42549:6;42542:4;42534:6;42530:17;42471:90;:::i;:::-;42462:99;;42285:282;42212:355;;;;:::o;42573:524::-;42653:6;42702:2;42690:9;42681:7;42677:23;42673:32;42670:119;;;42708:79;;:::i;:::-;42670:119;42849:1;42838:9;42834:17;42828:24;42879:18;42871:6;42868:30;42865:117;;;42901:79;;:::i;:::-;42865:117;43006:74;43072:7;43063:6;43052:9;43048:22;43006:74;:::i;:::-;42996:84;;42799:291;42573:524;;;;:::o;43103:164::-;43243:16;43239:1;43231:6;43227:14;43220:40;43103:164;:::o;43273:366::-;43415:3;43436:67;43500:2;43495:3;43436:67;:::i;:::-;43429:74;;43512:93;43601:3;43512:93;:::i;:::-;43630:2;43625:3;43621:12;43614:19;;43273:366;;;:::o;43645:419::-;43811:4;43849:2;43838:9;43834:18;43826:26;;43898:9;43892:4;43888:20;43884:1;43873:9;43869:17;43862:47;43926:131;44052:4;43926:131;:::i;:::-;43918:139;;43645:419;;;:::o;44070:295::-;44212:3;44234:105;44335:3;44326:6;44318;44234:105;:::i;:::-;44227:112;;44356:3;44349:10;;44070:295;;;;;:::o;44371:169::-;44511:21;44507:1;44499:6;44495:14;44488:45;44371:169;:::o;44546:366::-;44688:3;44709:67;44773:2;44768:3;44709:67;:::i;:::-;44702:74;;44785:93;44874:3;44785:93;:::i;:::-;44903:2;44898:3;44894:12;44887:19;;44546:366;;;:::o;44918:419::-;45084:4;45122:2;45111:9;45107:18;45099:26;;45171:9;45165:4;45161:20;45157:1;45146:9;45142:17;45135:47;45199:131;45325:4;45199:131;:::i;:::-;45191:139;;44918:419;;;:::o;45343:225::-;45483:34;45479:1;45471:6;45467:14;45460:58;45552:8;45547:2;45539:6;45535:15;45528:33;45343:225;:::o;45574:366::-;45716:3;45737:67;45801:2;45796:3;45737:67;:::i;:::-;45730:74;;45813:93;45902:3;45813:93;:::i;:::-;45931:2;45926:3;45922:12;45915:19;;45574:366;;;:::o;45946:419::-;46112:4;46150:2;46139:9;46135:18;46127:26;;46199:9;46193:4;46189:20;46185:1;46174:9;46170:17;46163:47;46227:131;46353:4;46227:131;:::i;:::-;46219:139;;45946:419;;;:::o;46371:231::-;46511:34;46507:1;46499:6;46495:14;46488:58;46580:14;46575:2;46567:6;46563:15;46556:39;46371:231;:::o;46608:366::-;46750:3;46771:67;46835:2;46830:3;46771:67;:::i;:::-;46764:74;;46847:93;46936:3;46847:93;:::i;:::-;46965:2;46960:3;46956:12;46949:19;;46608:366;;;:::o;46980:419::-;47146:4;47184:2;47173:9;47169:18;47161:26;;47233:9;47227:4;47223:20;47219:1;47208:9;47204:17;47197:47;47261:131;47387:4;47261:131;:::i;:::-;47253:139;;46980:419;;;:::o;47405:228::-;47545:34;47541:1;47533:6;47529:14;47522:58;47614:11;47609:2;47601:6;47597:15;47590:36;47405:228;:::o;47639:366::-;47781:3;47802:67;47866:2;47861:3;47802:67;:::i;:::-;47795:74;;47878:93;47967:3;47878:93;:::i;:::-;47996:2;47991:3;47987:12;47980:19;;47639:366;;;:::o;48011:419::-;48177:4;48215:2;48204:9;48200:18;48192:26;;48264:9;48258:4;48254:20;48250:1;48239:9;48235:17;48228:47;48292:131;48418:4;48292:131;:::i;:::-;48284:139;;48011:419;;;:::o;48436:223::-;48576:34;48572:1;48564:6;48560:14;48553:58;48645:6;48640:2;48632:6;48628:15;48621:31;48436:223;:::o;48665:366::-;48807:3;48828:67;48892:2;48887:3;48828:67;:::i;:::-;48821:74;;48904:93;48993:3;48904:93;:::i;:::-;49022:2;49017:3;49013:12;49006:19;;48665:366;;;:::o;49037:419::-;49203:4;49241:2;49230:9;49226:18;49218:26;;49290:9;49284:4;49280:20;49276:1;49265:9;49261:17;49254:47;49318:131;49444:4;49318:131;:::i;:::-;49310:139;;49037:419;;;:::o;49462:233::-;49501:3;49524:24;49542:5;49524:24;:::i;:::-;49515:33;;49570:66;49563:5;49560:77;49557:103;;49640:18;;:::i;:::-;49557:103;49687:1;49680:5;49676:13;49669:20;;49462:233;;;:::o;49701:180::-;49749:77;49746:1;49739:88;49846:4;49843:1;49836:15;49870:4;49867:1;49860:15;49887:185;49927:1;49944:20;49962:1;49944:20;:::i;:::-;49939:25;;49978:20;49996:1;49978:20;:::i;:::-;49973:25;;50017:1;50007:35;;50022:18;;:::i;:::-;50007:35;50064:1;50061;50057:9;50052:14;;49887:185;;;;:::o;50078:176::-;50110:1;50127:20;50145:1;50127:20;:::i;:::-;50122:25;;50161:20;50179:1;50161:20;:::i;:::-;50156:25;;50200:1;50190:35;;50205:18;;:::i;:::-;50190:35;50246:1;50243;50239:9;50234:14;;50078:176;;;;:::o;50260:237::-;50400:34;50396:1;50388:6;50384:14;50377:58;50469:20;50464:2;50456:6;50452:15;50445:45;50260:237;:::o;50503:366::-;50645:3;50666:67;50730:2;50725:3;50666:67;:::i;:::-;50659:74;;50742:93;50831:3;50742:93;:::i;:::-;50860:2;50855:3;50851:12;50844:19;;50503:366;;;:::o;50875:419::-;51041:4;51079:2;51068:9;51064:18;51056:26;;51128:9;51122:4;51118:20;51114:1;51103:9;51099:17;51092:47;51156:131;51282:4;51156:131;:::i;:::-;51148:139;;50875:419;;;:::o;51300:98::-;51351:6;51385:5;51379:12;51369:22;;51300:98;;;:::o;51404:168::-;51487:11;51521:6;51516:3;51509:19;51561:4;51556:3;51552:14;51537:29;;51404:168;;;;:::o;51578:373::-;51664:3;51692:38;51724:5;51692:38;:::i;:::-;51746:70;51809:6;51804:3;51746:70;:::i;:::-;51739:77;;51825:65;51883:6;51878:3;51871:4;51864:5;51860:16;51825:65;:::i;:::-;51915:29;51937:6;51915:29;:::i;:::-;51910:3;51906:39;51899:46;;51668:283;51578:373;;;;:::o;51957:640::-;52152:4;52190:3;52179:9;52175:19;52167:27;;52204:71;52272:1;52261:9;52257:17;52248:6;52204:71;:::i;:::-;52285:72;52353:2;52342:9;52338:18;52329:6;52285:72;:::i;:::-;52367;52435:2;52424:9;52420:18;52411:6;52367:72;:::i;:::-;52486:9;52480:4;52476:20;52471:2;52460:9;52456:18;52449:48;52514:76;52585:4;52576:6;52514:76;:::i;:::-;52506:84;;51957:640;;;;;;;:::o;52603:141::-;52659:5;52690:6;52684:13;52675:22;;52706:32;52732:5;52706:32;:::i;:::-;52603:141;;;;:::o;52750:349::-;52819:6;52868:2;52856:9;52847:7;52843:23;52839:32;52836:119;;;52874:79;;:::i;:::-;52836:119;52994:1;53019:63;53074:7;53065:6;53054:9;53050:22;53019:63;:::i;:::-;53009:73;;52965:127;52750:349;;;;:::o;53105:182::-;53245:34;53241:1;53233:6;53229:14;53222:58;53105:182;:::o;53293:366::-;53435:3;53456:67;53520:2;53515:3;53456:67;:::i;:::-;53449:74;;53532:93;53621:3;53532:93;:::i;:::-;53650:2;53645:3;53641:12;53634:19;;53293:366;;;:::o;53665:419::-;53831:4;53869:2;53858:9;53854:18;53846:26;;53918:9;53912:4;53908:20;53904:1;53893:9;53889:17;53882:47;53946:131;54072:4;53946:131;:::i;:::-;53938:139;;53665:419;;;:::o;54090:178::-;54230:30;54226:1;54218:6;54214:14;54207:54;54090:178;:::o;54274:366::-;54416:3;54437:67;54501:2;54496:3;54437:67;:::i;:::-;54430:74;;54513:93;54602:3;54513:93;:::i;:::-;54631:2;54626:3;54622:12;54615:19;;54274:366;;;:::o;54646:419::-;54812:4;54850:2;54839:9;54835:18;54827:26;;54899:9;54893:4;54889:20;54885:1;54874:9;54870:17;54863:47;54927:131;55053:4;54927:131;:::i;:::-;54919:139;;54646:419;;;:::o
Swarm Source
ipfs://069c705c4a98c772316bc62943a1577edaff35f6adc002d0f96e3763e3379677
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.