Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 25 from a total of 29 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Mint_card | 16263371 | 1185 days ago | IN | 0.05 ETH | 0.00597471 | ||||
| Mint_card | 16263324 | 1185 days ago | IN | 0.05 ETH | 0.00575674 | ||||
| Mint_card | 16263237 | 1185 days ago | IN | 0.05 ETH | 0.00609671 | ||||
| Mint_card | 16262323 | 1186 days ago | IN | 0.05 ETH | 0.00657892 | ||||
| Mint_card | 16262283 | 1186 days ago | IN | 0.05 ETH | 0.00803376 | ||||
| Mint_card | 16261685 | 1186 days ago | IN | 0.05 ETH | 0.00557892 | ||||
| Mint_card | 16261047 | 1186 days ago | IN | 0.1 ETH | 0.00612509 | ||||
| Mint_card | 16261027 | 1186 days ago | IN | 0.05 ETH | 0.00577193 | ||||
| Mint_card | 16261009 | 1186 days ago | IN | 0.05 ETH | 0.00692179 | ||||
| Mint_card | 16260987 | 1186 days ago | IN | 0.05 ETH | 0.00648535 | ||||
| Mint_card | 16260948 | 1186 days ago | IN | 0.05 ETH | 0.00694235 | ||||
| Mint_card | 16242820 | 1188 days ago | IN | 0.01 ETH | 0.01111693 | ||||
| Mint_card | 16239687 | 1189 days ago | IN | 0.01 ETH | 0.00633253 | ||||
| Mint_card | 16239500 | 1189 days ago | IN | 0.01 ETH | 0.00589825 | ||||
| Add_NGO | 16228682 | 1190 days ago | IN | 0 ETH | 0.00123832 | ||||
| Add_NGO | 16228660 | 1190 days ago | IN | 0 ETH | 0.00130257 | ||||
| Add_NGO | 16228659 | 1190 days ago | IN | 0 ETH | 0.00130466 | ||||
| Add_NGO | 16228657 | 1190 days ago | IN | 0 ETH | 0.00121993 | ||||
| Add_NGO | 16228657 | 1190 days ago | IN | 0 ETH | 0.00121993 | ||||
| Add_NGO | 16228652 | 1190 days ago | IN | 0 ETH | 0.00125912 | ||||
| Add_NGO | 16228651 | 1190 days ago | IN | 0 ETH | 0.0012223 | ||||
| Add_NGO | 16228646 | 1190 days ago | IN | 0 ETH | 0.00114429 | ||||
| Add_NGO | 16228635 | 1190 days ago | IN | 0 ETH | 0.00114501 | ||||
| Add_NGO | 16228630 | 1190 days ago | IN | 0 ETH | 0.00114573 | ||||
| Mint_card | 16224452 | 1191 days ago | IN | 0.05 ETH | 0.00523371 |
Latest 18 internal transactions
Advanced mode:
| Parent Transaction Hash | Method | Block |
From
|
|
To
|
||
|---|---|---|---|---|---|---|---|
| Transfer | 16263371 | 1185 days ago | 0.05 ETH | ||||
| Transfer | 16263324 | 1185 days ago | 0.05 ETH | ||||
| Transfer | 16263237 | 1185 days ago | 0.05 ETH | ||||
| Transfer | 16262323 | 1186 days ago | 0.05 ETH | ||||
| Transfer | 16262283 | 1186 days ago | 0.05 ETH | ||||
| Transfer | 16261685 | 1186 days ago | 0.05 ETH | ||||
| Transfer | 16261047 | 1186 days ago | 0.1 ETH | ||||
| Transfer | 16261027 | 1186 days ago | 0.05 ETH | ||||
| Transfer | 16261009 | 1186 days ago | 0.05 ETH | ||||
| Transfer | 16260987 | 1186 days ago | 0.05 ETH | ||||
| Transfer | 16260948 | 1186 days ago | 0.05 ETH | ||||
| Transfer | 16242820 | 1188 days ago | 0.01 ETH | ||||
| Transfer | 16239687 | 1189 days ago | 0.01 ETH | ||||
| Transfer | 16239500 | 1189 days ago | 0.01 ETH | ||||
| Transfer | 16224452 | 1191 days ago | 0.05 ETH | ||||
| Transfer | 16174248 | 1198 days ago | 0.05 ETH | ||||
| Transfer | 16164923 | 1199 days ago | 0.05 ETH | ||||
| Transfer | 16164828 | 1199 days ago | 0.05 ETH |
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
Xmas
Compiler Version
v0.8.17+commit.8df45f5f
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
pragma solidity ^0.8.0;
// SPDX-License-Identifier: MIT
// https://donate-xmas.com/
/*
_«φ≥»_
___ ;░▒[ ____
__ _ _▓▓_ _____
_ __ _▓▓▓▓_ __
_ ╓▓▓▓▓▓▓╖_ ⁿ _ __
_ _ _▄▄▓▓╟▓▀▒▓▓▓▓▄▄__ __
╓▓█▓██▓▓██▓█▓▄ _
_ _▓██████████▓__ __
_ ,▄▓▓▓▓▓▓▓╬▓▀▓███▓M_ _ _
__ ▄▓███▓██▓▓█████▓▓▓▓ç__ _
_ └█████╣▓╣██████▒│╟█████─ _ _
__ _▄▓██████████████████▓▄_ _ _
_ ___█████████▓█▓██████─_ _ _
_ ,▓███▓▓▓▓████████████_ __
▀██████████████████▓████▓▄µ _
_-- ╓▓█████████▀░███████▓▓█████,_ _ _ _
_ "▀████████████▄▄████▓█████▓█████▀^ _
_ ▀█████▓█▓▀█████████████████▀ _
_ _ ▄████████████▓▓▓▓████████████▄ ]~
"▓█████████▓███████████████▓████████▄ _
_ ╓▄▄▄▓██▓█▓▓████╬▓█████████████████╬█████████▄▄▄,
_ _'╙╙▀████▓███▓▓▀███▓█████▀░╠██████▓████████▀╙╙'_
_ _▓█▀███████████▓███████▓▓█████████████▀▀█_ _
_ 'φ╓φ#_ ╙└└__▀▀▀▓████▀╝▀████▀▌╙▀████▀▀▀__└└╙╓▄_ ╓▄_ _
╟▓▒╬▓▒ _ ,_''_ __j████⌐__ __ _ ╓╠╬╫▓╬╬╓_ _
__ ╫▓▒╣▓L ]▄▓▓▓▄⌐ α_▀███▓▓███▀ _▒▒╟▓╬▒╠
_ ╣▓▒╣▓▌ ,╠▒φ╬▓▓▓╣ ▀▓╬▓▓▓▓▓▓▓▓▓▒▓▓⌐______ ]▒╠║▓╬╠╠_
,-»≤≤≤╫▓╣╣▓▓╣▓▓▓▓▓╬╟▓▓▓▓▓,,║▓╬╫▓▓▓▓▓▓▓▓╣▓▓▓▓▓╫╫╫╫╥╓,{▒╠╟▓╬▒╬╓╓▄▄≥≥≤»,,_
_"=░││││║▓╣▓▓▓▓╣▓▓▓╫▒║╫╫▓▓▌│'▓▓╬╫▓▓▓▓▓▓▓▓▓▓▓▓▓▓╬╬╬▒╬╬▒╠▒╟╣╬╬╬▓╣╬▓▌│││││Γ^
_ __ `░││││││╚▀▀╝▀▀││││││││││││││░╙╙╙╙╙╙╙╙╙╙╙╙╙╙'││'└└│└└│ _ ____
__ ``"""""""ⁿⁿⁿⁿⁿⁿⁿⁿⁿⁿⁿⁿ==ⁿⁿⁿⁿⁿⁿⁿⁿⁿⁿⁿ""""""`` _
*/
import "./ERC721Tradable.sol";
/**
* @title Donate-Xmas
*/
contract Xmas is ERC721Tradable {
struct NGO {
address addr;
string name;
}
struct ICON {
string name;
string part_1;
string part_2;
string part_3;
string part_4;
string part_5;
uint256 min_donation;
}
event new_NGO (uint256 NGO_id );
event new_ICON (uint256 icon_id);
event new_COLOR(uint256 color_id);
mapping (uint256 => string ) internal DONAs;
mapping (uint256 => ICON ) public ICONs;
mapping (uint256 => NGO ) public NGOs;
mapping (uint256 => string ) public COLORs;
uint256 public number_of_NGOs;
uint256 public number_of_icons;
uint256 public number_of_colors;
using strings for *;
constructor(address _proxyRegistryAddress) ERC721Tradable("DonateXMas", "XMAS", _proxyRegistryAddress) {
DONAs[ 10000000000000000] = " 0.01";
DONAs[ 50000000000000000] = " 0.05";
DONAs[ 100000000000000000] = " 0.1";
DONAs[ 250000000000000000] = " 0.25";
DONAs[ 500000000000000000] = " 0.5";
DONAs[ 1000000000000000000] = " 1";
DONAs[ 5000000000000000000] = " 5";
DONAs[10000000000000000000] = "10";
// Icons
ICONs[1] = ICON("Star 1",
'<g transform="translate(100 470.37)" fill="',
'"><circle cx="770.37" cy="29.63" r="29.63"/><circle cx="29.63" cy="29.63" r="29.63"/></g><g transform="translate(470.37 100)" fill="',
'"><circle cx="29.63" cy="29.63" r="29.63"/><circle cx="29.63" cy="770.37" r="29.63"/></g><path fill="',
'" d="m499.94 159.2 60.993 193.492 179.948-93.691-93.693 179.947 193.494 60.992-193.493 60.993L740.88 740.88l-179.948-93.692-60.992 193.493-60.993-193.493L259 740.88l93.692-179.948L159.2 499.94l193.492-60.993L259.001 259l179.947 93.692z"/><path fill="',
'" />',
100000000000000
);
ICONs[2] = ICON("Mountains",
'<path fill="',
'" d="m400 0 400 400H0z" transform="translate(100 100)"/><path fill="',
'" d="m400 400 400 400H0z" transform="translate(100 100)"/><path d="m400 0 200 200H200L400 0ZM266.666 266.4 200 200h133.334l-66.667 66.4Zm266.668 0L466.667 200h133.334l-66.667 66.4ZM400 266.4 333.334 200h133.332L400 266.4Z" fill="',
'" transform="translate(100 100)"/><path d="m400 400 200 200H200l200-200ZM266.666 666.4 200 600h133.334l-66.667 66.4Zm266.668 0L466.667 600h133.334l-66.667 66.4ZM400 666.4 333.334 600h133.332L400 666.4Z" fill="',
'" transform="translate(100 100)"/>',
100000000000000
);
ICONs[3] = ICON("Tree 1",
'<g transform="translate(100 100)"><path fill="',
'" d="m400 0 400 652H0z"/><circle fill="',
'" cx="399.6" cy="726" r="74"/></g><path fill="',
'" /><path fill="',
'" />',
100000000000000
);
ICONs[4] = ICON("Hat",
'<g transform="translate(100 100)"><path fill="',
'" d="m400 148.217 400 503.937H0z"/><ellipse fill="',
'" cx="400" cy="74.109" rx="74.074" ry="74.109"/><path fill="',
'" d="M.37 652.525h799.26V800H.37z"/></g><path fill="',
'"/>',
100000000000000
);
ICONs[5] = ICON("Tree 2",
'<g transform="translate(100.000000, 100.000000)"><polygon fill="',
'" points="400 59.2 800 244 0 244"></polygon><polygon fill="',
'" points="400 429.6 800 615.2 0 615.2"></polygon><path d="M400,244.8 L800,430.4 L0,430.4 L400,244.8 Z M400,615.2 L800,800 L0,800 L400,615.2 Z" fill="',
'"></path><circle fill="',
'" cx="399.2" cy="29.6" r="29.6"></circle></g>',
100000000000000
);
ICONs[6] = ICON("Snowman",
'<g transform="translate(100 100)"><circle fill="',
'" cx="400.8" cy="200" r="200"/><path fill="',
'" d="M600.8 200.4 400 237.6v-74.4z"/><path d="M800 800H0c0-27.13 2.72-54.19 8.126-80.775a399.03 399.03 0 0 1 60.188-143.316 401.281 401.281 0 0 1 175.988-145.212 397.432 397.432 0 0 1 75.083-23.355 403.116 403.116 0 0 1 161.228 0 397.385 397.385 0 0 1 143.03 60.306C734.062 542.181 800.173 666.768 800 800Z" fill="',
'"/></g><path fill="',
'" />',
100000000000000
);
ICONs[7] = ICON("Snow 1",
'<g transform="translate(300 100)" fill="',
'"><circle transform="rotate(90 400 400)" cx="400" cy="400" r="200"/><circle cx="200" cy="200" r="200"/></g><g transform="translate(100 300)" fill="',
'"><circle transform="rotate(90 200 200)" cx="200" cy="200" r="200"/><circle cx="400" cy="400" r="200"/></g><path fill="',
'"/><path fill="',
'"/>',
100000000000000
);
ICONs[8] = ICON("Ball 1",
'<g transform="translate(100 100)"><circle fill="',
'" cx="400" cy="400" r="400"/><path d="M800 400C800 179.086 620.914 0 400 0S0 179.086 0 400c0 .8 800 .8 800 0Z" fill="',
'"/></g><path fill="',
'" /><path fill="',
'" />',
100000000000000
);
ICONs[9] = ICON("Tree 3",
'<path fill="',
'" d="M902 1000 662.861 624.68h72.317L500.494 285 265.822 624.68h72.317L99 1000z"/><g transform="translate(176 124)" fill="',
'"><path d="m331.903 4.966 14.365 29.101a8.819 8.819 0 0 0 6.677 4.812l32.123 4.668a8.879 8.879 0 0 1 4.909 15.134L366.733 81.37a8.914 8.914 0 0 0-2.551 7.855l5.486 31.988a8.854 8.854 0 0 1-12.8 9.348l-28.731-15.098a8.88 8.88 0 0 0-8.266 0l-28.73 15.098a8.856 8.856 0 0 1-12.861-9.348l5.486-31.988a8.89 8.89 0 0 0-2.563-7.855l-23.232-22.653a8.866 8.866 0 0 1 4.909-15.134l32.123-4.668a8.819 8.819 0 0 0 6.677-4.812l14.281-29.137a8.879 8.879 0 0 1 15.942 0Z"/><ellipse cx="429.788" cy="613.112" rx="37.212" ry="37.209"/><ellipse cx="37.212" cy="714.791" rx="37.212" ry="37.209"/></g><g transform="translate(345 399)" fill="',
'"><ellipse cx="37.242" cy="37.239" rx="37.242" ry="37.239"/><ellipse cx="155.697" cy="172.89" rx="37.242" ry="37.239"/><ellipse cx="49.186" cy="338.002" rx="37.242" ry="37.239"/><ellipse cx="440.758" cy="439.761" rx="37.242" ry="37.239"/></g><g transform="translate(462 399)" fill="',
'"><ellipse cx="143.789" cy="37.258" rx="37.211" ry="37.258"/><ellipse cx="37.211" cy="497.742" rx="37.211" ry="37.258"/></g>',
100000000000000
);
ICONs[9] = ICON("Tree 3",
'<path fill="',
'" d="M902 1000 662.861 624.68h72.317L500.494 285 265.822 624.68h72.317L99 1000z"/><g transform="translate(176 124)" fill="',
'"><path d="m331.903 4.966 14.365 29.101a8.819 8.819 0 0 0 6.677 4.812l32.123 4.668a8.879 8.879 0 0 1 4.909 15.134L366.733 81.37a8.914 8.914 0 0 0-2.551 7.855l5.486 31.988a8.854 8.854 0 0 1-12.8 9.348l-28.731-15.098a8.88 8.88 0 0 0-8.266 0l-28.73 15.098a8.856 8.856 0 0 1-12.861-9.348l5.486-31.988a8.89 8.89 0 0 0-2.563-7.855l-23.232-22.653a8.866 8.866 0 0 1 4.909-15.134l32.123-4.668a8.819 8.819 0 0 0 6.677-4.812l14.281-29.137a8.879 8.879 0 0 1 15.942 0Z"/><ellipse cx="429.788" cy="613.112" rx="37.212" ry="37.209"/><ellipse cx="37.212" cy="714.791" rx="37.212" ry="37.209"/></g><g transform="translate(345 399)" fill="',
'"><ellipse cx="37.242" cy="37.239" rx="37.242" ry="37.239"/><ellipse cx="155.697" cy="172.89" rx="37.242" ry="37.239"/><ellipse cx="49.186" cy="338.002" rx="37.242" ry="37.239"/><ellipse cx="440.758" cy="439.761" rx="37.242" ry="37.239"/></g><g transform="translate(462 399)" fill="',
'"><ellipse cx="143.789" cy="37.258" rx="37.211" ry="37.258"/><ellipse cx="37.211" cy="497.742" rx="37.211" ry="37.258"/></g>',
100000000000000
);
ICONs[10] = ICON("Skate",
'<g transform="translate(217 344)" fill="',
'"><circle cx="541" cy="26" r="26"/><circle cx="26" cy="26" r="26"/><path d="M399.177 508a6.815 6.815 0 0 0-6.81 6.82c-.007 7.476-6.058 13.535-13.525 13.541H369.2v-15.038h-13.61v15.038h-40.983v-15.038h-13.621v15.038H289.81a6.815 6.815 0 0 0-6.811 6.82c0 3.766 3.05 6.819 6.81 6.819h89.044c14.987-.013 27.133-12.175 27.146-27.18 0-1.811-.72-3.548-1.999-4.827a6.806 6.806 0 0 0-4.824-1.993Zm-287.525-24.954a6.744 6.744 0 0 0-3.386-3.9 6.705 6.705 0 0 0-5.142-.35c-7.011 2.349-14.595-1.435-16.961-8.463l-3.018-9.061 14.099-4.788-4.294-12.832-14.087 4.788-12.93-38.58 14.087-4.787-4.294-12.82-14.086 4.788-3.543-10.522c-1.223-3.488-5.011-5.343-8.503-4.165-3.493 1.178-5.395 4.953-4.271 8.474l28.065 83.79c4.733 14.113 19.963 21.71 34.03 16.974 3.515-1.193 5.408-5.013 4.234-8.546Z"/></g><path d="M507 610h55v180h-55zM342.248 764 326 712.236l23.904-7.527c47.645-15.093 82.149-56.61 88.332-106.289V598L492 604.627l-.06.432c-8.801 70.766-57.945 129.91-125.812 151.414L342.248 764ZM436 324.154V205.878L577 205v119.202c0 39.1-31.564 70.798-70.5 70.798a70.338 70.338 0 0 1-49.871-20.75c-13.224-13.288-20.645-31.31-20.629-50.096Z" fill="',
'"/><path d="M561.962 785v28.74c20.25 3.8 35.65 21.786 35.994 43.516l.006.744h-55v-1h-36v-72h55Zm-205.81-82.984 17.994 52.493-26.884 9.215a44.372 44.372 0 0 1-29.027 48.069l-.546.19-11.694-34.115-.002.002L288 725.377l68.153-23.36ZM438.49 343a70.85 70.85 0 0 0 18.1 31.25A70.338 70.338 0 0 0 506.463 395l1.166-.01c31.942-.52 58.72-22.372 66.822-51.99h135.512v67.836H595.324V613H412.56V410.836H292.962V343H438.49Zm69.297-229 1.12.009c36.889.57 67.446 28.938 70.53 65.71 6.101 1.074 10.543 6.368 10.525 12.545v13.048c0 7.007-5.698 12.688-12.727 12.688H437.69a12.747 12.747 0 0 1-9-3.716 12.669 12.669 0 0 1-3.728-8.972v-13.048c-.029-6.43 4.775-11.862 11.176-12.64 3.162-37.106 34.295-65.62 71.65-65.624Z" fill="',
'"/><g transform="translate(258 218)" fill="',
'"><rect x="452" y="118" width="35" height="79" rx="8.91"/><rect y="118" width="35" height="79" rx="8.91"/><path d="M197 0v14.294C197 42.07 222.142 67 250.196 67h-.06C278.19 67 300 42.07 300 14.294V.012L197 0Zm52 217c5.523 0 10-4.477 10-10s-4.477-10-10-10-10 4.477-10 10 4.477 10 10 10Zm.012 21a10 10 0 1 0 9.988 9.988 10 10 0 0 0-9.988-9.988ZM249 280c-5.523 0-10 4.477-10 10s4.477 10 10 10 10-4.477 10-10c-.007-5.52-4.48-9.993-10-10Z"/></g><g transform="translate(484 233)"><circle cx="7.5" cy="7.5" r="7.5"/><circle cx="41.5" cy="7.5" r="7.5"/></g>',
100000000000000
);
ICONs[11] = ICON("Gifts",
'<path fill="',
'" d="M168.84 0H497.2v561.28H168.84z" transform="translate(251.4 219.77)"/><path fill="',
'" d="M0 234.95h337.68v326.32H0z" transform="translate(251.4 219.77)"/><path d="M204.6 353.32V235.06c30.244-12.925 45.377-47.008 34.68-78.11a62.7 62.7 0 0 0-64.77 15 63.46 63.46 0 0 0-5.65 6.48 63.46 63.46 0 0 0-5.65-6.48 62.7 62.7 0 0 0-64.77-15c-10.697 31.102 4.436 65.185 34.68 78.11v118.26H0v71.48h133.1v136.43h71.5V424.8h133.1v-71.48H204.6Z" fill="',
'" transform="translate(251.4 219.77)"/><path d="M412.2 110.1a41.89 41.89 0 0 0 29.65-51.32 41.9 41.9 0 0 0-51.33 29.64 41.88 41.88 0 0 0-51.32-29.64 41.87 41.87 0 0 0 29.65 51.32 41.89 41.89 0 0 0-29.65 51.33 41.89 41.89 0 0 0 51.32-29.65 41.91 41.91 0 0 0 51.33 29.65 41.91 41.91 0 0 0-29.65-51.33Z" fill="',
'" transform="translate(251.4 219.77)"/>',
100000000000000
);
ICONs[12] = ICON("Glasses",
'<path d="M388.675 526.155 359.986 514l-68.59 161.446-41.227-17.48L238 686.623l111.132 47.105 12.169-28.645-41.216-17.481zM756.64 753.883l-43.845 9.146-35.86-171.69-30.506 6.363 35.86 171.68-43.833 9.146 6.36 30.472L763 784.355z" fill="',
'"/><g fill="',
'"><path d="m416.591 191.014 163.89 69.568-104.75 246.777c-19.214 45.266-71.486 66.386-116.752 47.17-45.246-19.226-66.347-71.485-47.138-116.737l104.75-246.779Z"/><path d="m508.847 299.818 174.311-36.384 54.78 262.445c10.048 48.139-20.831 95.307-68.969 105.355a89.04 89.04 0 0 1-105.354-68.969l-54.78-262.444.012-.002Z"/></g><path d="M363.087 316.992 527 386.57l-51.278 120.802c-19.214 45.266-71.485 66.385-116.752 47.17-45.266-19.214-66.386-71.485-47.171-116.752l51.277-120.8.01.004Z" fill="',
'"/><path d="m535.582 427.924 174.323-36.386L737.95 525.89c10.038 48.121-20.82 95.272-68.936 105.336a89.04 89.04 0 0 1-105.354-68.969l-28.041-134.341-.036.007Z" fill="',
'"/>',
100000000000000
);
ICONs[13] = ICON("Snow 2",
'<path d="M797.86 456.09 786.69 408l-82.94 19.2 33.5-53.74-41.93-26.14L635.69 443l-59.82 13.88a86.73 86.73 0 0 0-27.44-29.43l17.95-58.7 99.55-52.91-23.19-43.63-55.92 29.72 24.9-81.42-47.24-14.45-24.91 81.42-29.73-55.92-43.62 23.19 52.91 99.55-17.95 58.7a86.56 86.56 0 0 0-39.36 9.12l-41.9-44.89 3.88-112.68-49.38-1.7-2.18 63.3-58.1-62.24L278 297.62l58.1 62.24-63.3-2.18-1.7 49.38 112.68 3.88 41.89 44.88a86.66 86.66 0 0 0-11.78 38.65l-59.8 13.88-95.68-59.64-26.14 41.93 53.73 33.5-82.9 19.25 11.17 48.13 82.94-19.25-33.5 53.73 41.93 26.14 59.64-95.68 59.82-13.89A86.53 86.53 0 0 0 452.54 572l-18 58.7L335 683.64l23.19 43.63 55.92-29.73L389.24 779l47.25 14.46 24.9-81.46 29.73 55.93 43.63-23.19-52.92-99.56 18-58.69a86.68 86.68 0 0 0 39.35-9.12l41.91 44.89-3.88 112.68 49.38 1.7 2.18-63.3 58.1 62.24L723 701.86l-58.1-62.25 63.29 2.18 1.7-49.38-112.67-3.87-41.9-44.88A86.5 86.5 0 0 0 587.06 505l59.8-13.88 95.68 59.64 26.13-41.93-53.75-33.51 82.94-19.23Zm-264.21 53.79a34.68 34.68 0 1 1-23-43.31c18.305 5.615 28.6 25 23 43.31Z" fill="',
'"/><path fill="',
'"/><path fill="',
'"/><path fill="',
'"/>',
100000000000000
);
ICONs[14] = ICON("Gift",
'<path d="M412.09 733.7v25c-18.429 3.497-31.767 19.603-31.77 38.36h80.59V733.7h-48.82Zm129.65 25.03v-25h-48.82v63.39h80.59c.032-18.776-13.32-34.91-31.77-38.39Zm-67.38-400.01c43.986.006 79.64 35.664 79.64 79.65v194.69H394.71V438.37c0-43.99 35.66-79.65 79.65-79.65Z" fill="',
'"/><path d="M509 228.14a41.44 41.44 0 1 0-79.8 4A56.776 56.776 0 1 0 476 335.6a56.75 56.75 0 1 0 33-107.46Zm-45.67 582.13h-13.46v-13.18h-12v13.18h-36v-13.18H390v13.18h-4.78c-6.555-.005-11.869-5.315-11.88-11.87a6 6 0 1 0-11.95 0c.017 13.153 10.678 23.81 23.83 23.82h78.12a6 6 0 1 0 0-12l-.01.05Zm123.15-17.85a6 6 0 0 0-6 6c-.005 6.554-5.317 11.865-11.87 11.87h-4.79v-13.2h-11.93v13.18h-36v-13.18H504v13.18h-13.5a6 6 0 0 0 0 12h78.13c13.149-.016 23.804-10.671 23.82-23.82a6 6 0 0 0-5.97-6.03ZM451.7 396.07h163.57v123.37H451.7z" fill="',
'"/><g transform="translate(429.05 276.32)" fill="',
'"><path d="M.38 0v36c0 26.82 24 50.89 50.85 50.89 26.82 0 47.66-24.07 47.66-50.89V0H.38Zm83.94 119.75h40.23v123.37H84.32z"/><circle cx="22.65" cy="203.3" r="22.65"/><circle cx="186.22" cy="203.3" r="22.65"/></g><path d="M412.505 633.05h48v105h-48zm129.065 105H493.1v-105h48.47zM429.43 314.21h210.15v89.4H429.43z" fill="',
'"/><g transform="translate(443.27 294.61)"><circle cx="56.64" cy="6.36" r="6.36"/><circle cx="25.31" cy="6.36" r="6.36"/><circle cx="8.43" cy="79.46" r="8.43"/><path d="M35.39 40.47a8.43 8.43 0 1 0 0 16.86 8.43 8.43 0 0 0 0-16.86Z"/><circle cx="134.65" cy="83.47" r="8.43"/><circle cx="110.74" cy="43.29" r="8.43"/><circle cx="76.19" cy="75.03" r="8.43"/><circle cx="165.89" cy="46.3" r="8.43"/></g>',
100000000000000
);
ICONs[15] = ICON("Candy",
'<path d="M322.608 849 244 770.477l385.286-384.865a53.03 53.03 0 0 0 14.064-51.411c-4.892-18.416-19.291-32.8-37.727-37.686a53.166 53.166 0 0 0-51.468 14.048l-22.98 22.955-78.595-78.523 22.98-22.942c64.164-64.08 168.184-64.07 232.334.025 64.151 64.095 64.14 168-.025 232.082L322.61 849Z" fill="',
'"/><path fill="',
'" d="m492.321 522.428 124.662 32.519-25.974 25.945-124.662-32.519zm255.42-225.813-102.633 52.607a52.972 52.972 0 0 0-1.758-15.021 52.991 52.991 0 0 0-7.227-15.95l98.8-50.646a162.897 162.897 0 0 1 12.818 29.01ZM580.624 184.372l.529 111.486a53.12 53.12 0 0 0-26.998 14.705l-4.59 4.585-.597-125.524a164.925 164.925 0 0 1 31.656-5.252Zm13.392 236.472 136.161 15.649a164.743 164.743 0 0 1-22.308 27.667l-1.47 1.467-140.995-16.202 28.612-28.581ZM284.162 730.359l124.662 32.519-25.973 25.945-124.663-32.519zM388.285 626.35l124.991 32.191-26.066 26.037-124.99-32.192z"/><path fill="',
'"/><path fill="',
'"/>',
100000000000000
);
ICONs[16] = ICON("Ball 2",
'<circle fill="',
'" cx="500.5" cy="574.5" r="294.5"/><path d="m268.898 393 521.259 232.081c-8.18 48.637-28.282 93.228-57.198 130.664L210 522.906c8.805-48.477 29.477-92.818 58.898-129.906Z" fill="',
'"/><path d="M727.66 217.564c11.226-25.187 4.347-54.79-16.826-72.403-21.172-17.614-51.451-18.926-74.059-3.208-22.607 15.717-32.005 44.615-22.987 70.679l-16.722-7.52a26.16 26.16 0 0 0-20.069-.583 26.262 26.262 0 0 0-14.6 13.822L534 281.829 696.626 355l28.397-63.464a26.377 26.377 0 0 0 .587-20.135 26.275 26.275 0 0 0-13.788-14.65l-16.707-7.52a61.023 61.023 0 0 0 32.545-31.667Zm-27.242-12.294c-7.117 15.818-25.663 22.866-41.445 15.751s-22.836-25.705-15.764-41.543c7.072-15.838 25.598-22.94 41.4-15.87a31.272 31.272 0 0 1 16.59 17.516 31.394 31.394 0 0 1-.781 24.146Z" fill="',
'"/><path fill="',
'"/>',
100000000000000
);
ICONs[17] = ICON("Tree 4",
'<path fill="',
'" d="M0 1000h1000V-1H826.307z"/><g transform="translate(429 113)" fill="',
'"><circle cx="82" cy="716" r="82"/><path d="M571 14.257C536.894-9.04 490.806-3.26 463.488 27.74c-27.317 31-27.317 77.519 0 108.518 27.318 31 73.406 36.78 107.512 13.484V14.257Z"/></g><g transform="translate(418 335)" fill="',
'"><circle cx="82" cy="82" r="82"/><path d="M582 558.215c-31.26-21.294-73.051-18.415-101.09 6.962-28.04 25.378-35.024 66.645-16.895 99.823H582V558.215Z"/></g><circle fill="',
'" cx="790" cy="582" r="82"/>',
100000000000000
);
ICONs[18] = ICON("Wreath",
'<path d="M839.774 512.895a42.555 42.555 0 0 0-20.52-32.228 42.61 42.61 0 0 0 5.806-37.747 42.624 42.624 0 0 0-26.771-27.242 42.623 42.623 0 0 0-2.193-38.139 42.642 42.642 0 0 0-31.872-21.07 42.612 42.612 0 0 0-10.071-36.826 42.634 42.634 0 0 0-35.531-13.987 42.603 42.603 0 0 0-17.47-33.938 42.624 42.624 0 0 0-37.65-6.33 42.583 42.583 0 0 0-24.145-29.613 42.6 42.6 0 0 0-38.177 1.665 42.649 42.649 0 0 0-66.783-14.33 42.569 42.569 0 0 0-34.09-17.11h-.763a42.543 42.543 0 0 0-34.128 17.086 42.534 42.534 0 0 0-36.975-9.655 42.424 42.424 0 0 0-29.897 23.831 42.6 42.6 0 0 0-38.175-1.767 42.583 42.583 0 0 0-24.225 29.55 42.65 42.65 0 0 0-37.677 6.239 42.629 42.629 0 0 0-17.569 33.902 42.609 42.609 0 0 0-35.587 13.88 42.587 42.587 0 0 0-10.154 36.818 42.591 42.591 0 0 0-31.924 20.972 42.572 42.572 0 0 0-2.268 38.123 42.624 42.624 0 0 0-26.874 27.178 42.61 42.61 0 0 0 5.718 37.786 42.626 42.626 0 0 0-7.128 67.86 42.626 42.626 0 0 0 7.065 67.873 42.649 42.649 0 0 0-5.744 37.768 42.662 42.662 0 0 0 26.81 27.221 42.661 42.661 0 0 0 2.272 38.123 42.68 42.68 0 0 0 31.882 21.036 42.561 42.561 0 0 0 10.107 36.813 42.583 42.583 0 0 0 35.559 13.91 42.578 42.578 0 0 0 17.49 33.937 42.599 42.599 0 0 0 37.667 6.281 42.583 42.583 0 0 0 24.23 29.67 42.6 42.6 0 0 0 38.27-1.8 42.636 42.636 0 0 0 66.808 14.24A42.708 42.708 0 0 0 499.137 890a42.518 42.518 0 0 0 34.104-17.048 42.636 42.636 0 0 0 66.846-14.075 42.65 42.65 0 0 0 38.203 1.807 42.634 42.634 0 0 0 24.285-29.538 42.637 42.637 0 0 0 37.663-6.217 42.616 42.616 0 0 0 17.583-33.874 42.621 42.621 0 0 0 35.551-13.868 42.6 42.6 0 0 0 10.191-36.766 42.642 42.642 0 0 0 31.951-20.937 42.623 42.623 0 0 0 2.355-38.12 42.586 42.586 0 0 0 26.89-27.148 42.573 42.573 0 0 0-5.709-37.778 42.614 42.614 0 0 0 7.23-67.873 42.55 42.55 0 0 0 13.494-35.67ZM386.32 548.019c-.006-45.781 27.575-87.057 69.88-104.58 42.306-17.522 91.003-7.839 123.383 24.534 32.38 32.372 42.064 81.058 24.538 123.353-17.526 42.296-58.811 69.87-104.603 69.865-62.515-.007-113.191-50.672-113.198-113.172Z" fill="',
'"/><g transform="translate(206 225)" fill="',
'"><path d="m353 143-58.5-38.304L236 143V0h117z"/><circle cx="306" cy="568" r="31"/><circle cx="31" cy="351" r="31"/></g><g transform="translate(302 110)" fill="',
'"><path d="M333 0 197.5 63.33 62 0v190l135.5-63.33L333 190z"/><circle cx="31" cy="621" r="31"/><circle cx="441" cy="438" r="31"/></g><g transform="translate(267 354)" fill="',
'"><circle cx="31" cy="42" r="31"/><circle cx="415" cy="31" r="31"/><circle cx="403" cy="373" r="31"/></g>',
100000000000000
);
ICONs[19] = ICON("Biscuit",
'<path d="M802.175 372.242H576.994c55.785-34.82 81.736-102.352 63.61-165.529C622.477 143.536 564.659 100 498.884 100c-65.776 0-123.595 43.536-141.721 106.713-18.127 63.177 7.824 130.709 63.609 165.53H196.774c-39.316-.323-71.449 31.26-71.774 70.544-.32 39.283 31.29 71.39 70.605 71.713h173.782L292.6 784.32c-8.803 30.95-.412 64.24 22.012 87.333 22.424 23.092 55.474 32.477 86.7 24.62 31.227-7.858 55.886-31.765 64.69-62.714l30.333-106.666 30.361 106.638c8.508 31.302 33.202 55.616 64.652 63.655 31.449 8.04 64.795-1.437 87.303-24.81 22.507-23.374 30.699-57.034 21.446-88.124L623.27 514.527h177.736c39.014-.114 70.671-31.577 70.994-70.558.318-38.981-30.818-70.96-69.825-71.713v-.014Z" fill="',
'"/><g transform="translate(449 189)" fill="',
'"><circle cx="21" cy="21" r="21"/><circle cx="86" cy="24" r="21"/><path d="M97.817 71c.604.003 1.18.248 1.592.68.412.43.624 1.008.587 1.597C98.753 98.335 77.609 118.021 51.959 118 26.31 117.979 5.2 98.257 4 73.197a2.122 2.122 0 0 1 .623-1.55A2.217 2.217 0 0 1 6.193 71h91.624Z"/></g><g transform="translate(474 435)" fill="',
'"><circle cx="27" cy="27" r="27"/><circle cx="27" cy="142" r="27"/></g><path fill="',
'"/>',
100000000000000
);
ICONs[20] = ICON("Star 2",
'<g><path fill="',
'" d="M424.489 410.228 163.048 377.05l222.061 141.774-159.805 210.463 234.206-118.64 101.616 243.414 15.348-264.194 261.494 33.266-222.077-141.956 159.825-210.235-234.218 118.502-101.715-243.497z"/><path fill="',
'" d="m465.536 405.254-201.183-103.54 137.524 179.588-190.73 122.872 223.792-26.942 10.505 226.22 89.961-208.64 201.201 103.626-137.483-179.74L789.8 396.016l-223.76 26.828-10.56-226.317z"/><path fill="',
'" d="m430.187 549.702-40.875 188.532 117.553-152.887 143.279 129.96-71.573-178.357 183.987-58.571-191.678-28.047 40.942-188.566-117.687 152.887-143.111-129.96 71.472 178.357-184.054 58.638z"/><path fill="',
'" d="m464.108 448.517-138.044-29.929L438.01 504.66l-95.16 104.91 130.594-52.406 42.886 134.715 20.536-140.346 138.069 29.977-111.945-86.17 95.158-104.787-130.594 52.332-42.935-134.764z"/></g>',
100000000000000
);
ICONs[21] = ICON("Nordic Trees",
'<g><path fill="',
'" d="m618.03 196 203.002 804.806H415.03z"/><path fill="',
'" d="m154.813 557.23 154.812 443.576H0z"/><path fill="',
'" d="m395.266 387.045 154.813 613.761H240.454z"/><path fill="',
'" d="M838.05 583.58 1000 1000.807H676.101z"/></g>',
100000000000000
);
number_of_icons = 21;
// NGOs
NGOs[1] = NGO(0xc3e302e8FDa21b9C020e6388d8052C8055530AdA, "Save the Children");
NGOs[2] = NGO(0x63BBc9a8a5D3f66277d9553B73453f59A3C5EcA0, "Coral Restoration Foundation");
NGOs[3] = NGO(0xE9bc9DdcEd5685B3871d52EaD8253C4BeA78B935, "Stichting The Ocean Cleanup");
NGOs[4] = NGO(0xCdB1cd005918CB00514F3d31872fe40443A52c8c, "Pollinator Partnership Canada");
NGOs[5] = NGO(0xcD26C12578B3FDF80D4203CD932e99825F218E6B, "FundLife International");
NGOs[6] = NGO(0xB41077c30a1cD16b04776740806Fe2BA18E7AD8D, "AfricAid");
NGOs[7] = NGO(0xfA371b51f11B9B32AD597d7c43A302107F66bf94, "National PCF");
NGOs[8] = NGO(0x777e24f9d6Aa4CBe853079935560C8c5B80f9B42, "Fondazione Umberto Veronesi");
NGOs[9] = NGO(0x496c13C7Ab3cD4Ea167062956da08cade3A562dF, "Global Impact");
NGOs[10] = NGO(0x8d53637779338c27FC41c323defe8dB4F8dFdDf0, "International Medical Corps");
NGOs[11] = NGO(0xA4166BC4Be559b762B346CB4AAad3b051E584E39, "Razom");
NGOs[12] = NGO(0x968DC9065969bBf2652639658b963E287336bF34, "Operation Broken Silence");
NGOs[13] = NGO(0x36f66F445340E1d58419c6d5EeB71a19323B88e4, "Autism Speaks");
NGOs[14] = NGO(0xaF3e16a5bf3320A919A6f67c85954d94EA70224e, "Girls Who Code");
NGOs[15] = NGO(0xf6285e6a3293b4C658F19cC6cAA9123cF5190a84, "2535 Water");
number_of_NGOs = 15;
// Colors
COLORs[0] = '#000000';
COLORs[1] = '#2D2D2D';
COLORs[2] = '#0E1F4E';
COLORs[3] = '#7F336B';
COLORs[4] = '#144100';
COLORs[5] = '#006657';
COLORs[6] = '#8FAB70';
COLORs[7] = '#88171A';
COLORs[8] = '#EF4046';
COLORs[9] = '#FF5A00';
COLORs[10] = '#85D1FF';
COLORs[11] = '#94BAAF';
COLORs[12] = '#E0B82F';
COLORs[13] = '#F1E65E';
COLORs[14] = '#FDE9F1';
COLORs[15] = '#EBE6DC';
COLORs[16] = '#FFFFFF';
number_of_colors = 16;
}
string private constant BG_1 = '<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="1000" height="1000" viewBox="0 0 1000 1000"><g stroke="none" fill="none"><rect fill="';
string private constant BG_2 = '" x="0" y="0" width="1000" height="1000"></rect></g>';
string private constant TEXT_1 = '<g stroke="none" stroke-width="1" font-family="Helvetica, Arial" font-size="83" font-weight="normal" letter-spacing="0.0166" line-spacing="79"><text x="60" y="1.5em" fill="#FFFFFF">';
string private constant TX_1 = '</text></g><g stroke="none" stroke-width="1" font-family="Helvetica, Arial" font-size="30" font-weight="normal" letter-spacing="0.0166" line-spacing="79"><text x="50%" y="950" dominant-baseline="middle" text-anchor="middle" fill="#FFFFFF">';
string private constant TX_2 = '</text></g>';
function baseTokenURI() override public pure returns (string memory) { return ""; }
// String Concat functions
function con(string memory s_1, string memory s_2) internal pure returns (string memory) {
return string(s_1.toSlice().concat(s_2.toSlice()));
}
function con(string memory s_1, string memory s_2, string memory s_3) internal pure returns (string memory) {
return con(con(s_1,s_2),s_3);
}
function con(string memory s_1, string memory s_2, string memory s_3, string memory s_4) internal pure returns (string memory) {
return con(con(s_1,s_2,s_3),s_4);
}
function con(string memory s_1, string memory s_2, string memory s_3, string memory s_4, string memory s_5) internal pure returns (string memory) {
return con(con(s_1,s_2,s_3,s_4),s_5);
}
function con(string memory s_1, string memory s_2, string memory s_3, string memory s_4, string memory s_5, string memory s_6) internal pure returns (string memory) {
return con(con(s_1,s_2,s_3,s_4,s_5),s_6);
}
function getTOKEN(uint256 _tokenId) public view returns (string memory) {
Card memory card = get_card(_tokenId);
string memory bg = con(BG_1, COLORs[card.bg_color], BG_2);
string memory icon;
icon = con(ICONs[card.icon_id].part_1, COLORs[card.icon_color_1], ICONs[card.icon_id].part_2, COLORs[card.icon_color_2], ICONs[card.icon_id].part_3);
icon = con(icon, COLORs[card.icon_color_3], ICONs[card.icon_id].part_4, COLORs[card.icon_color_4], ICONs[card.icon_id].part_5);
string memory txt = con(TEXT_1, card.message);
string memory dona = con(TX_1, DONAs[card.donated], ' ETH donated to ', NGOs[card.NGO_id].name, TX_2);
string memory svg = con(bg, icon, txt, dona, '</svg>');
return string(abi.encodePacked('","image":"data:image/svg+xml;base64,',Base64.encode(bytes(svg))));
}
function getAttributes(uint256 _tokenId) internal view returns (string memory) {
Card memory card = get_card(_tokenId);
string memory json = con( '", "attributes":[ {"trait_type":"Donated to","value":"', NGOs[card.NGO_id].name);
json = con( json,'"},{"trait_type":"Donated amount","value":"', DONAs[card.donated], ' ETH"},' );
json = con( json, '{"trait_type":"Icon","value":"', ICONs[card.icon_id].name, '"}]}' );
return json;
}
function tokenURI(uint256 _tokenId) override public view returns (string memory) {
return string(
abi.encodePacked(
"data:application/json;base64,",
Base64.encode(
bytes(
abi.encodePacked(
con('{"name":"Xmas Card #', Strings.toString(_tokenId), '",'),
con('"description":"This unique NFT certifies that', DONAs[get_card(_tokenId).donated], ' ETH were donated to ', NGOs[get_card(_tokenId).NGO_id].name),
getTOKEN(_tokenId),
getAttributes(_tokenId)
)
)
)
)
);
}
function contractURI() public pure returns (string memory) {
return string(abi.encodePacked(
"data:application/json;base64,",
Base64.encode(
bytes(
'{"name":"Donate Xmas","description":"Create your NFT Christmas postcard and donate to a charity organization","image":"","external_link":"https://donate-xmas.com","seller_fee_basis_points":0,"fee_recipient":""}'
)
)
));
}
// Donation
function donate(uint256 amount, uint256 NGO_id) internal {
payable(NGOs[NGO_id].addr).transfer(amount);
}
// Mint
function mint_card(
address _to,
string memory _message,
uint256 _NGO_id,
uint256 _icon_id,
uint256 _bg_color,
uint256 _icon_color_1,
uint256 _icon_color_2,
uint256 _icon_color_3,
uint256 _icon_color_4
) external payable returns(uint256 _token_id) {
require(msg.value >= ICONs[_icon_id].min_donation, "Minimum donation amount not crossed");
require( bytes(DONAs[msg.value]).length > 0, "Donation amount should be one of 0.01, 0.05, 0.1, 0.25, 0.5, 1, 5, or 10 ETH");
uint256 token_id = mintTo(_to, _message, msg.value, _NGO_id, _icon_id, _bg_color, _icon_color_1, _icon_color_2, _icon_color_3, _icon_color_4);
donate(msg.value, _NGO_id);
return token_id;
}
// Functions to add new icons, colors, and NGOs after publication
function add_icon(
string memory name,
string memory part_1,
string memory part_2,
string memory part_3,
string memory part_4,
string memory part_5,
uint256 min_donation
) external returns(uint256 _number_of_icons) {
require(msg.sender == owner(), 'Only the owner can do this');
number_of_icons ++;
ICONs[number_of_icons] = ICON(name, part_1, part_2, part_3, part_4, part_5, min_donation);
emit new_ICON(number_of_icons);
return number_of_icons;
}
function add_color(
string memory color_hex
) external returns(uint256 _number_of_colors) {
require(msg.sender == owner(), 'Only the owner can do this');
number_of_colors ++;
COLORs[number_of_colors] = color_hex;
emit new_COLOR(number_of_colors);
return number_of_colors;
}
function add_NGO(
string memory name,
address addr
) external returns(uint256 _number_of_NGOs) {
require(msg.sender == owner(), 'Only the owner can do this');
number_of_NGOs ++;
NGOs[number_of_NGOs] = NGO(addr, name);
emit new_NGO(number_of_NGOs);
return number_of_NGOs;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "openzeppelin-solidity/contracts/token/ERC721/ERC721.sol";
import "openzeppelin-solidity/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import "openzeppelin-solidity/contracts/access/Ownable.sol";
//import "openzeppelin-solidity/contracts/utils/math/SafeMath.sol";
//import "openzeppelin-solidity/contracts/utils/Strings.sol";
import "./common/meta-transactions/ContentMixin.sol";
import "./common/meta-transactions/NativeMetaTransaction.sol";
import "./Base64.sol";
import "./strings.sol";
contract OwnableDelegateProxy {}
contract ProxyRegistry {
mapping(address => OwnableDelegateProxy) public proxies;
}
/**
* @title ERC721Tradable
* ERC721Tradable - ERC721 contract that whitelists a trading address, and has minting functionality.
*/
abstract contract ERC721Tradable is ContextMixin, ERC721Enumerable, NativeMetaTransaction, Ownable {
//using SafeMath for uint256;
address proxyRegistryAddress;
uint256 private _currentTokenId = 0;
event Created(uint256 tokenId, address receiver, uint256 amount, uint256 NGO_id);
struct Card {
address creator;
string message;
uint256 donated;
uint256 NGO_id;
uint256 icon_id;
uint256 bg_color;
uint256 icon_color_1;
uint256 icon_color_2;
uint256 icon_color_3;
uint256 icon_color_4;
}
mapping(uint256 => Card) private cards_list;
constructor(
string memory _name,
string memory _symbol,
address _proxyRegistryAddress
) ERC721(_name, _symbol) {
proxyRegistryAddress = _proxyRegistryAddress;
_initializeEIP712(_name);
}
/**
* @dev Mints a card to an address with a tokenURI.
* @param _to address of the future owner of the card
*/
function mintTo(
address _to,
string memory _message,
uint256 _amount,
uint256 _NGO_id,
uint256 _icon_id,
uint256 _bg_color,
uint256 _icon_color_1,
uint256 _icon_color_2,
uint256 _icon_color_3,
uint256 _icon_color_4
) internal returns(uint256 _token_id) {
uint256 newTokenId = _getNextTokenId();
_mint(_to, newTokenId);
_incrementTokenId();
//string memory dona = Strings.toString(_amount/10**14);
cards_list[_currentTokenId] = Card(msg.sender, _message, _amount, _NGO_id, _icon_id, _bg_color, _icon_color_1, _icon_color_2, _icon_color_3, _icon_color_4);
emit Created(newTokenId, _to, _amount, _NGO_id);
return newTokenId;
}
// Views
function read_card(uint256 card_id) public view returns(string memory) {
return cards_list[card_id].message;
}
function get_card(uint256 card_id) public view returns(Card memory) {
return cards_list[card_id];
}
function _getNextTokenId() private view returns (uint256) { return _currentTokenId + 1; }
function _incrementTokenId() private { _currentTokenId++; }
function baseTokenURI() virtual public pure returns (string memory);
function tokenURI(uint256 _tokenId) override public view virtual returns (string memory) {
return string(abi.encodePacked(baseTokenURI(), Strings.toString(_tokenId)));
}
/**
* This is used instead of msg.sender as transactions won't be sent by the original token owner, but by OpenSea.
*/
function _msgSender()
internal
override
view
returns (address sender)
{
return ContextMixin.msgSender();
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0;
library Base64 {
string internal constant TABLE_ENCODE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
bytes internal constant TABLE_DECODE = hex"0000000000000000000000000000000000000000000000000000000000000000"
hex"00000000000000000000003e0000003f3435363738393a3b3c3d000000000000"
hex"00000102030405060708090a0b0c0d0e0f101112131415161718190000000000"
hex"001a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132330000000000";
function encode(bytes memory data) internal pure returns (string memory) {
if (data.length == 0) return '';
string memory table = TABLE_ENCODE;
uint256 encodedLen = 4 * ((data.length + 2) / 3);
string memory result = new string(encodedLen + 32);
assembly {
mstore(result, encodedLen)
let tablePtr := add(table, 1)
let dataPtr := data
let endPtr := add(dataPtr, mload(data))
let resultPtr := add(result, 32)
for {} lt(dataPtr, endPtr) {}
{
dataPtr := add(dataPtr, 3)
let input := mload(dataPtr)
mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))
resultPtr := add(resultPtr, 1)
mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))
resultPtr := add(resultPtr, 1)
mstore8(resultPtr, mload(add(tablePtr, and(shr( 6, input), 0x3F))))
resultPtr := add(resultPtr, 1)
mstore8(resultPtr, mload(add(tablePtr, and( input, 0x3F))))
resultPtr := add(resultPtr, 1)
}
switch mod(mload(data), 3)
case 1 { mstore(sub(resultPtr, 2), shl(240, 0x3d3d)) }
case 2 { mstore(sub(resultPtr, 1), shl(248, 0x3d)) }
}
return result;
}
function decode(string memory _data) internal pure returns (bytes memory) {
bytes memory data = bytes(_data);
if (data.length == 0) return new bytes(0);
require(data.length % 4 == 0, "invalid base64 decoder input");
bytes memory table = TABLE_DECODE;
uint256 decodedLen = (data.length / 4) * 3;
bytes memory result = new bytes(decodedLen + 32);
assembly {
let lastBytes := mload(add(data, mload(data)))
if eq(and(lastBytes, 0xFF), 0x3d) {
decodedLen := sub(decodedLen, 1)
if eq(and(lastBytes, 0xFFFF), 0x3d3d) {
decodedLen := sub(decodedLen, 1)
}
}
mstore(result, decodedLen)
let tablePtr := add(table, 1)
let dataPtr := data
let endPtr := add(dataPtr, mload(data))
let resultPtr := add(result, 32)
for {} lt(dataPtr, endPtr) {}
{
dataPtr := add(dataPtr, 4)
let input := mload(dataPtr)
let output := add(
add(
shl(18, and(mload(add(tablePtr, and(shr(24, input), 0xFF))), 0xFF)),
shl(12, and(mload(add(tablePtr, and(shr(16, input), 0xFF))), 0xFF))),
add(
shl( 6, and(mload(add(tablePtr, and(shr( 8, input), 0xFF))), 0xFF)),
and(mload(add(tablePtr, and( input , 0xFF))), 0xFF)
)
)
mstore(resultPtr, shl(232, output))
resultPtr := add(resultPtr, 3)
}
}
return result;
}
}/*
* @title String & slice utility library for Solidity contracts.
* @author Nick Johnson <arachnid@notdot.net>
*
* @dev Functionality in this library is largely implemented using an
* abstraction called a 'slice'. A slice represents a part of a string -
* anything from the entire string to a single character, or even no
* characters at all (a 0-length slice). Since a slice only has to specify
* an offset and a length, copying and manipulating slices is a lot less
* expensive than copying and manipulating the strings they reference.
*
* To further reduce gas costs, most functions on slice that need to return
* a slice modify the original one instead of allocating a new one; for
* instance, `s.split(".")` will return the text up to the first '.',
* modifying s to only contain the remainder of the string after the '.'.
* In situations where you do not want to modify the original slice, you
* can make a copy first with `.copy()`, for example:
* `s.copy().split(".")`. Try and avoid using this idiom in loops; since
* Solidity has no memory management, it will result in allocating many
* short-lived slices that are later discarded.
*
* Functions that return two slices come in two versions: a non-allocating
* version that takes the second slice as an argument, modifying it in
* place, and an allocating version that allocates and returns the second
* slice; see `nextRune` for example.
*
* Functions that have to copy string data will return strings rather than
* slices; these can be cast back to slices for further processing if
* required.
*
* For convenience, some functions are provided with non-modifying
* variants that create a new slice and return both; for instance,
* `s.splitNew('.')` leaves s unmodified, and returns two values
* corresponding to the left and right parts of the string.
*/
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
library strings {
struct slice {
uint _len;
uint _ptr;
}
function memcpy(uint dest, uint src, uint _len) private pure {
// Copy word-length chunks while possible
for(; _len >= 32; _len -= 32) {
assembly {
mstore(dest, mload(src))
}
dest += 32;
src += 32;
}
// Copy remaining bytes
uint mask = type(uint).max;
if (_len > 0) {
mask = 256 ** (32 - _len) - 1;
}
assembly {
let srcpart := and(mload(src), not(mask))
let destpart := and(mload(dest), mask)
mstore(dest, or(destpart, srcpart))
}
}
/*
* @dev Returns a slice containing the entire string.
* @param self The string to make a slice from.
* @return A newly allocated slice containing the entire string.
*/
function toSlice(string memory self) internal pure returns (slice memory) {
uint ptr;
assembly {
ptr := add(self, 0x20)
}
return slice(bytes(self).length, ptr);
}
/*
* @dev Returns the length of a null-terminated bytes32 string.
* @param self The value to find the length of.
* @return The length of the string, from 0 to 32.
*/
function len(bytes32 self) internal pure returns (uint) {
uint ret;
if (self == 0)
return 0;
if (uint(self) & type(uint128).max == 0) {
ret += 16;
self = bytes32(uint(self) / 0x100000000000000000000000000000000);
}
if (uint(self) & type(uint64).max == 0) {
ret += 8;
self = bytes32(uint(self) / 0x10000000000000000);
}
if (uint(self) & type(uint32).max == 0) {
ret += 4;
self = bytes32(uint(self) / 0x100000000);
}
if (uint(self) & type(uint16).max == 0) {
ret += 2;
self = bytes32(uint(self) / 0x10000);
}
if (uint(self) & type(uint8).max == 0) {
ret += 1;
}
return 32 - ret;
}
/*
* @dev Returns a slice containing the entire bytes32, interpreted as a
* null-terminated utf-8 string.
* @param self The bytes32 value to convert to a slice.
* @return A new slice containing the value of the input argument up to the
* first null.
*/
function toSliceB32(bytes32 self) internal pure returns (slice memory ret) {
// Allocate space for `self` in memory, copy it there, and point ret at it
assembly {
let ptr := mload(0x40)
mstore(0x40, add(ptr, 0x20))
mstore(ptr, self)
mstore(add(ret, 0x20), ptr)
}
ret._len = len(self);
}
/*
* @dev Returns a new slice containing the same data as the current slice.
* @param self The slice to copy.
* @return A new slice containing the same data as `self`.
*/
function copy(slice memory self) internal pure returns (slice memory) {
return slice(self._len, self._ptr);
}
/*
* @dev Copies a slice to a new string.
* @param self The slice to copy.
* @return A newly allocated string containing the slice's text.
*/
function toString(slice memory self) internal pure returns (string memory) {
string memory ret = new string(self._len);
uint retptr;
assembly { retptr := add(ret, 32) }
memcpy(retptr, self._ptr, self._len);
return ret;
}
/*
* @dev Returns the length in runes of the slice. Note that this operation
* takes time proportional to the length of the slice; avoid using it
* in loops, and call `slice.empty()` if you only need to know whether
* the slice is empty or not.
* @param self The slice to operate on.
* @return The length of the slice in runes.
*/
function len(slice memory self) internal pure returns (uint l) {
// Starting at ptr-31 means the LSB will be the byte we care about
uint ptr = self._ptr - 31;
uint end = ptr + self._len;
for (l = 0; ptr < end; l++) {
uint8 b;
assembly { b := and(mload(ptr), 0xFF) }
if (b < 0x80) {
ptr += 1;
} else if(b < 0xE0) {
ptr += 2;
} else if(b < 0xF0) {
ptr += 3;
} else if(b < 0xF8) {
ptr += 4;
} else if(b < 0xFC) {
ptr += 5;
} else {
ptr += 6;
}
}
}
/*
* @dev Returns true if the slice is empty (has a length of 0).
* @param self The slice to operate on.
* @return True if the slice is empty, False otherwise.
*/
function empty(slice memory self) internal pure returns (bool) {
return self._len == 0;
}
/*
* @dev Returns a positive number if `other` comes lexicographically after
* `self`, a negative number if it comes before, or zero if the
* contents of the two slices are equal. Comparison is done per-rune,
* on unicode codepoints.
* @param self The first slice to compare.
* @param other The second slice to compare.
* @return The result of the comparison.
*/
function compare(slice memory self, slice memory other) internal pure returns (int) {
uint shortest = self._len;
if (other._len < self._len)
shortest = other._len;
uint selfptr = self._ptr;
uint otherptr = other._ptr;
for (uint idx = 0; idx < shortest; idx += 32) {
uint a;
uint b;
assembly {
a := mload(selfptr)
b := mload(otherptr)
}
if (a != b) {
// Mask out irrelevant bytes and check again
uint mask = type(uint).max; // 0xffff...
if(shortest < 32) {
mask = ~(2 ** (8 * (32 - shortest + idx)) - 1);
}
unchecked {
uint diff = (a & mask) - (b & mask);
if (diff != 0)
return int(diff);
}
}
selfptr += 32;
otherptr += 32;
}
return int(self._len) - int(other._len);
}
/*
* @dev Returns true if the two slices contain the same text.
* @param self The first slice to compare.
* @param self The second slice to compare.
* @return True if the slices are equal, false otherwise.
*/
function equals(slice memory self, slice memory other) internal pure returns (bool) {
return compare(self, other) == 0;
}
/*
* @dev Extracts the first rune in the slice into `rune`, advancing the
* slice to point to the next rune and returning `self`.
* @param self The slice to operate on.
* @param rune The slice that will contain the first rune.
* @return `rune`.
*/
function nextRune(slice memory self, slice memory rune) internal pure returns (slice memory) {
rune._ptr = self._ptr;
if (self._len == 0) {
rune._len = 0;
return rune;
}
uint l;
uint b;
// Load the first byte of the rune into the LSBs of b
assembly { b := and(mload(sub(mload(add(self, 32)), 31)), 0xFF) }
if (b < 0x80) {
l = 1;
} else if(b < 0xE0) {
l = 2;
} else if(b < 0xF0) {
l = 3;
} else {
l = 4;
}
// Check for truncated codepoints
if (l > self._len) {
rune._len = self._len;
self._ptr += self._len;
self._len = 0;
return rune;
}
self._ptr += l;
self._len -= l;
rune._len = l;
return rune;
}
/*
* @dev Returns the first rune in the slice, advancing the slice to point
* to the next rune.
* @param self The slice to operate on.
* @return A slice containing only the first rune from `self`.
*/
function nextRune(slice memory self) internal pure returns (slice memory ret) {
nextRune(self, ret);
}
/*
* @dev Returns the number of the first codepoint in the slice.
* @param self The slice to operate on.
* @return The number of the first codepoint in the slice.
*/
function ord(slice memory self) internal pure returns (uint ret) {
if (self._len == 0) {
return 0;
}
uint word;
uint length;
uint divisor = 2 ** 248;
// Load the rune into the MSBs of b
assembly { word:= mload(mload(add(self, 32))) }
uint b = word / divisor;
if (b < 0x80) {
ret = b;
length = 1;
} else if(b < 0xE0) {
ret = b & 0x1F;
length = 2;
} else if(b < 0xF0) {
ret = b & 0x0F;
length = 3;
} else {
ret = b & 0x07;
length = 4;
}
// Check for truncated codepoints
if (length > self._len) {
return 0;
}
for (uint i = 1; i < length; i++) {
divisor = divisor / 256;
b = (word / divisor) & 0xFF;
if (b & 0xC0 != 0x80) {
// Invalid UTF-8 sequence
return 0;
}
ret = (ret * 64) | (b & 0x3F);
}
return ret;
}
/*
* @dev Returns the keccak-256 hash of the slice.
* @param self The slice to hash.
* @return The hash of the slice.
*/
function keccak(slice memory self) internal pure returns (bytes32 ret) {
assembly {
ret := keccak256(mload(add(self, 32)), mload(self))
}
}
/*
* @dev Returns true if `self` starts with `needle`.
* @param self The slice to operate on.
* @param needle The slice to search for.
* @return True if the slice starts with the provided text, false otherwise.
*/
function startsWith(slice memory self, slice memory needle) internal pure returns (bool) {
if (self._len < needle._len) {
return false;
}
if (self._ptr == needle._ptr) {
return true;
}
bool equal;
assembly {
let length := mload(needle)
let selfptr := mload(add(self, 0x20))
let needleptr := mload(add(needle, 0x20))
equal := eq(keccak256(selfptr, length), keccak256(needleptr, length))
}
return equal;
}
/*
* @dev If `self` starts with `needle`, `needle` is removed from the
* beginning of `self`. Otherwise, `self` is unmodified.
* @param self The slice to operate on.
* @param needle The slice to search for.
* @return `self`
*/
function beyond(slice memory self, slice memory needle) internal pure returns (slice memory) {
if (self._len < needle._len) {
return self;
}
bool equal = true;
if (self._ptr != needle._ptr) {
assembly {
let length := mload(needle)
let selfptr := mload(add(self, 0x20))
let needleptr := mload(add(needle, 0x20))
equal := eq(keccak256(selfptr, length), keccak256(needleptr, length))
}
}
if (equal) {
self._len -= needle._len;
self._ptr += needle._len;
}
return self;
}
/*
* @dev Returns true if the slice ends with `needle`.
* @param self The slice to operate on.
* @param needle The slice to search for.
* @return True if the slice starts with the provided text, false otherwise.
*/
function endsWith(slice memory self, slice memory needle) internal pure returns (bool) {
if (self._len < needle._len) {
return false;
}
uint selfptr = self._ptr + self._len - needle._len;
if (selfptr == needle._ptr) {
return true;
}
bool equal;
assembly {
let length := mload(needle)
let needleptr := mload(add(needle, 0x20))
equal := eq(keccak256(selfptr, length), keccak256(needleptr, length))
}
return equal;
}
/*
* @dev If `self` ends with `needle`, `needle` is removed from the
* end of `self`. Otherwise, `self` is unmodified.
* @param self The slice to operate on.
* @param needle The slice to search for.
* @return `self`
*/
function until(slice memory self, slice memory needle) internal pure returns (slice memory) {
if (self._len < needle._len) {
return self;
}
uint selfptr = self._ptr + self._len - needle._len;
bool equal = true;
if (selfptr != needle._ptr) {
assembly {
let length := mload(needle)
let needleptr := mload(add(needle, 0x20))
equal := eq(keccak256(selfptr, length), keccak256(needleptr, length))
}
}
if (equal) {
self._len -= needle._len;
}
return self;
}
// Returns the memory address of the first byte of the first occurrence of
// `needle` in `self`, or the first byte after `self` if not found.
function findPtr(uint selflen, uint selfptr, uint needlelen, uint needleptr) private pure returns (uint) {
uint ptr = selfptr;
uint idx;
if (needlelen <= selflen) {
if (needlelen <= 32) {
bytes32 mask;
if (needlelen > 0) {
mask = bytes32(~(2 ** (8 * (32 - needlelen)) - 1));
}
bytes32 needledata;
assembly { needledata := and(mload(needleptr), mask) }
uint end = selfptr + selflen - needlelen;
bytes32 ptrdata;
assembly { ptrdata := and(mload(ptr), mask) }
while (ptrdata != needledata) {
if (ptr >= end)
return selfptr + selflen;
ptr++;
assembly { ptrdata := and(mload(ptr), mask) }
}
return ptr;
} else {
// For long needles, use hashing
bytes32 hash;
assembly { hash := keccak256(needleptr, needlelen) }
for (idx = 0; idx <= selflen - needlelen; idx++) {
bytes32 testHash;
assembly { testHash := keccak256(ptr, needlelen) }
if (hash == testHash)
return ptr;
ptr += 1;
}
}
}
return selfptr + selflen;
}
// Returns the memory address of the first byte after the last occurrence of
// `needle` in `self`, or the address of `self` if not found.
function rfindPtr(uint selflen, uint selfptr, uint needlelen, uint needleptr) private pure returns (uint) {
uint ptr;
if (needlelen <= selflen) {
if (needlelen <= 32) {
bytes32 mask;
if (needlelen > 0) {
mask = bytes32(~(2 ** (8 * (32 - needlelen)) - 1));
}
bytes32 needledata;
assembly { needledata := and(mload(needleptr), mask) }
ptr = selfptr + selflen - needlelen;
bytes32 ptrdata;
assembly { ptrdata := and(mload(ptr), mask) }
while (ptrdata != needledata) {
if (ptr <= selfptr)
return selfptr;
ptr--;
assembly { ptrdata := and(mload(ptr), mask) }
}
return ptr + needlelen;
} else {
// For long needles, use hashing
bytes32 hash;
assembly { hash := keccak256(needleptr, needlelen) }
ptr = selfptr + (selflen - needlelen);
while (ptr >= selfptr) {
bytes32 testHash;
assembly { testHash := keccak256(ptr, needlelen) }
if (hash == testHash)
return ptr + needlelen;
ptr -= 1;
}
}
}
return selfptr;
}
/*
* @dev Modifies `self` to contain everything from the first occurrence of
* `needle` to the end of the slice. `self` is set to the empty slice
* if `needle` is not found.
* @param self The slice to search and modify.
* @param needle The text to search for.
* @return `self`.
*/
function find(slice memory self, slice memory needle) internal pure returns (slice memory) {
uint ptr = findPtr(self._len, self._ptr, needle._len, needle._ptr);
self._len -= ptr - self._ptr;
self._ptr = ptr;
return self;
}
/*
* @dev Modifies `self` to contain the part of the string from the start of
* `self` to the end of the first occurrence of `needle`. If `needle`
* is not found, `self` is set to the empty slice.
* @param self The slice to search and modify.
* @param needle The text to search for.
* @return `self`.
*/
function rfind(slice memory self, slice memory needle) internal pure returns (slice memory) {
uint ptr = rfindPtr(self._len, self._ptr, needle._len, needle._ptr);
self._len = ptr - self._ptr;
return self;
}
/*
* @dev Splits the slice, setting `self` to everything after the first
* occurrence of `needle`, and `token` to everything before it. If
* `needle` does not occur in `self`, `self` is set to the empty slice,
* and `token` is set to the entirety of `self`.
* @param self The slice to split.
* @param needle The text to search for in `self`.
* @param token An output parameter to which the first token is written.
* @return `token`.
*/
function split(slice memory self, slice memory needle, slice memory token) internal pure returns (slice memory) {
uint ptr = findPtr(self._len, self._ptr, needle._len, needle._ptr);
token._ptr = self._ptr;
token._len = ptr - self._ptr;
if (ptr == self._ptr + self._len) {
// Not found
self._len = 0;
} else {
self._len -= token._len + needle._len;
self._ptr = ptr + needle._len;
}
return token;
}
/*
* @dev Splits the slice, setting `self` to everything after the first
* occurrence of `needle`, and returning everything before it. If
* `needle` does not occur in `self`, `self` is set to the empty slice,
* and the entirety of `self` is returned.
* @param self The slice to split.
* @param needle The text to search for in `self`.
* @return The part of `self` up to the first occurrence of `delim`.
*/
function split(slice memory self, slice memory needle) internal pure returns (slice memory token) {
split(self, needle, token);
}
/*
* @dev Splits the slice, setting `self` to everything before the last
* occurrence of `needle`, and `token` to everything after it. If
* `needle` does not occur in `self`, `self` is set to the empty slice,
* and `token` is set to the entirety of `self`.
* @param self The slice to split.
* @param needle The text to search for in `self`.
* @param token An output parameter to which the first token is written.
* @return `token`.
*/
function rsplit(slice memory self, slice memory needle, slice memory token) internal pure returns (slice memory) {
uint ptr = rfindPtr(self._len, self._ptr, needle._len, needle._ptr);
token._ptr = ptr;
token._len = self._len - (ptr - self._ptr);
if (ptr == self._ptr) {
// Not found
self._len = 0;
} else {
self._len -= token._len + needle._len;
}
return token;
}
/*
* @dev Splits the slice, setting `self` to everything before the last
* occurrence of `needle`, and returning everything after it. If
* `needle` does not occur in `self`, `self` is set to the empty slice,
* and the entirety of `self` is returned.
* @param self The slice to split.
* @param needle The text to search for in `self`.
* @return The part of `self` after the last occurrence of `delim`.
*/
function rsplit(slice memory self, slice memory needle) internal pure returns (slice memory token) {
rsplit(self, needle, token);
}
/*
* @dev Counts the number of nonoverlapping occurrences of `needle` in `self`.
* @param self The slice to search.
* @param needle The text to search for in `self`.
* @return The number of occurrences of `needle` found in `self`.
*/
function count(slice memory self, slice memory needle) internal pure returns (uint cnt) {
uint ptr = findPtr(self._len, self._ptr, needle._len, needle._ptr) + needle._len;
while (ptr <= self._ptr + self._len) {
cnt++;
ptr = findPtr(self._len - (ptr - self._ptr), ptr, needle._len, needle._ptr) + needle._len;
}
}
/*
* @dev Returns True if `self` contains `needle`.
* @param self The slice to search.
* @param needle The text to search for in `self`.
* @return True if `needle` is found in `self`, false otherwise.
*/
function contains(slice memory self, slice memory needle) internal pure returns (bool) {
return rfindPtr(self._len, self._ptr, needle._len, needle._ptr) != self._ptr;
}
/*
* @dev Returns a newly allocated string containing the concatenation of
* `self` and `other`.
* @param self The first slice to concatenate.
* @param other The second slice to concatenate.
* @return The concatenation of the two strings.
*/
function concat(slice memory self, slice memory other) internal pure returns (string memory) {
string memory ret = new string(self._len + other._len);
uint retptr;
assembly { retptr := add(ret, 32) }
memcpy(retptr, self._ptr, self._len);
memcpy(retptr + self._len, other._ptr, other._len);
return ret;
}
/*
* @dev Joins an array of slices, using `self` as a delimiter, returning a
* newly allocated string.
* @param self The delimiter to use.
* @param parts A list of slices to join.
* @return A newly allocated string containing all the slices in `parts`,
* joined with `self`.
*/
function join(slice memory self, slice[] memory parts) internal pure returns (string memory) {
if (parts.length == 0)
return "";
uint length = self._len * (parts.length - 1);
for(uint i = 0; i < parts.length; i++)
length += parts[i]._len;
string memory ret = new string(length);
uint retptr;
assembly { retptr := add(ret, 32) }
for(uint i = 0; i < parts.length; i++) {
memcpy(retptr, parts[i]._ptr, parts[i]._len);
retptr += parts[i]._len;
if (i < parts.length - 1) {
memcpy(retptr, self._ptr, self._len);
retptr += self._len;
}
}
return ret;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
abstract contract ContextMixin {
function msgSender()
internal
view
returns (address payable sender)
{
if (msg.sender == address(this)) {
bytes memory array = msg.data;
uint256 index = msg.data.length;
assembly {
// Load the 32 bytes word from memory with the address on the lower 20 bytes, and mask those.
sender := and(
mload(add(array, index)),
0xffffffffffffffffffffffffffffffffffffffff
)
}
} else {
sender = payable(msg.sender);
}
return sender;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {SafeMath} from "openzeppelin-solidity/contracts/utils/math/SafeMath.sol";
import {EIP712Base} from "./EIP712Base.sol";
contract NativeMetaTransaction is EIP712Base {
using SafeMath for uint256;
bytes32 private constant META_TRANSACTION_TYPEHASH = keccak256(
bytes(
"MetaTransaction(uint256 nonce,address from,bytes functionSignature)"
)
);
event MetaTransactionExecuted(
address userAddress,
address payable relayerAddress,
bytes functionSignature
);
mapping(address => uint256) nonces;
/*
* Meta transaction structure.
* No point of including value field here as if user is doing value transfer then he has the funds to pay for gas
* He should call the desired function directly in that case.
*/
struct MetaTransaction {
uint256 nonce;
address from;
bytes functionSignature;
}
function executeMetaTransaction(
address userAddress,
bytes memory functionSignature,
bytes32 sigR,
bytes32 sigS,
uint8 sigV
) public payable returns (bytes memory) {
MetaTransaction memory metaTx = MetaTransaction({
nonce: nonces[userAddress],
from: userAddress,
functionSignature: functionSignature
});
require(
verify(userAddress, metaTx, sigR, sigS, sigV),
"Signer and signature do not match"
);
// increase nonce for user (to avoid re-use)
nonces[userAddress] = nonces[userAddress].add(1);
emit MetaTransactionExecuted(
userAddress,
payable(msg.sender),
functionSignature
);
// Append userAddress and relayer address at the end to extract it from calling context
(bool success, bytes memory returnData) = address(this).call(
abi.encodePacked(functionSignature, userAddress)
);
require(success, "Function call not successful");
return returnData;
}
function hashMetaTransaction(MetaTransaction memory metaTx)
internal
pure
returns (bytes32)
{
return
keccak256(
abi.encode(
META_TRANSACTION_TYPEHASH,
metaTx.nonce,
metaTx.from,
keccak256(metaTx.functionSignature)
)
);
}
function getNonce(address user) public view returns (uint256 nonce) {
nonce = nonces[user];
}
function verify(
address signer,
MetaTransaction memory metaTx,
bytes32 sigR,
bytes32 sigS,
uint8 sigV
) internal view returns (bool) {
require(signer != address(0), "NativeMetaTransaction: INVALID_SIGNER");
return
signer ==
ecrecover(
toTypedMessageHash(hashMetaTransaction(metaTx)),
sigV,
sigR,
sigS
);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)
pragma solidity ^0.8.0;
import "../utils/Context.sol";
/**
* @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() {
_transferOwnership(_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 {
_transferOwnership(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");
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/ERC721.sol)
pragma solidity ^0.8.0;
import "./IERC721.sol";
import "./IERC721Receiver.sol";
import "./extensions/IERC721Metadata.sol";
import "../../utils/Address.sol";
import "../../utils/Context.sol";
import "../../utils/Strings.sol";
import "../../utils/introspection/ERC165.sol";
/**
* @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 overridden 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 {
_setApprovalForAll(_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 || isApprovedForAll(owner, spender) || getApproved(tokenId) == 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);
_afterTokenTransfer(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);
_afterTokenTransfer(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 from incorrect owner");
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);
_afterTokenTransfer(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 Approve `operator` to operate on all of `owner` tokens
*
* Emits a {ApprovalForAll} event.
*/
function _setApprovalForAll(
address owner,
address operator,
bool approved
) internal virtual {
require(owner != operator, "ERC721: approve to caller");
_operatorApprovals[owner][operator] = approved;
emit ApprovalForAll(owner, operator, approved);
}
/**
* @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.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 {}
/**
* @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.
* - `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 tokenId
) internal virtual {}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Enumerable.sol)
pragma solidity ^0.8.0;
import "../ERC721.sol";
import "./IERC721Enumerable.sol";
/**
* @dev This implements an optional extension of {ERC721} defined in the EIP that adds
* enumerability of all the token ids in the contract as well as all token ids owned by each
* account.
*/
abstract contract ERC721Enumerable is ERC721, IERC721Enumerable {
// Mapping from owner to list of owned token IDs
mapping(address => mapping(uint256 => uint256)) private _ownedTokens;
// Mapping from token ID to index of the owner tokens list
mapping(uint256 => uint256) private _ownedTokensIndex;
// Array with all token ids, used for enumeration
uint256[] private _allTokens;
// Mapping from token id to position in the allTokens array
mapping(uint256 => uint256) private _allTokensIndex;
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {
return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);
}
/**
* @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.
*/
function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {
require(index < ERC721.balanceOf(owner), "ERC721Enumerable: owner index out of bounds");
return _ownedTokens[owner][index];
}
/**
* @dev See {IERC721Enumerable-totalSupply}.
*/
function totalSupply() public view virtual override returns (uint256) {
return _allTokens.length;
}
/**
* @dev See {IERC721Enumerable-tokenByIndex}.
*/
function tokenByIndex(uint256 index) public view virtual override returns (uint256) {
require(index < ERC721Enumerable.totalSupply(), "ERC721Enumerable: global index out of bounds");
return _allTokens[index];
}
/**
* @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` cannot be the zero address.
* - `to` cannot be the zero address.
*
* 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 override {
super._beforeTokenTransfer(from, to, tokenId);
if (from == address(0)) {
_addTokenToAllTokensEnumeration(tokenId);
} else if (from != to) {
_removeTokenFromOwnerEnumeration(from, tokenId);
}
if (to == address(0)) {
_removeTokenFromAllTokensEnumeration(tokenId);
} else if (to != from) {
_addTokenToOwnerEnumeration(to, tokenId);
}
}
/**
* @dev Private function to add a token to this extension's ownership-tracking data structures.
* @param to address representing the new owner of the given token ID
* @param tokenId uint256 ID of the token to be added to the tokens list of the given address
*/
function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {
uint256 length = ERC721.balanceOf(to);
_ownedTokens[to][length] = tokenId;
_ownedTokensIndex[tokenId] = length;
}
/**
* @dev Private function to add a token to this extension's token tracking data structures.
* @param tokenId uint256 ID of the token to be added to the tokens list
*/
function _addTokenToAllTokensEnumeration(uint256 tokenId) private {
_allTokensIndex[tokenId] = _allTokens.length;
_allTokens.push(tokenId);
}
/**
* @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that
* while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for
* gas optimizations e.g. when performing a transfer operation (avoiding double writes).
* This has O(1) time complexity, but alters the order of the _ownedTokens array.
* @param from address representing the previous owner of the given token ID
* @param tokenId uint256 ID of the token to be removed from the tokens list of the given address
*/
function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {
// To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and
// then delete the last slot (swap and pop).
uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;
uint256 tokenIndex = _ownedTokensIndex[tokenId];
// When the token to delete is the last token, the swap operation is unnecessary
if (tokenIndex != lastTokenIndex) {
uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];
_ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
_ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index
}
// This also deletes the contents at the last position of the array
delete _ownedTokensIndex[tokenId];
delete _ownedTokens[from][lastTokenIndex];
}
/**
* @dev Private function to remove a token from this extension's token tracking data structures.
* This has O(1) time complexity, but alters the order of the _allTokens array.
* @param tokenId uint256 ID of the token to be removed from the tokens list
*/
function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {
// To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and
// then delete the last slot (swap and pop).
uint256 lastTokenIndex = _allTokens.length - 1;
uint256 tokenIndex = _allTokensIndex[tokenId];
// When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so
// rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding
// an 'if' statement (like in _removeTokenFromOwnerEnumeration)
uint256 lastTokenId = _allTokens[lastTokenIndex];
_allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
_allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index
// This also deletes the contents at the last position of the array
delete _allTokensIndex[tokenId];
_allTokens.pop();
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {Initializable} from "./Initializable.sol";
contract EIP712Base is Initializable {
struct EIP712Domain {
string name;
string version;
address verifyingContract;
bytes32 salt;
}
string constant public ERC712_VERSION = "1";
bytes32 internal constant EIP712_DOMAIN_TYPEHASH = keccak256(
bytes(
"EIP712Domain(string name,string version,address verifyingContract,bytes32 salt)"
)
);
bytes32 internal domainSeperator;
// supposed to be called once while initializing.
// one of the contracts that inherits this contract follows proxy pattern
// so it is not possible to do this in a constructor
function _initializeEIP712(
string memory name
)
internal
initializer
{
_setDomainSeperator(name);
}
function _setDomainSeperator(string memory name) internal {
domainSeperator = keccak256(
abi.encode(
EIP712_DOMAIN_TYPEHASH,
keccak256(bytes(name)),
keccak256(bytes(ERC712_VERSION)),
address(this),
bytes32(getChainId())
)
);
}
function getDomainSeperator() public view returns (bytes32) {
return domainSeperator;
}
function getChainId() public view returns (uint256) {
uint256 id;
assembly {
id := chainid()
}
return id;
}
/**
* Accept message hash and returns hash message in EIP712 compatible form
* So that it can be used to recover signer from signature signed using EIP712 formatted data
* https://eips.ethereum.org/EIPS/eip-712
* "\\x19" makes the encoding deterministic
* "\\x01" is the version byte to make it compatible to EIP-191
*/
function toTypedMessageHash(bytes32 messageHash)
internal
view
returns (bytes32)
{
return
keccak256(
abi.encodePacked("\x19\x01", getDomainSeperator(), messageHash)
);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (utils/math/SafeMath.sol)
pragma solidity ^0.8.0;
// CAUTION
// This version of SafeMath should only be used with Solidity 0.8 or later,
// because it relies on the compiler's built in overflow checks.
/**
* @dev Wrappers over Solidity's arithmetic operations.
*
* NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler
* now has built in overflow checking.
*/
library SafeMath {
/**
* @dev Returns the addition of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
}
/**
* @dev Returns the subtraction of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b > a) return (false, 0);
return (true, a - b);
}
}
/**
* @dev Returns the multiplication of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
}
/**
* @dev Returns the division of two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a / b);
}
}
/**
* @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a % b);
}
}
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
*
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
return a + b;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return a - b;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
*
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
return a * b;
}
/**
* @dev Returns the integer division of two unsigned integers, reverting on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator.
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return a / b;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return a % b;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {trySub}.
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
unchecked {
require(b <= a, errorMessage);
return a - b;
}
}
/**
* @dev Returns the integer division of two unsigned integers, reverting with custom message on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a / b;
}
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting with custom message when dividing by zero.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryMod}.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a % b;
}
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Initializable {
bool inited = false;
modifier initializer() {
require(!inited, "already inited");
_;
inited = true;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
pragma solidity ^0.8.0;
/**
* @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;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)
pragma solidity ^0.8.1;
/**
* @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
* ====
*
* [IMPORTANT]
* ====
* You shouldn't rely on `isContract` to protect against flash loan attacks!
*
* Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
* constructor.
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize/address.code.length, which returns 0
// for contracts in construction, since the code is only stored at the end
// of the constructor execution.
return account.code.length > 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);
}
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)
pragma solidity ^0.8.0;
/**
* @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);
}
/**
* @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);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)
pragma solidity ^0.8.0;
import "./IERC165.sol";
/**
* @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;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)
pragma solidity ^0.8.0;
/**
* @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 `IERC721Receiver.onERC721Received.selector`.
*/
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes calldata data
) external returns (bytes4);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721.sol)
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165.sol";
/**
* @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`.
*
* 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;
/**
* @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 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 the account approved for `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function getApproved(uint256 tokenId) external view returns (address operator);
/**
* @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);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)
pragma solidity ^0.8.0;
import "../IERC721.sol";
/**
* @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);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)
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);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)
pragma solidity ^0.8.0;
import "../IERC721.sol";
/**
* @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
* @dev See https://eips.ethereum.org/EIPS/eip-721
*/
interface IERC721Enumerable is IERC721 {
/**
* @dev Returns the total amount of tokens stored by the contract.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns a token ID owned by `owner` at a given `index` of its token list.
* Use along with {balanceOf} to enumerate all of ``owner``'s tokens.
*/
function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);
/**
* @dev Returns a token ID at a given `index` of all the tokens stored by the contract.
* Use along with {totalSupply} to enumerate all tokens.
*/
function tokenByIndex(uint256 index) external view returns (uint256);
}{
"optimizer": {
"enabled": true,
"runs": 200
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_proxyRegistryAddress","type":"address"}],"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":"tokenId","type":"uint256"},{"indexed":false,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"NGO_id","type":"uint256"}],"name":"Created","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"userAddress","type":"address"},{"indexed":false,"internalType":"address payable","name":"relayerAddress","type":"address"},{"indexed":false,"internalType":"bytes","name":"functionSignature","type":"bytes"}],"name":"MetaTransactionExecuted","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"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"color_id","type":"uint256"}],"name":"new_COLOR","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"icon_id","type":"uint256"}],"name":"new_ICON","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"NGO_id","type":"uint256"}],"name":"new_NGO","type":"event"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"COLORs","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ERC712_VERSION","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"ICONs","outputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"part_1","type":"string"},{"internalType":"string","name":"part_2","type":"string"},{"internalType":"string","name":"part_3","type":"string"},{"internalType":"string","name":"part_4","type":"string"},{"internalType":"string","name":"part_5","type":"string"},{"internalType":"uint256","name":"min_donation","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"NGOs","outputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"string","name":"name","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"address","name":"addr","type":"address"}],"name":"add_NGO","outputs":[{"internalType":"uint256","name":"_number_of_NGOs","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"color_hex","type":"string"}],"name":"add_color","outputs":[{"internalType":"uint256","name":"_number_of_colors","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"part_1","type":"string"},{"internalType":"string","name":"part_2","type":"string"},{"internalType":"string","name":"part_3","type":"string"},{"internalType":"string","name":"part_4","type":"string"},{"internalType":"string","name":"part_5","type":"string"},{"internalType":"uint256","name":"min_donation","type":"uint256"}],"name":"add_icon","outputs":[{"internalType":"uint256","name":"_number_of_icons","type":"uint256"}],"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":"baseTokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"},{"internalType":"bytes","name":"functionSignature","type":"bytes"},{"internalType":"bytes32","name":"sigR","type":"bytes32"},{"internalType":"bytes32","name":"sigS","type":"bytes32"},{"internalType":"uint8","name":"sigV","type":"uint8"}],"name":"executeMetaTransaction","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getChainId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDomainSeperator","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getNonce","outputs":[{"internalType":"uint256","name":"nonce","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"getTOKEN","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"card_id","type":"uint256"}],"name":"get_card","outputs":[{"components":[{"internalType":"address","name":"creator","type":"address"},{"internalType":"string","name":"message","type":"string"},{"internalType":"uint256","name":"donated","type":"uint256"},{"internalType":"uint256","name":"NGO_id","type":"uint256"},{"internalType":"uint256","name":"icon_id","type":"uint256"},{"internalType":"uint256","name":"bg_color","type":"uint256"},{"internalType":"uint256","name":"icon_color_1","type":"uint256"},{"internalType":"uint256","name":"icon_color_2","type":"uint256"},{"internalType":"uint256","name":"icon_color_3","type":"uint256"},{"internalType":"uint256","name":"icon_color_4","type":"uint256"}],"internalType":"struct ERC721Tradable.Card","name":"","type":"tuple"}],"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":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"string","name":"_message","type":"string"},{"internalType":"uint256","name":"_NGO_id","type":"uint256"},{"internalType":"uint256","name":"_icon_id","type":"uint256"},{"internalType":"uint256","name":"_bg_color","type":"uint256"},{"internalType":"uint256","name":"_icon_color_1","type":"uint256"},{"internalType":"uint256","name":"_icon_color_2","type":"uint256"},{"internalType":"uint256","name":"_icon_color_3","type":"uint256"},{"internalType":"uint256","name":"_icon_color_4","type":"uint256"}],"name":"mint_card","outputs":[{"internalType":"uint256","name":"_token_id","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"number_of_NGOs","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"number_of_colors","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"number_of_icons","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"card_id","type":"uint256"}],"name":"read_card","outputs":[{"internalType":"string","name":"","type":"string"}],"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":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","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":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","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":"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"}]Contract Creation Code
6080604052600a805460ff191690556000600f553480156200002057600080fd5b506040516200cbf23803806200cbf2833981016040819052620000439162003bbd565b6040518060400160405280600a815260200169446f6e617465584d617360b01b81525060405180604001604052806004815260200163584d415360e01b815250828282816000908162000097919062003c94565b506001620000a6828262003c94565b505050620000c3620000bd620039eb60201b60201c565b62003a07565b600e80546001600160a01b0319166001600160a01b038316179055620000e98362003a59565b505060408051808201909152600581526420302e303160d81b602080830191909152662386f26fc10000600052601190527f7421538268e3246d6d709e3eff1e94bee601f4392a8725719509884dfd0189cb915062000149908262003c94565b5060408051808201909152600581526420302e303560d81b60208083019190915266b1a2bc2ec50000600052601190527f8e227a443d2ff44275f468715e11469ca75342cb3473ec3b126362c94c6da57e90620001a7908262003c94565b5060408051808201909152600481526320302e3160e01b60208083019190915267016345785d8a0000600052601190527fec4b5e6ea717b31a48023802e93d75b3229d4a8e896544822bf4571ca3c8d5ea9062000205908262003c94565b5060408051808201909152600581526420302e323560d81b6020808301919091526703782dace9d90000600052601190527f04f01fe9140fc8b646431c76d661b2d4e08c5cc1f58ae459a69f121afedd86199062000264908262003c94565b5060408051808201909152600481526320302e3560e01b6020808301919091526706f05b59d3b20000600052601190527f90ae6f83cb2a1d8822cc59342f530811184beb50d4d76f4ffc20cd210a46244090620002c2908262003c94565b50604080518082019091526002815261203160f01b602080830191909152670de0b6b3a7640000600052601190527f607c100c4b33103aea8ff6d3f5307b3ed5fab72d8a23ae128c451c38cc5cc94f906200031e908262003c94565b50604080518082019091526002815261203560f01b602080830191909152674563918244f40000600052601190527f0e4cbb8fefcc1d741a4a2e27f74cdf34947ea9edc2c2b3cb14b566c9fb86f5c0906200037a908262003c94565b50604080518082019091526002815261031360f41b602080830191909152678ac7230489e80000600052601190527ff9d0b13f70d589e5b1cc7b7b2744ec0607809815f8c5c6271f2d9f073d0f222c90620003d6908262003c94565b506040518060e001604052806040518060400160405280600681526020016553746172203160d01b81525081526020016040518060600160405280602b81526020016200c702602b913981526020016040518060c00160405280608481526020016200b60f6084913981526020016040518060a00160405280606581526020016200a02d60659139815260200160405180610120016040528060fa815260200162008daf60fa9139815260408051808201825260048152631110179f60e11b60208281019190915280840191909152655af3107a4000919092015260016000526012905280517f71a67924699a20698523213e55fe499d539379d7769cd5567e2c45d583f815a3908190620004ec908262003c94565b506020820151600182019062000503908262003c94565b50604082015160028201906200051a908262003c94565b506060820151600382019062000531908262003c94565b506080820151600482019062000548908262003c94565b5060a082015160058201906200055f908262003c94565b5060c082015181600601559050506040518060e00160405280604051806040016040528060098152602001684d6f756e7461696e7360b81b81525081526020016040518060400160405280600c81526020016b1e3830ba34103334b6361e9160a11b81525081526020016040518060800160405280604481526020016200c53660449139815260200160405180610120016040528060e581526020016200baf160e59139815260200160405180610100016040528060d181526020016200b96f60d1913981526020016040518060600160405280602281526020016200adaa602291398152655af3107a400060209182015260026000526012905280517f8e1fee8c88a9e04123b21e90cae2727a7715bf522a1e46eb5934ccd05203a6b29081906200068c908262003c94565b5060208201516001820190620006a3908262003c94565b5060408201516002820190620006ba908262003c94565b5060608201516003820190620006d1908262003c94565b5060808201516004820190620006e8908262003c94565b5060a08201516005820190620006ff908262003c94565b5060c082015181600601559050506040518060e001604052806040518060400160405280600681526020016554726565203160d01b81525081526020016040518060600160405280602e815260200162008933602e91398152602001604051806060016040528060278152602001620090e66027913981526020016040518060600160405280602e81526020016200c508602e91398152604080518082018252601081526f1110179f1e3830ba34103334b6361e9160811b602082810191909152808401919091528151808301835260048152631110179f60e11b8183015291830191909152655af3107a400060609092019190915260036000526012905280517f0f36ad39aee03e7108cc48f54934702a5f0d4066f10344cebf8198978d86976a90819062000830908262003c94565b506020820151600182019062000847908262003c94565b50604082015160028201906200085e908262003c94565b506060820151600382019062000875908262003c94565b50608082015160048201906200088c908262003c94565b5060a08201516005820190620008a3908262003c94565b5060c082015181600601559050506040518060e001604052806040518060400160405280600381526020016212185d60ea1b81525081526020016040518060600160405280602e815260200162008933602e91398152602001604051806060016040528060328152602001620092b36032913981526020016040518060600160405280603c81526020016200b3f8603c913981526020016040518060600160405280603481526020016200a32a603491398152604080518082018252600381526211179f60e91b60208281019190915280840191909152655af3107a4000919092015260046000526012905280517fb4fcd034df3d20faa1c133b66d862ce92732727d40916b48ffb4020cb00fe053908190620009c1908262003c94565b5060208201516001820190620009d8908262003c94565b5060408201516002820190620009ef908262003c94565b506060820151600382019062000a06908262003c94565b506080820151600482019062000a1d908262003c94565b5060a0820151600582019062000a34908262003c94565b5060c09190910151600691820155604080516101208101825260e08101928352652a3932b2901960d11b6101008201529182528051606081018252818152602080840192906200ac779083013981526020016040518060600160405280603b81526020016200c17d603b913981526020016040518060c00160405280609581526020016200a88f6095913981526020016040518060400160405280601781526020017f223e3c2f706174683e3c636972636c652066696c6c3d2200000000000000000081525081526020016040518060600160405280602d815260200162009553602d91398152655af3107a400060209182015260056000526012905280517f45429b9195d4ec5c0cf6c69e9c21a4ca0ea773b702c2de5735f85d2631f2674690819062000b63908262003c94565b506020820151600182019062000b7a908262003c94565b506040820151600282019062000b91908262003c94565b506060820151600382019062000ba8908262003c94565b506080820151600482019062000bbf908262003c94565b5060a0820151600582019062000bd6908262003c94565b5060c082015181600601559050506040518060e001604052806040518060400160405280600781526020016629b737bbb6b0b760c91b81525081526020016040518060600160405280603081526020016200b6fc6030913981526020016040518060600160405280602b81526020016200ad7f602b9139815260200160405180610160016040528061013a815260200162008a8561013a91398152604080518082018252601381527211179f1e17b39f1e3830ba34103334b6361e9160691b602082810191909152808401919091528151808301835260048152631110179f60e11b8183015291830191909152655af3107a400060609092019190915260066000526012905280517f1223f9031f9dca49a7844c397098ce9a4e80513444d0a8bb59820dff564808e490819062000d0e908262003c94565b506020820151600182019062000d25908262003c94565b506040820151600282019062000d3c908262003c94565b506060820151600382019062000d53908262003c94565b506080820151600482019062000d6a908262003c94565b5060a0820151600582019062000d81908262003c94565b5060c082015181600601559050506040518060e0016040528060405180604001604052806006815260200165536e6f77203160d01b81525081526020016040518060600160405280602881526020016200be926028913981526020016040518060c00160405280609381526020016200c86c6093913981526020016040518060a00160405280607781526020016200906f607791398152604080518082018252600f81526e11179f1e3830ba34103334b6361e9160891b6020828101919091528084019190915281518083018352600381526211179f60e91b8183015291830191909152655af3107a400060609092019190915260076000526012905280517f724fd36bd271795fe7866d4cc83b61084ef704502b00c2e0b28047123b3c1acc90819062000eb0908262003c94565b506020820151600182019062000ec7908262003c94565b506040820151600282019062000ede908262003c94565b506060820151600382019062000ef5908262003c94565b506080820151600482019062000f0c908262003c94565b5060a0820151600582019062000f23908262003c94565b5060c082015181600601559050506040518060e001604052806040518060400160405280600681526020016542616c6c203160d01b81525081526020016040518060600160405280603081526020016200b6fc6030913981526020016040518060a001604052806075815260200162008cf2607591398152604080518082018252601381527211179f1e17b39f1e3830ba34103334b6361e9160691b6020828101919091528084019190915281518083018352601081526f1110179f1e3830ba34103334b6361e9160811b8183015282840152815180830190925260048252631110179f60e11b828201526060830191909152655af3107a400060809092019190915260086000526012905280517f855d8d6df66418fea944661cfca175a2245b01f09908f1f662c4fa2b3cbf929990819062001061908262003c94565b506020820151600182019062001078908262003c94565b50604082015160028201906200108f908262003c94565b5060608201516003820190620010a6908262003c94565b5060808201516004820190620010bd908262003c94565b5060a08201516005820190620010d4908262003c94565b5060c082015181600601559050506040518060e001604052806040518060400160405280600681526020016554726565203360d01b81525081526020016040518060400160405280600c81526020016b1e3830ba34103334b6361e9160a11b81525081526020016040518060a00160405280607a81526020016200b434607a91398152602001604051806102a0016040528061026d81526020016200a0bd61026d9139815260200160405180610140016040528061011a81526020016200914a61011a913981526020016040518060a00160405280607c81526020016200b72c607c91398152655af3107a400060209182015260096000526012905280516000805160206200b7a8833981519152908190620011f1908262003c94565b506020820151600182019062001208908262003c94565b50604082015160028201906200121f908262003c94565b506060820151600382019062001236908262003c94565b50608082015160048201906200124d908262003c94565b5060a0820151600582019062001264908262003c94565b5060c082015181600601559050506040518060e001604052806040518060400160405280600681526020016554726565203360d01b81525081526020016040518060400160405280600c81526020016b1e3830ba34103334b6361e9160a11b81525081526020016040518060a00160405280607a81526020016200b434607a91398152602001604051806102a0016040528061026d81526020016200a0bd61026d9139815260200160405180610140016040528061011a81526020016200914a61011a913981526020016040518060a00160405280607c81526020016200b72c607c91398152655af3107a400060209182015260096000526012905280516000805160206200b7a883398151915290819062001381908262003c94565b506020820151600182019062001398908262003c94565b5060408201516002820190620013af908262003c94565b5060608201516003820190620013c6908262003c94565b5060808201516004820190620013dd908262003c94565b5060a08201516005820190620013f4908262003c94565b5060c082015181600601559050506040518060e0016040528060405180604001604052806005815260200164536b61746560d81b81525081526020016040518060600160405280602881526020016200c6da602891398152602001604051806104a0016040528061046581526020016200a42a610465913981526020016040518061030001604052806102c381526020016200beba6102c3913981526020016040518060600160405280602b81526020016200a092602b9139815260200160405180610260016040528061022581526020016200b1d361022591398152655af3107a4000602091820152600a6000526012905280517f4d862627e71449ad0902e42fb445c6fefb557d066705175da90fdc325bd76e4e90819062001519908262003c94565b506020820151600182019062001530908262003c94565b506040820151600282019062001547908262003c94565b50606082015160038201906200155e908262003c94565b506080820151600482019062001575908262003c94565b5060a082015160058201906200158c908262003c94565b5060c082015181600601559050506040518060e0016040528060405180604001604052806005815260200164476966747360d81b81525081526020016040518060400160405280600c81526020016b1e3830ba34103334b6361e9160a11b81525081526020016040518060800160405280605681526020016200a92460569139815260200160405180610180016040528061016081526020016200c57a61016091398152602001604051806101600160405280610133815260200162008bbf610133913981526020016040518060600160405280602781526020016200be6b602791398152655af3107a4000602091820152600b6000526012905280517f2495f4cb142bcb5be5e6e3ea9aaf4f6b4f9ecc9f26c2c53a2c4a12cbcae156ee908190620016b9908262003c94565b5060208201516001820190620016d0908262003c94565b5060408201516002820190620016e7908262003c94565b5060608201516003820190620016fe908262003c94565b506080820151600482019062001715908262003c94565b5060a082015160058201906200172c908262003c94565b5060c082015181600601559050506040518060e0016040528060405180604001604052806007815260200166476c617373657360c81b815250815260200160405180610120016040528060eb81526020016200bd4a60eb913981526020016040518060400160405280600c81526020016b11179f1e33903334b6361e9160a11b81525081526020016040518061022001604052806101ea815260200162009e436101ea913981526020016040518060e0016040528060a681526020016200888d60a691398152604080518082018252600381526211179f60e91b60208281019190915280840191909152655af3107a40009190920152600c6000526012905280517f102203beef086490b6ace526d3f440341863884040816888f0c1d8918d4daa7a9081906200185d908262003c94565b506020820151600182019062001874908262003c94565b50604082015160028201906200188b908262003c94565b5060608201516003820190620018a2908262003c94565b5060808201516004820190620018b9908262003c94565b5060a08201516005820190620018d0908262003c94565b5060c082015181600601559050506040518060e001604052806040518060400160405280600681526020016529b737bb901960d11b815250815260200160405180610440016040528061040781526020016200adcc61040791398152604080518082018252600f8082526e11179f1e3830ba34103334b6361e9160891b6020838101829052808601939093528351808501855282815280840182905284860152835180850185529182528183015260608401528151808301909252600382526211179f60e91b828201526080830191909152655af3107a400060a090920191909152600d6000526012905280517f08002daeba8533611007c300fe5b0f2097c5e194f0f4087c9468255bee0bf7d9908190620019ed908262003c94565b506020820151600182019062001a04908262003c94565b506040820151600282019062001a1b908262003c94565b506060820151600382019062001a32908262003c94565b506080820151600482019062001a49908262003c94565b5060a0820151600582019062001a60908262003c94565b5060c082015181600601559050506040518060e001604052806040518060400160405280600481526020016311da599d60e21b815250815260200160405180610140016040528061010e81526020016200b4ae61010e9139815260200160405180610240016040528061021481526020016200c8ff610214913981526020016040518060600160405280603181526020016200bd1960319139815260200160405180610160016040528061013f81526020016200c72d61013f91398152602001604051806101c0016040528061018f815260200162008ee061018f91398152655af3107a4000602091820152600e6000526012905280517f8f34c6b109aecf3bfac1757bacc0152b60fcb822751554c6190a91f3c234a27890819062001b87908262003c94565b506020820151600182019062001b9e908262003c94565b506040820151600282019062001bb5908262003c94565b506060820151600382019062001bcc908262003c94565b506080820151600482019062001be3908262003c94565b5060a0820151600582019062001bfa908262003c94565b5060c082015181600601559050506040518060e001604052806040518060400160405280600581526020016443616e647960d81b8152508152602001604051806101600160405280610124815260200162008961610124913981526020016040518060400160405280600f81526020016e11179f1e3830ba34103334b6361e9160891b815250815260200160405180610260016040528061023e81526020016200a97a61023e91398152604080518082018252600f8082526e11179f1e3830ba34103334b6361e9160891b6020838101919091528085019290925282518084018452600381526211179f60e91b8184015292840192909252655af3107a40006060909301929092526000526012905280517f12864ea1602358025af3b40bb8d939272d37cf8b937fccc858336e2eaa450d8090819062001d3b908262003c94565b506020820151600182019062001d52908262003c94565b506040820151600282019062001d69908262003c94565b506060820151600382019062001d80908262003c94565b506080820151600482019062001d97908262003c94565b5060a0820151600582019062001dae908262003c94565b5060c082015181600601559050506040518060e00160405280604051806040016040528060068152602001652130b636101960d11b81525081526020016040518060400160405280600e81526020016d1e31b4b931b632903334b6361e9160911b81525081526020016040518060e0016040528060b181526020016200ba4060b19139815260200160405180610260016040528061023d8152602001620092e561023d91398152604080518082018252600f81526e11179f1e3830ba34103334b6361e9160891b6020828101919091528084019190915281518083018352600381526211179f60e91b8183015291830191909152655af3107a400060609092019190915260106000526012905280517f47cca4e5cf2ef3d1cf48e381e7c50f235175233c59e08319e054e746d4722a9890819062001eed908262003c94565b506020820151600182019062001f04908262003c94565b506040820151600282019062001f1b908262003c94565b506060820151600382019062001f32908262003c94565b506080820151600482019062001f49908262003c94565b5060a0820151600582019062001f60908262003c94565b5060c082015181600601559050506040518060e0016040528060405180604001604052806006815260200165151c9959480d60d21b81525081526020016040518060400160405280600c81526020016b1e3830ba34103334b6361e9160a11b815250815260200160405180608001604052806048815260200162008d6760489139815260200160405180610100016040528060df81526020016200cb1360df913981526020016040518060e0016040528060ab81526020016200b8c460ab91398152604080518082018252601c81527f222063783d22373930222063793d223538322220723d223832222f3e0000000060208281019190915280840191909152655af3107a4000919092015260116000526012905280517f6b485436b9b234417e59960d9ab1366322cfad1c365f281a05863557ce7f5ce4908190620020a7908262003c94565b5060208201516001820190620020be908262003c94565b5060408201516002820190620020d5908262003c94565b5060608201516003820190620020ec908262003c94565b506080820151600482019062002103908262003c94565b5060a082015160058201906200211a908262003c94565b5060c082015181600601559050506040518060e00160405280604051806040016040528060068152602001650aee4cac2e8d60d31b81525081526020016040518061082001604052806107eb8152602001620096586107eb913981526020016040518060600160405280602b81526020016200b7c8602b913981526020016040518060c0016040528060a081526020016200c46860a0913981526020016040518060e0016040528060ad8152602001620095ab60ad913981526020016040518060a00160405280606981526020016200b693606991398152655af3107a400060209182015260126000819052905280517f9f06b6a21011ceaf77e412292865f39f3e7ad40a4f4dee40defc38983937e0b79081906200223a908262003c94565b506020820151600182019062002251908262003c94565b506040820151600282019062002268908262003c94565b50606082015160038201906200227f908262003c94565b506080820151600482019062002296908262003c94565b5060a08201516005820190620022ad908262003c94565b5060c082015181600601559050506040518060e0016040528060405180604001604052806007815260200166109a5cd8dd5a5d60ca1b8152508152602001604051806102e001604052806102b081526020016200c1b86102b0913981526020016040518060600160405280602b815260200162009580602b9139815260200160405180610180016040528061014381526020016200bbd6610143913981526020016040518060800160405280605381526020016200b5bc605391398152604080518082018252600381526211179f60e91b60208281019190915280840191909152655af3107a4000919092015260136000526012905280517f51bff16c12f072e1c63eaac76d27ed06d041061648bf74844ad006ae6bd44d6e908190620023d5908262003c94565b5060208201516001820190620023ec908262003c94565b506040820151600282019062002403908262003c94565b50606082015160038201906200241a908262003c94565b506080820151600482019062002431908262003c94565b5060a0820151600582019062002448908262003c94565b5060c082015181600601559050506040518060e001604052806040518060400160405280600681526020016529ba30b9101960d11b81525081526020016040518060400160405280600f81526020016e1e339f1e3830ba34103334b6361e9160891b815250815260200160405180610100016040528060d181526020016200b7f360d19139815260200160405180610100016040528060c881526020016200acb760c89139815260200160405180610100016040528060cc81526020016200a35e60cc913981526020016040518060e0016040528060bf81526020016200abb860bf91398152655af3107a400060209182015260146000526012905280517f17bb5cf2fc7a6f50cc94c2441aa8b40633d519c366ef1355ea0dd04dd3027f2090819062002576908262003c94565b50602082015160018201906200258d908262003c94565b5060408201516002820190620025a4908262003c94565b5060608201516003820190620025bb908262003c94565b5060808201516004820190620025d2908262003c94565b5060a08201516005820190620025e9908262003c94565b5060c082015181600601559050506040518060e001604052806040518060400160405280600c81526020016b4e6f7264696320547265657360a01b81525081526020016040518060400160405280600f81526020016e1e339f1e3830ba34103334b6361e9160891b815250815260200160405180606001604052806037815260200162008ea96037913981526020016040518060600160405280603681526020016200be356036913981526020016040518060600160405280603d81526020016200910d603d9139815260200160405180606001604052806031815260200162009522603191398152655af3107a400060209182015260156000526012905280517fa5769ab4976232a10e433776f09325b00d3bcdda881193f84d5157d906680d179081906200271a908262003c94565b506020820151600182019062002731908262003c94565b506040820151600282019062002748908262003c94565b50606082015160038201906200275f908262003c94565b506080820151600482019062002776908262003c94565b5060a082015160058201906200278d908262003c94565b5060c09190910151600690910155601560165560408051808201825273c3e302e8fda21b9c020e6388d8052c8055530ada81528151808301909252601182527029b0bb32903a34329021b434b6323932b760791b60208084019190915280820192835260016000526013905280517f4155c2f711f2cdd34f8262ab8fb9b7020a700fe7b6948222152f7670d1fdf34d80546001600160a01b0319166001600160a01b0390921691909117815591519091907f4155c2f711f2cdd34f8262ab8fb9b7020a700fe7b6948222152f7670d1fdf34e906200286c908262003c94565b50506040805180820182527363bbc9a8a5d3f66277d9553b73453f59a3c5eca081528151808301909252601c82527f436f72616c20526573746f726174696f6e20466f756e646174696f6e0000000060208084019190915280820192835260026000526013905280517f0b9d2c0c271bb30544eb78c59bdaebdae2728e5f65814c07768a0abe90ed192380546001600160a01b0319166001600160a01b0390921691909117815591519092507f0b9d2c0c271bb30544eb78c59bdaebdae2728e5f65814c07768a0abe90ed19249062002946908262003c94565b505060408051808201825273e9bc9ddced5685b3871d52ead8253c4bea78b93581528151808301909252601b82527f537469636874696e6720546865204f6365616e20436c65616e7570000000000060208084019190915280820192835260036000526013905280517f0d2a6872ef858a7f8ead18dc4f3f2e8d35c853d47e2816cbb9cdd49202554e0c80546001600160a01b0319166001600160a01b0390921691909117815591519092507f0d2a6872ef858a7f8ead18dc4f3f2e8d35c853d47e2816cbb9cdd49202554e0d9062002a20908262003c94565b505060408051808201825273cdb1cd005918cb00514f3d31872fe40443a52c8c81528151808301909252601d82527f506f6c6c696e61746f7220506172746e6572736869702043616e61646100000060208084019190915280820192835260046000526013905280517f01413ff7a3b1d5b6c016c061d48e2c7014700c777a29fcd068fff04265813d5d80546001600160a01b0319166001600160a01b0390921691909117815591519092507f01413ff7a3b1d5b6c016c061d48e2c7014700c777a29fcd068fff04265813d5e9062002afa908262003c94565b505060408051808201825273cd26c12578b3fdf80d4203cd932e99825f218e6b81528151808301909252601682527f46756e644c69666520496e7465726e6174696f6e616c0000000000000000000060208084019190915280820192835260056000526013905280517ff4b2859895858d6aa26d656e4999d552f6a869b74c43bba7d2a941c4d22c355980546001600160a01b0319166001600160a01b0390921691909117815591519092507ff4b2859895858d6aa26d656e4999d552f6a869b74c43bba7d2a941c4d22c355a9062002bd4908262003c94565b505060408051808201825273b41077c30a1cd16b04776740806fe2ba18e7ad8d81528151808301909252600882526710599c9a58d05a5960c21b60208084019190915280820192835260066000526013905280517f709d0e3cf89777a1e1f9c99632e4494f29b0327befd0df15e277a12d9482579580546001600160a01b0319166001600160a01b0390921691909117815591519092507f709d0e3cf89777a1e1f9c99632e4494f29b0327befd0df15e277a12d948257969062002c99908262003c94565b505060408051808201825273fa371b51f11b9b32ad597d7c43a302107f66bf9481528151808301909252600c82526b2730ba34b7b730b6102821a360a11b60208084019190915280820192835260076000526013905280517f8ba6fb577925b0796671c737df59b8aaae861b630513fb12823699e3e0e3ee6080546001600160a01b0319166001600160a01b0390921691909117815591519092507f8ba6fb577925b0796671c737df59b8aaae861b630513fb12823699e3e0e3ee619062002d62908262003c94565b505060408051808201825273777e24f9d6aa4cbe853079935560c8c5b80f9b4281528151808301909252601b82527f466f6e64617a696f6e6520556d626572746f205665726f6e657369000000000060208084019190915280820192835260086000526013905280517f7b49122965436243734b7a552847e7503db682b4cbd4d2fd428feb216e8bcdf880546001600160a01b0319166001600160a01b0390921691909117815591519092507f7b49122965436243734b7a552847e7503db682b4cbd4d2fd428feb216e8bcdf99062002e3c908262003c94565b505060408051808201825273496c13c7ab3cd4ea167062956da08cade3a562df81528151808301909252600d82526c11db1bd8985b08125b5c1858dd609a1b60208084019190915280820192835260096000526013905280517f76aa7d3cd4f559a3c98822aa7e1c37143eb9f80ceff73a5023a8fc3d6d44af6180546001600160a01b0319166001600160a01b0390921691909117815591519092507f76aa7d3cd4f559a3c98822aa7e1c37143eb9f80ceff73a5023a8fc3d6d44af629062002f06908262003c94565b5050604080518082018252738d53637779338c27fc41c323defe8db4f8dfddf081528151808301909252601b82527f496e7465726e6174696f6e616c204d65646963616c20436f7270730000000000602080840191909152808201928352600a6000526013905280517f522e87d3d671f2915034f38e0229384befcd14fcb6842a4a7158cb5222bace8f80546001600160a01b0319166001600160a01b0390921691909117815591519092507f522e87d3d671f2915034f38e0229384befcd14fcb6842a4a7158cb5222bace909062002fe0908262003c94565b505060408051808201825273a4166bc4be559b762b346cb4aaad3b051e584e3981528151808301909252600582526452617a6f6d60d81b602080840191909152808201928352600b6000526013905280517f096c4a5a35712f3bccddea911ca4c882190a673235afa6b733222c1c4155d4d880546001600160a01b0319166001600160a01b0390921691909117815591519092507f096c4a5a35712f3bccddea911ca4c882190a673235afa6b733222c1c4155d4d990620030a2908262003c94565b505060408051808201825273968dc9065969bbf2652639658b963e287336bf3481528151808301909252601882527f4f7065726174696f6e2042726f6b656e2053696c656e63650000000000000000602080840191909152808201928352600c6000526013905280517fcfe7df53cb540a76cd59225a83802812c158f2244765c115f543988963e43a9080546001600160a01b0319166001600160a01b0390921691909117815591519092507fcfe7df53cb540a76cd59225a83802812c158f2244765c115f543988963e43a91906200317c908262003c94565b50506040805180820182527336f66f445340e1d58419c6d5eeb71a19323b88e481528151808301909252600d8083526c41757469736d20537065616b7360981b6020808501919091528083019384526000919091526013905280517f36b2512b73409a9488d8a6ff5f55d24a81b2d0acc0dc87ddb304454989acb2d580546001600160a01b0319166001600160a01b0390921691909117815591519092507f36b2512b73409a9488d8a6ff5f55d24a81b2d0acc0dc87ddb304454989acb2d69062003248908262003c94565b505060408051808201825273af3e16a5bf3320a919a6f67c85954d94ea70224e81528151808301909252600e8083526d4769726c732057686f20436f646560901b6020808501919091528083019384526000919091526013905280517ffae1088c0c49138f1267ebc5a924540f6cbd3964866b6ad69d6610f0306bd32680546001600160a01b0319166001600160a01b0390921691909117815591519092507ffae1088c0c49138f1267ebc5a924540f6cbd3964866b6ad69d6610f0306bd3279062003315908262003c94565b505060408051808201825273f6285e6a3293b4c658f19cc6caa9123cf5190a8481528151808301909252600a825269191a999a902bb0ba32b960b11b602080840191909152808201928352600f6000526013905280517fea3598560a9bf02d80b97a08938925140b6320f14c1458a4e11acb962d6ca70a80546001600160a01b0319166001600160a01b0390921691909117815591519092507fea3598560a9bf02d80b97a08938925140b6320f14c1458a4e11acb962d6ca70b90620033dc908262003c94565b5050600f601555506040805180820190915260078152660233030303030360cc1b60208083019190915260008052601490527f4f26c3876aa9f4b92579780beea1161a61f87ebf1ec6ee865b299e447ecba99c906200343c908262003c94565b5060408051808201909152600781526608cc910c910c9160ca1b6020808301919091526001600052601490527fb6c61a840592cc84133e4b25bd509abf4659307c57b160799b38490a5aa48f2c9062003496908262003c94565b506040805180820190915260078152662330453146344560c81b6020808301919091526002600052601490527fa1930aa930426c54c34daad2b9ada7c5d0ef0c96078a3c5bb79f6fa6602c4a7a90620034f0908262003c94565b50604080518082019091526007815266119ba319999b2160c91b6020808301919091526003600052601490527f63d87a887046e0430be80fdeb014107d7198c879cbf2cddf39a6df195c86cb38906200354a908262003c94565b506040805180820190915260078152660233134343130360cc1b6020808301919091526004600052601490527f52102136546d97ed3f65ec1070a32935d3048ea12f310d29c378dc9d6555c0d690620035a4908262003c94565b506040805180820190915260078152662330303636353760c81b6020808301919091526005600052601490527f116126bec5aaa49b347e966c49378cf0c441de9121e306ea3d824584a9615aa290620035fe908262003c94565b506040805180820190915260078152660233846414237360cc1b6020808301919091526006600052601490527fe1f6b6a5fb7e47dad87547d4b0671e7e995a1dae22fbe5b3b5d10e2a77ed7aff9062003658908262003c94565b50604080518082019091526007808252662338383137314160c81b602080840191909152600091909152601490527f904977a779b22381a36c6463d4166ef55ee8cb3392c83093cb1750f1a00c9d9490620036b4908262003c94565b5060408051808201909152600781526611a2a31a181a1b60c91b6020808301919091526008600052601490527f125fdacc24f94fb724c0c32a4eab75d67204551eb2448dadf875d535a7449726906200370e908262003c94565b506040805180820190915260078152660234646354130360cc1b6020808301919091526009600052601490527ff517404d914a19d455440d961937db67771e4bfb0b4293ff6fd7c75855208c199062003768908262003c94565b50604080518082019091526007815266119c1aa218a32360c91b602080830191909152600a600052601490527f65f9512343925c57130fd77667cb42fc83560c400ede0c87f3de7c6c27cf09a690620037c2908262003c94565b50604080518082019091526007815266119c9a2120a0a360c91b602080830191909152600b600052601490527fdabe84bb17a8774762b6726edd7eb728da1732e1ab123804fc9345b7300e0a2e906200381c908262003c94565b5060408051808201909152600781526611a298211c192360c91b602080830191909152600c600052601490527f3a61d736b87fed11cf463325a3a6df55734cfb04ef5868e0125df26f708fa9c59062003876908262003c94565b506040805180820190915260078152662346314536354560c81b602080830191909152600d600052601490527f7f52294eda93879c98196ba8dfee8e39c94fda44d3e2327cc2c6d0806e39c2cf90620038d0908262003c94565b506040805180820190915260078152662346444539463160c81b602080830191909152600e600052601490527fb429c61f7b03e67aad73431d2c25f054ce4133be1680124f402536c7d48c1eed906200392a908262003c94565b506040805180820190915260078152662345424536444360c81b602080830191909152600f600052601490527f2f4111c4623d442ba4f89af8583239431566f63c7c6e0af548a5302cca50a54f9062003984908262003c94565b5060408051808201909152600781526611a3232323232360c91b6020808301919091526010600052601490527fb9aa073911e1c5f8bd8c04c7214fb2acd89aeb4180f5a23dea34f2fa40cb91d290620039de908262003c94565b5050601060175562003d60565b600062003a0262003abd60201b620026361760201c565b905090565b600d80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600a5460ff161562003aa25760405162461bcd60e51b815260206004820152600e60248201526d185b1c9958591e481a5b9a5d195960921b604482015260640160405180910390fd5b62003aad8162003b1b565b50600a805460ff19166001179055565b600030330362003b1557600080368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505050503601516001600160a01b0316915062003b189050565b50335b90565b6040518060800160405280604f815260200162009264604f9139805160209182012082519282019290922060408051808201825260018152603160f81b90840152805180840194909452838101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608401523060808401524660a0808501919091528151808503909101815260c090930190528151910120600b55565b60006020828403121562003bd057600080fd5b81516001600160a01b038116811462003be857600080fd5b9392505050565b634e487b7160e01b600052604160045260246000fd5b600181811c9082168062003c1a57607f821691505b60208210810362003c3b57634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111562003c8f57600081815260208120601f850160051c8101602086101562003c6a5750805b601f850160051c820191505b8181101562003c8b5782815560010162003c76565b5050505b505050565b81516001600160401b0381111562003cb05762003cb062003bef565b62003cc88162003cc1845462003c05565b8462003c41565b602080601f83116001811462003d00576000841562003ce75750858301515b600019600386901b1c1916600185901b17855562003c8b565b600085815260208120601f198616915b8281101562003d315788860151825594840194600190910190840162003d10565b508582101562003d505787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b614b1d8062003d706000396000f3fe6080604052600436106102305760003560e01c80634f6ccce71161012e57806395d89b41116100ab578063dd0812f71161006f578063dd0812f714610699578063e8a3d485146106b9578063e985e9c5146106ce578063f2fde38b14610717578063fe9b9b5f1461073757600080fd5b806395d89b4114610603578063a22cb46514610618578063b88d4fde14610638578063c87b56dd14610658578063d547cfb71461067857600080fd5b8063715018a6116100f2578063715018a61461057d57806371f6b3d31461059257806376a30d06146105b25780638b3d72ce146105c55780638da5cb5b146105e557600080fd5b80634f6ccce7146104d95780635e49a596146104f95780636352211e14610527578063707be7a01461054757806370a082311461055d57600080fd5b806320379ee5116101bc5780632f745c59116101805780632f745c59146104335780633408e470146104535780634282ccbc1461046657806342842e0e146104995780634c0ef795146104b957600080fd5b806320379ee51461038857806323b872dd1461039d57806325f9972e146103bd5780632d0335ab146103dd5780632da6b81e1461041357600080fd5b80630c53c51c116102035780630c53c51c146102e65780630f7e5970146102f957806316a0d9c21461032657806318160ddd146103535780631d622c521461037257600080fd5b806301ffc9a71461023557806306fdde031461026a578063081812fc1461028c578063095ea7b3146102c4575b600080fd5b34801561024157600080fd5b50610255610250366004613a58565b61074d565b60405190151581526020015b60405180910390f35b34801561027657600080fd5b5061027f610778565b6040516102619190613ac5565b34801561029857600080fd5b506102ac6102a7366004613ad8565b61080a565b6040516001600160a01b039091168152602001610261565b3480156102d057600080fd5b506102e46102df366004613b0d565b6108a4565b005b61027f6102f4366004613bda565b6109cb565b34801561030557600080fd5b5061027f604051806040016040528060018152602001603160f81b81525081565b34801561033257600080fd5b50610346610341366004613ad8565b610bb5565b6040516102619190613c56565b34801561035f57600080fd5b506008545b604051908152602001610261565b34801561037e57600080fd5b5061036460165481565b34801561039457600080fd5b50600b54610364565b3480156103a957600080fd5b506102e46103b8366004613cf3565b610d2a565b3480156103c957600080fd5b506103646103d8366004613d2f565b610d62565b3480156103e957600080fd5b506103646103f8366004613d7d565b6001600160a01b03166000908152600c602052604090205490565b34801561041f57600080fd5b5061036461042e366004613d98565b610e56565b34801561043f57600080fd5b5061036461044e366004613b0d565b610fcd565b34801561045f57600080fd5b5046610364565b34801561047257600080fd5b50610486610481366004613ad8565b611063565b6040516102619796959493929190613e98565b3480156104a557600080fd5b506102e46104b4366004613cf3565b6113cd565b3480156104c557600080fd5b5061027f6104d4366004613ad8565b6113e8565b3480156104e557600080fd5b506103646104f4366004613ad8565b61148d565b34801561050557600080fd5b50610519610514366004613ad8565b611520565b604051610261929190613f22565b34801561053357600080fd5b506102ac610542366004613ad8565b6115cf565b34801561055357600080fd5b5061036460155481565b34801561056957600080fd5b50610364610578366004613d7d565b611646565b34801561058957600080fd5b506102e46116cd565b34801561059e57600080fd5b506103646105ad366004613f46565b611752565b6103646105c0366004613f7b565b61180a565b3480156105d157600080fd5b5061027f6105e0366004613ad8565b611949565b3480156105f157600080fd5b50600d546001600160a01b03166102ac565b34801561060f57600080fd5b5061027f6121a7565b34801561062457600080fd5b506102e4610633366004614008565b6121b6565b34801561064457600080fd5b506102e4610653366004614044565b6121cc565b34801561066457600080fd5b5061027f610673366004613ad8565b61220b565b34801561068457600080fd5b5060408051602081019091526000815261027f565b3480156106a557600080fd5b5061027f6106b4366004613ad8565b61246a565b3480156106c557600080fd5b5061027f612504565b3480156106da57600080fd5b506102556106e93660046140ac565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b34801561072357600080fd5b506102e4610732366004613d7d565b61254c565b34801561074357600080fd5b5061036460175481565b60006001600160e01b0319821663780e9d6360e01b1480610772575061077282612692565b92915050565b606060008054610787906140d6565b80601f01602080910402602001604051908101604052809291908181526020018280546107b3906140d6565b80156108005780601f106107d557610100808354040283529160200191610800565b820191906000526020600020905b8154815290600101906020018083116107e357829003601f168201915b5050505050905090565b6000818152600260205260408120546001600160a01b03166108885760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b60006108af826115cf565b9050806001600160a01b0316836001600160a01b03160361091c5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b606482015260840161087f565b806001600160a01b031661092e6126e2565b6001600160a01b0316148061094a575061094a816106e96126e2565b6109bc5760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000606482015260840161087f565b6109c683836126f1565b505050565b60408051606081810183526001600160a01b0388166000818152600c602090815290859020548452830152918101869052610a09878287878761275f565b610a5f5760405162461bcd60e51b815260206004820152602160248201527f5369676e657220616e64207369676e617475726520646f206e6f74206d6174636044820152600d60fb1b606482015260840161087f565b6001600160a01b0387166000908152600c6020526040902054610a8390600161284f565b6001600160a01b0388166000908152600c60205260409081902091909155517f5845892132946850460bff5a0083f71031bc5bf9aadcd40f1de79423eac9b10b90610ad390899033908a90614110565b60405180910390a1600080306001600160a01b0316888a604051602001610afb92919061413c565b60408051601f1981840301815290829052610b1591614173565b6000604051808303816000865af19150503d8060008114610b52576040519150601f19603f3d011682016040523d82523d6000602084013e610b57565b606091505b509150915081610ba95760405162461bcd60e51b815260206004820152601c60248201527f46756e6374696f6e2063616c6c206e6f74207375636365737366756c00000000604482015260640161087f565b98975050505050505050565b610c1460405180610140016040528060006001600160a01b031681526020016060815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b6000828152601060209081526040918290208251610140810190935280546001600160a01b031683526001810180549192840191610c51906140d6565b80601f0160208091040260200160405190810160405280929190818152602001828054610c7d906140d6565b8015610cca5780601f10610c9f57610100808354040283529160200191610cca565b820191906000526020600020905b815481529060010190602001808311610cad57829003601f168201915b50505050508152602001600282015481526020016003820154815260200160048201548152602001600582015481526020016006820154815260200160078201548152602001600882015481526020016009820154815250509050919050565b610d3b610d356126e2565b82612862565b610d575760405162461bcd60e51b815260040161087f9061418f565b6109c6838383612959565b6000610d76600d546001600160a01b031690565b6001600160a01b0316336001600160a01b031614610da65760405162461bcd60e51b815260040161087f906141e0565b60158054906000610db68361422d565b90915550506040805180820182526001600160a01b038481168252602080830187815260155460009081526013909252939020825181546001600160a01b031916921691909117815591519091906001820190610e139082614294565b50506015546040519081527fea3d275ca6ab8360bdc4171efd62803f424bb703aa4524ba2955d75f02cde971915060200160405180910390a15060155492915050565b6000610e6a600d546001600160a01b031690565b6001600160a01b0316336001600160a01b031614610e9a5760405162461bcd60e51b815260040161087f906141e0565b60168054906000610eaa8361422d565b91905055506040518060e00160405280898152602001888152602001878152602001868152602001858152602001848152602001838152506012600060165481526020019081526020016000206000820151816000019081610f0c9190614294565b5060208201516001820190610f219082614294565b5060408201516002820190610f369082614294565b5060608201516003820190610f4b9082614294565b5060808201516004820190610f609082614294565b5060a08201516005820190610f759082614294565b5060c082015181600601559050507f9d58aaf1948e68fdbeb8affd7c369952e6d63703e2f3933aa7e4499ed1d0909f601654604051610fb691815260200190565b60405180910390a150601654979650505050505050565b6000610fd883611646565b821061103a5760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b606482015260840161087f565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b60126020526000908152604090208054819061107e906140d6565b80601f01602080910402602001604051908101604052809291908181526020018280546110aa906140d6565b80156110f75780601f106110cc576101008083540402835291602001916110f7565b820191906000526020600020905b8154815290600101906020018083116110da57829003601f168201915b50505050509080600101805461110c906140d6565b80601f0160208091040260200160405190810160405280929190818152602001828054611138906140d6565b80156111855780601f1061115a57610100808354040283529160200191611185565b820191906000526020600020905b81548152906001019060200180831161116857829003601f168201915b50505050509080600201805461119a906140d6565b80601f01602080910402602001604051908101604052809291908181526020018280546111c6906140d6565b80156112135780601f106111e857610100808354040283529160200191611213565b820191906000526020600020905b8154815290600101906020018083116111f657829003601f168201915b505050505090806003018054611228906140d6565b80601f0160208091040260200160405190810160405280929190818152602001828054611254906140d6565b80156112a15780601f10611276576101008083540402835291602001916112a1565b820191906000526020600020905b81548152906001019060200180831161128457829003601f168201915b5050505050908060040180546112b6906140d6565b80601f01602080910402602001604051908101604052809291908181526020018280546112e2906140d6565b801561132f5780601f106113045761010080835404028352916020019161132f565b820191906000526020600020905b81548152906001019060200180831161131257829003601f168201915b505050505090806005018054611344906140d6565b80601f0160208091040260200160405190810160405280929190818152602001828054611370906140d6565b80156113bd5780601f10611392576101008083540402835291602001916113bd565b820191906000526020600020905b8154815290600101906020018083116113a057829003601f168201915b5050505050908060060154905087565b6109c6838383604051806020016040528060008152506121cc565b6000818152601060205260409020600101805460609190611408906140d6565b80601f0160208091040260200160405190810160405280929190818152602001828054611434906140d6565b80156114815780601f1061145657610100808354040283529160200191611481565b820191906000526020600020905b81548152906001019060200180831161146457829003601f168201915b50505050509050919050565b600061149860085490565b82106114fb5760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b606482015260840161087f565b6008828154811061150e5761150e614354565b90600052602060002001549050919050565b601360205260009081526040902080546001820180546001600160a01b03909216929161154c906140d6565b80601f0160208091040260200160405190810160405280929190818152602001828054611578906140d6565b80156115c55780601f1061159a576101008083540402835291602001916115c5565b820191906000526020600020905b8154815290600101906020018083116115a857829003601f168201915b5050505050905082565b6000818152600260205260408120546001600160a01b0316806107725760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b606482015260840161087f565b60006001600160a01b0382166116b15760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b606482015260840161087f565b506001600160a01b031660009081526003602052604090205490565b6116d56126e2565b6001600160a01b03166116f0600d546001600160a01b031690565b6001600160a01b0316146117465760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161087f565b6117506000612b00565b565b6000611766600d546001600160a01b031690565b6001600160a01b0316336001600160a01b0316146117965760405162461bcd60e51b815260040161087f906141e0565b601780549060006117a68361422d565b909155505060175460009081526014602052604090206117c68382614294565b507fc87090b910fa439016ec996ed31f4a343d3e56d4961ca8e2cef0d792887e11656017546040516117fa91815260200190565b60405180910390a1505060175490565b6000868152601260205260408120600601543410156118775760405162461bcd60e51b815260206004820152602360248201527f4d696e696d756d20646f6e6174696f6e20616d6f756e74206e6f742063726f736044820152621cd95960ea1b606482015260840161087f565b3460009081526011602052604081208054611891906140d6565b90501161191b5760405162461bcd60e51b815260206004820152604c60248201527f446f6e6174696f6e20616d6f756e742073686f756c64206265206f6e65206f6660448201527f20302e30312c20302e30352c20302e312c20302e32352c20302e352c20312c2060648201526b06a5840dee4406260408aa8960a31b608482015260a40161087f565b600061192f8b8b348c8c8c8c8c8c8c612b52565b905061193b348a612cc1565b9a9950505050505050505050565b6060600061195683610bb5565b90506000611a306040518060e0016040528060af8152602001614a3960af913960a084015160009081526014602052604090208054611994906140d6565b80601f01602080910402602001604051908101604052809291908181526020018280546119c0906140d6565b8015611a0d5780601f106119e257610100808354040283529160200191611a0d565b820191906000526020600020905b8154815290600101906020018083116119f057829003601f168201915b50505050506040518060600160405280603481526020016148eb60349139612d05565b90506060611d5d60126000856080015181526020019081526020016000206001018054611a5c906140d6565b80601f0160208091040260200160405190810160405280929190818152602001828054611a88906140d6565b8015611ad55780601f10611aaa57610100808354040283529160200191611ad5565b820191906000526020600020905b815481529060010190602001808311611ab857829003601f168201915b50505060c087015160009081526014602052604090208054909250611afa91506140d6565b80601f0160208091040260200160405190810160405280929190818152602001828054611b26906140d6565b8015611b735780601f10611b4857610100808354040283529160200191611b73565b820191906000526020600020905b815481529060010190602001808311611b5657829003601f168201915b505050608088015160009081526012602052604090206002018054909250611b9b91506140d6565b80601f0160208091040260200160405190810160405280929190818152602001828054611bc7906140d6565b8015611c145780601f10611be957610100808354040283529160200191611c14565b820191906000526020600020905b815481529060010190602001808311611bf757829003601f168201915b50505060e089015160009081526014602052604090208054909250611c3991506140d6565b80601f0160208091040260200160405190810160405280929190818152602001828054611c65906140d6565b8015611cb25780601f10611c8757610100808354040283529160200191611cb2565b820191906000526020600020905b815481529060010190602001808311611c9557829003601f168201915b50505060808a015160009081526012602052604090206003018054909250611cda91506140d6565b80601f0160208091040260200160405190810160405280929190818152602001828054611d06906140d6565b8015611d535780601f10611d2857610100808354040283529160200191611d53565b820191906000526020600020905b815481529060010190602001808311611d3657829003601f168201915b5050505050612d1a565b9050611f67816014600086610100015181526020019081526020016000208054611d86906140d6565b80601f0160208091040260200160405190810160405280929190818152602001828054611db2906140d6565b8015611dff5780601f10611dd457610100808354040283529160200191611dff565b820191906000526020600020905b815481529060010190602001808311611de257829003601f168201915b505050608088015160009081526012602052604090206004018054909250611e2791506140d6565b80601f0160208091040260200160405190810160405280929190818152602001828054611e53906140d6565b8015611ea05780601f10611e7557610100808354040283529160200191611ea0565b820191906000526020600020905b815481529060010190602001808311611e8357829003601f168201915b50505061012089015160009081526014602052604090208054909250611ec691506140d6565b80601f0160208091040260200160405190810160405280929190818152602001828054611ef2906140d6565b8015611f3f5780601f10611f1457610100808354040283529160200191611f3f565b820191906000526020600020905b815481529060010190602001808311611f2257829003601f168201915b50505060808a015160009081526012602052604090206005018054909250611cda91506140d6565b90506000611f916040518060e0016040528060b581526020016146c060b591398560200151612d35565b9050600061214160405180610120016040528060ef815260200161491f60ef913960408088015160009081526011602052208054611fce906140d6565b80601f0160208091040260200160405190810160405280929190818152602001828054611ffa906140d6565b80156120475780601f1061201c57610100808354040283529160200191612047565b820191906000526020600020905b81548152906001019060200180831161202a57829003601f168201915b50505050506040518060400160405280601081526020016f01022aa24103237b730ba32b2103a37960851b815250601360008a606001518152602001908152602001600020600101805461209a906140d6565b80601f01602080910402602001604051908101604052809291908181526020018280546120c6906140d6565b80156121135780601f106120e857610100808354040283529160200191612113565b820191906000526020600020905b8154815290600101906020018083116120f657829003601f168201915b50505050506040518060400160405280600b81526020016a1e17ba32bc3a1f1e17b39f60a91b815250612d1a565b9050600061217085858585604051806040016040528060068152602001651e17b9bb339f60d11b815250612d1a565b905061217b81612d90565b60405160200161218b919061436a565b6040516020818303038152906040529650505050505050919050565b606060018054610787906140d6565b6121c86121c16126e2565b8383612ef5565b5050565b6121dd6121d76126e2565b83612862565b6121f95760405162461bcd60e51b815260040161087f9061418f565b61220584848484612fc3565b50505050565b6060612444612269604051806040016040528060148152602001737b226e616d65223a22586d61732043617264202360601b81525061224985612ff6565b60405180604001604052806002815260200161088b60f21b815250612d05565b61240b6040518060600160405280602d8152602001614775602d91396011600061229288610bb5565b60400151815260200190815260200160002080546122af906140d6565b80601f01602080910402602001604051908101604052809291908181526020018280546122db906140d6565b80156123285780601f106122fd57610100808354040283529160200191612328565b820191906000526020600020905b81548152906001019060200180831161230b57829003601f168201915b50505050506040518060400160405280601581526020017401022aa24103bb2b932903237b730ba32b2103a379605d1b815250601360006123688a610bb5565b6060015181526020019081526020016000206001018054612388906140d6565b80601f01602080910402602001604051908101604052809291908181526020018280546123b4906140d6565b80156124015780601f106123d657610100808354040283529160200191612401565b820191906000526020600020905b8154815290600101906020018083116123e457829003601f168201915b50505050506130f7565b61241485611949565b61241d86613110565b60405160200161243094939291906143bd565b604051602081830303815290604052612d90565b6040516020016124549190614414565b6040516020818303038152906040529050919050565b60146020526000908152604090208054612483906140d6565b80601f01602080910402602001604051908101604052809291908181526020018280546124af906140d6565b80156124fc5780601f106124d1576101008083540402835291602001916124fc565b820191906000526020600020905b8154815290600101906020018083116124df57829003601f168201915b505050505081565b606061252860405180610100016040528060d2815260200161481960d29139612d90565b6040516020016125389190614414565b604051602081830303815290604052905090565b6125546126e2565b6001600160a01b031661256f600d546001600160a01b031690565b6001600160a01b0316146125c55760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161087f565b6001600160a01b03811661262a5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161087f565b61263381612b00565b50565b600030330361268c57600080368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505050503601516001600160a01b0316915061268f9050565b50335b90565b60006001600160e01b031982166380ac58cd60e01b14806126c357506001600160e01b03198216635b5e139f60e01b145b8061077257506301ffc9a760e01b6001600160e01b0319831614610772565b60006126ec612636565b905090565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190612726826115cf565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60006001600160a01b0386166127c55760405162461bcd60e51b815260206004820152602560248201527f4e61746976654d6574615472616e73616374696f6e3a20494e56414c49445f5360448201526424a3a722a960d91b606482015260840161087f565b60016127d86127d3876133c0565b61343d565b6040805160008152602081018083529290925260ff851690820152606081018690526080810185905260a0016020604051602081039080840390855afa158015612826573d6000803e3d6000fd5b505050602060405103516001600160a01b0316866001600160a01b031614905095945050505050565b600061285b8284614459565b9392505050565b6000818152600260205260408120546001600160a01b03166128db5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b606482015260840161087f565b60006128e6836115cf565b9050806001600160a01b0316846001600160a01b0316148061292d57506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b806129515750836001600160a01b03166129468461080a565b6001600160a01b0316145b949350505050565b826001600160a01b031661296c826115cf565b6001600160a01b0316146129d05760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201526437bbb732b960d91b606482015260840161087f565b6001600160a01b038216612a325760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b606482015260840161087f565b612a3d83838361346d565b612a486000826126f1565b6001600160a01b0383166000908152600360205260408120805460019290612a7190849061446c565b90915550506001600160a01b0382166000908152600360205260408120805460019290612a9f908490614459565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600d80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600080612b5d613525565b9050612b698c82613536565b612b71613684565b604080516101408101825233815260208082018e81528284018e9052606083018d9052608083018c905260a083018b905260c083018a905260e0830189905261010083018890526101208301879052600f5460009081526010909252929020815181546001600160a01b0319166001600160a01b0390911617815591519091906001820190612c009082614294565b5060408201518160020155606082015181600301556080820151816004015560a0820151816005015560c0820151816006015560e08201518160070155610100820151816008015561012082015181600901559050507f21414cdba6b56757af56c4673643b26d24349f57c89f66dff6744d42682243f2818d8c8c604051612caa94939291909384526001600160a01b039290921660208401526040830152606082015260800190565b60405180910390a19b9a5050505050505050505050565b6000818152601360205260408082205490516001600160a01b039091169184156108fc02918591818181858888f193505050501580156109c6573d6000803e3d6000fd5b6060612951612d148585612d35565b83612d35565b6060612d2b612d14878787876130f7565b9695505050505050565b60408051808201825260008082526020918201528151808301909252825182528083019082015260609061285b906040805180820182526000808252602091820152815180830190925286518252808701908201529061369b565b60608151600003612daf57505060408051602081019091526000815290565b60006040518060600160405280604081526020016147a26040913990506000600384516002612dde9190614459565b612de89190614495565b612df39060046144a9565b90506000612e02826020614459565b67ffffffffffffffff811115612e1a57612e1a613b37565b6040519080825280601f01601f191660200182016040528015612e44576020820181803683370190505b509050818152600183018586518101602084015b81831015612eb0576003830192508251603f8160121c168501518253600182019150603f81600c1c168501518253600182019150603f8160061c168501518253600182019150603f8116850151825350600101612e58565b600389510660018114612eca5760028114612edb57612ee7565b613d3d60f01b600119830152612ee7565b603d60f81b6000198301525b509398975050505050505050565b816001600160a01b0316836001600160a01b031603612f565760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604482015260640161087f565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b612fce848484612959565b612fda84848484613733565b6122055760405162461bcd60e51b815260040161087f906144c0565b60608160000361301d5750506040805180820190915260018152600360fc1b602082015290565b8160005b811561304757806130318161422d565b91506130409050600a83614495565b9150613021565b60008167ffffffffffffffff81111561306257613062613b37565b6040519080825280601f01601f19166020018201604052801561308c576020820181803683370190505b5090505b8415612951576130a160018361446c565b91506130ae600a86614512565b6130b9906030614459565b60f81b8183815181106130ce576130ce614354565b60200101906001600160f81b031916908160001a9053506130f0600a86614495565b9450613090565b6060613107612d14868686612d05565b95945050505050565b6060600061311d83610bb5565b905060006131e16040518060600160405280603781526020016147e26037913960608401516000908152601360205260409020600101805461315e906140d6565b80601f016020809104026020016040519081016040528092919081815260200182805461318a906140d6565b80156131d75780601f106131ac576101008083540402835291602001916131d7565b820191906000526020600020905b8154815290600101906020018083116131ba57829003601f168201915b5050505050612d35565b90506132bf816040518060600160405280602b8152602001614a0e602b91396040808601516000908152601160205220805461321c906140d6565b80601f0160208091040260200160405190810160405280929190818152602001828054613248906140d6565b80156132955780601f1061326a57610100808354040283529160200191613295565b820191906000526020600020905b81548152906001019060200180831161327857829003601f168201915b50505050506040518060400160405280600781526020016608115512089f4b60ca1b8152506130f7565b9050612951816040518060400160405280601e81526020017f7b2274726169745f74797065223a2249636f6e222c2276616c7565223a22000081525060126000866080015181526020019081526020016000206000018054613320906140d6565b80601f016020809104026020016040519081016040528092919081815260200182805461334c906140d6565b80156133995780601f1061336e57610100808354040283529160200191613399565b820191906000526020600020905b81548152906001019060200180831161337c57829003601f168201915b505050505060405180604001604052806004815260200163227d5d7d60e01b8152506130f7565b600060405180608001604052806043815260200161467d6043913980516020918201208351848301516040808701518051908601209051613420950193845260208401929092526001600160a01b03166040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b6000613448600b5490565b60405161190160f01b6020820152602281019190915260428101839052606201613420565b6001600160a01b0383166134c8576134c381600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b6134eb565b816001600160a01b0316836001600160a01b0316146134eb576134eb8382613838565b6001600160a01b038216613502576109c6816138d5565b826001600160a01b0316826001600160a01b0316146109c6576109c68282613984565b6000600f5460016126ec9190614459565b6001600160a01b03821661358c5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604482015260640161087f565b6000818152600260205260409020546001600160a01b0316156135f15760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604482015260640161087f565b6135fd6000838361346d565b6001600160a01b0382166000908152600360205260408120805460019290613626908490614459565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b600f80549060006136948361422d565b9190505550565b805182516060916000916136af9190614459565b67ffffffffffffffff8111156136c7576136c7613b37565b6040519080825280601f01601f1916602001820160405280156136f1576020820181803683370190505b509050600060208201905061370f81866020015187600001516139c8565b845161372b9061371f9083614459565b602086015186516139c8565b509392505050565b60006001600160a01b0384163b1561383057836001600160a01b031663150b7a0261375c6126e2565b8786866040518563ffffffff1660e01b815260040161377e9493929190614526565b6020604051808303816000875af19250505080156137b9575060408051601f3d908101601f191682019092526137b691810190614559565b60015b613816573d8080156137e7576040519150601f19603f3d011682016040523d82523d6000602084013e6137ec565b606091505b50805160000361380e5760405162461bcd60e51b815260040161087f906144c0565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050612951565b506001612951565b6000600161384584611646565b61384f919061446c565b6000838152600760205260409020549091508082146138a2576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b6008546000906138e79060019061446c565b6000838152600960205260408120546008805493945090928490811061390f5761390f614354565b90600052602060002001549050806008838154811061393057613930614354565b600091825260208083209091019290925582815260099091526040808220849055858252812055600880548061396857613968614576565b6001900381819060005260206000200160009055905550505050565b600061398f83611646565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b60208110613a0057815183526139df602084614459565b92506139ec602083614459565b91506139f960208261446c565b90506139c8565b6000198115613a2f576001613a1683602061446c565b613a2290610100614670565b613a2c919061446c565b90505b9151835183169219169190911790915250565b6001600160e01b03198116811461263357600080fd5b600060208284031215613a6a57600080fd5b813561285b81613a42565b60005b83811015613a90578181015183820152602001613a78565b50506000910152565b60008151808452613ab1816020860160208601613a75565b601f01601f19169290920160200192915050565b60208152600061285b6020830184613a99565b600060208284031215613aea57600080fd5b5035919050565b80356001600160a01b0381168114613b0857600080fd5b919050565b60008060408385031215613b2057600080fd5b613b2983613af1565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b600082601f830112613b5e57600080fd5b813567ffffffffffffffff80821115613b7957613b79613b37565b604051601f8301601f19908116603f01168101908282118183101715613ba157613ba1613b37565b81604052838152866020858801011115613bba57600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600080600060a08688031215613bf257600080fd5b613bfb86613af1565b9450602086013567ffffffffffffffff811115613c1757600080fd5b613c2388828901613b4d565b9450506040860135925060608601359150608086013560ff81168114613c4857600080fd5b809150509295509295909350565b60208152613c706020820183516001600160a01b03169052565b60006020830151610140806040850152613c8e610160850183613a99565b91506040850151606085015260608501516080850152608085015160a085015260a085015160c085015260c085015160e085015260e0850151610100818187015280870151915050610120818187015280870151838701525050508091505092915050565b600080600060608486031215613d0857600080fd5b613d1184613af1565b9250613d1f60208501613af1565b9150604084013590509250925092565b60008060408385031215613d4257600080fd5b823567ffffffffffffffff811115613d5957600080fd5b613d6585828601613b4d565b925050613d7460208401613af1565b90509250929050565b600060208284031215613d8f57600080fd5b61285b82613af1565b600080600080600080600060e0888a031215613db357600080fd5b873567ffffffffffffffff80821115613dcb57600080fd5b613dd78b838c01613b4d565b985060208a0135915080821115613ded57600080fd5b613df98b838c01613b4d565b975060408a0135915080821115613e0f57600080fd5b613e1b8b838c01613b4d565b965060608a0135915080821115613e3157600080fd5b613e3d8b838c01613b4d565b955060808a0135915080821115613e5357600080fd5b613e5f8b838c01613b4d565b945060a08a0135915080821115613e7557600080fd5b50613e828a828b01613b4d565b92505060c0880135905092959891949750929550565b60e081526000613eab60e083018a613a99565b8281036020840152613ebd818a613a99565b90508281036040840152613ed18189613a99565b90508281036060840152613ee58188613a99565b90508281036080840152613ef98187613a99565b905082810360a0840152613f0d8186613a99565b9150508260c083015298975050505050505050565b6001600160a01b038316815260406020820181905260009061295190830184613a99565b600060208284031215613f5857600080fd5b813567ffffffffffffffff811115613f6f57600080fd5b61295184828501613b4d565b60008060008060008060008060006101208a8c031215613f9a57600080fd5b613fa38a613af1565b985060208a013567ffffffffffffffff811115613fbf57600080fd5b613fcb8c828d01613b4d565b999c999b505050506040880135976060810135976080820135975060a0820135965060c0820135955060e082013594506101009091013592509050565b6000806040838503121561401b57600080fd5b61402483613af1565b91506020830135801515811461403957600080fd5b809150509250929050565b6000806000806080858703121561405a57600080fd5b61406385613af1565b935061407160208601613af1565b925060408501359150606085013567ffffffffffffffff81111561409457600080fd5b6140a087828801613b4d565b91505092959194509250565b600080604083850312156140bf57600080fd5b6140c883613af1565b9150613d7460208401613af1565b600181811c908216806140ea57607f821691505b60208210810361410a57634e487b7160e01b600052602260045260246000fd5b50919050565b6001600160a01b0384811682528316602082015260606040820181905260009061310790830184613a99565b6000835161414e818460208801613a75565b60609390931b6bffffffffffffffffffffffff19169190920190815260140192915050565b60008251614185818460208701613a75565b9190910192915050565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6020808252601a908201527f4f6e6c7920746865206f776e65722063616e20646f2074686973000000000000604082015260600190565b634e487b7160e01b600052601160045260246000fd5b60006001820161423f5761423f614217565b5060010190565b601f8211156109c657600081815260208120601f850160051c8101602086101561426d5750805b601f850160051c820191505b8181101561428c57828155600101614279565b505050505050565b815167ffffffffffffffff8111156142ae576142ae613b37565b6142c2816142bc84546140d6565b84614246565b602080601f8311600181146142f757600084156142df5750858301515b600019600386901b1c1916600185901b17855561428c565b600085815260208120601f198616915b8281101561432657888601518255948401946001909101908401614307565b50858210156143445787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052603260045260246000fd5b7f222c22696d616765223a22646174613a696d6167652f7376672b786d6c3b62618152641cd94d8d0b60da1b6020820152600082516143b0816025850160208701613a75565b9190910160250192915050565b600085516143cf818460208a01613a75565b8551908301906143e3818360208a01613a75565b85519101906143f6818360208901613a75565b8451910190614409818360208801613a75565b019695505050505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c00000081526000825161444c81601d850160208701613a75565b91909101601d0192915050565b8082018082111561077257610772614217565b8181038181111561077257610772614217565b634e487b7160e01b600052601260045260246000fd5b6000826144a4576144a461447f565b500490565b808202811582820484141761077257610772614217565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6000826145215761452161447f565b500690565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090612d2b90830184613a99565b60006020828403121561456b57600080fd5b815161285b81613a42565b634e487b7160e01b600052603160045260246000fd5b600181815b808511156145c75781600019048211156145ad576145ad614217565b808516156145ba57918102915b93841c9390800290614591565b509250929050565b6000826145de57506001610772565b816145eb57506000610772565b8160018114614601576002811461460b57614627565b6001915050610772565b60ff84111561461c5761461c614217565b50506001821b610772565b5060208310610133831016604e8410600b841016171561464a575081810a610772565b614654838361458c565b806000190482111561466857614668614217565b029392505050565b600061285b83836145cf56fe4d6574615472616e73616374696f6e2875696e74323536206e6f6e63652c616464726573732066726f6d2c62797465732066756e6374696f6e5369676e6174757265293c67207374726f6b653d226e6f6e6522207374726f6b652d77696474683d22312220666f6e742d66616d696c793d2248656c7665746963612c20417269616c2220666f6e742d73697a653d2238332220666f6e742d7765696768743d226e6f726d616c22206c65747465722d73706163696e673d22302e3031363622206c696e652d73706163696e673d223739223e3c7465787420783d2236302220793d22312e35656d222066696c6c3d2223464646464646223e226465736372697074696f6e223a225468697320756e69717565204e46542063657274696669657320746861744142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f222c202261747472696275746573223a5b20207b2274726169745f74797065223a22446f6e6174656420746f222c2276616c7565223a227b226e616d65223a22446f6e61746520586d6173222c226465736372697074696f6e223a2243726561746520796f7572204e4654204368726973746d617320706f73746361726420616e6420646f6e61746520746f20612063686172697479206f7267616e697a6174696f6e222c22696d616765223a22222c2265787465726e616c5f6c696e6b223a2268747470733a2f2f646f6e6174652d786d61732e636f6d222c2273656c6c65725f6665655f62617369735f706f696e7473223a302c226665655f726563697069656e74223a22227d2220783d22302220793d2230222077696474683d223130303022206865696768743d2231303030223e3c2f726563743e3c2f673e3c2f746578743e3c2f673e3c67207374726f6b653d226e6f6e6522207374726f6b652d77696474683d22312220666f6e742d66616d696c793d2248656c7665746963612c20417269616c2220666f6e742d73697a653d2233302220666f6e742d7765696768743d226e6f726d616c22206c65747465722d73706163696e673d22302e3031363622206c696e652d73706163696e673d223739223e3c7465787420783d223530252220793d223935302220646f6d696e616e742d626173656c696e653d226d6964646c652220746578742d616e63686f723d226d6964646c65222066696c6c3d2223464646464646223e227d2c7b2274726169745f74797065223a22446f6e6174656420616d6f756e74222c2276616c7565223a223c73766720786d6c6e733a786c696e6b3d22687474703a2f2f7777772e77332e6f72672f313939392f786c696e6b2220786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323030302f737667222077696474683d223130303022206865696768743d2231303030222076696577426f783d2230203020313030302031303030223e3c67207374726f6b653d226e6f6e65222066696c6c3d226e6f6e65223e3c726563742066696c6c3d22a26469706673582212208646aa017d3c07699d7c737137b7f768deda70055ab7cae545446c3c1fce739f64736f6c63430008110033222f3e3c7061746820643d226d3533352e353832203432372e393234203137342e3332332d33362e3338364c3733372e3935203532352e38396331302e3033382034382e3132312d32302e38322039352e3237322d36382e393336203130352e3333366138392e30342038392e30342030203020312d3130352e3335342d36382e3936396c2d32382e3034312d3133342e3334312d2e3033362e3030375a222066696c6c3d223c67207472616e73666f726d3d227472616e736c617465283130302031303029223e3c706174682066696c6c3d223c7061746820643d224d3332322e3630382038343920323434203737302e3437376c3338352e3238362d3338342e3836356135332e30332035332e30332030203020302031342e3036342d35312e343131632d342e3839322d31382e3431362d31392e3239312d33322e382d33372e3732372d33372e3638366135332e3136362035332e3136362030203020302d35312e3436382031342e3034386c2d32322e39382032322e3935352d37382e3539352d37382e3532332032322e39382d32322e3934326336342e3136342d36342e3038203136382e3138342d36342e3037203233322e3333342e3032352036342e3135312036342e3039352036342e3134203136382d2e303235203233322e3038324c3332322e3631203834395a222066696c6c3d222220643d224d3630302e38203230302e3420343030203233372e36762d37342e347a222f3e3c7061746820643d224d38303020383030483063302d32372e313320322e37322d35342e313920382e3132362d38302e373735613339392e3033203339392e30332030203020312036302e3138382d3134332e333136203430312e323831203430312e323831203020302031203137352e3938382d3134352e323132203339372e343332203339372e3433322030203020312037352e3038332d32332e333535203430332e313136203430332e313136203020302031203136312e3232382030203339372e333835203339372e333835203020302031203134332e30332036302e333036433733342e303632203534322e313831203830302e313733203636362e37363820383030203830305a222066696c6c3d2222207472616e73666f726d3d227472616e736c617465283235312e34203231392e373729222f3e3c7061746820643d224d3431322e32203131302e316134312e38392034312e38392030203020302032392e36352d35312e33322034312e392034312e392030203020302d35312e33332032392e36342034312e38382034312e38382030203020302d35312e33322d32392e36342034312e38372034312e38372030203020302032392e36352035312e33322034312e38392034312e38392030203020302d32392e36352035312e33332034312e38392034312e38392030203020302035312e33322d32392e36352034312e39312034312e39312030203020302035312e33332032392e36352034312e39312034312e39312030203020302d32392e36352d35312e33335a222066696c6c3d22222063783d22343030222063793d223430302220723d22343030222f3e3c7061746820643d224d3830302034303043383030203137392e303836203632302e39313420302034303020305330203137392e3038362030203430306330202e3820383030202e382038303020305a222066696c6c3d222220643d224d3020313030306831303030562d31483832362e3330377a222f3e3c67207472616e73666f726d3d227472616e736c617465283432392031313329222066696c6c3d222220643d226d3439392e3934203135392e322036302e393933203139332e343932203137392e3934382d39332e3639312d39332e363933203137392e393437203139332e3439342036302e3939322d3139332e3439332036302e3939334c3734302e3838203734302e38386c2d3137392e3934382d39332e3639322d36302e393932203139332e3439332d36302e3939332d3139332e3439334c323539203734302e38386c39332e3639322d3137392e3934384c3135392e32203439392e39346c3139332e3439322d36302e3939334c3235392e303031203235396c3137392e3934372039332e3639327a222f3e3c706174682066696c6c3d222220643d226d3631382e303320313936203230332e303032203830342e383036483431352e30337a222f3e3c706174682066696c6c3d22222f3e3c67207472616e73666f726d3d227472616e736c617465283434332e3237203239342e363129223e3c636972636c652063783d2235362e3634222063793d22362e33362220723d22362e3336222f3e3c636972636c652063783d2232352e3331222063793d22362e33362220723d22362e3336222f3e3c636972636c652063783d22382e3433222063793d2237392e34362220723d22382e3433222f3e3c7061746820643d224d33352e33392034302e343761382e343320382e343320302031203020302031362e383620382e343320382e343320302030203020302d31362e38365a222f3e3c636972636c652063783d223133342e3635222063793d2238332e34372220723d22382e3433222f3e3c636972636c652063783d223131302e3734222063793d2234332e32392220723d22382e3433222f3e3c636972636c652063783d2237362e3139222063793d2237352e30332220723d22382e3433222f3e3c636972636c652063783d223136352e3839222063793d2234362e332220723d22382e3433222f3e3c2f673e223e3c636972636c65207472616e73666f726d3d22726f74617465283930203230302032303029222063783d22323030222063793d223230302220723d22323030222f3e3c636972636c652063783d22343030222063793d223430302220723d22323030222f3e3c2f673e3c706174682066696c6c3d222220643d226d3430302030203430302036353248307a222f3e3c636972636c652066696c6c3d222220643d226d3339352e323636203338372e303435203135342e383133203631332e373631483234302e3435347a222f3e3c706174682066696c6c3d22223e3c656c6c697073652063783d2233372e323432222063793d2233372e323339222072783d2233372e323432222072793d2233372e323339222f3e3c656c6c697073652063783d223135352e363937222063793d223137322e3839222072783d2233372e323432222072793d2233372e323339222f3e3c656c6c697073652063783d2234392e313836222063793d223333382e303032222072783d2233372e323432222072793d2233372e323339222f3e3c656c6c697073652063783d223434302e373538222063793d223433392e373631222072783d2233372e323432222072793d2233372e323339222f3e3c2f673e3c67207472616e73666f726d3d227472616e736c617465283436322033393929222066696c6c3d22454950373132446f6d61696e28737472696e67206e616d652c737472696e672076657273696f6e2c6164647265737320766572696679696e67436f6e74726163742c627974657333322073616c74292220643d226d343030203134382e32313720343030203530332e39333748307a222f3e3c656c6c697073652066696c6c3d22222f3e3c7061746820643d224d3732372e3636203231372e3536346331312e3232362d32352e31383720342e3334372d35342e37392d31362e3832362d37322e3430332d32312e3137322d31372e3631342d35312e3435312d31382e3932362d37342e3035392d332e3230382d32322e3630372031352e3731372d33322e3030352034342e3631352d32322e3938372037302e3637396c2d31362e3732322d372e35326132362e31362032362e31362030203020302d32302e3036392d2e3538332032362e3236322032362e3236322030203020302d31342e362031332e3832324c353334203238312e383239203639362e363236203335356c32382e3339372d36332e3436346132362e3337372032362e333737203020302030202e3538372d32302e3133352032362e3237352032362e3237352030203020302d31332e3738382d31342e36356c2d31362e3730372d372e35326136312e3032332036312e3032332030203020302033322e3534352d33312e3636375a6d2d32372e3234322d31322e323934632d372e3131372031352e3831382d32352e3636332032322e3836362d34312e3434352031352e373531732d32322e3833362d32352e3730352d31352e3736342d34312e35343363372e3037322d31352e3833382032352e3539382d32322e39342034312e342d31352e38376133312e3237322033312e3237322030203020312031362e35392031372e3531362033312e3339342033312e3339342030203020312d2e3738312032342e3134365a222066696c6c3d222220643d224d3833382e3035203538332e3538203130303020313030302e383037483637362e3130317a222f3e3c2f673e222063783d223339392e32222063793d2232392e362220723d2232392e36223e3c2f636972636c653e3c2f673e222f3e3c67207472616e73666f726d3d227472616e736c617465283434392031383929222066696c6c3d22223e3c7061746820643d224d3333332030203139372e352036332e33332036322030763139306c3133352e352d36332e33334c333333203139307a222f3e3c636972636c652063783d223331222063793d223632312220723d223331222f3e3c636972636c652063783d22343431222063793d223433382220723d223331222f3e3c2f673e3c67207472616e73666f726d3d227472616e736c617465283236372033353429222066696c6c3d223c7061746820643d224d3833392e373734203531322e3839356134322e3535352034322e3535352030203020302d32302e35322d33322e3232382034322e36312034322e363120302030203020352e3830362d33372e3734372034322e3632342034322e3632342030203020302d32362e3737312d32372e3234322034322e3632332034322e3632332030203020302d322e3139332d33382e3133392034322e3634322034322e3634322030203020302d33312e3837322d32312e30372034322e3631322034322e3631322030203020302d31302e3037312d33362e3832362034322e3633342034322e3633342030203020302d33352e3533312d31332e3938372034322e3630332034322e3630332030203020302d31372e34372d33332e3933382034322e3632342034322e3632342030203020302d33372e36352d362e33332034322e3538332034322e3538332030203020302d32342e3134352d32392e3631332034322e362034322e362030203020302d33382e31373720312e3636352034322e3634392034322e3634392030203020302d36362e3738332d31342e33332034322e3536392034322e3536392030203020302d33342e30392d31372e3131682d2e3736336134322e3534332034322e3534332030203020302d33342e3132382031372e3038362034322e3533342034322e3533342030203020302d33362e3937352d392e3635352034322e3432342034322e3432342030203020302d32392e3839372032332e3833312034322e362034322e362030203020302d33382e3137352d312e3736372034322e3538332034322e3538332030203020302d32342e3232352032392e35352034322e36352034322e36352030203020302d33372e36373720362e3233392034322e3632392034322e3632392030203020302d31372e3536392033332e3930322034322e3630392034322e3630392030203020302d33352e3538372031332e38382034322e3538372034322e3538372030203020302d31302e3135342033362e3831382034322e3539312034322e3539312030203020302d33312e3932342032302e3937322034322e3537322034322e3537322030203020302d322e3236382033382e3132332034322e3632342034322e3632342030203020302d32362e3837342032372e3137382034322e36312034322e363120302030203020352e3731382033372e3738362034322e3632362034322e3632362030203020302d372e3132382036372e38362034322e3632362034322e36323620302030203020372e3036352036372e3837332034322e3634392034322e3634392030203020302d352e3734342033372e3736382034322e3636322034322e3636322030203020302032362e38312032372e3232312034322e3636312034322e36363120302030203020322e3237322033382e3132332034322e36382034322e36382030203020302033312e3838322032312e3033362034322e3536312034322e3536312030203020302031302e3130372033362e3831332034322e3538332034322e3538332030203020302033352e3535392031332e39312034322e3537382034322e3537382030203020302031372e34392033332e3933372034322e3539392034322e3539392030203020302033372e36363720362e3238312034322e3538332034322e3538332030203020302032342e32332032392e36372034322e362034322e362030203020302033382e32372d312e382034322e3633362034322e3633362030203020302036362e3830382031342e32344134322e3730382034322e373038203020302030203439392e313337203839306134322e3531382034322e3531382030203020302033342e3130342d31372e3034382034322e3633362034322e3633362030203020302036362e3834362d31342e3037352034322e36352034322e36352030203020302033382e32303320312e3830372034322e3633342034322e3633342030203020302032342e3238352d32392e3533382034322e3633372034322e3633372030203020302033372e3636332d362e3231372034322e3631362034322e3631362030203020302031372e3538332d33332e3837342034322e3632312034322e3632312030203020302033352e3535312d31332e3836382034322e362034322e362030203020302031302e3139312d33362e3736362034322e3634322034322e3634322030203020302033312e3935312d32302e3933372034322e3632332034322e36323320302030203020322e3335352d33382e31322034322e3538362034322e3538362030203020302032362e38392d32372e3134382034322e3537332034322e3537332030203020302d352e3730392d33372e3737382034322e3631342034322e36313420302030203020372e32332d36372e3837332034322e35352034322e35352030203020302031332e3439342d33352e36375a4d3338362e3332203534382e303139632d2e3030362d34352e3738312032372e3537352d38372e3035372036392e38382d3130342e35382034322e3330362d31372e3532322039312e3030332d372e383339203132332e3338332032342e3533342033322e33382033322e3337322034322e3036342038312e3035382032342e353338203132332e3335332d31372e3532362034322e3239362d35382e3831312036392e38372d3130342e3630332036392e3836352d36322e3531352d2e3030372d3131332e3139312d35302e3637322d3131332e3139382d3131332e3137325a222066696c6c3d22223e3c7061746820643d226d3431362e353931203139312e303134203136332e38392036392e3536382d3130342e3735203234362e373737632d31392e3231342034352e3236362d37312e3438362036362e3338362d3131362e3735322034372e31372d34352e3234362d31392e3232362d36362e3334372d37312e3438352d34372e3133382d3131362e3733376c3130342e37352d3234362e3737395a222f3e3c7061746820643d226d3530382e383437203239392e383138203137342e3331312d33362e3338342035342e3738203236322e3434356331302e3034382034382e3133392d32302e3833312039352e3330372d36382e393639203130352e3335356138392e30342038392e30342030203020312d3130352e3335342d36382e3936396c2d35342e37382d3236322e3434342e3031322d2e3030325a222f3e3c2f673e3c7061746820643d224d3336332e303837203331362e39393220353237203338362e35376c2d35312e323738203132302e383032632d31392e3231342034352e3236362d37312e3438352036362e3338352d3131362e3735322034372e31372d34352e3236362d31392e3231342d36362e3338362d37312e3438352d34372e3137312d3131362e3735326c35312e3237372d3132302e382e30312e3030345a222066696c6c3d22223e3c636972636c652063783d2232392e3633222063793d2232392e36332220723d2232392e3633222f3e3c636972636c652063783d2232392e3633222063793d223737302e33372220723d2232392e3633222f3e3c2f673e3c706174682066696c6c3d22222f3e3c67207472616e73666f726d3d227472616e736c617465283235382032313829222066696c6c3d22223e3c7061746820643d226d3333312e39303320342e3936362031342e3336352032392e31303161382e38313920382e38313920302030203020362e36373720342e3831326c33322e31323320342e36363861382e38373920382e38373920302030203120342e3930392031352e3133344c3336362e3733332038312e333761382e39313420382e3931342030203020302d322e35353120372e3835356c352e3438362033312e39383861382e38353420382e3835342030203020312d31322e3820392e3334386c2d32382e3733312d31352e30393861382e383820382e38382030203020302d382e32363620306c2d32382e37332031352e30393861382e38353620382e3835362030203020312d31322e3836312d392e3334386c352e3438362d33312e39383861382e383920382e38392030203020302d322e3536332d372e3835356c2d32332e3233322d32322e36353361382e38363620382e38363620302030203120342e3930392d31352e3133346c33322e3132332d342e36363861382e38313920382e38313920302030203020362e3637372d342e3831326c31342e3238312d32392e31333761382e38373920382e3837392030203020312031352e39343220305a222f3e3c656c6c697073652063783d223432392e373838222063793d223631332e313132222072783d2233372e323132222072793d2233372e323039222f3e3c656c6c697073652063783d2233372e323132222063793d223731342e373931222072783d2233372e323132222072793d2233372e323039222f3e3c2f673e3c67207472616e73666f726d3d227472616e736c617465283334352033393929222066696c6c3d222220643d224d2e3337203635322e353235683739392e323656383030482e33377a222f3e3c2f673e3c706174682066696c6c3d222220643d226d3433302e313837203534392e3730322d34302e383735203138382e353332203131372e3535332d3135322e383837203134332e323739203132392e39362d37312e3537332d3137382e333537203138332e3938372d35382e3537312d3139312e3637382d32382e3034372034302e3934322d3138382e3536362d3131372e363837203135322e3838372d3134332e3131312d3132392e39362037312e343732203137382e3335372d3138342e3035342035382e3633387a222f3e3c706174682066696c6c3d22223e3c636972636c652063783d22353431222063793d2232362220723d223236222f3e3c636972636c652063783d223236222063793d2232362220723d223236222f3e3c7061746820643d224d3339392e3137372035303861362e38313520362e3831352030203020302d362e383120362e3832632d2e30303720372e3437362d362e3035382031332e3533352d31332e3532352031332e353431483336392e32762d31352e303338682d31332e36317631352e303338682d34302e393833762d31352e303338682d31332e3632317631352e303338483238392e383161362e38313520362e3831352030203020302d362e38313120362e3832633020332e37363620332e303520362e38313920362e383120362e3831396838392e3034346331342e3938372d2e3031332032372e3133332d31322e3137352032372e3134362d32372e313820302d312e3831312d2e37322d332e3534382d312e3939392d342e38323761362e38303620362e3830362030203020302d342e3832342d312e3939335a6d2d3238372e3532352d32342e39353461362e37343420362e3734342030203020302d332e3338362d332e3920362e37303520362e3730352030203020302d352e3134322d2e3335632d372e30313120322e3334392d31342e3539352d312e3433352d31362e3936312d382e3436336c2d332e3031382d392e3036312031342e3039392d342e3738382d342e3239342d31322e3833322d31342e30383720342e3738382d31322e39332d33382e35382031342e3038372d342e3738372d342e3239342d31322e38322d31342e30383620342e3738382d332e3534332d31302e353232632d312e3232332d332e3438382d352e3031312d352e3334332d382e3530332d342e3136352d332e34393320312e3137382d352e33393520342e3935332d342e32373120382e3437346c32382e3036352038332e373963342e3733332031342e3131332031392e3936332032312e37312033342e30332031362e39373420332e3531352d312e31393320352e3430382d352e30313320342e3233342d382e3534365a222f3e3c2f673e3c7061746820643d224d3530372036313068353576313830682d35357a4d3334322e3234382037363420333236203731322e3233366c32332e3930342d372e3532376334372e3634352d31352e3039332038322e3134392d35362e36312038382e3333322d3130362e323839563539384c343932203630342e3632376c2d2e30362e343332632d382e3830312037302e3736362d35372e393435203132392e39312d3132352e383132203135312e3431344c3334322e323438203736345a4d343336203332342e313534563230352e3837384c35373720323035763131392e32303263302033392e312d33312e3536342037302e3739382d37302e352037302e3739386137302e3333382037302e3333382030203020312d34392e3837312d32302e3735632d31332e3232342d31332e3238382d32302e3634352d33312e33312d32302e3632392d35302e3039365a222066696c6c3d222220706f696e74733d22343030203432392e3620383030203631352e322030203631352e32223e3c2f706f6c79676f6e3e3c7061746820643d224d3430302c3234342e38204c3830302c3433302e34204c302c3433302e34204c3430302c3234342e38205a204d3430302c3631352e32204c3830302c383030204c302c383030204c3430302c3631352e32205a222066696c6c3d222220643d224d3136382e38342030483439372e32763536312e3238483136382e38347a22207472616e73666f726d3d227472616e736c617465283235312e34203231392e373729222f3e3c706174682066696c6c3d222220643d226d3439322e333231203532322e343238203132342e3636322033322e3531392d32352e3937342032352e3934352d3132342e3636322d33322e3531397a6d3235352e34322d3232352e3831332d3130322e3633332035322e3630376135322e3937322035322e3937322030203020302d312e3735382d31352e3032312035322e3939312035322e3939312030203020302d372e3232372d31352e39356c39382e382d35302e363436613136322e383937203136322e3839372030203020312031322e3831382032392e30315a4d3538302e363234203138342e3337326c2e353239203131312e3438366135332e31322035332e31322030203020302d32362e3939382031342e3730356c2d342e353920342e3538352d2e3539372d3132352e353234613136342e393235203136342e3932352030203020312033312e3635362d352e3235325a6d31332e333932203233362e343732203133362e3136312031352e363439613136342e373433203136342e3734332030203020312d32322e3330382032372e3636376c2d312e343720312e3436372d3134302e3939352d31362e3230322032382e3631322d32382e3538315a4d3238342e313632203733302e3335396c3132342e3636322033322e3531392d32352e3937332032352e3934352d3132342e3636332d33322e3531397a4d3338382e323835203632362e33356c3132342e3939312033322e3139312d32362e3036362032362e3033372d3132342e39392d33322e3139327a222f3e3c706174682066696c6c3d222220643d226d3436342e313038203434382e3531372d3133382e3034342d32392e3932394c3433382e3031203530342e36366c2d39352e3136203130342e3931203133302e3539342d35322e3430362034322e383836203133342e3731352032302e3533362d3134302e333436203133382e3036392032392e3937372d3131312e3934352d38362e31372039352e3135382d3130342e3738372d3133302e3539342035322e3333322d34322e3933352d3133342e3736347a222f3e3c2f673e3c67207472616e73666f726d3d227472616e736c617465283130302e3030303030302c203130302e30303030303029223e3c706f6c79676f6e2066696c6c3d222220643d226d3436352e353336203430352e3235342d3230312e3138332d3130332e3534203133372e353234203137392e3538382d3139302e3733203132322e383732203232332e3739322d32362e3934322031302e353035203232362e32322038392e3936312d3230382e3634203230312e323031203130332e3632362d3133372e3438332d3137392e37344c3738392e38203339362e3031366c2d3232332e37362032362e3832382d31302e35362d3232362e3331377a222f3e3c706174682066696c6c3d22222063783d223430302e38222063793d223230302220723d22323030222f3e3c706174682066696c6c3d2222207472616e73666f726d3d227472616e736c617465283130302031303029222f3e3c7061746820643d224d3739372e3836203435362e3039203738362e3639203430386c2d38322e39342031392e322033332e352d35332e37342d34312e39332d32362e31344c3633352e3639203434336c2d35392e38322031332e38386138362e37332038362e37332030203020302d32372e34342d32392e34336c31372e39352d35382e372039392e35352d35322e39312d32332e31392d34332e36332d35352e39322032392e37322032342e392d38312e34322d34372e32342d31342e34352d32342e39312038312e34322d32392e37332d35352e39322d34332e36322032332e31392035322e39312039392e35352d31372e39352035382e376138362e35362038362e35362030203020302d33392e333620392e31326c2d34312e392d34342e383920332e38382d3131322e36382d34392e33382d312e372d322e31382036332e332d35382e312d36322e32344c323738203239372e36326c35382e312036322e32342d36332e332d322e31382d312e372034392e3338203131322e363820332e38382034312e38392034342e38386138362e36362038362e36362030203020302d31312e37382033382e36356c2d35392e382031332e38382d39352e36382d35392e36342d32362e31342034312e39332035332e37332033332e352d38322e392031392e32352031312e31372034382e31332038322e39342d31392e32352d33332e352035332e37332034312e39332032362e31342035392e36342d39352e36382035392e38322d31332e38394138362e35332038362e3533203020302030203435322e3534203537326c2d31382035382e374c333335203638332e36346c32332e31392034332e36332035352e39322d32392e37334c3338392e3234203737396c34372e32352031342e34362032342e392d38312e34362032392e37332035352e39332034332e36332d32332e31392d35322e39322d39392e35362031382d35382e36396138362e36382038362e36382030203020302033392e33352d392e31326c34312e39312034342e38392d332e3838203131322e36382034392e333820312e3720322e31382d36332e332035382e312036322e32344c373233203730312e38366c2d35382e312d36322e32352036332e323920322e313820312e372d34392e33382d3131322e36372d332e38372d34312e392d34342e38384138362e352038362e35203020302030203538372e3036203530356c35392e382d31332e38382039352e36382035392e36342032362e31332d34312e39332d35332e37352d33332e35312038322e39342d31392e32335a6d2d3236342e32312035332e37396133342e36382033342e36382030203120312d32332d34332e33316331382e33303520352e3631352032382e362032352032332034332e33315a222066696c6c3d22223e3c7265637420783d223435322220793d22313138222077696474683d22333522206865696768743d223739222072783d22382e3931222f3e3c7265637420793d22313138222077696474683d22333522206865696768743d223739222072783d22382e3931222f3e3c7061746820643d224d31393720307631342e323934433139372034322e3037203232322e313432203637203235302e313936203637682d2e3036433237382e3139203637203330302034322e3037203330302031342e323934562e3031324c31393720305a6d35322032313763352e35323320302031302d342e3437372031302d3130732d342e3437372d31302d31302d31302d313020342e3437372d313020313020342e3437372031302031302031305a6d2e30313220323161313020313020302031203020392e39383820392e3938382031302031302030203020302d392e3938382d392e3938385a4d32343920323830632d352e35323320302d313020342e3437372d313020313073342e3437372031302031302031302031302d342e3437372031302d3130632d2e3030372d352e35322d342e34382d392e3939332d31302d31305a222f3e3c2f673e3c67207472616e73666f726d3d227472616e736c617465283438342032333329223e3c636972636c652063783d22372e35222063793d22372e352220723d22372e35222f3e3c636972636c652063783d2234312e35222063793d22372e352220723d22372e35222f3e3c2f673e222063783d22343030222063793d2237342e313039222072783d2237342e303734222072793d2237342e313039222f3e3c706174682066696c6c3d222220643d224d3930322031303030203636322e383631203632342e36386837322e3331374c3530302e34393420323835203236352e383232203632342e36386837322e3331374c393920313030307a222f3e3c67207472616e73666f726d3d227472616e736c617465283137362031323429222066696c6c3d223c7061746820643d224d3431322e3039203733332e37763235632d31382e34323920332e3439372d33312e3736372031392e3630332d33312e37372033382e33366838302e3539563733332e37682d34382e38325a6d3132392e36352032352e3033762d3235682d34382e38327636332e33396838302e3539632e3033322d31382e3737362d31332e33322d33342e39312d33312e37372d33382e33395a6d2d36372e33382d3430302e30316334332e3938362e3030362037392e36342033352e3636342037392e36342037392e3635763139342e3639483339342e3731563433382e333763302d34332e39392033352e36362d37392e36352037392e36352d37392e36355a222066696c6c3d22223e3c636972636c652063783d223237222063793d2232372220723d223237222f3e3c636972636c652063783d223237222063793d223134322220723d223237222f3e3c2f673e3c706174682066696c6c3d22223e3c636972636c652063783d223737302e3337222063793d2232392e36332220723d2232392e3633222f3e3c636972636c652063783d2232392e3633222063793d2232392e36332220723d2232392e3633222f3e3c2f673e3c67207472616e73666f726d3d227472616e736c617465283437302e33372031303029222066696c6c3d22223e3c636972636c652063783d223331222063793d2234322220723d223331222f3e3c636972636c652063783d22343135222063793d2233312220723d223331222f3e3c636972636c652063783d22343033222063793d223337332220723d223331222f3e3c2f673e3c67207472616e73666f726d3d227472616e736c617465283130302031303029223e3c636972636c652066696c6c3d22223e3c656c6c697073652063783d223134332e373839222063793d2233372e323538222072783d2233372e323131222072793d2233372e323538222f3e3c656c6c697073652063783d2233372e323131222063793d223439372e373432222072783d2233372e323131222072793d2233372e323538222f3e3c2f673eb9bfc87ab6d50430c17fad3d76aa4e9fce5cb9f8a8035e5ad64505fa1e31bdb9222f3e3c67207472616e73666f726d3d227472616e736c617465283230362032323529222066696c6c3d222220643d224d3432342e343839203431302e323238203136332e303438203337372e30356c3232322e303631203134312e3737342d3135392e383035203231302e343633203233342e3230362d3131382e3634203130312e363136203234332e3431342031352e3334382d3236342e313934203236312e3439342033332e3236362d3232322e3037372d3134312e393536203135392e3832352d3231302e3233352d3233342e323138203131382e3530322d3130312e3731352d3234332e3439377a222f3e3c706174682066696c6c3d22223e3c636972636c652063783d223832222063793d2238322220723d223832222f3e3c7061746820643d224d353832203535382e323135632d33312e32362d32312e3239342d37332e3035312d31382e3431352d3130312e303920362e3936322d32382e30342032352e3337382d33352e3032342036362e3634352d31362e3839352039392e38323348353832563535382e3231355a222f3e3c2f673e3c636972636c652066696c6c3d2222207472616e73666f726d3d227472616e736c617465283130302031303029222f3e3c7061746820643d226d343030203430302032303020323030483230306c3230302d3230305a4d3236362e363636203636362e342032303020363030683133332e3333346c2d36362e3636372036362e345a6d3236362e36363820304c3436362e36363720363030683133332e3333346c2d36362e3636372036362e345a4d343030203636362e34203333332e33333420363030683133332e3333324c343030203636362e345a222066696c6c3d22222063783d223530302e35222063793d223537342e352220723d223239342e35222f3e3c7061746820643d226d3236382e38393820333933203532312e323539203233322e303831632d382e31382034382e3633372d32382e3238322039332e3232382d35372e313938203133302e3636344c323130203532322e39303663382e3830352d34382e3437372032392e3437372d39322e3831382035382e3839382d3132392e3930365a222066696c6c3d222220643d226d34303020343030203430302034303048307a22207472616e73666f726d3d227472616e736c617465283130302031303029222f3e3c7061746820643d226d34303020302032303020323030483230304c34303020305a4d3236362e363636203236362e342032303020323030683133332e3333346c2d36362e3636372036362e345a6d3236362e36363820304c3436362e36363720323030683133332e3333346c2d36362e3636372036362e345a4d343030203236362e34203333332e33333420323030683133332e3333324c343030203236362e345a222066696c6c3d22223e3c636972636c652063783d223231222063793d2232312220723d223231222f3e3c636972636c652063783d223836222063793d2232342220723d223231222f3e3c7061746820643d224d39372e383137203731632e3630342e30303320312e31382e32343820312e3539322e36382e3431322e34332e36323420312e3030382e35383720312e3539374339382e3735332039382e3333352037372e363039203131382e3032312035312e393539203131382032362e3331203131372e39373920352e322039382e32353720342037332e31393761322e31323220322e313232203020302031202e3632332d312e353541322e32313720322e32313720302030203120362e3139332037316839312e3632345a222f3e3c2f673e3c67207472616e73666f726d3d227472616e736c617465283437342034333529222066696c6c3d22222f3e3c67207472616e73666f726d3d227472616e736c617465283432392e3035203237362e333229222066696c6c3d223c7061746820643d224d3338382e363735203532362e313535203335392e393836203531346c2d36382e3539203136312e3434362d34312e3232372d31372e34384c323338203638362e3632336c3131312e3133322034372e3130352031322e3136392d32382e3634352d34312e3231362d31372e3438317a4d3735362e3634203735332e3838336c2d34332e38343520392e3134362d33352e38362d3137312e36392d33302e35303620362e3336332033352e3836203137312e36382d34332e38333320392e31343620362e33362033302e3437324c373633203738342e3335357a222066696c6c3d222220643d226d3135342e383133203535372e3233203135342e383132203434332e35373648307a222f3e3c706174682066696c6c3d2222207472616e73666f726d3d227472616e736c617465283235312e34203231392e373729222f3e3c67207472616e73666f726d3d227472616e736c617465283330302031303029222066696c6c3d22222f3e3c7061746820643d224d3536312e393632203738357632382e37346332302e323520332e382033352e36352032312e3738362033352e3939342034332e3531366c2e3030362e373434682d3535762d31682d3336762d37326835355a6d2d3230352e38312d38322e3938342031372e3939342035322e3439332d32362e38383420392e3231356134342e3337322034342e3337322030203020312d32392e3032372034382e3036396c2d2e3534362e31392d31312e3639342d33342e3131352d2e3030322e3030324c323838203732352e3337376c36382e3135332d32332e33365a4d3433382e3439203334336137302e38352037302e38352030203020302031382e312033312e32354137302e3333382037302e333338203020302030203530362e343633203339356c312e3136362d2e30316333312e3934322d2e35322035382e37322d32322e3337322036362e3832322d35312e3939683133352e3531327636372e383336483539352e33323456363133483431322e3536563431302e383336483239322e39363256333433483433382e34395a6d36392e3239372d32323920312e31322e3030396333362e3838392e35372036372e3434362032382e3933382037302e35332036352e373120362e31303120312e3037342031302e35343320362e3336382031302e3532352031322e3534357631332e303438633020372e3030372d352e3639382031322e3638382d31322e3732372031322e363838483433372e36396131322e3734372031322e3734372030203020312d392d332e3731362031322e3636392031322e3636392030203020312d332e3732382d382e393732762d31332e303438632d2e3032392d362e343320342e3737352d31312e3836322031312e3137362d31322e363420332e3136322d33372e3130362033342e3239352d36352e36322037312e36352d36352e3632345a222066696c6c3d222220706f696e74733d223430302035392e322038303020323434203020323434223e3c2f706f6c79676f6e3e3c706f6c79676f6e2066696c6c3d223c7061746820643d224d3830322e313735203337322e323432483537362e3939346335352e3738352d33342e38322038312e3733362d3130322e3335322036332e36312d3136352e353239433632322e343737203134332e353336203536342e36353920313030203439382e38383420313030632d36352e37373620302d3132332e3539352034332e3533362d3134312e373231203130362e3731332d31382e3132372036332e31373720372e383234203133302e3730392036332e363039203136352e3533483139362e373734632d33392e3331362d2e3332332d37312e3434392033312e32362d37312e3737342037302e3534342d2e33322033392e3238332033312e32392037312e33392037302e3630352037312e373133683137332e3738324c3239322e36203738342e3332632d382e3830332033302e39352d2e3431322036342e32342032322e3031322038372e3333332032322e3432342032332e3039322035352e3437342033322e3437372038362e372032342e36322033312e3232372d372e3835382035352e3838362d33312e3736352036342e36392d36322e3731346c33302e3333332d3130362e3636362033302e333631203130362e36333863382e3530382033312e3330322033332e3230322035352e3631362036342e3635322036332e3635352033312e34343920382e30342036342e3739352d312e3433372038372e3330332d32342e38312032322e3530372d32332e3337342033302e3639392d35372e3033342032312e3434362d38382e3132344c3632332e3237203531342e353237683137372e3733366333392e3031342d2e3131342037302e3637312d33312e3537372037302e3939342d37302e3535382e3331382d33382e3938312d33302e3831382d37302e39362d36392e3832352d37312e373133762d2e3031345a222066696c6c3d22223e3c7061746820643d226d333533203134332d35382e352d33382e3330344c323336203134335630683131377a222f3e3c636972636c652063783d22333036222063793d223536382220723d223331222f3e3c636972636c652063783d223331222063793d223335312220723d223331222f3e3c2f673e3c67207472616e73666f726d3d227472616e736c617465283330322031313029222066696c6c3d22222063783d223339392e36222063793d223732362220723d223734222f3e3c2f673e3c706174682066696c6c3d222220643d226d3430302030203430302034303048307a22207472616e73666f726d3d227472616e736c617465283130302031303029222f3e3c706174682066696c6c3d222220643d224d30203233342e3935683333372e3638763332362e333248307a22207472616e73666f726d3d227472616e736c617465283235312e34203231392e373729222f3e3c7061746820643d224d3230342e36203335332e3332563233352e30366333302e3234342d31322e3932352034352e3337372d34372e3030382033342e36382d37382e31316136322e372036322e372030203020302d36342e37372031352036332e34362036332e34362030203020302d352e363520362e34382036332e34362036332e34362030203020302d352e36352d362e34382036322e372036322e372030203020302d36342e37372d3135632d31302e3639372033312e31303220342e3433362036352e3138352033342e36382037382e3131763131382e323648307637312e3438683133332e31763133362e34336837312e35563432342e38683133332e31762d37312e3438483230342e365a222066696c6c3d223c67207472616e73666f726d3d227472616e736c617465283231372033343429222066696c6c3d223c67207472616e73666f726d3d227472616e736c61746528313030203437302e333729222066696c6c3d22223e3c7061746820643d224d2e3338203076333663302032362e38322032342035302e38392035302e38352035302e38392032362e383220302034372e36362d32342e30372034372e36362d35302e38395630482e33385a6d38332e3934203131392e37356834302e3233763132332e33374838342e33327a222f3e3c636972636c652063783d2232322e3635222063793d223230332e332220723d2232322e3635222f3e3c636972636c652063783d223138362e3232222063793d223230332e332220723d2232322e3635222f3e3c2f673e3c7061746820643d224d3431322e353035203633332e303568343876313035682d34387a6d3132392e30363520313035483439332e31762d3130356834382e34377a4d3432392e3433203331342e3231683231302e31357638392e34483432392e34337a222066696c6c3d22223e3c636972636c65207472616e73666f726d3d22726f74617465283930203430302034303029222063783d22343030222063793d223430302220723d22323030222f3e3c636972636c652063783d22323030222063793d223230302220723d22323030222f3e3c2f673e3c67207472616e73666f726d3d227472616e736c617465283130302033303029222066696c6c3d22222f3e3c7061746820643d224d353039203232382e31346134312e34342034312e34342030203120302d37392e3820344135362e3737362035362e37373620302031203020343736203333352e366135362e37352035362e37352030203120302033332d3130372e34365a6d2d34352e3637203538322e3133682d31332e3436762d31332e3138682d31327631332e3138682d3336762d31332e3138483339307631332e3138682d342e3738632d362e3535352d2e3030352d31312e3836392d352e3331352d31312e38382d31312e3837613620362030203120302d31312e39352030632e3031372031332e3135332031302e3637382032332e38312032332e38332032332e38326837382e31326136203620302031203020302d31326c2d2e30312e30355a6d3132332e31352d31372e3835613620362030203020302d362036632d2e30303520362e3535342d352e3331372031312e3836352d31312e38372031312e3837682d342e3739762d31332e32682d31312e39337631332e3138682d3336762d31332e3138483530347631332e3138682d31332e356136203620302030203020302031326837382e31336331332e3134392d2e3031362032332e3830342d31302e3637312032332e38322d32332e3832613620362030203020302d352e39372d362e30335a4d3435312e37203339362e3037683136332e3537763132332e3337483435312e377a222066696c6c3d22223e3c636972636c652063783d223832222063793d223731362220723d223832222f3e3c7061746820643d224d3537312031342e323537433533362e3839342d392e3034203439302e3830362d332e3236203436332e3438382032372e3734632d32372e3331372033312d32372e3331372037372e3531392030203130382e3531382032372e3331382033312037332e3430362033362e3738203130372e3531322031332e3438345631342e3235375a222f3e3c2f673e3c67207472616e73666f726d3d227472616e736c617465283431382033333529222066696c6c3d22000000000000000000000000a5409ec958c83c3f309868babaca7c86dcb077c1
Deployed Bytecode
0x6080604052600436106102305760003560e01c80634f6ccce71161012e57806395d89b41116100ab578063dd0812f71161006f578063dd0812f714610699578063e8a3d485146106b9578063e985e9c5146106ce578063f2fde38b14610717578063fe9b9b5f1461073757600080fd5b806395d89b4114610603578063a22cb46514610618578063b88d4fde14610638578063c87b56dd14610658578063d547cfb71461067857600080fd5b8063715018a6116100f2578063715018a61461057d57806371f6b3d31461059257806376a30d06146105b25780638b3d72ce146105c55780638da5cb5b146105e557600080fd5b80634f6ccce7146104d95780635e49a596146104f95780636352211e14610527578063707be7a01461054757806370a082311461055d57600080fd5b806320379ee5116101bc5780632f745c59116101805780632f745c59146104335780633408e470146104535780634282ccbc1461046657806342842e0e146104995780634c0ef795146104b957600080fd5b806320379ee51461038857806323b872dd1461039d57806325f9972e146103bd5780632d0335ab146103dd5780632da6b81e1461041357600080fd5b80630c53c51c116102035780630c53c51c146102e65780630f7e5970146102f957806316a0d9c21461032657806318160ddd146103535780631d622c521461037257600080fd5b806301ffc9a71461023557806306fdde031461026a578063081812fc1461028c578063095ea7b3146102c4575b600080fd5b34801561024157600080fd5b50610255610250366004613a58565b61074d565b60405190151581526020015b60405180910390f35b34801561027657600080fd5b5061027f610778565b6040516102619190613ac5565b34801561029857600080fd5b506102ac6102a7366004613ad8565b61080a565b6040516001600160a01b039091168152602001610261565b3480156102d057600080fd5b506102e46102df366004613b0d565b6108a4565b005b61027f6102f4366004613bda565b6109cb565b34801561030557600080fd5b5061027f604051806040016040528060018152602001603160f81b81525081565b34801561033257600080fd5b50610346610341366004613ad8565b610bb5565b6040516102619190613c56565b34801561035f57600080fd5b506008545b604051908152602001610261565b34801561037e57600080fd5b5061036460165481565b34801561039457600080fd5b50600b54610364565b3480156103a957600080fd5b506102e46103b8366004613cf3565b610d2a565b3480156103c957600080fd5b506103646103d8366004613d2f565b610d62565b3480156103e957600080fd5b506103646103f8366004613d7d565b6001600160a01b03166000908152600c602052604090205490565b34801561041f57600080fd5b5061036461042e366004613d98565b610e56565b34801561043f57600080fd5b5061036461044e366004613b0d565b610fcd565b34801561045f57600080fd5b5046610364565b34801561047257600080fd5b50610486610481366004613ad8565b611063565b6040516102619796959493929190613e98565b3480156104a557600080fd5b506102e46104b4366004613cf3565b6113cd565b3480156104c557600080fd5b5061027f6104d4366004613ad8565b6113e8565b3480156104e557600080fd5b506103646104f4366004613ad8565b61148d565b34801561050557600080fd5b50610519610514366004613ad8565b611520565b604051610261929190613f22565b34801561053357600080fd5b506102ac610542366004613ad8565b6115cf565b34801561055357600080fd5b5061036460155481565b34801561056957600080fd5b50610364610578366004613d7d565b611646565b34801561058957600080fd5b506102e46116cd565b34801561059e57600080fd5b506103646105ad366004613f46565b611752565b6103646105c0366004613f7b565b61180a565b3480156105d157600080fd5b5061027f6105e0366004613ad8565b611949565b3480156105f157600080fd5b50600d546001600160a01b03166102ac565b34801561060f57600080fd5b5061027f6121a7565b34801561062457600080fd5b506102e4610633366004614008565b6121b6565b34801561064457600080fd5b506102e4610653366004614044565b6121cc565b34801561066457600080fd5b5061027f610673366004613ad8565b61220b565b34801561068457600080fd5b5060408051602081019091526000815261027f565b3480156106a557600080fd5b5061027f6106b4366004613ad8565b61246a565b3480156106c557600080fd5b5061027f612504565b3480156106da57600080fd5b506102556106e93660046140ac565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b34801561072357600080fd5b506102e4610732366004613d7d565b61254c565b34801561074357600080fd5b5061036460175481565b60006001600160e01b0319821663780e9d6360e01b1480610772575061077282612692565b92915050565b606060008054610787906140d6565b80601f01602080910402602001604051908101604052809291908181526020018280546107b3906140d6565b80156108005780601f106107d557610100808354040283529160200191610800565b820191906000526020600020905b8154815290600101906020018083116107e357829003601f168201915b5050505050905090565b6000818152600260205260408120546001600160a01b03166108885760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b60006108af826115cf565b9050806001600160a01b0316836001600160a01b03160361091c5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b606482015260840161087f565b806001600160a01b031661092e6126e2565b6001600160a01b0316148061094a575061094a816106e96126e2565b6109bc5760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000606482015260840161087f565b6109c683836126f1565b505050565b60408051606081810183526001600160a01b0388166000818152600c602090815290859020548452830152918101869052610a09878287878761275f565b610a5f5760405162461bcd60e51b815260206004820152602160248201527f5369676e657220616e64207369676e617475726520646f206e6f74206d6174636044820152600d60fb1b606482015260840161087f565b6001600160a01b0387166000908152600c6020526040902054610a8390600161284f565b6001600160a01b0388166000908152600c60205260409081902091909155517f5845892132946850460bff5a0083f71031bc5bf9aadcd40f1de79423eac9b10b90610ad390899033908a90614110565b60405180910390a1600080306001600160a01b0316888a604051602001610afb92919061413c565b60408051601f1981840301815290829052610b1591614173565b6000604051808303816000865af19150503d8060008114610b52576040519150601f19603f3d011682016040523d82523d6000602084013e610b57565b606091505b509150915081610ba95760405162461bcd60e51b815260206004820152601c60248201527f46756e6374696f6e2063616c6c206e6f74207375636365737366756c00000000604482015260640161087f565b98975050505050505050565b610c1460405180610140016040528060006001600160a01b031681526020016060815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b6000828152601060209081526040918290208251610140810190935280546001600160a01b031683526001810180549192840191610c51906140d6565b80601f0160208091040260200160405190810160405280929190818152602001828054610c7d906140d6565b8015610cca5780601f10610c9f57610100808354040283529160200191610cca565b820191906000526020600020905b815481529060010190602001808311610cad57829003601f168201915b50505050508152602001600282015481526020016003820154815260200160048201548152602001600582015481526020016006820154815260200160078201548152602001600882015481526020016009820154815250509050919050565b610d3b610d356126e2565b82612862565b610d575760405162461bcd60e51b815260040161087f9061418f565b6109c6838383612959565b6000610d76600d546001600160a01b031690565b6001600160a01b0316336001600160a01b031614610da65760405162461bcd60e51b815260040161087f906141e0565b60158054906000610db68361422d565b90915550506040805180820182526001600160a01b038481168252602080830187815260155460009081526013909252939020825181546001600160a01b031916921691909117815591519091906001820190610e139082614294565b50506015546040519081527fea3d275ca6ab8360bdc4171efd62803f424bb703aa4524ba2955d75f02cde971915060200160405180910390a15060155492915050565b6000610e6a600d546001600160a01b031690565b6001600160a01b0316336001600160a01b031614610e9a5760405162461bcd60e51b815260040161087f906141e0565b60168054906000610eaa8361422d565b91905055506040518060e00160405280898152602001888152602001878152602001868152602001858152602001848152602001838152506012600060165481526020019081526020016000206000820151816000019081610f0c9190614294565b5060208201516001820190610f219082614294565b5060408201516002820190610f369082614294565b5060608201516003820190610f4b9082614294565b5060808201516004820190610f609082614294565b5060a08201516005820190610f759082614294565b5060c082015181600601559050507f9d58aaf1948e68fdbeb8affd7c369952e6d63703e2f3933aa7e4499ed1d0909f601654604051610fb691815260200190565b60405180910390a150601654979650505050505050565b6000610fd883611646565b821061103a5760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b606482015260840161087f565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b60126020526000908152604090208054819061107e906140d6565b80601f01602080910402602001604051908101604052809291908181526020018280546110aa906140d6565b80156110f75780601f106110cc576101008083540402835291602001916110f7565b820191906000526020600020905b8154815290600101906020018083116110da57829003601f168201915b50505050509080600101805461110c906140d6565b80601f0160208091040260200160405190810160405280929190818152602001828054611138906140d6565b80156111855780601f1061115a57610100808354040283529160200191611185565b820191906000526020600020905b81548152906001019060200180831161116857829003601f168201915b50505050509080600201805461119a906140d6565b80601f01602080910402602001604051908101604052809291908181526020018280546111c6906140d6565b80156112135780601f106111e857610100808354040283529160200191611213565b820191906000526020600020905b8154815290600101906020018083116111f657829003601f168201915b505050505090806003018054611228906140d6565b80601f0160208091040260200160405190810160405280929190818152602001828054611254906140d6565b80156112a15780601f10611276576101008083540402835291602001916112a1565b820191906000526020600020905b81548152906001019060200180831161128457829003601f168201915b5050505050908060040180546112b6906140d6565b80601f01602080910402602001604051908101604052809291908181526020018280546112e2906140d6565b801561132f5780601f106113045761010080835404028352916020019161132f565b820191906000526020600020905b81548152906001019060200180831161131257829003601f168201915b505050505090806005018054611344906140d6565b80601f0160208091040260200160405190810160405280929190818152602001828054611370906140d6565b80156113bd5780601f10611392576101008083540402835291602001916113bd565b820191906000526020600020905b8154815290600101906020018083116113a057829003601f168201915b5050505050908060060154905087565b6109c6838383604051806020016040528060008152506121cc565b6000818152601060205260409020600101805460609190611408906140d6565b80601f0160208091040260200160405190810160405280929190818152602001828054611434906140d6565b80156114815780601f1061145657610100808354040283529160200191611481565b820191906000526020600020905b81548152906001019060200180831161146457829003601f168201915b50505050509050919050565b600061149860085490565b82106114fb5760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b606482015260840161087f565b6008828154811061150e5761150e614354565b90600052602060002001549050919050565b601360205260009081526040902080546001820180546001600160a01b03909216929161154c906140d6565b80601f0160208091040260200160405190810160405280929190818152602001828054611578906140d6565b80156115c55780601f1061159a576101008083540402835291602001916115c5565b820191906000526020600020905b8154815290600101906020018083116115a857829003601f168201915b5050505050905082565b6000818152600260205260408120546001600160a01b0316806107725760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b606482015260840161087f565b60006001600160a01b0382166116b15760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b606482015260840161087f565b506001600160a01b031660009081526003602052604090205490565b6116d56126e2565b6001600160a01b03166116f0600d546001600160a01b031690565b6001600160a01b0316146117465760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161087f565b6117506000612b00565b565b6000611766600d546001600160a01b031690565b6001600160a01b0316336001600160a01b0316146117965760405162461bcd60e51b815260040161087f906141e0565b601780549060006117a68361422d565b909155505060175460009081526014602052604090206117c68382614294565b507fc87090b910fa439016ec996ed31f4a343d3e56d4961ca8e2cef0d792887e11656017546040516117fa91815260200190565b60405180910390a1505060175490565b6000868152601260205260408120600601543410156118775760405162461bcd60e51b815260206004820152602360248201527f4d696e696d756d20646f6e6174696f6e20616d6f756e74206e6f742063726f736044820152621cd95960ea1b606482015260840161087f565b3460009081526011602052604081208054611891906140d6565b90501161191b5760405162461bcd60e51b815260206004820152604c60248201527f446f6e6174696f6e20616d6f756e742073686f756c64206265206f6e65206f6660448201527f20302e30312c20302e30352c20302e312c20302e32352c20302e352c20312c2060648201526b06a5840dee4406260408aa8960a31b608482015260a40161087f565b600061192f8b8b348c8c8c8c8c8c8c612b52565b905061193b348a612cc1565b9a9950505050505050505050565b6060600061195683610bb5565b90506000611a306040518060e0016040528060af8152602001614a3960af913960a084015160009081526014602052604090208054611994906140d6565b80601f01602080910402602001604051908101604052809291908181526020018280546119c0906140d6565b8015611a0d5780601f106119e257610100808354040283529160200191611a0d565b820191906000526020600020905b8154815290600101906020018083116119f057829003601f168201915b50505050506040518060600160405280603481526020016148eb60349139612d05565b90506060611d5d60126000856080015181526020019081526020016000206001018054611a5c906140d6565b80601f0160208091040260200160405190810160405280929190818152602001828054611a88906140d6565b8015611ad55780601f10611aaa57610100808354040283529160200191611ad5565b820191906000526020600020905b815481529060010190602001808311611ab857829003601f168201915b50505060c087015160009081526014602052604090208054909250611afa91506140d6565b80601f0160208091040260200160405190810160405280929190818152602001828054611b26906140d6565b8015611b735780601f10611b4857610100808354040283529160200191611b73565b820191906000526020600020905b815481529060010190602001808311611b5657829003601f168201915b505050608088015160009081526012602052604090206002018054909250611b9b91506140d6565b80601f0160208091040260200160405190810160405280929190818152602001828054611bc7906140d6565b8015611c145780601f10611be957610100808354040283529160200191611c14565b820191906000526020600020905b815481529060010190602001808311611bf757829003601f168201915b50505060e089015160009081526014602052604090208054909250611c3991506140d6565b80601f0160208091040260200160405190810160405280929190818152602001828054611c65906140d6565b8015611cb25780601f10611c8757610100808354040283529160200191611cb2565b820191906000526020600020905b815481529060010190602001808311611c9557829003601f168201915b50505060808a015160009081526012602052604090206003018054909250611cda91506140d6565b80601f0160208091040260200160405190810160405280929190818152602001828054611d06906140d6565b8015611d535780601f10611d2857610100808354040283529160200191611d53565b820191906000526020600020905b815481529060010190602001808311611d3657829003601f168201915b5050505050612d1a565b9050611f67816014600086610100015181526020019081526020016000208054611d86906140d6565b80601f0160208091040260200160405190810160405280929190818152602001828054611db2906140d6565b8015611dff5780601f10611dd457610100808354040283529160200191611dff565b820191906000526020600020905b815481529060010190602001808311611de257829003601f168201915b505050608088015160009081526012602052604090206004018054909250611e2791506140d6565b80601f0160208091040260200160405190810160405280929190818152602001828054611e53906140d6565b8015611ea05780601f10611e7557610100808354040283529160200191611ea0565b820191906000526020600020905b815481529060010190602001808311611e8357829003601f168201915b50505061012089015160009081526014602052604090208054909250611ec691506140d6565b80601f0160208091040260200160405190810160405280929190818152602001828054611ef2906140d6565b8015611f3f5780601f10611f1457610100808354040283529160200191611f3f565b820191906000526020600020905b815481529060010190602001808311611f2257829003601f168201915b50505060808a015160009081526012602052604090206005018054909250611cda91506140d6565b90506000611f916040518060e0016040528060b581526020016146c060b591398560200151612d35565b9050600061214160405180610120016040528060ef815260200161491f60ef913960408088015160009081526011602052208054611fce906140d6565b80601f0160208091040260200160405190810160405280929190818152602001828054611ffa906140d6565b80156120475780601f1061201c57610100808354040283529160200191612047565b820191906000526020600020905b81548152906001019060200180831161202a57829003601f168201915b50505050506040518060400160405280601081526020016f01022aa24103237b730ba32b2103a37960851b815250601360008a606001518152602001908152602001600020600101805461209a906140d6565b80601f01602080910402602001604051908101604052809291908181526020018280546120c6906140d6565b80156121135780601f106120e857610100808354040283529160200191612113565b820191906000526020600020905b8154815290600101906020018083116120f657829003601f168201915b50505050506040518060400160405280600b81526020016a1e17ba32bc3a1f1e17b39f60a91b815250612d1a565b9050600061217085858585604051806040016040528060068152602001651e17b9bb339f60d11b815250612d1a565b905061217b81612d90565b60405160200161218b919061436a565b6040516020818303038152906040529650505050505050919050565b606060018054610787906140d6565b6121c86121c16126e2565b8383612ef5565b5050565b6121dd6121d76126e2565b83612862565b6121f95760405162461bcd60e51b815260040161087f9061418f565b61220584848484612fc3565b50505050565b6060612444612269604051806040016040528060148152602001737b226e616d65223a22586d61732043617264202360601b81525061224985612ff6565b60405180604001604052806002815260200161088b60f21b815250612d05565b61240b6040518060600160405280602d8152602001614775602d91396011600061229288610bb5565b60400151815260200190815260200160002080546122af906140d6565b80601f01602080910402602001604051908101604052809291908181526020018280546122db906140d6565b80156123285780601f106122fd57610100808354040283529160200191612328565b820191906000526020600020905b81548152906001019060200180831161230b57829003601f168201915b50505050506040518060400160405280601581526020017401022aa24103bb2b932903237b730ba32b2103a379605d1b815250601360006123688a610bb5565b6060015181526020019081526020016000206001018054612388906140d6565b80601f01602080910402602001604051908101604052809291908181526020018280546123b4906140d6565b80156124015780601f106123d657610100808354040283529160200191612401565b820191906000526020600020905b8154815290600101906020018083116123e457829003601f168201915b50505050506130f7565b61241485611949565b61241d86613110565b60405160200161243094939291906143bd565b604051602081830303815290604052612d90565b6040516020016124549190614414565b6040516020818303038152906040529050919050565b60146020526000908152604090208054612483906140d6565b80601f01602080910402602001604051908101604052809291908181526020018280546124af906140d6565b80156124fc5780601f106124d1576101008083540402835291602001916124fc565b820191906000526020600020905b8154815290600101906020018083116124df57829003601f168201915b505050505081565b606061252860405180610100016040528060d2815260200161481960d29139612d90565b6040516020016125389190614414565b604051602081830303815290604052905090565b6125546126e2565b6001600160a01b031661256f600d546001600160a01b031690565b6001600160a01b0316146125c55760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161087f565b6001600160a01b03811661262a5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161087f565b61263381612b00565b50565b600030330361268c57600080368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505050503601516001600160a01b0316915061268f9050565b50335b90565b60006001600160e01b031982166380ac58cd60e01b14806126c357506001600160e01b03198216635b5e139f60e01b145b8061077257506301ffc9a760e01b6001600160e01b0319831614610772565b60006126ec612636565b905090565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190612726826115cf565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60006001600160a01b0386166127c55760405162461bcd60e51b815260206004820152602560248201527f4e61746976654d6574615472616e73616374696f6e3a20494e56414c49445f5360448201526424a3a722a960d91b606482015260840161087f565b60016127d86127d3876133c0565b61343d565b6040805160008152602081018083529290925260ff851690820152606081018690526080810185905260a0016020604051602081039080840390855afa158015612826573d6000803e3d6000fd5b505050602060405103516001600160a01b0316866001600160a01b031614905095945050505050565b600061285b8284614459565b9392505050565b6000818152600260205260408120546001600160a01b03166128db5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b606482015260840161087f565b60006128e6836115cf565b9050806001600160a01b0316846001600160a01b0316148061292d57506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b806129515750836001600160a01b03166129468461080a565b6001600160a01b0316145b949350505050565b826001600160a01b031661296c826115cf565b6001600160a01b0316146129d05760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201526437bbb732b960d91b606482015260840161087f565b6001600160a01b038216612a325760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b606482015260840161087f565b612a3d83838361346d565b612a486000826126f1565b6001600160a01b0383166000908152600360205260408120805460019290612a7190849061446c565b90915550506001600160a01b0382166000908152600360205260408120805460019290612a9f908490614459565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600d80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600080612b5d613525565b9050612b698c82613536565b612b71613684565b604080516101408101825233815260208082018e81528284018e9052606083018d9052608083018c905260a083018b905260c083018a905260e0830189905261010083018890526101208301879052600f5460009081526010909252929020815181546001600160a01b0319166001600160a01b0390911617815591519091906001820190612c009082614294565b5060408201518160020155606082015181600301556080820151816004015560a0820151816005015560c0820151816006015560e08201518160070155610100820151816008015561012082015181600901559050507f21414cdba6b56757af56c4673643b26d24349f57c89f66dff6744d42682243f2818d8c8c604051612caa94939291909384526001600160a01b039290921660208401526040830152606082015260800190565b60405180910390a19b9a5050505050505050505050565b6000818152601360205260408082205490516001600160a01b039091169184156108fc02918591818181858888f193505050501580156109c6573d6000803e3d6000fd5b6060612951612d148585612d35565b83612d35565b6060612d2b612d14878787876130f7565b9695505050505050565b60408051808201825260008082526020918201528151808301909252825182528083019082015260609061285b906040805180820182526000808252602091820152815180830190925286518252808701908201529061369b565b60608151600003612daf57505060408051602081019091526000815290565b60006040518060600160405280604081526020016147a26040913990506000600384516002612dde9190614459565b612de89190614495565b612df39060046144a9565b90506000612e02826020614459565b67ffffffffffffffff811115612e1a57612e1a613b37565b6040519080825280601f01601f191660200182016040528015612e44576020820181803683370190505b509050818152600183018586518101602084015b81831015612eb0576003830192508251603f8160121c168501518253600182019150603f81600c1c168501518253600182019150603f8160061c168501518253600182019150603f8116850151825350600101612e58565b600389510660018114612eca5760028114612edb57612ee7565b613d3d60f01b600119830152612ee7565b603d60f81b6000198301525b509398975050505050505050565b816001600160a01b0316836001600160a01b031603612f565760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604482015260640161087f565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b612fce848484612959565b612fda84848484613733565b6122055760405162461bcd60e51b815260040161087f906144c0565b60608160000361301d5750506040805180820190915260018152600360fc1b602082015290565b8160005b811561304757806130318161422d565b91506130409050600a83614495565b9150613021565b60008167ffffffffffffffff81111561306257613062613b37565b6040519080825280601f01601f19166020018201604052801561308c576020820181803683370190505b5090505b8415612951576130a160018361446c565b91506130ae600a86614512565b6130b9906030614459565b60f81b8183815181106130ce576130ce614354565b60200101906001600160f81b031916908160001a9053506130f0600a86614495565b9450613090565b6060613107612d14868686612d05565b95945050505050565b6060600061311d83610bb5565b905060006131e16040518060600160405280603781526020016147e26037913960608401516000908152601360205260409020600101805461315e906140d6565b80601f016020809104026020016040519081016040528092919081815260200182805461318a906140d6565b80156131d75780601f106131ac576101008083540402835291602001916131d7565b820191906000526020600020905b8154815290600101906020018083116131ba57829003601f168201915b5050505050612d35565b90506132bf816040518060600160405280602b8152602001614a0e602b91396040808601516000908152601160205220805461321c906140d6565b80601f0160208091040260200160405190810160405280929190818152602001828054613248906140d6565b80156132955780601f1061326a57610100808354040283529160200191613295565b820191906000526020600020905b81548152906001019060200180831161327857829003601f168201915b50505050506040518060400160405280600781526020016608115512089f4b60ca1b8152506130f7565b9050612951816040518060400160405280601e81526020017f7b2274726169745f74797065223a2249636f6e222c2276616c7565223a22000081525060126000866080015181526020019081526020016000206000018054613320906140d6565b80601f016020809104026020016040519081016040528092919081815260200182805461334c906140d6565b80156133995780601f1061336e57610100808354040283529160200191613399565b820191906000526020600020905b81548152906001019060200180831161337c57829003601f168201915b505050505060405180604001604052806004815260200163227d5d7d60e01b8152506130f7565b600060405180608001604052806043815260200161467d6043913980516020918201208351848301516040808701518051908601209051613420950193845260208401929092526001600160a01b03166040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b6000613448600b5490565b60405161190160f01b6020820152602281019190915260428101839052606201613420565b6001600160a01b0383166134c8576134c381600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b6134eb565b816001600160a01b0316836001600160a01b0316146134eb576134eb8382613838565b6001600160a01b038216613502576109c6816138d5565b826001600160a01b0316826001600160a01b0316146109c6576109c68282613984565b6000600f5460016126ec9190614459565b6001600160a01b03821661358c5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604482015260640161087f565b6000818152600260205260409020546001600160a01b0316156135f15760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604482015260640161087f565b6135fd6000838361346d565b6001600160a01b0382166000908152600360205260408120805460019290613626908490614459565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b600f80549060006136948361422d565b9190505550565b805182516060916000916136af9190614459565b67ffffffffffffffff8111156136c7576136c7613b37565b6040519080825280601f01601f1916602001820160405280156136f1576020820181803683370190505b509050600060208201905061370f81866020015187600001516139c8565b845161372b9061371f9083614459565b602086015186516139c8565b509392505050565b60006001600160a01b0384163b1561383057836001600160a01b031663150b7a0261375c6126e2565b8786866040518563ffffffff1660e01b815260040161377e9493929190614526565b6020604051808303816000875af19250505080156137b9575060408051601f3d908101601f191682019092526137b691810190614559565b60015b613816573d8080156137e7576040519150601f19603f3d011682016040523d82523d6000602084013e6137ec565b606091505b50805160000361380e5760405162461bcd60e51b815260040161087f906144c0565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050612951565b506001612951565b6000600161384584611646565b61384f919061446c565b6000838152600760205260409020549091508082146138a2576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b6008546000906138e79060019061446c565b6000838152600960205260408120546008805493945090928490811061390f5761390f614354565b90600052602060002001549050806008838154811061393057613930614354565b600091825260208083209091019290925582815260099091526040808220849055858252812055600880548061396857613968614576565b6001900381819060005260206000200160009055905550505050565b600061398f83611646565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b60208110613a0057815183526139df602084614459565b92506139ec602083614459565b91506139f960208261446c565b90506139c8565b6000198115613a2f576001613a1683602061446c565b613a2290610100614670565b613a2c919061446c565b90505b9151835183169219169190911790915250565b6001600160e01b03198116811461263357600080fd5b600060208284031215613a6a57600080fd5b813561285b81613a42565b60005b83811015613a90578181015183820152602001613a78565b50506000910152565b60008151808452613ab1816020860160208601613a75565b601f01601f19169290920160200192915050565b60208152600061285b6020830184613a99565b600060208284031215613aea57600080fd5b5035919050565b80356001600160a01b0381168114613b0857600080fd5b919050565b60008060408385031215613b2057600080fd5b613b2983613af1565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b600082601f830112613b5e57600080fd5b813567ffffffffffffffff80821115613b7957613b79613b37565b604051601f8301601f19908116603f01168101908282118183101715613ba157613ba1613b37565b81604052838152866020858801011115613bba57600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600080600060a08688031215613bf257600080fd5b613bfb86613af1565b9450602086013567ffffffffffffffff811115613c1757600080fd5b613c2388828901613b4d565b9450506040860135925060608601359150608086013560ff81168114613c4857600080fd5b809150509295509295909350565b60208152613c706020820183516001600160a01b03169052565b60006020830151610140806040850152613c8e610160850183613a99565b91506040850151606085015260608501516080850152608085015160a085015260a085015160c085015260c085015160e085015260e0850151610100818187015280870151915050610120818187015280870151838701525050508091505092915050565b600080600060608486031215613d0857600080fd5b613d1184613af1565b9250613d1f60208501613af1565b9150604084013590509250925092565b60008060408385031215613d4257600080fd5b823567ffffffffffffffff811115613d5957600080fd5b613d6585828601613b4d565b925050613d7460208401613af1565b90509250929050565b600060208284031215613d8f57600080fd5b61285b82613af1565b600080600080600080600060e0888a031215613db357600080fd5b873567ffffffffffffffff80821115613dcb57600080fd5b613dd78b838c01613b4d565b985060208a0135915080821115613ded57600080fd5b613df98b838c01613b4d565b975060408a0135915080821115613e0f57600080fd5b613e1b8b838c01613b4d565b965060608a0135915080821115613e3157600080fd5b613e3d8b838c01613b4d565b955060808a0135915080821115613e5357600080fd5b613e5f8b838c01613b4d565b945060a08a0135915080821115613e7557600080fd5b50613e828a828b01613b4d565b92505060c0880135905092959891949750929550565b60e081526000613eab60e083018a613a99565b8281036020840152613ebd818a613a99565b90508281036040840152613ed18189613a99565b90508281036060840152613ee58188613a99565b90508281036080840152613ef98187613a99565b905082810360a0840152613f0d8186613a99565b9150508260c083015298975050505050505050565b6001600160a01b038316815260406020820181905260009061295190830184613a99565b600060208284031215613f5857600080fd5b813567ffffffffffffffff811115613f6f57600080fd5b61295184828501613b4d565b60008060008060008060008060006101208a8c031215613f9a57600080fd5b613fa38a613af1565b985060208a013567ffffffffffffffff811115613fbf57600080fd5b613fcb8c828d01613b4d565b999c999b505050506040880135976060810135976080820135975060a0820135965060c0820135955060e082013594506101009091013592509050565b6000806040838503121561401b57600080fd5b61402483613af1565b91506020830135801515811461403957600080fd5b809150509250929050565b6000806000806080858703121561405a57600080fd5b61406385613af1565b935061407160208601613af1565b925060408501359150606085013567ffffffffffffffff81111561409457600080fd5b6140a087828801613b4d565b91505092959194509250565b600080604083850312156140bf57600080fd5b6140c883613af1565b9150613d7460208401613af1565b600181811c908216806140ea57607f821691505b60208210810361410a57634e487b7160e01b600052602260045260246000fd5b50919050565b6001600160a01b0384811682528316602082015260606040820181905260009061310790830184613a99565b6000835161414e818460208801613a75565b60609390931b6bffffffffffffffffffffffff19169190920190815260140192915050565b60008251614185818460208701613a75565b9190910192915050565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6020808252601a908201527f4f6e6c7920746865206f776e65722063616e20646f2074686973000000000000604082015260600190565b634e487b7160e01b600052601160045260246000fd5b60006001820161423f5761423f614217565b5060010190565b601f8211156109c657600081815260208120601f850160051c8101602086101561426d5750805b601f850160051c820191505b8181101561428c57828155600101614279565b505050505050565b815167ffffffffffffffff8111156142ae576142ae613b37565b6142c2816142bc84546140d6565b84614246565b602080601f8311600181146142f757600084156142df5750858301515b600019600386901b1c1916600185901b17855561428c565b600085815260208120601f198616915b8281101561432657888601518255948401946001909101908401614307565b50858210156143445787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052603260045260246000fd5b7f222c22696d616765223a22646174613a696d6167652f7376672b786d6c3b62618152641cd94d8d0b60da1b6020820152600082516143b0816025850160208701613a75565b9190910160250192915050565b600085516143cf818460208a01613a75565b8551908301906143e3818360208a01613a75565b85519101906143f6818360208901613a75565b8451910190614409818360208801613a75565b019695505050505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c00000081526000825161444c81601d850160208701613a75565b91909101601d0192915050565b8082018082111561077257610772614217565b8181038181111561077257610772614217565b634e487b7160e01b600052601260045260246000fd5b6000826144a4576144a461447f565b500490565b808202811582820484141761077257610772614217565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6000826145215761452161447f565b500690565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090612d2b90830184613a99565b60006020828403121561456b57600080fd5b815161285b81613a42565b634e487b7160e01b600052603160045260246000fd5b600181815b808511156145c75781600019048211156145ad576145ad614217565b808516156145ba57918102915b93841c9390800290614591565b509250929050565b6000826145de57506001610772565b816145eb57506000610772565b8160018114614601576002811461460b57614627565b6001915050610772565b60ff84111561461c5761461c614217565b50506001821b610772565b5060208310610133831016604e8410600b841016171561464a575081810a610772565b614654838361458c565b806000190482111561466857614668614217565b029392505050565b600061285b83836145cf56fe4d6574615472616e73616374696f6e2875696e74323536206e6f6e63652c616464726573732066726f6d2c62797465732066756e6374696f6e5369676e6174757265293c67207374726f6b653d226e6f6e6522207374726f6b652d77696474683d22312220666f6e742d66616d696c793d2248656c7665746963612c20417269616c2220666f6e742d73697a653d2238332220666f6e742d7765696768743d226e6f726d616c22206c65747465722d73706163696e673d22302e3031363622206c696e652d73706163696e673d223739223e3c7465787420783d2236302220793d22312e35656d222066696c6c3d2223464646464646223e226465736372697074696f6e223a225468697320756e69717565204e46542063657274696669657320746861744142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f222c202261747472696275746573223a5b20207b2274726169745f74797065223a22446f6e6174656420746f222c2276616c7565223a227b226e616d65223a22446f6e61746520586d6173222c226465736372697074696f6e223a2243726561746520796f7572204e4654204368726973746d617320706f73746361726420616e6420646f6e61746520746f20612063686172697479206f7267616e697a6174696f6e222c22696d616765223a22222c2265787465726e616c5f6c696e6b223a2268747470733a2f2f646f6e6174652d786d61732e636f6d222c2273656c6c65725f6665655f62617369735f706f696e7473223a302c226665655f726563697069656e74223a22227d2220783d22302220793d2230222077696474683d223130303022206865696768743d2231303030223e3c2f726563743e3c2f673e3c2f746578743e3c2f673e3c67207374726f6b653d226e6f6e6522207374726f6b652d77696474683d22312220666f6e742d66616d696c793d2248656c7665746963612c20417269616c2220666f6e742d73697a653d2233302220666f6e742d7765696768743d226e6f726d616c22206c65747465722d73706163696e673d22302e3031363622206c696e652d73706163696e673d223739223e3c7465787420783d223530252220793d223935302220646f6d696e616e742d626173656c696e653d226d6964646c652220746578742d616e63686f723d226d6964646c65222066696c6c3d2223464646464646223e227d2c7b2274726169745f74797065223a22446f6e6174656420616d6f756e74222c2276616c7565223a223c73766720786d6c6e733a786c696e6b3d22687474703a2f2f7777772e77332e6f72672f313939392f786c696e6b2220786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323030302f737667222077696474683d223130303022206865696768743d2231303030222076696577426f783d2230203020313030302031303030223e3c67207374726f6b653d226e6f6e65222066696c6c3d226e6f6e65223e3c726563742066696c6c3d22a26469706673582212208646aa017d3c07699d7c737137b7f768deda70055ab7cae545446c3c1fce739f64736f6c63430008110033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000a5409ec958c83c3f309868babaca7c86dcb077c1
-----Decoded View---------------
Arg [0] : _proxyRegistryAddress (address): 0xa5409ec958C83C3f309868babACA7c86DCB077c1
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000a5409ec958c83c3f309868babaca7c86dcb077c1
Loading...
Loading
Loading...
Loading
OVERVIEW
Create your NFT Christmas postcard and donate to a charity organizationNet Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 33 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.