ETH Price: $3,486.03 (+2.88%)
Gas: 3 Gwei

Token

DGFamily Glass (DGGLASS)
 

Overview

Max Total Supply

4,935 DGGLASS

Holders

691

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
1 DGGLASS
0xcb9ef2a95b520a27d6e193c7b58502a21c01da1f
Loading...
Loading
Loading...
Loading
Loading...
Loading

OVERVIEW

DGFamily Glass Boxes are redeemed for a tiered DGFamily Box during an on-chain reveal accessible in the coming weeks on UNXD. DGFamily Boxes are the key to unlock access to the Dolce&Gabbana NFT universe – a world of digital, physical, and experiential benefits straight fro...

# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
DGFamilyGlassBox

Compiler Version
v0.8.9+commit.e5eed63a

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion
File 1 of 20 : DGFamilyGlassBox.sol
//SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.9;

import "openzeppelin-solidity/contracts/utils/math/SafeMath.sol";
import "openzeppelin-solidity/contracts/access/Ownable.sol";
import "openzeppelin-solidity/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "openzeppelin-solidity/contracts/utils/Strings.sol";
import "openzeppelin-solidity/contracts/security/ReentrancyGuard.sol";
import "@chainlink/contracts/src/v0.8/interfaces/LinkTokenInterface.sol";
import "@chainlink/contracts/src/v0.8/interfaces/VRFCoordinatorV2Interface.sol";
import "@chainlink/contracts/src/v0.8/VRFConsumerBaseV2.sol";

import "../biconomy/EIP712MetaTransaction.sol";
import "./DGFamilyCollection.sol";

/**
 * DGFamily Glass box Collection
 * https://drops.unxd.com/dgfamily
 *
 * This is the initial glass box collection for DGFamily Sale.
 * Glass Box NFTs will be available at a fixed price. After the sale is done and reveal phase starts,
 * users will burn their glass box in return for the Black, Gold and Platinum Boxes.
 */
contract DGFamilyGlassBox is
    ERC721URIStorage,
    Ownable,
    EIP712MetaTransaction,
    VRFConsumerBaseV2,
    ReentrancyGuard
{
    using Strings for uint256;
    using SafeMath for uint256;

    /**************************************************************************************************
    * DGFamilyCollection will have total supply of 5000. The distribution of Platinum/Gold/Black boxes
    * will be as below. Box Types are identified by token index range.
    *
    *
    * Platinum Boxes: #1-75 (Index Range)
    * #48, 56, 57, 59, 61, 62, 63, 64, 65, 68, 70, 71, 72, 73, 74
    * 15 Platinum boxes.
    *
    * Gold Boxes: #76-750 (Index Range)
    * #76-745
    * 670 Gold boxes.
    *
    * Black Boxes: #751-5000 (Index Range)
    * #751-5000
    * 4250 Black boxes.
    *
    * Seed contains => 15 Platinum Boxes, 670 Gold Boxes and 4250 Black Boxes
    * Total => 4935
    ***************************************************************************************************/
    uint16[] public seed = [1982,739,329,2506,4524,4704,4814,3891,2602,2490,3157,4885,2933,4976,1081,581,3689,3884,3543,3842,4142,459,1318,1127,1461,4650,1351,1108,777,4114,4411,1530,1244,4376,2414,4075,2286,2380,3972,2420,4314,3824,3430,4308,491,3452,440,1532,2000,2004,856,1812,3967,3533,2045,1203,3260,1770,1873,277,1314,2502,634,3953,2465,2471,3635,4003,1768,3657,4713,2464,3994,2835,1181,3387,4515,1022,723,2144,2669,4329,611,4226,1551,3300,4959,3105,325,3568,3650,4792,3400,1672,4293,4387,4591,3943,1922,2632,2383,1212,4196,2336,137,1284,2972,2294,2926,419,900,3490,2702,2213,4550,4210,4184,1695,3028,1913,3909,4219,1055,2351,1923,3512,3252,961,4581,802,2338,3145,3863,2682,3679,1225,1280,2649,1330,2064,2910,4415,4577,3916,4034,3336,1698,4574,3547,2656,3254,3000,4449,4397,4047,1851,484,2511,1715,1370,1419,4123,960,1712,2493,3869,2214,1586,1125,3807,1092,4276,2115,2781,2335,3797,3627,165,2979,1533,4110,3858,4364,2805,4652,4145,4883,4863,959,4815,2151,2517,4115,3843,1360,3988,4944,463,3036,1619,4060,626,2252,2706,2855,4183,2551,1363,3287,3762,2154,1078,4816,3160,4005,4306,1664,679,2954,2242,4008,725,2008,3444,307,2598,2999,174,3043,4750,4942,804,2267,2293,83,3589,1501,1412,1058,3605,1068,3816,3859,3900,2634,534,4663,762,1261,3131,4084,2067,4995,2296,878,3272,2364,4583,1792,2514,898,81,3309,881,1806,1131,1909,3277,138,1771,521,3022,203,4957,4731,1494,1159,4407,3381,391,327,939,1392,2853,4136,1731,134,1333,710,248,3436,4349,4181,3698,1520,2412,3258,1458,3425,563,542,1285,1478,1408,3806,3787,2526,4447,3721,4560,3991,1624,3067,1841,2928,1298,360,1060,615,3371,975,48,924,4831,1590,3643,4682,3322,4910,4953,3801,3873,3729,866,973,582,1282,4602,1544,3694,2863,2750,941,1579,1847,585,1825,1192,1155,4057,1391,3504,2794,362,4365,2995,4541,1647,1437,2413,1785,3138,1576,2530,3491,240,2422,2840,3155,2310,4690,483,1186,4997,1820,1434,3745,510,1308,1206,97,1445,2223,2023,4645,987,2857,1657,2181,4379,4138,4277,431,4505,3486,2816,2749,3421,3435,630,1705,3071,1299,4066,981,2468,2977,1254,1228,4199,1233,2695,4511,2836,4729,3132,4299,547,3507,3077,197,2406,382,3324,253,4435,2913,2982,1523,1042,98,1279,4620,4232,1278,3788,2041,3699,4171,4632,105,4952,2106,4044,1149,1492,1365,2087,3455,4268,2730,2873,2694,1562,4634,3583,2731,1780,4822,1782,4758,1334,296,103,4772,208,189,2691,449,2878,2219,995,1652,2035,114,696,291,1453,4283,2469,4091,3646,2714,2581,194,4941,1502,1482,3493,3935,758,2117,2301,1987,2801,3754,2432,3274,1767,4636,2271,4400,2316,3166,2898,82,948,2342,4987,4784,3087,2368,2520,3195,4147,1634,4383,3103,3813,374,3135,3626,3914,4933,3722,436,4968,476,202,2437,4346,1510,1324,2195,71,418,2893,1410,3056,1905,2636,4585,1917,848,3571,4187,4290,544,2220,2906,4639,4730,953,321,4593,4594,241,2049,1100,1522,1152,2932,1584,2556,3714,807,2344,1725,3771,3123,937,62,4683,2567,3753,4320,785,2537,3828,3339,3063,513,790,3883,3919,1143,952,870,3550,4370,2016,2311,4889,2480,4605,3271,257,3737,4829,4036,3017,1822,683,1934,2202,3625,1033,4681,1660,1387,928,2235,2429,2653,825,4113,4961,3775,2994,1145,1489,4966,1327,1539,4448,4791,3704,968,2618,4835,2947,3211,3544,4394,2819,1843,1994,2326,2668,4733,2444,2174,1459,603,849,753,3382,2279,3564,2789,3031,1114,73,3233,3594,4434,254,3081,2676,3276,2329,3178,3481,3107,4766,2849,4898,3165,3534,141,59,330,3705,4143,2531,4556,543,2975,1388,2047,2780,4589,1650,2983,3340,283,2862,2216,3094,3848,2450,3653,761,3227,1176,4700,199,1691,1118,1582,922,3767,1856,811,1182,4543,2442,4744,4990,4923,1999,4190,2454,308,2425,4444,4770,4310,1739,1080,245,624,4646,2478,4569,1472,2472,3222,4530,2964,2631,2763,3251,389,2260,4102,2489,2762,3289,1427,4201,4539,2321,3035,4390,3514,4954,4261,914,2619,3538,4342,1306,2738,485,3569,693,3232,3680,984,4271,3137,4369,1372,343,2384,285,2597,1439,3197,4432,359,781,1375,172,1749,4549,3736,3203,185,4629,3204,1267,1928,1493,3118,4212,1593,2667,1699,445,602,810,1985,4104,755,3755,4464,4980,3257,926,1648,3551,3062,2052,4446,3262,2914,1608,2470,2175,4691,4068,1303,3263,473,537,3759,1386,2247,4146,3027,2937,398,4782,1973,2146,4211,4536,3315,1726,3793,962,1264,1071,4059,2698,1260,4736,4317,954,2569,242,1018,4203,3172,3572,4072,2014,3199,226,1636,1550,2160,2881,1497,686,1742,181,4103,2130,357,1897,3110,947,4827,4288,1732,3372,2011,2317,3658,1556,1052,3996,4894,460,2739,272,413,2377,1028,4624,4258,1718,3691,3428,1171,3112,3268,2399,2859,4847,2681,2692,1621,3255,1823,4479,631,4897,4476,2449,4790,376,2095,3218,2962,4238,1561,1703,4506,2145,4130,3665,1754,2395,2509,239,1347,605,2021,1304,1602,2949,3932,3465,1026,3323,3440,2098,4374,2733,3634,403,3116,3990,2729,3928,839,2249,907,2270,2677,2261,3766,815,3226,1775,1357,2020,353,4930,2589,2657,3866,1701,1626,1027,4077,2800,3299,1491,4494,3416,4779,3337,2108,4015,2770,1744,421,1349,1241,1123,1090,681,3221,2843,3184,735,2375,1290,3423,3237,4958,3836,3005,1547,2093,4689,2813,3096,3390,976,3862,1727,3969,1571,4762,4338,4126,4315,2229,3407,3414,2183,985,4220,3212,1148,4603,1289,1563,122,2611,2563,344,2693,3789,3537,2679,872,4875,379,2769,2904,2939,882,1620,1629,1878,3069,247,2829,3683,409,4586,2911,1471,4046,3642,3383,3007,1988,1216,3106,1037,1972,2903,3662,1700,1021,1266,2080,2790,1888,2663,86,2582,3822,859,4865,1135,996,3453,1061,4107,4208,3117,3530,861,3854,3182,3068,2578,3908,899,1777,978,578,4886,4433,4592,429,3325,2723,935,4544,2486,3835,444,2193,3867,1237,148,1816,1361,2573,2178,3159,2157,2328,368,2234,712,4793,3450,2415,664,1756,273,4019,4765,3021,507,1681,2211,3220,2027,4485,3844,271,428,4820,472,120,1047,3685,1094,4915,3366,2541,1631,3707,1312,3174,910,408,1311,1069,4975,3670,4493,4635,3716,149,1464,4956,1323,4783,235,4481,1671,4207,1371,4611,4527,2806,4676,4879,367,4571,3238,850,3298,4726,2461,1991,95,2612,2887,2231,1665,4841,1188,3621,3820,1044,1964,852,2104,1043,1804,1173,969,2428,2852,2613,349,1603,3697,3638,1442,1366,2699,498,4426,3427,4913,1339,3219,2285,4122,891,531,4561,1142,3104,160,2284,2837,385,223,583,1947,4422,465,668,3037,1622,4245,3113,3556,348,2244,1019,1029,4105,3224,4509,1835,3827,2834,2096,4798,1505,4257,4474,2900,4401,1861,3817,3558,4600,1645,4182,687,3541,3193,2462,136,3633,1736,4093,3095,1846,1219,663,1553,2799,897,854,1567,1554,1384,2605,1531,4513,3080,4027,2291,3185,2167,3825,355,738,1301,4131,970,559,3821,3351,4922,2929,1779,1008,3168,2680,3904,4710,92,4388,4672,2268,1961,1638,2272,131,3812,4007,4333,519,3051,4339,4760,4868,4162,613,4937,126,3622,791,1892,3437,4562,108,3772,774,452,1908,4035,3295,2617,4609,3865,4425,1197,4157,4969,354,4393,4794,2783,2720,358,934,4525,4234,4484,1256,229,2674,1085,3102,3109,2028,4846,1331,1024,1251,1642,728,4854,2128,4160,220,523,4614,1309,2273,1185,2350,4533,1802,2498,3266,1697,2484,1297,4359,3933,765,2243,3294,1015,3948,4647,2269,2105,4278,3246,2212,299,3945,4297,1591,2851,3180,3877,564,1355,1710,797,3923,812,2076,378,688,1803,2441,180,3023,1676,3949,1190,4193,3576,2917,597,276,3244,4752,1463,4654,680,2547,575,4498,1223,1852,1980,2038,2924,844,745,3957,4086,1979,3401,3595,3004,1077,352,474,971,4361,350,4021,90,411,731,256,4860,2481,4535,3673,2934,3242,1772,4492,826,3874,783,4064,3020,430,2078,3415,1097,3259,1234,4295,3147,614,3353,2330,4243,3173,3075,4112,2970,4964,3925,1500,76,4523,857,586,3024,2628,911,1977,1300,3645,4418,4517,682,4141,1268,480,1187,468,265,2879,2057,1653,3579,1545,1837,2719,1307,2060,991,4522,113,4095,3942,2403,2149,2705,1870,4231,1036,3879,4597,1242,3678,426,3800,4716,309,2974,3032,1430,3256,3040,604,4356,4127,2670,361,2387,4304,218,3397,2488,4380,1543,2124,4725,963,1659,1766,3446,1855,1864,892,3962,3809,2847,2362,2205,3388,3922,3319,4451,860,1824,116,1054,2624,4692,2411,567,1692,4595,3659,4247,675,1938,1574,167,4623,2518,1295,1320,1679,268,3194,3146,2473,4172,2640,654,1422,4625,3142,4089,1658,3808,2177,3954,2239,3718,4668,2308,591,315,3603,4849,1273,2046,1103,1128,4368,2081,2830,540,3739,4626,3559,4578,2576,3764,943,267,1787,3030,871,2094,2485,3847,3245,771,3347,2512,2978,3768,217,3887,3845,3190,4722,767,988,4098,1329,3369,1941,1031,2356,2540,3210,1446,1259,3492,372,3700,2854,396,3307,282,339,2072,596,3555,4176,1121,2409,3770,4951,4244,2894,684,685,3496,4140,3982,1088,4548,4316,2192,264,628,2088,3676,1321,2734,1073,3536,2654,894,384,1737,4657,1483,79,3488,3839,1828,1178,4463,1238,3125,4092,4256,1328,2500,2897,4706,904,2895,3757,2861,732,2599,923,1095,1084,972,642,1833,1200,4416,599,2194,1685,1046,338,186,1838,1070,865,1163,3053,3655,1460,4839,486,4168,2793,800,2074,2560,1517,2665,499,1112,4164,806,4006,1939,2561,475,4708,632,1305,3432,1168,3868,1253,3318,716,100,571,1906,2985,2361,4996,4437,1907,3346,244,144,1689,4266,1287,2355,2245,392,4431,2110,2884,2572,1845,3644,863,3208,3419,893,4512,2539,1476,3320,3153,4640,4009,3979,2522,3223,594,1874,2155,478,1064,1157,2447,2885,4621,1839,2007,3581,1034,2998,1853,1911,3418,2950,346,1723,224,2546,1881,3019,656,1221,4773,2760,3973,4398,620,913,4331,1496,3384,4325,3511,135,2768,1557,673,3395,4781,780,1195,2759,292,3368,2419,4367,4938,2376,715,3396,1326,1383,184,587,3682,4087,3931,1891,263,1252,1479,2960,3777,347,1294,1826,3499,757,2297,3273,1120,1429,2024,2061,3710,3885,1104,1751,3393,4842,4495,4327,1945,269,951,4714,4653,3615,2352,3964,908,2165,4807,4267,1438,1503,4502,1729,2942,737,3915,4606,1537,3344,219,3701,188,4737,1546,3610,2554,492,3647,3506,4026,4921,3086,335,3712,4534,2276,877,2388,4935,659,727,3695,4471,530,3191,4094,2838,3380,539,1840,3016,1343,4178,422,1106,3516,290,2848,2992,2869,2864,3703,3934,4477,4677,3341,4916,565,130,4661,4074,2558,2779,2029,4575,858,3413,1560,4312,512,4223,2944,2622,4490,2527,3164,3128,1183,590,4303,1010,332,3314,4462,697,2655,2186,3886,1848,4040,3161,3897,2525,2651,2044,2264,3779,1643,4873,3668,2224,4851,1540,786,4926,1875,1342,433,4909,4810,2391,4472,4125,1616,3464,2263,1504,1776,3472,3881,751,1717,1513,375,2238,4225,577,3002,1919,3375,2445,316,3365,669,3740,1598,2776,297,2557,2082,1208,820,788,702,1124,318,3151,3607,658,443,1836,4011,2955,3763,4358,4892,1374,4340,4215,2164,266,2389,2034,4555,1518,1470,1524,2253,1205,145,1377,417,4504,3774,2332,2877,3838,903,966,526,4684,4988,4042,2168,3279,1255,230,4081,1398,1609,412,1249,1635,3612,1797,481,4108,3815,3187,2233,399,1585,1111,4828,639,1527,3872,404,3590,4545,4853,3520,1741,919,2716,221,901,4866,2936,3518,2986,1338,4742,3726,2018,1368,637,2135,4192,3189,312,225,2726,4582,420,1210,4389,1451,4109,4823,1041,393,1432,4200,3826,171,3296,3150,1487,3304,831,3426,1759,3539,916,2583,1201,156,3206,885,822,4440,2747,2876,4250,1269,3756,4630,4570,2398,2688,2591,4801,2961,3898,1526,3014,3420,2492,4384,4870,1706,3941,1435,4950,2114,1788,1396,4465,2984,4588,4755,2017,2315,4806,1086,552,423,4205,1337,3529,3089,3479,3769,4642,1915,1783,4055,1162,2182,4496,1115,1101,1716,1456,3154,1172,4206,864,795,2139,1910,1179,1745,2844,3938,4510,1072,4135,4012,1552,1669,380,1981,3029,4764,2491,3527,3352,1485,340,2077,336,3687,4185,4745,2025,1793,3213,2322,3692,2754,2940,2129,4204,2150,1644,1270,2808,1743,207,4984,538,1013,3663,1651,2807,3144,4177,3983,1730,4862,2068,3906,1413,1414,2871,4023,2666,3391,3064,1293,1757,456,1367,1000,1789,4302,4151,895,4579,2373,302,1568,4242,4443,1462,3798,3278,1807,2659,535,3306,4649,3732,3378,4900,5000,946,4323,3373,711,3574,177,3654,4170,4457,518,875,979,1379,4285,139,2804,667,3025,2169,1226,4608,4929,4821,2185,1154,1623,2112,3409,2153,3761,958,3328,2907,4743,3297,2086,259,2644,734,4939,1498,660,1475,4031,1817,3671,94,4641,3335,2030,2295,2070,3292,1380,1395,1240,1421,3870,2604,1693,2309,2246,1808,549,289,4321,3084,2516,3580,4693,3308,929,1296,880,994,2922,4727,3467,1473,1929,4763,2543,1713,2784,4079,592,4615,3119,2457,187,72,2171,2621,1818,68,2559,1005,3785,588,569,1409,566,950,448,1344,204,2773,4450,3350,809,4396,1275,3652,3234,832,706,3261,4227,2479,1769,2319,1575,2307,390,938,3513,2858,736,1440,4313,3100,2938,2372,2303,2378,1765,666,827,4420,3837,4809,665,1735,1827,580,3083,677,4106,3410,1017,740,1102,2248,4382,1755,4254,4063,4466,4826,1904,1606,3731,2382,4275,4132,3291,1746,2802,4292,3079,1748,3917,1549,295,2191,3624,763,3469,1834,4402,2991,3567,2767,2393,2013,1230,3475,838,1170,2091,4882,2102,4062,3834,2727,1733,4259,3546,191,281,999,782,1193,3358,742,2645,2981,608,1704,3065,942,4856,2856,3059,215,2324,2188,3681,1958,3892,2113,1974,381,4728,4454,3796,692,179,4097,1661,4209,3792,4757,334,4328,3735,4761,1962,609,1983,3902,1656,1231,4442,884,3773,4843,2386,3101,3709,1863,550,1633,2431,1778,2590,4998,127,3880,2392,2638,4850,2390,3896,2965,4381,2700,1687,4631,1358,371,2718,3519,2593,2586,3598,3963,2339,4024,1402,1415,2577,3713,709,2402,3048,4282,1096,889,4662,3743,514,1014,2340,4048,4749,323,3478,4372,4085,4139,3563,3050,405,1426,2262,3152,2288,600,3377,2513,1040,3629,4797,2189,834,4439,2161,3742,4924,1196,2782,370,1469,3602,4638,2348,3045,2968,1079,1535,2460,560,3628,500,2571,4054,3057,1248,1302,2615,4161,4326,3672,678,3802,1137,2084,4073,4311,2133,701,2056,814,2635,515,3531,4724,3462,1113,324,3631,3376,2127,4152,1310,1566,821,1666,3570,4335,3198,2320,3981,4453,3445,2658,1992,1117,4217,2476,63,1800,3039,2051,4409,3250,4274,4022,3810,3134,1618,182,1588,3814,2883,4030,4590,3566,930,617,2032,70,874,3441,940,1158,4001,4812,4038,1418,4799,3554,3505,1680,3750,3577,805,1857,2764,833,462,1087,801,4000,3143,2545,104,2083,293,2085,2006,4202,2236,4404,246,3176,789,1565,3247,1403,1936,2417,1516,482,249,4832,3549,2265,328,2803,4118,2043,3760,4627,4658,1406,4216,4872,3525,3677,4165,1336,570,4927,3281,4616,1995,1728,1003,3431,4753,4845,2923,2121,503,211,2504,1862,1417,2230,3910,4679,1684,867,124,4788,896,3348,579,2987,1686,1214,446,3360,4838,3829,1016,4878,977,2289,447,3186,2880,998,1405,4601,2459,4039,956,1605,754,1023,4405,4262,853,2400,3449,3724,3738,517,965,1604,2534,1511,2510,3412,1933,4117,2550,434,2905,1564,3140,1397,4065,2079,4553,4584,1536,2822,2710,2902,1452,107,3690,337,2792,4651,2435,4236,4598,3748,4613,1394,2012,2633,388,2170,4972,2111,4903,2980,4345,4777,3952,4248,140,3875,2818,4090,4891,730,4399,3085,1525,4531,4041,1011,3744,4778,2349,1335,1969,986,1955,2927,982,2163,589,2463,439,4241,3501,845,1682,1762,3330,4912,2179,3357,1617,1714,4497,2796,3433,3985,622,3121,3907,1573,2912,1831,3399,4412,3955,1641,3980,1989,3893,2222,2280,1871,154,2515,4711,4013,1133,2650,1488,3974,1045,1667,4385,1696,572,2701,505,497,3855,3976,2712,855,1615,3664,2722,4644,529,1194,1721,2809,123,4818,722,3267,3231,3747,647,4322,2203,3442,1257,2687,4343,1578,2675,2254,4840,1577,2711,3727,905,3447,4643,2916,2100,2609,689,4970,983,3216,3317,2870,3540,495,2812,1529,425,132,2627,671,1896,616,2092,159,2548,3575,1007,3127,3749,489,2497,4803,584,3477,1447,2908,989,4529,2777,1997,4558,170,3044,3460,1105,4436,2595,1688,4337,1009,4269,2538,2066,3588,2298,2626,3283,1799,1819,1872,2026,2724,3636,4813,4305,4235,766,4230,2901,2503,2367,142,2131,4373,3124,1512,129,1752,636,4622,4718,493,4659,1424,4967,4887,1628,4925,3901,2033,441,3930,2325,4540,4516,4428,3402,3927,1613,435,2292,3149,190,2728,902,3355,2090,1935,3649,2416,835,322,3434,4739,1747,3136,2440,106,250,1986,2042,4707,3818,2405,4709,3169,373,3009,2436,876,152,1180,326,2620,2467,3587,1724,1946,3288,3282,4076,2865,3585,4100,927,2875,4948,3911,676,3711,3523,4352,1654,2359,3230,2208,2772,3214,2240,80,4618,4445,2574,4088,4195,1286,1139,401,561,4377,4985,4307,4702,1153,4945,1416,3548,88,3899,65,576,1316,1960,2446,4675,726,1811,3999,3741,1354,3329,4552,3385,655,4392,4071,650,4901,2642,1786,2827,3090,4741,3944,2751,4301,4263,1345,4148,4688,402,4685,784,4294,4888,1382,4438,1890,3162,3379,4869,3010,1930,1359,3674,3648,1509,231,4334,2715,2031,4417,2890,2662,1006,3331,2673,3066,4286,288,2505,1083,2766,4194,3619,490,2448,96,1854,4363,4551,1595,1877,3179,1109,183,364,477,593,4768,1570,4175,2736,1407,2162,2109,2652,2660,4747,209,2116,119,1976,1271,619,3466,1191,1655,4715,2443,3986,2166,1592,1352,4908,3454,1998,4129,3993,453,2158,1420,2956,646,1053,1805,3895,4936,3013,548,3666,1056,2241,1720,993,4229,212,651,2053,1499,1601,3229,3463,3565,3217,2394,3667,3482,944,4918,4353,4824,1001,2811,3209,1246,2069,1927,2643,4289,4965,2896,2401,3042,4080,4069,787,365,1199,4940,1075,274,703,4355,3156,2421,3474,2482,2282,1559,2283,3617,3639,4134,2685,4962,4911,4811,3936,2788,4296,717,3823,817,1953,1263,2495,3929,3864,3181,168,568,3456,2299,1607,4017,3097,110,4043,3139,4429,1449,4251,4705,310,4051,2381,3239,2533,2785,162,1627,1639,427,279,4805,1441,3470,2791,733,918,1646,3099,2614,1683,4991,886,1506,3992,3126,836,2690,2989,4855,3122,1288,4010,997,741,4478,284,317,4932,2973,2775,3170,4410,1004,3001,1901,3058,1521,1957,3386,2996,213,2521,2001,3398,3856,1903,1177,2226,3937,4723,494,555,1222,4270,1719,4830,3008,4458,3088,3522,4150,2228,4360,2197,3215,2126,3356,4233,2346,1912,414,2741,4413,828,4703,4992,238,4696,4351,2507,4617,3561,2159,2584,3995,2187,3965,1098,4789,1858,2397,146,3111,743,601,1332,4198,525,4880,2637,2278,4537,2499,1116,3498,4249,621,1224,341,1217,1385,3725,1709,4983,3280,3183,3429,4971,1378,2771,2966,1810,2990,1971,957,3924,1815,2353,4721,1039,1722,3461,125,3417,4214,1239,457,532,2608,1763,2697,2639,1794,3141,2062,1951,206,2594,1599,454,1151,3243,3303,520,4720,3448,2019,3424,4222,2725,4687,2120,3946,1859,1450,4332,2696,980,369,3012,1632,4599,2580,471,2250,4756,627,4596,3133,2872,2815,3958,4666,173,2585,4974,3819,278,1126,3596,1136,4330,4319,1089,4375,2737,2347,2713,1528,1428,1784,176,2795,3706,56,3786,2404,4371,2587,3241,3484,2275,3959,4169,1668,2010,1990,4189,690,3591,3830,1814,4083,2758,255,2073,261,1373,4280,1161,2433,4566,3656,4284,633,2237,1952,4124,111,3411,2536,2005,4049,3497,2918,461,818,4699,2360,3326,4717,1996,74,163,1600,4480,2314,1538,3114,3606,2899,1144,4133,837,1860,1949,541,1832,1984,3846,1189,2039,4128,3364,3987,2152,2036,4701,3966,3033,2274,275,4943,4771,4067,4610,4166,1663,3438,1707,1813,458,4395,4671,4336,2055,1876,4546,1166,3799,3553,3200,4354,232,4928,2455,2752,356,1886,4045,4748,3526,4163,3977,1076,4475,1868,2089,2592,724,4858,2786,4612,1258,1548,3302,3363,1581,662,1740,210,4774,3049,2920,4240,606,2743,1882,1051,3489,1791,4680,4052,2125,228,3311,1274,792,3235,101,4607,3790,2173,2071,4500,3515,2438,2266,3599,3578,3804,2564,4526,205,2756,4697,1236,705,1012,2101,4503,4033,1809,1448,2418,4902,3641,3108,1542,4920,653,721,3078,2817,4014,2976,3240,2142,2184,4817,4344,699,3781,3120,3361,2304,1346,1879,2232,4563,2930,2508,395,816,3970,931,2206,4348,450,3961,2757,2218,2277,161,1211,3532,3301,1141,504,3269,4775,796,4264,4559,1924,2683,3060,3072,1773,2732,2040,1966,1829,4501,672,3524,768,4004,3502,1091,3675,2641,2704,2686,598,1884,3851,2141,2458,258,1245,1587,227,3614,1959,3660,2337,1926,1948,301,1443,1062,1940,1431,2826,2369,574,3018,2054,3861,4993,1213,1790,830,652,3521,1381,2892,2198,2661,432,3780,2221,846,3394,4734,2562,640,294,3784,4487,2603,1690,3630,4486,2742,2745,3073,3495,3582,4669,1844,2354,527,3327,3354,1589,237,1235,2137,4116,4572,1534,2707,1277,1132,4137,3971,879,649,3850,2037,3960,3876,4673,4459,2846,424,2941,386,3006,3026,2370,260,2201,4456,2345,4144,1612,3651,2496,2625,1507,1468,3803,2022,4896,2379,2426,4859,1350,3054,3926,128,1898,3831,3584,4028,674,4386,793,4557,704,2385,4834,3734,4488,3483,3349,3684,4796,407,314,2287,2671,912,2343,516,4667,1893,1894,1319,4468,4825,3794,3316,342,3192,1281,2868,3860,2523,251,2943,1059,3158,4877,2501,4769,4473,829,467,3163,4637,2607,4053,2787,2969,4159,3510,3618,2575,612,157,2579,1348,2823,1390,4580,4499,2255,3717,3471,470,3248,2957,3888,794,4255,4947,4224,1678,4300,3765,1369,4167,2407,84,2544,1950,1262,2842,2156,3778,915,4050,2553,1030,2227,488,2860,657,4576,4508,2357,1750,1849,2630,3076,554,558,3443,3833,4016,773,1796,3321,117,4554,1866,3857,3609,868,4906,2180,1393,888,2629,2945,1490,3715,4408,3912,2549,3290,2841,1243,3367,1760,175,1942,1937,4955,3557,4173,2251,1597,3457,1140,2993,4751,3552,1583,1207,3669,4279,1411,2601,1484,2915,3129,3408,1032,4155,1276,2519,3878,4686,3148,3093,3310,3719,1150,303,720,3728,3975,3509,752,1272,1610,4120,2951,4291,4518,4695,506,511,890,2453,1340,1364,270,2410,2334,2050,1895,2257,1887,4648,2209,3130,3611,351,648,756,397,4180,147,3795,3091,2331,1674,1283,1202,1821,2570,4977,3811,3950,2798,1480,4406,2610,524,4260,2281,1147,661,2058,2215,4213,4532,3720,4904,2176,4470,2606,1555,2946,4366,2147,4154,2333,4881,3920,1467,4341,2866,234,3038,4002,1389,3623,193,3997,3751,2721,4664,719,2555,1466,4018,1465,3968,437,4780,4149,2225,2988,4934,3293,3708,3508,1925,3207,2689,3503,2959,2761,1572,3225,3913,776,3600,3723,4919,99,3494,1798,1594,469,3175,2833,4800,4298,3196,2744,3947,3951,2009,2207,1156,556,2341,3034,4547,2753,936,1764,394,4158,3205,4221,4808,4318,502,1404,625,1956,3047,4324,3422,2065,1900,2596,233,3473,2327,2318,2483,4857,4419,3545,1400,508,2494,3752,1353,1250,4452,707,1356,4712,1675,4735,4978,333,4099,1734,1662,2487,61,2423,4787,851,2210,2256,2456,2451,546,2200,3055,2717,3989,496,618,3003,1425,4061,1247,1067,4430,2143,3597,1889,3480,3265,4287,643,645,3270,847,1795,764,3805,3333,2874,1850,4121,2952,670,479,3468,2882,1515,1093,3921,4981,416,2199,4469,320,2703,2302,216,166,89,383,1965,1673,4587,2258,3535,4191,4568,3459,4403,1541,3517,4427,1914,3733,1322,1781,133,1902,1063,3688,718,1918,4179,2568,778,841,2196,1082,1175,4252,2474,3249,1677,4678,2839,311,4802,3608,1020,2919,487,1830,2204,1455,3236,3359,3343,1943,4391,4656,887,698,1963,2845,1220,695,1580,4874,4907,1921,2306,1637,1160,1184,595,2797,3404,2963,1066,222,1880,1931,2312,4357,1774,1057,842,4836,2313,4848,3620,109,3782,178,3601,2909,4489,1708,2103,1869,4025,3956,2259,2190,3889,2953,1865,4272,4101,3905,883,4871,150,4899,3313,196,3082,4963,3061,1209,2935,2600,2408,1753,2566,729,1167,3284,4759,700,2831,4694,1640,2825,3918,1433,115,4078,3542,1313,2363,4483,4804,1630,4058,3882,3696,3758,3984,1325,3592,4890,4989,1134,3593,3345,4424,4960,2434,3894,1265,3528,1883,2684,121,3202,4564,533,3852,4633,2063,819,3228,1694,779,623,1920,1916,769,2565,2891,236,2623,4670,1495,2524,3776,112,1146,3451,1025,2118,262,1074,843,3586,551,3305,3560,4660,2967,3011,2921,2099,2535,2140,1315,2889,964,1099,3940,1970,4655,2850,1174,1569,3177,1486,4740,4507,1481,4754,3403,2925,1899,2122,3661,1198,2290,4767,3285,305,4514,4738,691,2828,2746,1229,2466,102,4467,313,3312,992,522,644,1291,744,91,921,3439,298,3998,195,3783,2814,4538,2002,1932,4819,2958,1711,4565,557,3693,4999,4917,4893,87,4876,1362,3853,1227,949,4521,713,2740,2672,2616,345,2003,1625,3275,1519,201,4895,4455,304,442,2678,3286,4931,1975,3052,2424,2532,509,1035,3849,932,1204,4378,1107,1457,1119,2374,3389,4665,4949,1614,2217,4237,77,1341,2075,803,3613,3485,1129,1758,4197,4174,3046,3746,2748,2132,1978,708,118,4795,169,192,78,3115,1399,2396,387,3342,1169,2552,2886,3890,2452,4461,4441,4982,545,143,3978,306,4265,2542,1477,1065,2439,4861,629,2648,4619,366,823,1611,151,3562,2810,3702,4362,2888,3405,4423,3167,2778,4491,455,4421,4867,4020,1944,2015,4119,772,3939,3791,4350,4156,158,2300,917,4567,1317,990,300,869,4253,610,694,3092,4884,775,4082,813,536,3458,57,3616,1423,3332,1049,4979,280,2172,319,3871,2867,3171,363,3201,4414,1110,3632,808,862,2588,331,2708,4520,3188,3392,955,438,3015,4786,641,3500,909,2646,2477,4719,4032,3832,4698,1122,2323,1968,873,4347,4604,3264,3604,3903,1885,164,3374,2774,4153,3730,1292,4281,4746,3074,1508,798,286,974,1558,2430,3070,638,4905,4096,4188,1596,4542,2048,501,2997,1738,553,4986,2647,4070,1867,287,1436,4273,4239,2709,4111,4973,760,1454,2097,1954,410,3840,85,1474,464,2824,945,4460,4837,2366,2119,2427,200,1050,4186,1165,198,153,377,920,3362,1702,2735,3637,1444,1232,2148,635,1842,3098,2123,2371,243,4732,2820,925,451,4519,1993,3253,4628,2305,2931,1048,2755,3334,759,64,1002,1761,406,3686,1038,4994,93,3041,933,4218,906,2134,607,2136,4037,770,155,2664,1215,1801,415,3573,1376,3640,1514,2358,2821,1670,1401,4844,4309,4482,4785,4914,840,3370,4833,4852,714,2365,967,799,214,3338,2059,2107,4864,4228,3476,1218,1130,2971,4946,400,4776,4246,4573,562,466,1967,528,824,252,2832,2765,2475,4056,2948,1138,4029,4674,4528,3406,2529,3487,1164,1649,573,3841,2528,2138];

    /******************************************************************************************************
     * Chainlink: Starts
     *******************************************************************************************************/

    // chainlink contract interfaces
    VRFCoordinatorV2Interface COORDINATOR;
    LinkTokenInterface LINKTOKEN;

    // Chainlink subscription ID.
    uint64 public subscriptionId;

    // Chainlink vrfCoordinator
    // see https://docs.chain.link/docs/vrf-contracts/#configurations
    address public vrfCoordinator;

    // Chainlink LINK token contract. For other networks,
    // see https://docs.chain.link/docs/vrf-contracts/#configurations
    address public link;

    // The gas lane to use, which specifies the maximum gas price to bump to.
    // For a list of available gas lanes on each network,
    // see https://docs.chain.link/docs/vrf-contracts/#configurations
    bytes32 private keyHash;
    uint32 private callbackGasLimit = 200000;
    uint16 private requestConfirmations = 30;
    uint32 private numWords = 1;

    // This is the random number generated by chain link vrf.
    uint256 private chainlinkRandomNumber;

    // This will be some random prime number set during reveal phase and
    // is used in reveal calculations
    uint256 private primeNumber;

    // This is the chainlink requestId for vrf.
    uint256 private requestId;

    /******************************************************************************************************
     * Chainlink: Ends
     *******************************************************************************************************/

    // base uri for meta data
    string private baseURI;

    // current token index minted.
    uint256 private tokenIndex;

    // current total public supply.
    uint256 public totalSupply;

    // royalty percentage for secondary sales in UNXD marketplace.
    uint256 public royaltyPercentage;

    // max total public supply for glass boxes
    uint256 public constant MAX_PUBLIC_SUPPLY = 4935;

    // After the initial sale phase is complete, reveal phase will be started.
    // During reveal phase users will burn their tokens to get the DGFamily token.
    bool public revealPhaseStarted = false;

    // the primary dgFamily contract address.
    address public dgFamilyContractAddress;

    // These are three types of boxes users will get in return for their glass box.
    enum BoxType {
        BLACK,
        GOLD,
        PLATINUM
    }

    // This is the list of whitelisted system wallet addresses. These are used by UNXD backend api to place
    // generate requests for glass box tokens.
    mapping(address => bool) public systems;

    // This stores tokenIds of the all the glass box NFTs which are revealed.
    mapping(uint256 => bool) public revealedTokens;

    // This store the Black/Gold/Platinum box type revealed for each glass box token id.
    mapping(uint256 => BoxType) public revealedResults;

    // This stores the short code for Black/Gold/Platinum.
    mapping(uint8 => BoxType) public boxTypeMapping;

    // This event is emitted once the royalty percentage is changed for this collection.
    event RoyaltyPercentageChanged(uint256 indexed newPercentage);

    // This event is emitted if the base URI is updated for the collection.
    event BaseUriUpdated(string indexed uri);

    // This event is emitted if the list of whitelisted system address change.
    event SystemAddressUpdated(address someAddress, bool enabled);

    // This event is emitted during the reveal phase when a glass box is burned and user receives Black/Gold/Platinum
    // box in return.
    event Revealed(uint256 glassBoxTokenId, uint256 dgTokenId, BoxType boxType);

    constructor(
        string memory _tokenName,
        string memory _tokenSymbol,
        string memory _baseURI1,
        uint256 _royaltyPercentage,
        address _dgFamilyContractAddress,
        uint64 _subscriptionId,
        address _vrfCoordinator,
        address _link,
        bytes32 _keyHash
    )
        ERC721(_tokenName, _tokenSymbol)
        EIP712MetaTransaction("DGFamilyGlassBox", "1")
        VRFConsumerBaseV2(_vrfCoordinator)
    {
        baseURI = _baseURI1;
        royaltyPercentage = _royaltyPercentage;
        dgFamilyContractAddress = _dgFamilyContractAddress;
        COORDINATOR = VRFCoordinatorV2Interface(_vrfCoordinator);
        LINKTOKEN = LinkTokenInterface(link);
        subscriptionId = _subscriptionId;
        vrfCoordinator = _vrfCoordinator;
        link = _link;
        keyHash = _keyHash;
        boxTypeMapping[1] = BoxType.BLACK;
        boxTypeMapping[2] = BoxType.GOLD;
        boxTypeMapping[3] = BoxType.PLATINUM;
    }

    /***
     * Check for only accessible by authorized system addresses.
     */
    modifier onlySystem() {
        require(systems[msgSender()], "SYSTEM_UNAUTHORIZED_ACCESS");
        _;
    }

    /***
     * Check for only accessible by authorized system addresses or owner.
     */
    modifier onlySystemOrOwner() {
        require(
            systems[msgSender()] || owner() == msgSender(),
            "UNAUTHORIZED_ACCESS"
        );
        _;
    }

    /**
     * Set system address. These addresses are used to generate tokens through secured *  * unxd-api calls.
     * @param someAddress: new address to add.
     * @param enabled: enable/disable access.
     */
    function setSystem(address someAddress, bool enabled) external onlyOwner {
        require(someAddress != address(0), "INVALID_ADDRESS");
        systems[someAddress] = enabled;
        emit SystemAddressUpdated(someAddress, enabled);
    }

    /**
     * Set baseURI for metafile root path.
     * @dev Emits "BaseUriUpdates"
     * @param uri: The new uri for tokenURI base.
     */
    function setBaseURI(string memory uri) external onlyOwner {
        baseURI = uri;
        emit BaseUriUpdated(baseURI);
    }

    /**
     * Sets royalty percentage for secondary sale.
     * @dev Emits "RoyaltyPercentageChanged"
     * @param _percentage: The percentage of royalty to be deducted.
     */
    function setRoyaltyPercentage(uint256 _percentage) external onlyOwner {
        royaltyPercentage = _percentage;
        emit RoyaltyPercentageChanged(royaltyPercentage);
    }

    /**
     * Mint NFT tokens. This will be called by the UNXD system wallets. Owner can also call this for specific cases.
     * @param numberOfTokens: The quantity of tokens to be minted.
     * @param destination: The minted token receiver.
     */
    function generate(uint256 numberOfTokens, address destination)
        external
        onlySystemOrOwner
        nonReentrant
    {
        require(destination != address(0), "ADDRESS_CAN_NOT_BE_ZERO");
        require(
            (!revealPhaseStarted),
            "PERMISSION_DENIED_REVEAL_PHASE_STARTED"
        );
        require(
            (totalSupply.add(numberOfTokens)) <= MAX_PUBLIC_SUPPLY,
            "MAX_PUBLIC_SUPPLY_REACHED"
        );

        for (uint256 i = 0; i < numberOfTokens; i = i.add(1)) {
            tokenIndex = totalSupply.add(1);
            totalSupply = totalSupply.add(1);
            _safeMint(destination, tokenIndex);
        }
    }

    /**
     * Get royalty amount at any specific price.
     * @param _price: price for sale.
     */
    function getRoyaltyInfo(uint256 _price)
        external
        view
        returns (uint256 royaltyAmount, address royaltyReceiver)
    {
        require(_price > 0, "PRICE_CAN_NOT_BE_ZERO");
        uint256 royalty = (_price.mul(royaltyPercentage)).div(100);
        return (royalty, owner());
    }

    /**
     * Provides token URI of the NFT.
     * @param _tokenId: target NFT.
     * @return The URI string for the token's metadata file.
     */
    function tokenURI(uint256 _tokenId)
        public
        view
        override(ERC721URIStorage)
        returns (string memory)
    {
        if (totalSupply == 0) {
            return _baseURI();
        }
        require(_exists(_tokenId), "TOKEN_DOES_NOT_EXIST");

        /// @dev Convert string to bytes so we can check if it's empty or not.
        return string(abi.encodePacked(_baseURI(), _tokenId.toString()));
    }

    /**
     * @dev See {IERC721-transferFrom}.
     * @param from: address of sender.
     * @param to: address of receiver.
     * @param tokenId: tokenId nft being transferred.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        require(
            _isApprovedOrOwner(msgSender(), tokenId),
            "CALLER_NOT_APPROVED"
        );
        _transfer(from, to, tokenId);
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     * @param from: address of sender.
     * @param to: address of receiver.
     * @param tokenId: tokenId nft being transferred.
     * @param _data: any additional data.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) public virtual override {
        require(
            _isApprovedOrOwner(msgSender(), tokenId),
            "CALLER_NOT_APPROVED"
        );
        _safeTransfer(from, to, tokenId, _data);
    }

    /**
     * @dev Overridden function to prevent Owner from relinquishing Ownership by accident.
     */
    function renounceOwnership() public view override onlyOwner {
        revert("CAN_NOT_RENOUNCE_OWNERSHIP");
    }

    /**
     * Approval.
     * @param to: address to approve.
     * @param tokenId: NFT to approve.
     */
    function approve(address to, uint256 tokenId) public virtual override {
        address tokenOwner = ERC721.ownerOf(tokenId);
        require(to != tokenOwner, "ERC721:APPROVAL_TO_CURRENT_OWNER");
        require(
            msgSender() == tokenOwner ||
                isApprovedForAll(tokenOwner, msgSender()),
            "ERC721:APPROVE_CALLER_NOT_OWNER_OR_APPROVED_FOR_ALL"
        );
        _approve(to, tokenId);
    }

    /**
     * Get baseURI of collection.
     */
    function _baseURI() internal view virtual override returns (string memory) {
        return baseURI;
    }

    /**
     * Check if specific glass box NFT is already revealed or not.
     */
    function checkIfRevealed(uint256 _tokenId) public view returns (bool) {
        return revealedTokens[_tokenId];
    }

    /**
     * Start reveal phase.
     * Once in reveal phase glass boxes can be burned to get the actual DGFamily NFT.
     * We request the Chainlink requestRandomWords to generate random number. The response will be handled by
     * fulfillRandomWords as callback once the request is complete.
     */
    function startRevealPhase(uint16 _primeNumber) public onlyOwner {
        require(!revealPhaseStarted, "REVEAL_PHASE_ALREADY_INITIATED");

        primeNumber = _primeNumber;

        requestId = COORDINATOR.requestRandomWords(
            keyHash,
            subscriptionId,
            requestConfirmations,
            callbackGasLimit,
            numWords
        );

    }

    /***********************************************************************************************************
     * This is the callback for the Chainlink requestRandomWords method called during the startRevealPhase
     * execution.
     * We store the random number and start the reveal phase.
     ***********************************************************************************************************/
    function fulfillRandomWords(
        uint256, /* requestId */
        uint256[] memory randomWords
    ) internal override {
        // get random number between 0 to 999,999,999,999,999.
        chainlinkRandomNumber = (randomWords[0].mod(999999999999999));
        revealPhaseStarted = true;
    }

    /***********************************************************************************************************
     * Reveal the actual NFT from the DGFamily collection.
     * Here we burn the initial glass box NFT user has and mint a random box from the
     * Black, Gold or Platinum boxes seed. Meta info will be
     * updated by capturing the Reveal event data by unxd backend.
     ***********************************************************************************************************/
    function revealBox(uint256 tokenId) public {
        require(
            _isApprovedOrOwner(msgSender(), tokenId),
            "CALLER_NOT_APPROVED"
        );
        require(revealPhaseStarted, "REVEAL_PHASE_NOT_INITIATED");
        require(!revealedTokens[tokenId], "BOX_ALREADY_REVEALED");

        // mark tokenId as revealed and burn the token.
        revealedTokens[tokenId] = true;
        _burn(tokenId);

        // reveal the box type.
        uint256 randomIndex = (((primeNumber * tokenId) + chainlinkRandomNumber) % seed.length);
        uint16 revealedBoxTokenId = seed[randomIndex];
        BoxType boxType = BoxType.BLACK;

        if (revealedBoxTokenId >=1 && revealedBoxTokenId <=75) {
            boxType = BoxType.PLATINUM;
        } else if (revealedBoxTokenId >=76 && revealedBoxTokenId <= 750) {
            boxType = BoxType.GOLD;
        }

        DGFamilyCollection dgFamilyContract = DGFamilyCollection(
            dgFamilyContractAddress
        );
        uint256 dgFamilyTokenId = dgFamilyContract.generate(msgSender(), revealedBoxTokenId);
        emit Revealed(tokenId, dgFamilyTokenId, boxType);
    }


}

File 2 of 20 : DGFamilyCollection.sol
//SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.9;

import "openzeppelin-solidity/contracts/utils/math/SafeMath.sol";
import "openzeppelin-solidity/contracts/access/Ownable.sol";
import "openzeppelin-solidity/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "openzeppelin-solidity/contracts/utils/Strings.sol";
import "../biconomy/EIP712MetaTransaction.sol";

/**
 * DGFamily Collection
 * https://drops.unxd.com/dgfamily
 */
contract DGFamilyCollection is
    ERC721URIStorage,
    Ownable,
    EIP712MetaTransaction
{
    using Strings for uint256;
    using SafeMath for uint256;

    string private baseURI;
    uint256 public constant MAX_PUBLIC_SUPPLY = 5000;
    uint256 public totalSupply;
    uint256 public royaltyPercentage;
    address public glassBoxContract;
    address public privateSaleContract;
    mapping(uint256 => bool) public privateSaleTokenIds;

    /*********************************
     *  EVENTS
     *********************************/
    event RoyaltyPercentageChanged(uint256 indexed newPercentage);
    event BaseUriUpdated(string indexed uri);

    /** @notice Initiator
     * @param tokenName The name of the NFT token
     * @param tokenSymbol The symbol of the NFT tokens
     * @param _baseUri The tokenURI base string
     * @param _royaltyPercentage Percentage of royalty to be taken per sale
     * @param _privateSaleTokenIds List of tokensIds to used in private sale
     */

    constructor(
        string memory tokenName,
        string memory tokenSymbol,
        string memory _baseUri,
        uint256 _royaltyPercentage,
        uint256[] memory _privateSaleTokenIds
    )
        ERC721(tokenName, tokenSymbol)
        EIP712MetaTransaction("NftCollectionBatch", "1")
    {
        baseURI = _baseUri;
        royaltyPercentage = _royaltyPercentage;
        for (uint256 i = 0; i < _privateSaleTokenIds.length; i = i.add(1)) {
            privateSaleTokenIds[_privateSaleTokenIds[i]] = true;
        }
    }

    modifier onlyGlassBoxOrOwnerOrPrivateSale() {
        require(
            glassBoxContract == msgSender() || owner() == msgSender() || privateSaleContract == msgSender(),
            "UNAUTHORIZED_ACCESS"
        );
        _;
    }

    /** @notice Set baseURI for metafile root path
     *  @dev Emits "BaseUriUpdates"
     * @param uri The new uri for tokenURI bsae
     */
    function setBaseURI(string memory uri) external onlyOwner {
        baseURI = uri;
        emit BaseUriUpdated(baseURI);
    }

    /** @notice Sets royalty percentage for secondary sale
     * @dev Emits "RoyaltyPercentageChanged"
     * @param _percentage The percentage of royalty to be deducted
     */
    function setRoyaltyPercentage(uint256 _percentage) external onlyOwner {
        royaltyPercentage = _percentage;

        emit RoyaltyPercentageChanged(royaltyPercentage);
    }

    /**
     * Mint the NFT.
     * @param destination wallet address
     * @return tokenId of newly minted nft.
     */
    function generate(address destination, uint256 tokenIndex)
        external
        onlyGlassBoxOrOwnerOrPrivateSale
        returns (uint256)
    {
        require(destination != address(0), "ADDRESS_CAN_NOT_BE_ZERO");
        require(
            totalSupply < MAX_PUBLIC_SUPPLY,
            "MAX_PUBLIC_SUPPLY_REACHED"
        );
        if ((privateSaleContract == msgSender()) || (owner() == msgSender())) {
            require(
                privateSaleTokenIds[tokenIndex],
                "PRIVATE_SALE_PERMISSION_DENIED"
            );
        }
        totalSupply = totalSupply.add(1);
        _safeMint(destination, tokenIndex);
        return tokenIndex;
    }

    /**
     * Get royalty amount at any specific price.
     * @param _price: price for sale.
     */
    function getRoyaltyInfo(uint256 _price)
        external
        view
        returns (uint256 royaltyAmount, address royaltyReceiver)
    {
        require(_price > 0, "PRICE_CAN_NOT_BE_ZERO");
        uint256 royalty = (_price.mul(royaltyPercentage)).div(100);

        return (royalty, owner());
    }

    /**
     * Set the glass box contract address which will be calling the generate NFT method.
     * @param _address: glass box contract address.
     */
    function setGlassBoxContract(address _address) external onlyOwner {
        glassBoxContract = _address;
    }

    /**
     * Set the private sale contract address which will be calling the generate NFT method.
     * @param _address: contract address.
     */
    function setPrivateSaleContract(address _address) external onlyOwner {
        privateSaleContract = _address;
    }

    /** @notice Provides token URI of the NFT
     * @param _tokenId The id of the specific NFT
     * @return The URI string for the token's metadata file
     */
    function tokenURI(uint256 _tokenId)
        public
        view
        override(ERC721URIStorage)
        returns (string memory)
    {
        if (totalSupply == 0) {
            return _baseURI();
        }
        require(_exists(_tokenId), "TOKEN_DOES_NOT_EXIST");

        /// @dev Convert string to bytes so we can check if it's empty or not.
        return string(abi.encodePacked(_baseURI(), _tokenId.toString()));
    }

    /**
     * @dev See {IERC721-transferFrom}.
     * @notice Only Trusted Marketplace contract can use
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        require(
            _isApprovedOrOwner(msgSender(), tokenId),
            "CALLER_NOT_APPROVED"
        );

        _transfer(from, to, tokenId);
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     * @notice Only Trusted Marketplace contract can use
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) public virtual override {
        require(
            _isApprovedOrOwner(msgSender(), tokenId),
            "CALLER_NOT_APPROVED"
        );
        _safeTransfer(from, to, tokenId, _data);
    }

    /// @dev Overridden function to prevent Owner from relinquishing Ownership by accident
    function renounceOwnership() public view override onlyOwner {
        revert("CAN_NOT_RENOUNCE_OWNERSHIP");
    }

    /**@dev Returns baseURI
     */

    function approve(address to, uint256 tokenId) public virtual override {
        address tokenOwner = ERC721.ownerOf(tokenId);
        require(to != tokenOwner, "ERC721:APPROVAL_TO_CURRENT_OWNER");

        require(
            msgSender() == tokenOwner ||
                isApprovedForAll(tokenOwner, msgSender()),
            "ERC721:APPROVE_CALLER_NOT_OWNER_OR_APPROVED_FOR_ALL"
        );

        _approve(to, tokenId);
    }

    /**
     * Get base URI for collection.
     */
    function _baseURI() internal view virtual override returns (string memory) {
        return baseURI;
    }
}

File 3 of 20 : EIP712MetaTransaction.sol
//SPDX-License-Identifier: MIT
pragma solidity 0.8.9;

import "./EIP712Base.sol";
import "openzeppelin-solidity/contracts/utils/math/SafeMath.sol";

contract EIP712MetaTransaction 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) private 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;
    }

    constructor(string memory name, string memory version)
        EIP712Base(name, version)
    {}

    function convertBytesToBytes4(bytes memory inBytes)
        internal
        pure
        returns (bytes4 outBytes4)
    {
        if (inBytes.length == 0) {
            return 0x0;
        }

        assembly {
            outBytes4 := mload(add(inBytes, 32))
        }
    }

    function executeMetaTransaction(
        address userAddress,
        bytes memory functionSignature,
        bytes32 sigR,
        bytes32 sigS,
        uint8 sigV
    ) public payable returns (bytes memory) {
        bytes4 destinationFunctionSig = convertBytesToBytes4(functionSignature);
        require(
            destinationFunctionSig != msg.sig,
            "functionSignature can not be of executeMetaTransaction method"
        );
        MetaTransaction memory metaTx = MetaTransaction({
            nonce: nonces[userAddress],
            from: userAddress,
            functionSignature: functionSignature
        });
        require(
            verify(userAddress, metaTx, sigR, sigS, sigV),
            "Signer and signature do not match"
        );
        nonces[userAddress] = nonces[userAddress].add(1);
        // Append userAddress at the end to extract it from calling context
        (bool success, bytes memory returnData) = address(this).call(
            abi.encodePacked(functionSignature, userAddress)
        );

        require(success, string(returnData));
        emit MetaTransactionExecuted(
            userAddress,
            payable(msg.sender),
            functionSignature
        );
        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) external view returns (uint256 nonce) {
        nonce = nonces[user];
    }

    function verify(
        address user,
        MetaTransaction memory metaTx,
        bytes32 sigR,
        bytes32 sigS,
        uint8 sigV
    ) internal view returns (bool) {
        address signer = ecrecover(
            toTypedMessageHash(hashMetaTransaction(metaTx)),
            sigV,
            sigR,
            sigS
        );
        require(signer != address(0), "Invalid signature");
        return signer == user;
    }

    function msgSender() internal view returns (address 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 = msg.sender;
        }
        return sender;
    }
}

File 4 of 20 : EIP712Base.sol
//SPDX-License-Identifier: MIT
pragma solidity 0.8.9;

contract EIP712Base {
    struct EIP712Domain {
        string name;
        string version;
        address verifyingContract;
        bytes32 salt;
    }

    bytes32 internal constant EIP712_DOMAIN_TYPEHASH =
        keccak256(
            bytes(
                "EIP712Domain(string name,string version,address verifyingContract,bytes32 salt)"
            )
        );

    bytes32 internal domainSeparator;

    constructor(string memory name, string memory version) {
        domainSeparator = keccak256(
            abi.encode(
                EIP712_DOMAIN_TYPEHASH,
                keccak256(bytes(name)),
                keccak256(bytes(version)),
                address(this),
                bytes32(getChainID())
            )
        );
    }

    function getChainID() internal view returns (uint256 id) {
        assembly {
            id := chainid()
        }
    }

    function getDomainSeparator() private view returns (bytes32) {
        return domainSeparator;
    }

    /**
     * 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", getDomainSeparator(), messageHash)
            );
    }
}

File 5 of 20 : SafeMath.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (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 substraction 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;
        }
    }
}

File 6 of 20 : IERC165.sol
// 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);
}

File 7 of 20 : ERC165.sol
// 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;
    }
}

File 8 of 20 : Strings.sol
// 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);
    }
}

File 9 of 20 : Context.sol
// 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;
    }
}

File 10 of 20 : Address.sol
// 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);
            }
        }
    }
}

File 11 of 20 : IERC721Metadata.sol
// 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);
}

File 12 of 20 : ERC721URIStorage.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721URIStorage.sol)

pragma solidity ^0.8.0;

import "../ERC721.sol";

/**
 * @dev ERC721 token with storage based token URI management.
 */
abstract contract ERC721URIStorage is ERC721 {
    using Strings for uint256;

    // Optional mapping for token URIs
    mapping(uint256 => string) private _tokenURIs;

    /**
     * @dev See {IERC721Metadata-tokenURI}.
     */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        require(_exists(tokenId), "ERC721URIStorage: URI query for nonexistent token");

        string memory _tokenURI = _tokenURIs[tokenId];
        string memory base = _baseURI();

        // If there is no base URI, return the token URI.
        if (bytes(base).length == 0) {
            return _tokenURI;
        }
        // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).
        if (bytes(_tokenURI).length > 0) {
            return string(abi.encodePacked(base, _tokenURI));
        }

        return super.tokenURI(tokenId);
    }

    /**
     * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {
        require(_exists(tokenId), "ERC721URIStorage: URI set of nonexistent token");
        _tokenURIs[tokenId] = _tokenURI;
    }

    /**
     * @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 override {
        super._burn(tokenId);

        if (bytes(_tokenURIs[tokenId]).length != 0) {
            delete _tokenURIs[tokenId];
        }
    }
}

File 13 of 20 : IERC721Receiver.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (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 `IERC721.onERC721Received.selector`.
     */
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}

File 14 of 20 : IERC721.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (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`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    /**
     * @dev Transfers `tokenId` token from `from` to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    /**
     * @dev Gives permission to `to` to transfer `tokenId` token to another account.
     * The approval is cleared when the token is transferred.
     *
     * Only a single account can be approved at a time, so approving the zero address clears previous approvals.
     *
     * Requirements:
     *
     * - The caller must own the token or be an approved operator.
     * - `tokenId` must exist.
     *
     * Emits an {Approval} event.
     */
    function approve(address to, uint256 tokenId) external;

    /**
     * @dev Returns the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) external view returns (address operator);

    /**
     * @dev Approve or remove `operator` as an operator for the caller.
     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
     *
     * Requirements:
     *
     * - The `operator` cannot be the caller.
     *
     * Emits an {ApprovalForAll} event.
     */
    function setApprovalForAll(address operator, bool _approved) external;

    /**
     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
     *
     * See {setApprovalForAll}
     */
    function isApprovedForAll(address owner, address operator) external view returns (bool);

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes calldata data
    ) external;
}

File 15 of 20 : ERC721.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.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 overriden in child contracts.
     */
    function _baseURI() internal view virtual returns (string memory) {
        return "";
    }

    /**
     * @dev See {IERC721-approve}.
     */
    function approve(address to, uint256 tokenId) public virtual override {
        address owner = ERC721.ownerOf(tokenId);
        require(to != owner, "ERC721: approval to current owner");

        require(
            _msgSender() == owner || isApprovedForAll(owner, _msgSender()),
            "ERC721: approve caller is not owner nor approved for all"
        );

        _approve(to, tokenId);
    }

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId) public view virtual override returns (address) {
        require(_exists(tokenId), "ERC721: approved query for nonexistent token");

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        _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 || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));
    }

    /**
     * @dev Safely mints `tokenId` and transfers it to `to`.
     *
     * Requirements:
     *
     * - `tokenId` must not exist.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeMint(address to, uint256 tokenId) internal virtual {
        _safeMint(to, tokenId, "");
    }

    /**
     * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is
     * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
     */
    function _safeMint(
        address to,
        uint256 tokenId,
        bytes memory _data
    ) internal virtual {
        _mint(to, tokenId);
        require(
            _checkOnERC721Received(address(0), to, tokenId, _data),
            "ERC721: transfer to non ERC721Receiver implementer"
        );
    }

    /**
     * @dev Mints `tokenId` and transfers it to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible
     *
     * Requirements:
     *
     * - `tokenId` must not exist.
     * - `to` cannot be the zero address.
     *
     * Emits a {Transfer} event.
     */
    function _mint(address to, uint256 tokenId) internal virtual {
        require(to != address(0), "ERC721: mint to the zero address");
        require(!_exists(tokenId), "ERC721: token already minted");

        _beforeTokenTransfer(address(0), to, tokenId);

        _balances[to] += 1;
        _owners[tokenId] = to;

        emit Transfer(address(0), to, tokenId);

        _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 {}
}

File 16 of 20 : ReentrancyGuard.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

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

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;

        _;

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

File 17 of 20 : Ownable.sol
// 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);
    }
}

File 18 of 20 : VRFCoordinatorV2Interface.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface VRFCoordinatorV2Interface {
  /**
   * @notice Get configuration relevant for making requests
   * @return minimumRequestConfirmations global min for request confirmations
   * @return maxGasLimit global max for request gas limit
   * @return s_provingKeyHashes list of registered key hashes
   */
  function getRequestConfig()
    external
    view
    returns (
      uint16,
      uint32,
      bytes32[] memory
    );

  /**
   * @notice Request a set of random words.
   * @param keyHash - Corresponds to a particular oracle job which uses
   * that key for generating the VRF proof. Different keyHash's have different gas price
   * ceilings, so you can select a specific one to bound your maximum per request cost.
   * @param subId  - The ID of the VRF subscription. Must be funded
   * with the minimum subscription balance required for the selected keyHash.
   * @param minimumRequestConfirmations - How many blocks you'd like the
   * oracle to wait before responding to the request. See SECURITY CONSIDERATIONS
   * for why you may want to request more. The acceptable range is
   * [minimumRequestBlockConfirmations, 200].
   * @param callbackGasLimit - How much gas you'd like to receive in your
   * fulfillRandomWords callback. Note that gasleft() inside fulfillRandomWords
   * may be slightly less than this amount because of gas used calling the function
   * (argument decoding etc.), so you may need to request slightly more than you expect
   * to have inside fulfillRandomWords. The acceptable range is
   * [0, maxGasLimit]
   * @param numWords - The number of uint256 random values you'd like to receive
   * in your fulfillRandomWords callback. Note these numbers are expanded in a
   * secure way by the VRFCoordinator from a single random value supplied by the oracle.
   * @return requestId - A unique identifier of the request. Can be used to match
   * a request to a response in fulfillRandomWords.
   */
  function requestRandomWords(
    bytes32 keyHash,
    uint64 subId,
    uint16 minimumRequestConfirmations,
    uint32 callbackGasLimit,
    uint32 numWords
  ) external returns (uint256 requestId);

  /**
   * @notice Create a VRF subscription.
   * @return subId - A unique subscription id.
   * @dev You can manage the consumer set dynamically with addConsumer/removeConsumer.
   * @dev Note to fund the subscription, use transferAndCall. For example
   * @dev  LINKTOKEN.transferAndCall(
   * @dev    address(COORDINATOR),
   * @dev    amount,
   * @dev    abi.encode(subId));
   */
  function createSubscription() external returns (uint64 subId);

  /**
   * @notice Get a VRF subscription.
   * @param subId - ID of the subscription
   * @return balance - LINK balance of the subscription in juels.
   * @return reqCount - number of requests for this subscription, determines fee tier.
   * @return owner - owner of the subscription.
   * @return consumers - list of consumer address which are able to use this subscription.
   */
  function getSubscription(uint64 subId)
    external
    view
    returns (
      uint96 balance,
      uint64 reqCount,
      address owner,
      address[] memory consumers
    );

  /**
   * @notice Request subscription owner transfer.
   * @param subId - ID of the subscription
   * @param newOwner - proposed new owner of the subscription
   */
  function requestSubscriptionOwnerTransfer(uint64 subId, address newOwner) external;

  /**
   * @notice Request subscription owner transfer.
   * @param subId - ID of the subscription
   * @dev will revert if original owner of subId has
   * not requested that msg.sender become the new owner.
   */
  function acceptSubscriptionOwnerTransfer(uint64 subId) external;

  /**
   * @notice Add a consumer to a VRF subscription.
   * @param subId - ID of the subscription
   * @param consumer - New consumer which can use the subscription
   */
  function addConsumer(uint64 subId, address consumer) external;

  /**
   * @notice Remove a consumer from a VRF subscription.
   * @param subId - ID of the subscription
   * @param consumer - Consumer to remove from the subscription
   */
  function removeConsumer(uint64 subId, address consumer) external;

  /**
   * @notice Cancel a subscription
   * @param subId - ID of the subscription
   * @param to - Where to send the remaining LINK to
   */
  function cancelSubscription(uint64 subId, address to) external;
}

File 19 of 20 : LinkTokenInterface.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface LinkTokenInterface {
  function allowance(address owner, address spender) external view returns (uint256 remaining);

  function approve(address spender, uint256 value) external returns (bool success);

  function balanceOf(address owner) external view returns (uint256 balance);

  function decimals() external view returns (uint8 decimalPlaces);

  function decreaseApproval(address spender, uint256 addedValue) external returns (bool success);

  function increaseApproval(address spender, uint256 subtractedValue) external;

  function name() external view returns (string memory tokenName);

  function symbol() external view returns (string memory tokenSymbol);

  function totalSupply() external view returns (uint256 totalTokensIssued);

  function transfer(address to, uint256 value) external returns (bool success);

  function transferAndCall(
    address to,
    uint256 value,
    bytes calldata data
  ) external returns (bool success);

  function transferFrom(
    address from,
    address to,
    uint256 value
  ) external returns (bool success);
}

File 20 of 20 : VRFConsumerBaseV2.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

/** ****************************************************************************
 * @notice Interface for contracts using VRF randomness
 * *****************************************************************************
 * @dev PURPOSE
 *
 * @dev Reggie the Random Oracle (not his real job) wants to provide randomness
 * @dev to Vera the verifier in such a way that Vera can be sure he's not
 * @dev making his output up to suit himself. Reggie provides Vera a public key
 * @dev to which he knows the secret key. Each time Vera provides a seed to
 * @dev Reggie, he gives back a value which is computed completely
 * @dev deterministically from the seed and the secret key.
 *
 * @dev Reggie provides a proof by which Vera can verify that the output was
 * @dev correctly computed once Reggie tells it to her, but without that proof,
 * @dev the output is indistinguishable to her from a uniform random sample
 * @dev from the output space.
 *
 * @dev The purpose of this contract is to make it easy for unrelated contracts
 * @dev to talk to Vera the verifier about the work Reggie is doing, to provide
 * @dev simple access to a verifiable source of randomness. It ensures 2 things:
 * @dev 1. The fulfillment came from the VRFCoordinator
 * @dev 2. The consumer contract implements fulfillRandomWords.
 * *****************************************************************************
 * @dev USAGE
 *
 * @dev Calling contracts must inherit from VRFConsumerBase, and can
 * @dev initialize VRFConsumerBase's attributes in their constructor as
 * @dev shown:
 *
 * @dev   contract VRFConsumer {
 * @dev     constructor(<other arguments>, address _vrfCoordinator, address _link)
 * @dev       VRFConsumerBase(_vrfCoordinator) public {
 * @dev         <initialization with other arguments goes here>
 * @dev       }
 * @dev   }
 *
 * @dev The oracle will have given you an ID for the VRF keypair they have
 * @dev committed to (let's call it keyHash). Create subscription, fund it
 * @dev and your consumer contract as a consumer of it (see VRFCoordinatorInterface
 * @dev subscription management functions).
 * @dev Call requestRandomWords(keyHash, subId, minimumRequestConfirmations,
 * @dev callbackGasLimit, numWords),
 * @dev see (VRFCoordinatorInterface for a description of the arguments).
 *
 * @dev Once the VRFCoordinator has received and validated the oracle's response
 * @dev to your request, it will call your contract's fulfillRandomWords method.
 *
 * @dev The randomness argument to fulfillRandomWords is a set of random words
 * @dev generated from your requestId and the blockHash of the request.
 *
 * @dev If your contract could have concurrent requests open, you can use the
 * @dev requestId returned from requestRandomWords to track which response is associated
 * @dev with which randomness request.
 * @dev See "SECURITY CONSIDERATIONS" for principles to keep in mind,
 * @dev if your contract could have multiple requests in flight simultaneously.
 *
 * @dev Colliding `requestId`s are cryptographically impossible as long as seeds
 * @dev differ.
 *
 * *****************************************************************************
 * @dev SECURITY CONSIDERATIONS
 *
 * @dev A method with the ability to call your fulfillRandomness method directly
 * @dev could spoof a VRF response with any random value, so it's critical that
 * @dev it cannot be directly called by anything other than this base contract
 * @dev (specifically, by the VRFConsumerBase.rawFulfillRandomness method).
 *
 * @dev For your users to trust that your contract's random behavior is free
 * @dev from malicious interference, it's best if you can write it so that all
 * @dev behaviors implied by a VRF response are executed *during* your
 * @dev fulfillRandomness method. If your contract must store the response (or
 * @dev anything derived from it) and use it later, you must ensure that any
 * @dev user-significant behavior which depends on that stored value cannot be
 * @dev manipulated by a subsequent VRF request.
 *
 * @dev Similarly, both miners and the VRF oracle itself have some influence
 * @dev over the order in which VRF responses appear on the blockchain, so if
 * @dev your contract could have multiple VRF requests in flight simultaneously,
 * @dev you must ensure that the order in which the VRF responses arrive cannot
 * @dev be used to manipulate your contract's user-significant behavior.
 *
 * @dev Since the block hash of the block which contains the requestRandomness
 * @dev call is mixed into the input to the VRF *last*, a sufficiently powerful
 * @dev miner could, in principle, fork the blockchain to evict the block
 * @dev containing the request, forcing the request to be included in a
 * @dev different block with a different hash, and therefore a different input
 * @dev to the VRF. However, such an attack would incur a substantial economic
 * @dev cost. This cost scales with the number of blocks the VRF oracle waits
 * @dev until it calls responds to a request. It is for this reason that
 * @dev that you can signal to an oracle you'd like them to wait longer before
 * @dev responding to the request (however this is not enforced in the contract
 * @dev and so remains effective only in the case of unmodified oracle software).
 */
abstract contract VRFConsumerBaseV2 {
  error OnlyCoordinatorCanFulfill(address have, address want);
  address private immutable vrfCoordinator;

  /**
   * @param _vrfCoordinator address of VRFCoordinator contract
   */
  constructor(address _vrfCoordinator) {
    vrfCoordinator = _vrfCoordinator;
  }

  /**
   * @notice fulfillRandomness handles the VRF response. Your contract must
   * @notice implement it. See "SECURITY CONSIDERATIONS" above for important
   * @notice principles to keep in mind when implementing your fulfillRandomness
   * @notice method.
   *
   * @dev VRFConsumerBaseV2 expects its subcontracts to have a method with this
   * @dev signature, and will call it once it has verified the proof
   * @dev associated with the randomness. (It is triggered via a call to
   * @dev rawFulfillRandomness, below.)
   *
   * @param requestId The Id initially returned by requestRandomness
   * @param randomWords the VRF output expanded to the requested number of words
   */
  function fulfillRandomWords(uint256 requestId, uint256[] memory randomWords) internal virtual;

  // rawFulfillRandomness is called by VRFCoordinator when it receives a valid VRF
  // proof. rawFulfillRandomness then calls fulfillRandomness, after validating
  // the origin of the call
  function rawFulfillRandomWords(uint256 requestId, uint256[] memory randomWords) external {
    if (msg.sender != vrfCoordinator) {
      revert OnlyCoordinatorCanFulfill(msg.sender, vrfCoordinator);
    }
    fulfillRandomWords(requestId, randomWords);
  }
}

Settings
{
  "remappings": [],
  "optimizer": {
    "enabled": false,
    "runs": 200
  },
  "evmVersion": "london",
  "libraries": {},
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"string","name":"_tokenName","type":"string"},{"internalType":"string","name":"_tokenSymbol","type":"string"},{"internalType":"string","name":"_baseURI1","type":"string"},{"internalType":"uint256","name":"_royaltyPercentage","type":"uint256"},{"internalType":"address","name":"_dgFamilyContractAddress","type":"address"},{"internalType":"uint64","name":"_subscriptionId","type":"uint64"},{"internalType":"address","name":"_vrfCoordinator","type":"address"},{"internalType":"address","name":"_link","type":"address"},{"internalType":"bytes32","name":"_keyHash","type":"bytes32"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"have","type":"address"},{"internalType":"address","name":"want","type":"address"}],"name":"OnlyCoordinatorCanFulfill","type":"error"},{"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":true,"internalType":"string","name":"uri","type":"string"}],"name":"BaseUriUpdated","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":false,"internalType":"uint256","name":"glassBoxTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"dgTokenId","type":"uint256"},{"indexed":false,"internalType":"enum DGFamilyGlassBox.BoxType","name":"boxType","type":"uint8"}],"name":"Revealed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"newPercentage","type":"uint256"}],"name":"RoyaltyPercentageChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"someAddress","type":"address"},{"indexed":false,"internalType":"bool","name":"enabled","type":"bool"}],"name":"SystemAddressUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"MAX_PUBLIC_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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":[{"internalType":"uint8","name":"","type":"uint8"}],"name":"boxTypeMapping","outputs":[{"internalType":"enum DGFamilyGlassBox.BoxType","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"checkIfRevealed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dgFamilyContractAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","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":"numberOfTokens","type":"uint256"},{"internalType":"address","name":"destination","type":"address"}],"name":"generate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getNonce","outputs":[{"internalType":"uint256","name":"nonce","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_price","type":"uint256"}],"name":"getRoyaltyInfo","outputs":[{"internalType":"uint256","name":"royaltyAmount","type":"uint256"},{"internalType":"address","name":"royaltyReceiver","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"link","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"requestId","type":"uint256"},{"internalType":"uint256[]","name":"randomWords","type":"uint256[]"}],"name":"rawFulfillRandomWords","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"revealBox","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"revealPhaseStarted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"revealedResults","outputs":[{"internalType":"enum DGFamilyGlassBox.BoxType","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"revealedTokens","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"royaltyPercentage","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":"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":"uint256","name":"","type":"uint256"}],"name":"seed","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"uri","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_percentage","type":"uint256"}],"name":"setRoyaltyPercentage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"someAddress","type":"address"},{"internalType":"bool","name":"enabled","type":"bool"}],"name":"setSystem","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_primeNumber","type":"uint16"}],"name":"startRevealPhase","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"subscriptionId","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","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":"address","name":"","type":"address"}],"name":"systems","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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"},{"inputs":[],"name":"vrfCoordinator","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]

60a060405260405180620268e001604052806107be61ffff1681526020016102e361ffff16815260200161014961ffff1681526020016109ca61ffff1681526020016111ac61ffff16815260200161126061ffff1681526020016112ce61ffff168152602001610f3361ffff168152602001610a2a61ffff1681526020016109ba61ffff168152602001610c5561ffff16815260200161131561ffff168152602001610b7561ffff16815260200161137061ffff16815260200161043961ffff16815260200161024561ffff168152602001610e6961ffff168152602001610f2c61ffff168152602001610dd761ffff168152602001610f0261ffff16815260200161102e61ffff1681526020016101cb61ffff16815260200161052661ffff16815260200161046761ffff1681526020016105b561ffff16815260200161122a61ffff16815260200161054761ffff16815260200161045461ffff16815260200161030961ffff16815260200161101261ffff16815260200161113b61ffff1681526020016105fa61ffff1681526020016104dc61ffff16815260200161111861ffff16815260200161096e61ffff168152602001610feb61ffff1681526020016108ee61ffff16815260200161094c61ffff168152602001610f8461ffff16815260200161097461ffff1681526020016110da61ffff168152602001610ef061ffff168152602001610d6661ffff1681526020016110d461ffff1681526020016101eb61ffff168152602001610d7c61ffff1681526020016101b861ffff1681526020016105fc61ffff1681526020016107d061ffff1681526020016107d461ffff16815260200161035861ffff16815260200161071461ffff168152602001610f7f61ffff168152602001610dcd61ffff1681526020016107fd61ffff1681526020016104b361ffff168152602001610cbc61ffff1681526020016106ea61ffff16815260200161075161ffff16815260200161011561ffff16815260200161052261ffff1681526020016109c661ffff16815260200161027a61ffff168152602001610f7161ffff1681526020016109a161ffff1681526020016109a761ffff168152602001610e3361ffff168152602001610fa361ffff1681526020016106e861ffff168152602001610e4961ffff16815260200161126961ffff1681526020016109a061ffff168152602001610f9a61ffff168152602001610b1361ffff16815260200161049d61ffff168152602001610d3b61ffff1681526020016111a361ffff1681526020016103fe61ffff1681526020016102d361ffff16815260200161086061ffff168152602001610a6d61ffff1681526020016110e961ffff16815260200161026361ffff16815260200161108261ffff16815260200161060f61ffff168152602001610ce461ffff16815260200161135f61ffff168152602001610c2161ffff16815260200161014561ffff168152602001610df061ffff168152602001610e4261ffff1681526020016112b861ffff168152602001610d4861ffff16815260200161068861ffff1681526020016110c561ffff16815260200161112361ffff1681526020016111ef61ffff168152602001610f6761ffff16815260200161078261ffff168152602001610a4861ffff16815260200161094f61ffff1681526020016104bc61ffff16815260200161106461ffff16815260200161092061ffff168152602001608961ffff16815260200161050461ffff168152602001610b9c61ffff1681526020016108f661ffff168152602001610b6e61ffff1681526020016101a361ffff16815260200161038461ffff168152602001610da261ffff168152602001610a8e61ffff1681526020016108a561ffff1681526020016111c661ffff16815260200161107261ffff16815260200161105861ffff16815260200161069f61ffff168152602001610bd461ffff16815260200161077961ffff168152602001610f4561ffff16815260200161107b61ffff16815260200161041f61ffff16815260200161092f61ffff16815260200161078361ffff168152602001610db861ffff168152602001610cb461ffff1681526020016103c161ffff1681526020016111e561ffff16815260200161032261ffff16815260200161092261ffff168152602001610c4961ffff168152602001610f1761ffff168152602001610a7a61ffff168152602001610e5f61ffff1681526020016104c961ffff16815260200161050061ffff168152602001610a5961ffff16815260200161053261ffff16815260200161081061ffff168152602001610b5e61ffff16815260200161113f61ffff1681526020016111e161ffff168152602001610f4c61ffff168152602001610fc261ffff168152602001610d0861ffff1681526020016106a261ffff1681526020016111de61ffff168152602001610ddb61ffff168152602001610a6061ffff168152602001610cb661ffff168152602001610bb861ffff16815260200161116161ffff16815260200161112d61ffff168152602001610fcf61ffff16815260200161073b61ffff1681526020016101e461ffff1681526020016109cf61ffff1681526020016106b361ffff16815260200161055a61ffff16815260200161058b61ffff16815260200161101b61ffff1681526020016103c061ffff1681526020016106b061ffff1681526020016109bd61ffff168152602001610f1d61ffff1681526020016108a661ffff16815260200161063261ffff16815260200161046561ffff168152602001610edf61ffff16815260200161044461ffff1681526020016110b461ffff16815260200161084361ffff168152602001610add61ffff16815260200161091f61ffff168152602001610ed561ffff168152602001610e2b61ffff16815260200160a561ffff168152602001610ba361ffff1681526020016105fd61ffff16815260200161100e61ffff168152602001610f1261ffff16815260200161110c61ffff168152602001610af561ffff16815260200161122c61ffff16815260200161103161ffff16815260200161131361ffff1681526020016112ff61ffff1681526020016103bf61ffff1681526020016112cf61ffff16815260200161086761ffff1681526020016109d561ffff16815260200161101361ffff168152602001610f0361ffff16815260200161055061ffff168152602001610f9461ffff16815260200161135061ffff1681526020016101cf61ffff168152602001610bdc61ffff16815260200161065361ffff168152602001610fdc61ffff16815260200161027261ffff1681526020016108cc61ffff168152602001610a9261ffff168152602001610b2761ffff16815260200161105761ffff1681526020016109f761ffff16815260200161055361ffff168152602001610cd761ffff168152602001610eb261ffff16815260200161086a61ffff16815260200161043661ffff1681526020016112d061ffff168152602001610c5861ffff168152602001610fa561ffff1681526020016110d261ffff16815260200161068061ffff1681526020016102a761ffff168152602001610b8a61ffff1681526020016108c261ffff168152602001610fa861ffff1681526020016102d561ffff1681526020016107d861ffff168152602001610d7461ffff16815260200161013361ffff168152602001610a2661ffff168152602001610bb761ffff16815260200160ae61ffff168152602001610be361ffff16815260200161128e61ffff16815260200161134e61ffff16815260200161032461ffff1681526020016108db61ffff1681526020016108f561ffff168152602001605361ffff168152602001610e0561ffff1681526020016105dd61ffff16815260200161058461ffff16815260200161042261ffff168152602001610e1561ffff16815260200161042c61ffff168152602001610ee861ffff168152602001610f1361ffff168152602001610f3c61ffff168152602001610a4a61ffff16815260200161021661ffff16815260200161123761ffff1681526020016102fa61ffff1681526020016104ed61ffff168152602001610c3b61ffff168152602001610ff461ffff16815260200161081361ffff16815260200161138361ffff1681526020016108f861ffff16815260200161036e61ffff168152602001610cc861ffff16815260200161093c61ffff1681526020016111e761ffff16815260200161070061ffff1681526020016109d261ffff16815260200161038261ffff168152602001605161ffff168152602001610ced61ffff16815260200161037161ffff16815260200161070e61ffff16815260200161046b61ffff16815260200161077561ffff168152602001610ccd61ffff168152602001608a61ffff1681526020016106eb61ffff16815260200161020961ffff168152602001610bce61ffff16815260200160cb61ffff16815260200161135d61ffff16815260200161127b61ffff1681526020016105d661ffff16815260200161048761ffff16815260200161113761ffff168152602001610d3561ffff16815260200161018761ffff16815260200161014761ffff1681526020016103ab61ffff16815260200161057061ffff168152602001610b2561ffff16815260200161102861ffff1681526020016106c361ffff168152602001608661ffff16815260200161053561ffff1681526020016102c661ffff16815260200160f861ffff168152602001610d6c61ffff1681526020016110fd61ffff16815260200161105561ffff168152602001610e7261ffff1681526020016105f061ffff16815260200161096c61ffff168152602001610cba61ffff1681526020016105b261ffff168152602001610d6161ffff16815260200161023361ffff16815260200161021e61ffff16815260200161050561ffff1681526020016105c661ffff16815260200161058061ffff168152602001610ede61ffff168152602001610ecb61ffff1681526020016109de61ffff16815260200161115f61ffff168152602001610e8961ffff1681526020016111d061ffff168152602001610f9761ffff16815260200161065861ffff168152602001610bfb61ffff16815260200161073161ffff168152602001610b7061ffff16815260200161051261ffff16815260200161016861ffff16815260200161042461ffff16815260200161026761ffff168152602001610d2b61ffff1681526020016103cf61ffff168152602001603061ffff16815260200161039c61ffff1681526020016112df61ffff16815260200161063661ffff168152602001610e3b61ffff16815260200161124a61ffff168152602001610cfa61ffff16815260200161132e61ffff16815260200161135961ffff168152602001610ed961ffff168152602001610f2161ffff168152602001610e9161ffff16815260200161036261ffff1681526020016103cd61ffff16815260200161024661ffff16815260200161050261ffff1681526020016111fa61ffff16815260200161060861ffff168152602001610e6e61ffff168152602001610b2f61ffff168152602001610abe61ffff1681526020016103ad61ffff16815260200161062b61ffff16815260200161073761ffff16815260200161024961ffff16815260200161072161ffff1681526020016104a861ffff16815260200161048361ffff168152602001610fd961ffff16815260200161056f61ffff168152602001610db061ffff168152602001610aea61ffff16815260200161016a61ffff16815260200161110d61ffff168152602001610bb361ffff1681526020016111bd61ffff16815260200161066f61ffff16815260200161059d61ffff16815260200161096d61ffff1681526020016106f961ffff168152602001610c4261ffff16815260200161062861ffff1681526020016109e261ffff168152602001610da361ffff16815260200160f061ffff16815260200161097661ffff168152602001610b1861ffff168152602001610c5361ffff16815260200161090661ffff16815260200161125261ffff1681526020016101e361ffff1681526020016104a261ffff16815260200161138561ffff16815260200161071c61ffff16815260200161059a61ffff168152602001610ea161ffff1681526020016101fe61ffff16815260200161051c61ffff1681526020016104b661ffff168152602001606161ffff1681526020016105a561ffff1681526020016108af61ffff1681526020016107e761ffff16815260200161122561ffff1681526020016103db61ffff168152602001610b2961ffff16815260200161067961ffff16815260200161088561ffff16815260200161111b61ffff16815260200161102a61ffff1681526020016110b561ffff1681526020016101af61ffff16815260200161119961ffff168152602001610d9e61ffff168152602001610b0061ffff168152602001610abd61ffff168152602001610d5d61ffff168152602001610d6b61ffff16815260200161027661ffff1681526020016106a961ffff168152602001610bff61ffff16815260200161051361ffff168152602001610fe261ffff1681526020016103d561ffff1681526020016109a461ffff168152602001610ba161ffff1681526020016104e661ffff1681526020016104cc61ffff16815260200161106761ffff1681526020016104d161ffff168152602001610a8761ffff16815260200161119f61ffff168152602001610b1461ffff16815260200161127961ffff168152602001610c3c61ffff1681526020016110cb61ffff16815260200161022361ffff168152602001610db361ffff168152602001610c0561ffff16815260200160c561ffff16815260200161096661ffff16815260200161017e61ffff168152602001610cfc61ffff16815260200160fd61ffff16815260200161115361ffff168152602001610b6161ffff168152602001610ba661ffff1681526020016105f361ffff16815260200161041261ffff168152602001606261ffff1681526020016104ff61ffff16815260200161120c61ffff16815260200161108861ffff1681526020016104fe61ffff168152602001610ecc61ffff1681526020016107f961ffff168152602001610e7361ffff16815260200161104b61ffff16815260200161121861ffff168152602001606961ffff16815260200161135861ffff16815260200161083a61ffff168152602001610fcc61ffff16815260200161047d61ffff1681526020016105d461ffff16815260200161055561ffff16815260200161082761ffff168152602001610d7f61ffff1681526020016110ac61ffff168152602001610aaa61ffff168152602001610b3961ffff168152602001610a8661ffff16815260200161061a61ffff16815260200161121a61ffff168152602001610dff61ffff168152602001610aab61ffff1681526020016106f461ffff1681526020016112d661ffff1681526020016106f661ffff16815260200161129661ffff16815260200161053661ffff16815260200161012861ffff168152602001606761ffff1681526020016112a461ffff16815260200160d061ffff16815260200160bd61ffff168152602001610a8361ffff1681526020016101c161ffff168152602001610b3e61ffff1681526020016108ab61ffff1681526020016103e361ffff16815260200161067461ffff1681526020016107f361ffff168152602001607261ffff1681526020016102b861ffff16815260200161012361ffff1681526020016105ad61ffff1681526020016110bb61ffff1681526020016109a561ffff168152602001610ffb61ffff168152602001610e3e61ffff168152602001610a9a61ffff168152602001610a1561ffff16815260200160c261ffff16815260200161134d61ffff1681526020016105de61ffff1681526020016105ca61ffff168152602001610da561ffff168152602001610f5f61ffff1681526020016102f661ffff16815260200161084561ffff1681526020016108fd61ffff1681526020016107c361ffff168152602001610af161ffff168152602001610eaa61ffff16815260200161098061ffff168152602001610cca61ffff1681526020016106e761ffff16815260200161121c61ffff1681526020016108df61ffff16815260200161113061ffff16815260200161090c61ffff168152602001610c5e61ffff168152602001610b5261ffff168152602001605261ffff1681526020016103b461ffff16815260200161092661ffff16815260200161137b61ffff1681526020016112b061ffff168152602001610c0f61ffff16815260200161094061ffff1681526020016109d861ffff168152602001610c7b61ffff16815260200161103361ffff16815260200161066261ffff16815260200161111f61ffff168152602001610c1f61ffff168152602001610ee561ffff16815260200161017661ffff168152602001610c3f61ffff168152602001610e2a61ffff168152602001610f4a61ffff16815260200161134561ffff168152602001610e8a61ffff1681526020016101b461ffff16815260200161136861ffff1681526020016101dc61ffff16815260200160ca61ffff16815260200161098561ffff1681526020016110fa61ffff1681526020016105e661ffff16815260200161052c61ffff16815260200161089361ffff168152602001604761ffff1681526020016101a261ffff168152602001610b4d61ffff16815260200161058261ffff168152602001610bf061ffff16815260200161077161ffff168152602001610a4c61ffff1681526020016111e961ffff16815260200161077d61ffff16815260200161035061ffff168152602001610df361ffff16815260200161105b61ffff1681526020016110c261ffff16815260200161022061ffff1681526020016108ac61ffff168152602001610b5a61ffff16815260200161121f61ffff16815260200161127a61ffff1681526020016103b961ffff16815260200161014161ffff1681526020016111f161ffff1681526020016111f261ffff16815260200160f161ffff16815260200161080161ffff16815260200161044c61ffff1681526020016105f261ffff16815260200161048061ffff168152602001610b7461ffff16815260200161063061ffff1681526020016109fc61ffff168152602001610e8261ffff16815260200161032761ffff16815260200161092861ffff1681526020016106bd61ffff168152602001610ebb61ffff168152602001610c3361ffff1681526020016103a961ffff168152602001603e61ffff16815260200161124b61ffff168152602001610a0761ffff168152602001610ea961ffff1681526020016110e061ffff16815260200161031161ffff1681526020016109e961ffff168152602001610ef461ffff168152602001610d0b61ffff168152602001610bf761ffff16815260200161020161ffff16815260200161031661ffff168152602001610f2b61ffff168152602001610f4f61ffff16815260200161047761ffff1681526020016103b861ffff16815260200161036661ffff168152602001610dde61ffff16815260200161111261ffff1681526020016107e061ffff16815260200161090761ffff16815260200161131961ffff1681526020016109b061ffff1681526020016111fd61ffff168152602001610cc761ffff16815260200161010161ffff168152602001610e9961ffff1681526020016112dd61ffff168152602001610fc461ffff168152602001610bc961ffff16815260200161071e61ffff1681526020016102ab61ffff16815260200161078e61ffff16815260200161089a61ffff168152602001610e2961ffff16815260200161040961ffff16815260200161124961ffff16815260200161067c61ffff16815260200161056b61ffff1681526020016103a061ffff1681526020016108bb61ffff16815260200161097d61ffff168152602001610a5d61ffff16815260200161033961ffff16815260200161101161ffff16815260200161136161ffff168152602001610ebf61ffff168152602001610bb261ffff16815260200161047961ffff1681526020016105d161ffff16815260200161136661ffff16815260200161052f61ffff16815260200161060361ffff16815260200161116061ffff1681526020016112b761ffff168152602001610e7861ffff1681526020016103c861ffff168152602001610a3a61ffff1681526020016112e361ffff168152602001610b8361ffff168152602001610c8b61ffff168152602001610dd861ffff16815260200161112a61ffff168152602001610b0361ffff16815260200161073361ffff1681526020016107ca61ffff16815260200161091661ffff168152602001610a6c61ffff16815260200161127d61ffff16815260200161098c61ffff16815260200161087e61ffff1681526020016105b361ffff16815260200161025b61ffff16815260200161035161ffff1681526020016102f161ffff168152602001610d3661ffff1681526020016108e761ffff168152602001610dec61ffff168152602001610ae561ffff168152602001610bd761ffff16815260200161045a61ffff168152602001604961ffff168152602001610ca161ffff168152602001610e0a61ffff16815260200161115261ffff16815260200160fe61ffff168152602001610c0961ffff168152602001610a7461ffff168152602001610ccc61ffff16815260200161091961ffff168152602001610c6a61ffff168152602001610d9961ffff168152602001610c2361ffff16815260200161129e61ffff168152602001610b2161ffff16815260200161132261ffff168152602001610c5d61ffff168152602001610dce61ffff168152602001608d61ffff168152602001603b61ffff16815260200161014a61ffff168152602001610e7961ffff16815260200161102f61ffff1681526020016109e361ffff1681526020016111cc61ffff16815260200161021f61ffff168152602001610b9f61ffff16815260200161056c61ffff1681526020016107ff61ffff168152602001610adc61ffff1681526020016111ed61ffff16815260200161067261ffff168152602001610ba761ffff168152602001610d0c61ffff16815260200161011b61ffff168152602001610b2e61ffff1681526020016108a861ffff168152602001610c1661ffff168152602001610f0861ffff16815260200161099261ffff168152602001610e4561ffff1681526020016102f961ffff168152602001610c9b61ffff16815260200161049861ffff16815260200161125c61ffff16815260200160c761ffff16815260200161069b61ffff16815260200161045e61ffff16815260200161062e61ffff16815260200161039a61ffff168152602001610eb761ffff16815260200161074061ffff16815260200161032b61ffff16815260200161049e61ffff1681526020016111bf61ffff16815260200161098a61ffff16815260200161128861ffff16815260200161137e61ffff16815260200161133b61ffff1681526020016107cf61ffff16815260200161105e61ffff16815260200161099661ffff16815260200161013461ffff16815260200161097961ffff16815260200161115c61ffff1681526020016112a261ffff1681526020016110d661ffff1681526020016106cb61ffff16815260200161043861ffff16815260200160f561ffff16815260200161027061ffff16815260200161122661ffff1681526020016109ae61ffff1681526020016111d961ffff1681526020016105c061ffff1681526020016109a861ffff168152602001610c9661ffff1681526020016111b261ffff168152602001610b9461ffff168152602001610a4761ffff168152602001610acb61ffff168152602001610cb361ffff16815260200161018561ffff1681526020016108d461ffff16815260200161100661ffff1681526020016109b961ffff168152602001610aca61ffff168152602001610cd961ffff16815260200161059361ffff16815260200161106961ffff1681526020016111bb61ffff16815260200161091161ffff168152602001610bdb61ffff16815260200161112661ffff168152602001610dba61ffff16815260200161135a61ffff1681526020016110a561ffff16815260200161039261ffff168152602001610a3b61ffff168152602001610dd261ffff1681526020016110f661ffff16815260200161051a61ffff168152602001610ab261ffff1681526020016101e561ffff168152602001610df161ffff1681526020016102b561ffff168152602001610ca061ffff168152602001610e6061ffff1681526020016103d861ffff1681526020016110af61ffff168152602001610c4161ffff16815260200161111161ffff16815260200161055c61ffff16815260200161015761ffff16815260200161095061ffff16815260200161011d61ffff168152602001610a2561ffff16815260200161059f61ffff168152602001610c7d61ffff16815260200161115061ffff16815260200161016761ffff16815260200161030d61ffff16815260200161055f61ffff16815260200160ac61ffff1681526020016106d561ffff1681526020016111c561ffff168152602001610e9861ffff168152602001610c8361ffff16815260200160b961ffff16815260200161121561ffff168152602001610c8461ffff1681526020016104f361ffff16815260200161078861ffff1681526020016105d561ffff168152602001610c2e61ffff16815260200161107461ffff16815260200161063961ffff168152602001610a6b61ffff1681526020016106a361ffff1681526020016101bd61ffff16815260200161025a61ffff16815260200161032a61ffff1681526020016107c161ffff16815260200161100861ffff1681526020016102f361ffff168152602001610eab61ffff16815260200161117061ffff16815260200161137461ffff168152602001610cb961ffff16815260200161039e61ffff16815260200161067061ffff168152602001610ddf61ffff168152602001610bf661ffff16815260200161080461ffff16815260200161115e61ffff168152602001610cbe61ffff168152602001610b6261ffff16815260200161064861ffff1681526020016109a661ffff16815260200161087f61ffff16815260200161125361ffff168152602001610fe461ffff16815260200161051761ffff168152602001610cbf61ffff1681526020016101d961ffff16815260200161021961ffff168152602001610eaf61ffff16815260200161056a61ffff1681526020016108c761ffff16815260200161103261ffff168152602001610bd361ffff168152602001610b7961ffff16815260200161018e61ffff1681526020016112ae61ffff1681526020016107b561ffff16815260200161086261ffff16815260200161107361ffff1681526020016111b861ffff168152602001610cf361ffff1681526020016106be61ffff168152602001610ed161ffff1681526020016103c261ffff1681526020016104f061ffff16815260200161042f61ffff168152602001610fdb61ffff168152602001610a8a61ffff1681526020016104ec61ffff16815260200161128061ffff1681526020016110dd61ffff1681526020016103ba61ffff168152602001610a0961ffff16815260200160f261ffff1681526020016103fa61ffff16815260200161106b61ffff168152602001610c6461ffff168152602001610df461ffff168152602001610fe861ffff1681526020016107de61ffff168152602001610c7f61ffff16815260200160e261ffff16815260200161066461ffff16815260200161060e61ffff16815260200161087061ffff168152602001610b4161ffff1681526020016105d961ffff1681526020016102ae61ffff1681526020016106ce61ffff16815260200160b561ffff16815260200161100761ffff16815260200161085261ffff16815260200161016561ffff16815260200161076961ffff168152602001610c2661ffff1681526020016103b361ffff1681526020016112db61ffff1681526020016110c061ffff1681526020016106c461ffff168152602001610d2c61ffff1681526020016107db61ffff16815260200161090d61ffff168152602001610e4a61ffff16815260200161061461ffff16815260200161041c61ffff168152602001610f9c61ffff16815260200161131e61ffff1681526020016101cc61ffff168152602001610ab361ffff16815260200161011061ffff16815260200161019d61ffff16815260200161094961ffff16815260200161040461ffff16815260200161121061ffff1681526020016110a261ffff1681526020016106b661ffff168152602001610e6b61ffff168152602001610d6461ffff16815260200161049361ffff168152602001610c2861ffff168152602001610cc461ffff16815260200161095f61ffff168152602001610b2b61ffff1681526020016112ef61ffff168152602001610a7961ffff168152602001610a8461ffff16815260200161065561ffff168152602001610cb761ffff16815260200161071f61ffff16815260200161117f61ffff16815260200161027761ffff16815260200161132161ffff16815260200161117c61ffff16815260200161099161ffff1681526020016112b661ffff16815260200161017861ffff16815260200161082f61ffff168152602001610c9261ffff168152602001610b9261ffff16815260200161108e61ffff16815260200161061961ffff1681526020016106a761ffff16815260200161119a61ffff16815260200161086161ffff16815260200161102261ffff168152602001610e5161ffff1681526020016106da61ffff16815260200161095b61ffff1681526020016109cd61ffff16815260200160ef61ffff16815260200161054361ffff16815260200161025d61ffff1681526020016107e561ffff16815260200161051861ffff16815260200161064261ffff168152602001610b8561ffff168152602001610f5c61ffff168152602001610d8961ffff16815260200161040261ffff168152602001610cfb61ffff168152602001610d7061ffff16815260200161083261ffff16815260200161111661ffff168152602001610aad61ffff168152602001610e3261ffff16815260200161019361ffff168152602001610c2c61ffff168152602001610f9661ffff168152602001610aa961ffff168152602001610f5861ffff16815260200161034761ffff1681526020016108c961ffff16815260200161038b61ffff1681526020016108de61ffff168152602001610a7561ffff1681526020016108d561ffff168152602001610eb661ffff16815260200161032f61ffff168152602001610c9a61ffff1681526020016106ef61ffff16815260200161054d61ffff1681526020016107e461ffff16815260200161016161ffff16815260200161134261ffff168152602001610a1d61ffff168152602001610a6161ffff168152602001610f1a61ffff1681526020016106a561ffff16815260200161065a61ffff16815260200161040361ffff168152602001610fed61ffff168152602001610af061ffff168152602001610ce361ffff1681526020016105d361ffff16815260200161118e61ffff168152602001610d5861ffff1681526020016112ab61ffff168152602001610d0961ffff16815260200161083c61ffff168152602001610faf61ffff168152602001610ad261ffff1681526020016106d061ffff1681526020016101a561ffff16815260200161054561ffff1681526020016104d961ffff16815260200161046361ffff16815260200161044261ffff1681526020016102a961ffff168152602001610c9561ffff168152602001610b1b61ffff168152602001610c7061ffff1681526020016102df61ffff16815260200161094761ffff16815260200161050a61ffff168152602001610d5f61ffff168152602001610ca561ffff16815260200161135e61ffff168152602001610efc61ffff168152602001610bbd61ffff16815260200161060b61ffff16815260200161082d61ffff16815260200161125161ffff168152602001610afd61ffff168152602001610c1861ffff168152602001610d3e61ffff1681526020016103d061ffff168152602001610f1661ffff1681526020016106bf61ffff168152602001610f8161ffff16815260200161062361ffff16815260200161129a61ffff1681526020016110f261ffff16815260200161101e61ffff1681526020016110db61ffff1681526020016108b561ffff168152602001610d4f61ffff168152602001610d5661ffff16815260200161088761ffff1681526020016103d961ffff16815260200161107c61ffff168152602001610c8c61ffff16815260200161047c61ffff1681526020016111fb61ffff16815260200161050961ffff16815260200161061b61ffff168152602001607a61ffff168152602001610a3361ffff168152602001610a0361ffff16815260200161015861ffff168152602001610a8561ffff168152602001610ecd61ffff168152602001610dd161ffff168152602001610a7761ffff16815260200161036861ffff16815260200161130b61ffff16815260200161017b61ffff168152602001610ad161ffff168152602001610b5861ffff168152602001610b7b61ffff16815260200161037261ffff16815260200161065461ffff16815260200161065d61ffff16815260200161075661ffff168152602001610bfd61ffff16815260200160f761ffff168152602001610b0d61ffff168152602001610e6361ffff16815260200161019961ffff1681526020016111ea61ffff168152602001610b5f61ffff1681526020016105bf61ffff168152602001610fce61ffff168152602001610e3a61ffff168152602001610d3761ffff168152602001610bbf61ffff1681526020016107c461ffff1681526020016104c061ffff168152602001610c2261ffff16815260200161040d61ffff1681526020016107b461ffff168152602001610b5761ffff168152602001610e4e61ffff1681526020016106a461ffff1681526020016103fd61ffff1681526020016104f261ffff16815260200161082061ffff168152602001610ae661ffff16815260200161076061ffff168152602001610a6761ffff168152602001605661ffff168152602001610a1661ffff168152602001610eee61ffff16815260200161035b61ffff16815260200161130161ffff16815260200161046f61ffff1681526020016103e461ffff168152602001610d7d61ffff16815260200161042561ffff16815260200161100b61ffff16815260200161107061ffff168152602001610c2d61ffff168152602001610dca61ffff16815260200161035d61ffff168152602001610f0e61ffff168152602001610c6e61ffff168152602001610bfc61ffff168152602001610a1261ffff168152602001610f4461ffff16815260200161038361ffff1681526020016106f161ffff1681526020016103d261ffff16815260200161024261ffff16815260200161131661ffff16815260200161115161ffff1681526020016111f061ffff1681526020016101ad61ffff168152602001610cfd61ffff168152602001610aa361ffff1681526020016103a761ffff1681526020016111c061ffff1681526020016109b661ffff168152602001610efb61ffff1681526020016101bc61ffff16815260200161089161ffff168152602001610f1b61ffff1681526020016104d561ffff168152602001609461ffff16815260200161071861ffff16815260200161055161ffff168152602001610a0d61ffff16815260200161088261ffff168152602001610c5761ffff16815260200161086d61ffff16815260200161091861ffff16815260200161017061ffff1681526020016108ba61ffff1681526020016102c861ffff1681526020016112b961ffff168152602001610d7a61ffff16815260200161096f61ffff16815260200161029861ffff1681526020016106dc61ffff16815260200161011161ffff168152602001610fb361ffff16815260200161129d61ffff168152602001610bcd61ffff1681526020016101fb61ffff16815260200161069161ffff1681526020016108a361ffff168152602001610c9461ffff1681526020016107eb61ffff16815260200161118561ffff168152602001610f0461ffff16815260200161010f61ffff1681526020016101ac61ffff1681526020016112d461ffff1681526020016101d861ffff168152602001607861ffff16815260200161041761ffff168152602001610e6561ffff16815260200161044661ffff16815260200161133361ffff168152602001610d2661ffff1681526020016109ed61ffff16815260200161065f61ffff168152602001610e7b61ffff16815260200161052061ffff168152602001610c6661ffff16815260200161038e61ffff16815260200161019861ffff16815260200161051f61ffff16815260200161042d61ffff16815260200161136f61ffff168152602001610e5661ffff16815260200161118d61ffff16815260200161121b61ffff168152602001610e8461ffff168152602001609561ffff1681526020016105b861ffff16815260200161135c61ffff16815260200161052b61ffff1681526020016112af61ffff16815260200160eb61ffff16815260200161118161ffff16815260200161068761ffff16815260200161106f61ffff16815260200161055b61ffff16815260200161120361ffff1681526020016111af61ffff168152602001610af661ffff16815260200161124461ffff16815260200161130f61ffff16815260200161016f61ffff1681526020016111db61ffff168152602001610ca661ffff16815260200161035261ffff168152602001610ce261ffff16815260200161127661ffff16815260200161099d61ffff1681526020016107c761ffff168152602001605f61ffff168152602001610a3461ffff168152602001610b4761ffff1681526020016108b761ffff16815260200161068161ffff1681526020016112e961ffff1681526020016104a461ffff168152602001610e2561ffff168152602001610eec61ffff16815260200161041461ffff1681526020016107ac61ffff16815260200161035461ffff16815260200161083861ffff16815260200161041361ffff16815260200161070c61ffff16815260200161049561ffff1681526020016103c961ffff16815260200161097c61ffff168152602001610b2461ffff168152602001610a3561ffff16815260200161015d61ffff16815260200161064361ffff168152602001610e7161ffff168152602001610e3661ffff1681526020016105a261ffff16815260200161055661ffff168152602001610a8b61ffff1681526020016101f261ffff16815260200161114a61ffff168152602001610d6361ffff16815260200161133161ffff16815260200161053b61ffff168152602001610c9361ffff1681526020016108ed61ffff16815260200161101a61ffff16815260200161037b61ffff16815260200161021361ffff1681526020016111d161ffff16815260200161047661ffff168152602001610c2061ffff16815260200160a061ffff1681526020016108ec61ffff168152602001610b1561ffff16815260200161018161ffff16815260200160df61ffff16815260200161024761ffff16815260200161079b61ffff16815260200161114661ffff1681526020016101d161ffff16815260200161029c61ffff168152602001610bdd61ffff16815260200161065661ffff16815260200161109561ffff168152602001610c2961ffff168152602001610de461ffff16815260200161015c61ffff1681526020016108c461ffff1681526020016103fb61ffff16815260200161040561ffff16815260200161100961ffff168152602001610c9861ffff16815260200161119d61ffff16815260200161072b61ffff168152602001610ef361ffff168152602001610b1261ffff16815260200161083061ffff1681526020016112be61ffff1681526020016105e161ffff1681526020016110a161ffff16815260200161117a61ffff168152602001610b5461ffff16815260200161113161ffff16815260200161074561ffff168152602001610ee961ffff168152602001610de661ffff1681526020016111f861ffff16815260200161066d61ffff16815260200161105661ffff1681526020016102af61ffff168152602001610dd561ffff168152602001610c7961ffff16815260200161099e61ffff168152602001608861ffff168152602001610e3161ffff1681526020016106c861ffff168152602001610ffd61ffff168152602001610c1761ffff16815260200161073661ffff1681526020016104c361ffff16815260200161029761ffff16815260200161061161ffff168152602001610aef61ffff16815260200161038161ffff16815260200161035661ffff16815260200161061f61ffff16815260200161061261ffff16815260200161056861ffff168152602001610a2d61ffff1681526020016105fb61ffff1681526020016111a161ffff168152602001610c0861ffff168152602001610fbb61ffff1681526020016108f361ffff168152602001610c7161ffff16815260200161087761ffff168152602001610ef161ffff16815260200161016361ffff1681526020016102e261ffff16815260200161051561ffff16815260200161102361ffff1681526020016103ca61ffff16815260200161022f61ffff168152602001610eed61ffff168152602001610d1761ffff16815260200161133a61ffff168152602001610b7161ffff1681526020016106f361ffff1681526020016103f061ffff168152602001610c6061ffff168152602001610a7861ffff168152602001610f4061ffff16815260200161126661ffff168152602001605c61ffff16815260200161112461ffff16815260200161124061ffff1681526020016108dc61ffff1681526020016107a961ffff16815260200161066661ffff1681526020016108e061ffff168152602001608361ffff168152602001610ee461ffff168152602001610fa761ffff1681526020016110ed61ffff16815260200161020761ffff168152602001610beb61ffff1681526020016110f361ffff16815260200161129861ffff16815260200161130461ffff16815260200161104261ffff16815260200161026561ffff16815260200161134961ffff168152602001607e61ffff168152602001610e2661ffff16815260200161031761ffff16815260200161076461ffff168152602001610d6d61ffff1681526020016111d261ffff168152602001606c61ffff168152602001610ebc61ffff16815260200161030661ffff1681526020016101c461ffff16815260200161077461ffff168152602001610fc361ffff168152602001610cdf61ffff168152602001610a3961ffff16815260200161120161ffff168152602001610f1961ffff16815260200161114961ffff1681526020016104ad61ffff16815260200161103d61ffff16815260200161136961ffff16815260200161016261ffff16815260200161112961ffff1681526020016112ba61ffff168152602001610adf61ffff168152602001610aa061ffff16815260200161016661ffff1681526020016103a661ffff1681526020016111ad61ffff16815260200161108a61ffff16815260200161118461ffff1681526020016104e861ffff16815260200160e561ffff168152602001610a7261ffff16815260200161043d61ffff168152602001610c1e61ffff168152602001610c2561ffff1681526020016107ec61ffff1681526020016112ee61ffff16815260200161053361ffff16815260200161040061ffff1681526020016104e361ffff16815260200161066a61ffff1681526020016102d861ffff1681526020016112f661ffff16815260200161085061ffff16815260200161104061ffff16815260200160dc61ffff16815260200161020b61ffff16815260200161120661ffff16815260200161051d61ffff1681526020016108e161ffff1681526020016104a161ffff16815260200161092e61ffff1681526020016111b561ffff16815260200161070a61ffff1681526020016109c261ffff168152602001610cc261ffff1681526020016106a161ffff1681526020016109b461ffff16815260200161051161ffff16815260200161110761ffff168152602001610f5d61ffff1681526020016102fd61ffff1681526020016108c361ffff168152602001610cde61ffff1681526020016103f761ffff168152602001610f6c61ffff16815260200161122761ffff1681526020016108dd61ffff16815260200161083961ffff1681526020016110b661ffff168152602001610cae61ffff1681526020016108a461ffff16815260200161012b61ffff168152602001610f6961ffff1681526020016110c961ffff16815260200161063761ffff168152602001610b2361ffff168152602001610c6c61ffff168152602001610f2561ffff16815260200161023461ffff16815260200161054b61ffff1681526020016106ae61ffff16815260200161031d61ffff168152602001610f5361ffff16815260200161032c61ffff16815260200161081c61ffff16815260200161017a61ffff1681526020016102b061ffff16815260200161070b61ffff16815260200161098961ffff16815260200160b461ffff168152602001610bcf61ffff16815260200161068c61ffff168152602001610f6d61ffff1681526020016104a661ffff16815260200161106161ffff168152602001610df861ffff168152602001610b6561ffff16815260200161025561ffff16815260200161011461ffff168152602001610cac61ffff16815260200161129061ffff1681526020016105b761ffff16815260200161122e61ffff1681526020016102a861ffff1681526020016109f361ffff16815260200161023f61ffff16815260200161119261ffff1681526020016104c761ffff16815260200161073c61ffff1681526020016107bc61ffff1681526020016107f661ffff168152602001610b6c61ffff16815260200161034c61ffff1681526020016102e961ffff168152602001610f7561ffff168152602001610ff661ffff1681526020016107bb61ffff168152602001610d4961ffff168152602001610e0b61ffff168152602001610bbc61ffff16815260200161043561ffff16815260200161016061ffff1681526020016101da61ffff1681526020016103cb61ffff16815260200161110961ffff16815260200161015e61ffff168152602001610fb561ffff168152602001605a61ffff16815260200161019b61ffff1681526020016102db61ffff16815260200161010061ffff1681526020016112fc61ffff1681526020016109b161ffff1681526020016111b761ffff168152602001610e5961ffff168152602001610b7661ffff168152602001610caa61ffff1681526020016106ec61ffff16815260200161118c61ffff16815260200161033a61ffff168152602001610f2261ffff16815260200161030f61ffff168152602001610fe061ffff168152602001610bcc61ffff1681526020016101ae61ffff16815260200161081e61ffff168152602001610d5761ffff16815260200161044961ffff168152602001610cbb61ffff1681526020016104d261ffff1681526020016110c761ffff168152602001610c4b61ffff16815260200161026661ffff168152602001610d1961ffff16815260200161091a61ffff16815260200161109361ffff168152602001610c6561ffff168152602001610c0361ffff16815260200161101061ffff168152602001610b9a61ffff16815260200161136461ffff168152602001610f5561ffff1681526020016105dc61ffff168152602001604c61ffff1681526020016111ab61ffff16815260200161035961ffff16815260200161024a61ffff168152602001610bd061ffff168152602001610a4461ffff16815260200161038f61ffff1681526020016107b961ffff16815260200161051461ffff168152602001610e3d61ffff16815260200161114261ffff1681526020016111a561ffff1681526020016102aa61ffff16815260200161102d61ffff1681526020016104f461ffff1681526020016101e061ffff1681526020016104a361ffff1681526020016101d461ffff16815260200161010961ffff168152602001610b3f61ffff16815260200161080961ffff16815260200161067561ffff168152602001610dfb61ffff16815260200161060961ffff16815260200161072d61ffff168152602001610a9f61ffff16815260200161051b61ffff16815260200161080c61ffff1681526020016103df61ffff1681526020016111aa61ffff168152602001607161ffff168152602001610fff61ffff168152602001610f6661ffff16815260200161096361ffff16815260200161086561ffff168152602001610a9161ffff16815260200161074e61ffff16815260200161108761ffff16815260200161040c61ffff168152602001610f2761ffff1681526020016111f561ffff1681526020016104da61ffff168152602001610e5e61ffff1681526020016101aa61ffff168152602001610ed861ffff16815260200161126c61ffff16815260200161013561ffff168152602001610b9e61ffff168152602001610bd861ffff16815260200161059661ffff168152602001610cb861ffff168152602001610be061ffff16815260200161025c61ffff16815260200161110461ffff16815260200161101f61ffff168152602001610a6e61ffff16815260200161016961ffff16815260200161095361ffff1681526020016110d061ffff16815260200160da61ffff168152602001610d4561ffff1681526020016109b861ffff16815260200161111c61ffff16815260200161060761ffff16815260200161084c61ffff16815260200161127561ffff1681526020016103c361ffff16815260200161067b61ffff1681526020016106e661ffff168152602001610d7661ffff16815260200161073f61ffff16815260200161074861ffff16815260200161037c61ffff168152602001610f7a61ffff168152602001610ee161ffff168152602001610b1f61ffff16815260200161093a61ffff16815260200161089d61ffff168152602001610d3c61ffff168152602001610f5261ffff168152602001610cf761ffff16815260200161116361ffff16815260200161035c61ffff16815260200161072061ffff168152602001607461ffff16815260200161041e61ffff168152602001610a4061ffff16815260200161125461ffff16815260200161096b61ffff16815260200161023761ffff16815260200161069c61ffff1681526020016111f361ffff168152602001610e4b61ffff16815260200161109761ffff1681526020016102a361ffff16815260200161079261ffff16815260200161062661ffff16815260200160a761ffff16815260200161120f61ffff1681526020016109d661ffff16815260200161050f61ffff16815260200161052861ffff16815260200161068f61ffff16815260200161010c61ffff168152602001610c7a61ffff168152602001610c4a61ffff1681526020016109a961ffff16815260200161104c61ffff168152602001610a5061ffff16815260200161028e61ffff16815260200161058e61ffff16815260200161121161ffff168152602001610c4661ffff168152602001610ff961ffff16815260200161067a61ffff168152602001610ee061ffff16815260200161088161ffff168152602001610f7261ffff1681526020016108bf61ffff168152602001610e8661ffff16815260200161123c61ffff16815260200161090461ffff16815260200161024f61ffff16815260200161013b61ffff168152602001610e1361ffff1681526020016112f161ffff1681526020016104f961ffff1681526020016107fe61ffff16815260200161044f61ffff16815260200161046861ffff16815260200161111061ffff16815260200161082161ffff168152602001610b0e61ffff16815260200161021c61ffff168152602001610e9b61ffff16815260200161121261ffff168152602001610de761ffff1681526020016111e261ffff168152602001610a1061ffff168152602001610eb461ffff1681526020016103af61ffff16815260200161010b61ffff1681526020016106fb61ffff168152602001610bd661ffff16815260200161036761ffff16815260200161082e61ffff1681526020016109b561ffff168152602001610f0761ffff168152602001610cad61ffff16815260200161030361ffff168152602001610d1361ffff1681526020016109d061ffff168152602001610ba261ffff168152602001610eb861ffff16815260200160d961ffff168152602001610f2f61ffff168152602001610f0561ffff168152602001610c7661ffff16815260200161127261ffff1681526020016102ff61ffff1681526020016103dc61ffff16815260200161100261ffff16815260200161053161ffff168152602001610d2961ffff16815260200161079561ffff16815260200161040761ffff16815260200161093461ffff1681526020016109ec61ffff168152602001610c8a61ffff1681526020016105a661ffff1681526020016104eb61ffff168152602001610da461ffff16815260200161017461ffff168152602001610e7461ffff168152602001610b2661ffff16815260200161018c61ffff168152602001610ceb61ffff16815260200161011a61ffff16815260200161015361ffff16815260200161081861ffff16815260200161025461ffff168152602001610de361ffff16815260200161105061ffff16815260200161046161ffff16815260200161096961ffff168152602001610eba61ffff16815260200161135761ffff16815260200161109461ffff168152602001610b4e61ffff1681526020016102ac61ffff1681526020016102ad61ffff168152602001610da861ffff16815260200161102c61ffff168152602001610f8e61ffff16815260200161044061ffff1681526020016111c461ffff1681526020016110dc61ffff16815260200161089061ffff16815260200161010861ffff16815260200161027461ffff16815260200161082861ffff168152602001610e5c61ffff16815260200161052961ffff168152602001610aae61ffff16815260200161043161ffff168152602001610dd061ffff168152602001610a5e61ffff16815260200161037e61ffff16815260200161018061ffff1681526020016106c961ffff16815260200161123161ffff1681526020016105cb61ffff168152602001604f61ffff168152602001610da061ffff168152602001610eff61ffff16815260200161072461ffff16815260200161049a61ffff16815260200161116f61ffff1681526020016104d661ffff168152602001610c3561ffff168152602001610ffc61ffff1681526020016110a061ffff16815260200161053061ffff1681526020016109c461ffff168152602001610b5161ffff16815260200161126261ffff16815260200161038861ffff168152602001610b4f61ffff168152602001610ead61ffff168152602001610b2d61ffff1681526020016102dc61ffff168152602001610a2761ffff16815260200161039b61ffff16815260200161044761ffff16815260200161043c61ffff1681526020016103cc61ffff16815260200161028261ffff16815260200161072961ffff1681526020016104b061ffff16815260200161114061ffff16815260200161025761ffff16815260200161089261ffff16815260200161069561ffff16815260200161041661ffff16815260200161015261ffff16815260200160ba61ffff16815260200161072e61ffff16815260200161042e61ffff16815260200161036161ffff16815260200161048b61ffff168152602001610bed61ffff168152602001610e4761ffff1681526020016105b461ffff1681526020016112e761ffff1681526020016101e661ffff16815260200161104861ffff168152602001610ae961ffff16815260200161032061ffff16815260200161081a61ffff168152602001610a0061ffff1681526020016105ed61ffff168152602001610a6961ffff1681526020016101f361ffff16815260200161045861ffff16815260200161104461ffff16815260200161032661ffff168152602001610fa661ffff16815260200161079361ffff168152602001610a0161ffff1681526020016101db61ffff16815260200161126461ffff16815260200161027861ffff16815260200161051961ffff168152602001610d6861ffff16815260200161049061ffff168152602001610f1c61ffff1681526020016104e561ffff168152602001610cf661ffff1681526020016102cc61ffff168152602001606461ffff16815260200161023b61ffff16815260200161077261ffff168152602001610ba961ffff16815260200161093961ffff16815260200161138461ffff16815260200161115561ffff16815260200161077361ffff168152602001610d1261ffff16815260200160f461ffff168152602001609061ffff16815260200161069961ffff1681526020016110aa61ffff16815260200161050761ffff16815260200161093361ffff1681526020016108c561ffff16815260200161018861ffff16815260200161114f61ffff16815260200161083e61ffff168152602001610b4461ffff168152602001610a0c61ffff16815260200161073561ffff168152602001610e3c61ffff16815260200161035f61ffff168152602001610c8861ffff168152602001610d5b61ffff16815260200161037d61ffff1681526020016111a061ffff1681526020016109eb61ffff1681526020016105c461ffff168152602001610cf861ffff168152602001610c5161ffff16815260200161122061ffff168152602001610fa961ffff168152602001610f8b61ffff1681526020016109da61ffff168152602001610c9761ffff16815260200161025261ffff16815260200161075261ffff16815260200161086b61ffff1681526020016101de61ffff16815260200161042861ffff16815260200161048561ffff16815260200161098f61ffff168152602001610b4561ffff16815260200161120d61ffff16815260200161072f61ffff1681526020016107d761ffff168152602001610dfd61ffff16815260200161040a61ffff168152602001610bb661ffff16815260200161073d61ffff16815260200161077761ffff168152602001610d5a61ffff168152602001610b8661ffff16815260200161015a61ffff1681526020016106bb61ffff16815260200160e061ffff1681526020016109f261ffff16815260200161075961ffff168152602001610bcb61ffff16815260200161029061ffff1681526020016104c561ffff1681526020016112a561ffff168152602001610ac861ffff168152602001610f8561ffff16815260200161112e61ffff16815260200161026c61ffff16815260200161039161ffff1681526020016110eb61ffff1681526020016105d861ffff168152602001610d3861ffff1681526020016110e561ffff168152602001610db761ffff168152602001608761ffff168152602001610ad061ffff16815260200161061561ffff1681526020016102a161ffff168152602001610d4361ffff1681526020016112ad61ffff16815260200161030c61ffff1681526020016104ab61ffff168152602001610ac761ffff16815260200161012461ffff168152602001610d2861ffff16815260200161097361ffff16815260200161110f61ffff16815260200161134a61ffff16815260200161094861ffff1681526020016102cb61ffff168152602001610d4461ffff16815260200161052e61ffff16815260200161056761ffff16815260200160b861ffff16815260200161024b61ffff168152602001610e6261ffff168152602001610ff761ffff168152602001610f5b61ffff16815260200161076361ffff16815260200161010761ffff1681526020016104e461ffff1681526020016105c761ffff168152602001610b9061ffff168152602001610ec161ffff16815260200161015b61ffff16815260200161050e61ffff16815260200161072261ffff168152602001610dab61ffff1681526020016102f561ffff1681526020016108f961ffff168152602001610cc961ffff16815260200161046061ffff16815260200161059561ffff1681526020016107e861ffff16815260200161080d61ffff168152602001610e7e61ffff168152602001610f2d61ffff16815260200161045061ffff1681526020016106d761ffff168152602001610d4161ffff1681526020016112ea61ffff16815260200161118f61ffff1681526020016110e761ffff16815260200161079961ffff16815260200161010d61ffff1681526020016103b761ffff16815260200161126a61ffff16815260200161122d61ffff168152602001610e1f61ffff16815260200161093061ffff168152602001610f7c61ffff16815260200161038c61ffff16815260200161087561ffff1681526020016112c761ffff1681526020016110ab61ffff16815260200161059e61ffff1681526020016105df61ffff16815260200161119661ffff1681526020016106c161ffff168152602001610b7e61ffff1681526020016102e161ffff168152602001610f4b61ffff1681526020016111fe61ffff16815260200161060161ffff168152602001610d1061ffff16815260200160db61ffff168152602001610e7561ffff16815260200160bc61ffff16815260200161128161ffff16815260200161060a61ffff168152602001610e1a61ffff1681526020016109fa61ffff1681526020016101ec61ffff168152602001610e3f61ffff168152602001610db261ffff168152602001610fba61ffff16815260200161133961ffff168152602001610c0e61ffff16815260200161014f61ffff168152602001610e8061ffff1681526020016111b661ffff1681526020016108e461ffff16815260200161036d61ffff16815260200161095461ffff16815260200161134761ffff16815260200161029361ffff1681526020016102d761ffff168152602001610e6f61ffff16815260200161117761ffff16815260200161021261ffff168152602001610c7761ffff168152602001610ffe61ffff168152602001610b1661ffff168152602001610d3461ffff16815260200161021b61ffff16815260200161073061ffff168152602001610bc861ffff16815260200161053f61ffff16815260200161105261ffff1681526020016101a661ffff16815260200161045261ffff168152602001610dbc61ffff16815260200161012261ffff168152602001610b2061ffff168152602001610bb061ffff168152602001610b3561ffff168152602001610b3061ffff168152602001610e7761ffff168152602001610f5e61ffff16815260200161117d61ffff16815260200161124561ffff168152602001610d0d61ffff16815260200161133461ffff16815260200161023561ffff168152602001608261ffff16815260200161123561ffff168152602001610fea61ffff1681526020016109fe61ffff168152602001610adb61ffff1681526020016107ed61ffff1681526020016111df61ffff16815260200161035a61ffff168152602001610d5561ffff16815260200161061861ffff1681526020016110d861ffff16815260200161020061ffff16815260200161107f61ffff168152602001610b8061ffff168152602001610a3e61ffff16815260200161118a61ffff1681526020016109df61ffff168152602001610c5c61ffff168152602001610c3861ffff16815260200161049f61ffff16815260200161024e61ffff1681526020016110cf61ffff1681526020016103f261ffff16815260200161014c61ffff168152602001610cf261ffff16815260200161116e61ffff1681526020016102b961ffff168152602001610a5f61ffff16815260200161088a61ffff168152602001610f2e61ffff16815260200161073861ffff168152602001610fc861ffff168152602001610c5961ffff168152602001610f3961ffff1681526020016109dd61ffff168152602001610a5b61ffff1681526020016107fc61ffff1681526020016108d861ffff168152602001610ec361ffff16815260200161066b61ffff16815260200161130961ffff168152602001610e5461ffff1681526020016108b061ffff1681526020016112f361ffff16815260200161060461ffff16815260200161031261ffff16815260200161133e61ffff16815260200161075361ffff16815260200161053e61ffff1681526020016101b161ffff16815260200161132d61ffff1681526020016112ca61ffff16815260200161095761ffff16815260200161117861ffff16815260200161101d61ffff16815260200161065061ffff168152602001610d8861ffff1681526020016108d761ffff1681526020016105e061ffff1681526020016106f061ffff168152602001610d9061ffff168152602001610f2961ffff1681526020016102ef61ffff1681526020016106b561ffff1681526020016105e961ffff16815260200161017761ffff1681526020016108be61ffff16815260200161108161ffff16815260200161024161ffff168152602001610bba61ffff16815260200161077f61ffff168152602001610d2f61ffff16815260200161098d61ffff16815260200161013c61ffff168152602001610d2561ffff16815260200161029d61ffff168152602001610e9c61ffff16815260200161063e61ffff168152602001610ad861ffff16815260200161012961ffff1681526020016109fd61ffff16815260200161082261ffff1681526020016104b861ffff16815260200161033461ffff16815260200161031461ffff1681526020016102be61ffff16815260200161046461ffff16815260200161013e61ffff168152602001610c4f61ffff168152602001610e1761ffff16815260200161029261ffff1681526020016101bb61ffff16815260200161072c61ffff168152602001610fab61ffff168152602001610b8b61ffff168152602001610eb361ffff16815260200161110661ffff16815260200161131c61ffff16815260200161055e61ffff1681526020016110f461ffff16815260200161107761ffff16815260200161087461ffff16815260200161010a61ffff16815260200161095561ffff1681526020016107f261ffff1681526020016111cb61ffff1681526020016105ee61ffff1681526020016105be61ffff1681526020016105f461ffff1681526020016108cd61ffff1681526020016104b561ffff168152602001609161ffff16815260200161056161ffff1681526020016101a161ffff16815260200161119861ffff168152602001610ebe61ffff16815260200161091c61ffff168152602001610b3d61ffff168152602001610efe61ffff16815260200161038761ffff1681526020016103c661ffff16815260200161020e61ffff16815260200161124c61ffff16815260200161137c61ffff168152602001610fca61ffff16815260200161087861ffff168152602001610ccf61ffff1681526020016104e761ffff16815260200160e661ffff168152602001610ff161ffff16815260200161057661ffff16815260200161064961ffff16815260200161019c61ffff1681526020016104e161ffff16815260200161066361ffff168152602001610e1c61ffff16815260200161070561ffff1681526020016101e161ffff16815260200161100c61ffff168152602001610ee761ffff168152602001610c7361ffff1681526020016108b961ffff16815260200161018f61ffff16815260200161063161ffff16815260200161045761ffff1681526020016112dc61ffff16815260200161027f61ffff1681526020016105f761ffff168152602001610f2061ffff16815260200161019461ffff168152602001610e0661ffff1681526020016111c161ffff1681526020016112f561ffff168152602001610dc061ffff1681526020016106cd61ffff16815260200161039761ffff168152602001610a9c61ffff16815260200160dd61ffff16815260200161038561ffff16815260200161130261ffff168152602001610b7861ffff168152602001610dbe61ffff168152602001610baa61ffff16815260200161053a61ffff16815260200161128661ffff168152602001610e8e61ffff1681526020016107e261ffff16815260200161055861ffff16815260200161027d61ffff16815260200161085761ffff16815260200161106061ffff168152602001610c7561ffff16815260200161013861ffff16815260200160e161ffff168152602001610aa661ffff1681526020016111e661ffff1681526020016101a461ffff1681526020016104ba61ffff16815260200161112561ffff1681526020016105ab61ffff16815260200161100d61ffff1681526020016112d761ffff16815260200161041161ffff16815260200161018961ffff16815260200161059861ffff16815260200161106861ffff168152602001610ef261ffff16815260200160ab61ffff168152602001610ce061ffff168152602001610c4e61ffff1681526020016105cf61ffff168152602001610ce861ffff16815260200161033f61ffff168152602001610d6261ffff1681526020016106df61ffff168152602001610dd361ffff16815260200161039461ffff168152602001610a1761ffff1681526020016104b161ffff168152602001609c61ffff168152602001610c8661ffff16815260200161037561ffff16815260200161033661ffff16815260200161115861ffff168152602001610abb61ffff168152602001610b3c61ffff16815260200161109a61ffff1681526020016104f561ffff168152602001610eac61ffff16815260200161121661ffff1681526020016111da61ffff16815260200161095e61ffff168152602001610a8061ffff168152602001610a1f61ffff1681526020016112c161ffff168152602001610b9161ffff168152602001610f3a61ffff1681526020016105f661ffff168152602001610bc661ffff168152602001610d5c61ffff1681526020016109bc61ffff16815260200161112061ffff16815260200161130661ffff1681526020016106aa61ffff168152602001610f6561ffff16815260200161059b61ffff16815260200161135661ffff16815260200161084261ffff1681526020016106fc61ffff16815260200161057461ffff16815260200161117161ffff168152602001610ba861ffff1681526020016111ec61ffff16815260200161129361ffff1681526020016107e161ffff16815260200161090b61ffff1681526020016112c661ffff16815260200161043e61ffff16815260200161022861ffff1681526020016101a761ffff16815260200161106d61ffff16815260200161053961ffff168152602001610dc961ffff168152602001610c1161ffff168152602001610d9761ffff168152602001610eb961ffff16815260200161122261ffff16815260200161077b61ffff1681526020016106f761ffff168152602001610fd761ffff16815260200161048a61ffff16815260200161088661ffff16815260200161119061ffff16815260200161045b61ffff16815260200161044d61ffff1681526020016106b461ffff1681526020016105b061ffff168152602001610c5261ffff16815260200161049461ffff16815260200161106e61ffff16815260200161036061ffff16815260200161031b61ffff16815260200161085b61ffff16815260200161077661ffff16815260200161049b61ffff1681526020016106d161ffff168152602001610b1c61ffff168152602001610f6261ffff16815260200161119e61ffff16815260200161043061ffff16815260200161102761ffff168152602001610fac61ffff16815260200161061061ffff16815260200161068561ffff16815260200161017c61ffff1681526020016107bd61ffff168152602001610bd561ffff16815260200161129c61ffff1681526020016109bb61ffff168152602001610dc761ffff168152602001610d1861ffff1681526020016105cd61ffff16815260200161015461ffff16815260200161081d61ffff16815260200161015061ffff168152602001610e6761ffff16815260200161105961ffff16815260200161128961ffff1681526020016107e961ffff16815260200161070161ffff168152602001610c8d61ffff16815260200161091261ffff168152602001610e6c61ffff168152602001610ac261ffff168152602001610b7c61ffff16815260200161085161ffff16815260200161106c61ffff16815260200161086661ffff16815260200161066c61ffff1681526020016104f661ffff168152602001610af861ffff1681526020016106cf61ffff16815260200160cf61ffff16815260200161137861ffff16815260200161021a61ffff1681526020016103f561ffff168152602001610e4f61ffff16815260200161067361ffff168152602001610af761ffff168152602001610c4861ffff16815260200161105161ffff168152602001610f8f61ffff1681526020016106c261ffff1681526020016112fe61ffff16815260200161081461ffff168152602001610f4261ffff16815260200161058561ffff16815260200161058661ffff168152602001610b3761ffff168152602001610fb761ffff168152602001610a6a61ffff168152602001610d3f61ffff168152602001610bf861ffff16815260200161050d61ffff1681526020016106dd61ffff1681526020016101c861ffff16815260200161055761ffff1681526020016103e861ffff1681526020016106fd61ffff1681526020016110ce61ffff16815260200161103761ffff16815260200161037f61ffff1681526020016111e361ffff16815260200161094561ffff16815260200161012e61ffff16815260200161062061ffff16815260200161109261ffff16815260200161115b61ffff1681526020016105b661ffff168152602001610ed661ffff168152602001610cce61ffff16815260200161070f61ffff168152602001610a6361ffff16815260200161021761ffff168152602001610cea61ffff16815260200161122961ffff168152602001610e9461ffff168152602001610d3261ffff16815260200161132461ffff16815260200161138861ffff1681526020016103b261ffff1681526020016110e361ffff168152602001610d2d61ffff1681526020016102c761ffff168152602001610df661ffff16815260200160b161ffff168152602001610e4661ffff16815260200161104a61ffff16815260200161116961ffff16815260200161020661ffff16815260200161036b61ffff1681526020016103d361ffff16815260200161056361ffff1681526020016110bd61ffff168152602001608b61ffff168152602001610af461ffff16815260200161029b61ffff168152602001610bd161ffff16815260200161087961ffff1681526020016104ca61ffff16815260200161120061ffff16815260200161134161ffff1681526020016112d561ffff16815260200161088961ffff16815260200161048261ffff16815260200161065761ffff16815260200161084061ffff168152602001610d5161ffff16815260200161086961ffff168152602001610eb161ffff1681526020016103be61ffff168152602001610d0061ffff168152602001610b5b61ffff16815260200161128761ffff168152602001610ce161ffff16815260200161082661ffff16815260200161010361ffff168152602001610a5461ffff1681526020016102de61ffff16815260200161134b61ffff1681526020016105da61ffff16815260200161029461ffff1681526020016105c361ffff168152602001610fbf61ffff16815260200161071961ffff168152602001610e5761ffff168152602001605e61ffff16815260200161122161ffff168152602001610d0761ffff1681526020016107ee61ffff1681526020016108f761ffff16815260200161081661ffff168152602001610cdc61ffff16815260200161056461ffff16815260200161057361ffff1681526020016104d861ffff16815260200161058d61ffff168152602001610f1e61ffff168152602001610a2c61ffff16815260200161069d61ffff16815260200161090561ffff1681526020016108c661ffff16815260200161071061ffff16815260200161022561ffff16815260200161012161ffff1681526020016110e161ffff168152602001610c0c61ffff1681526020016109d461ffff168152602001610dfc61ffff16815260200161125561ffff168152602001610cec61ffff1681526020016103a161ffff16815260200161051061ffff16815260200161037061ffff1681526020016103e261ffff168152602001610b6a61ffff16815260200161127761ffff168152602001610d8b61ffff1681526020016105c161ffff16815260200161078961ffff16815260200161129b61ffff1681526020016109ef61ffff1681526020016106b161ffff168152602001610ae061ffff168152602001610fef61ffff16815260200161025061ffff16815260200161120761ffff168152602001610c2f61ffff16815260200161099961ffff16815260200160bb61ffff168152602001604861ffff16815260200161087b61ffff168152602001610a3d61ffff16815260200161071a61ffff168152602001604461ffff1681526020016109ff61ffff1681526020016103ed61ffff168152602001610ec961ffff16815260200161024c61ffff16815260200161023961ffff16815260200161058161ffff16815260200161023661ffff1681526020016103b661ffff1681526020016101c061ffff16815260200161054061ffff16815260200160cc61ffff168152602001610ad561ffff16815260200161116261ffff168152602001610d1661ffff16815260200161032961ffff16815260200161112c61ffff1681526020016104fb61ffff168152602001610e4461ffff168152602001610ca261ffff16815260200161034061ffff1681526020016102c261ffff168152602001610cbd61ffff16815260200161108361ffff1681526020016109af61ffff1681526020016106e961ffff16815260200161090f61ffff16815260200161062761ffff16815260200161090361ffff16815260200161018661ffff1681526020016103aa61ffff168152602001610db961ffff168152602001610b2a61ffff1681526020016102e061ffff1681526020016105a061ffff1681526020016110d961ffff168152602001610c1c61ffff168152602001610b7a61ffff16815260200161094461ffff1681526020016108ff61ffff16815260200161094a61ffff1681526020016106e561ffff16815260200161029a61ffff16815260200161033b61ffff16815260200161114461ffff168152602001610efd61ffff1681526020016112c961ffff16815260200161029961ffff1681526020016106c761ffff16815260200161072361ffff16815260200161024461ffff168152602001610c0b61ffff1681526020016102a561ffff16815260200161100a61ffff168152602001610d5261ffff1681526020016103f961ffff1681526020016102e461ffff16815260200161044e61ffff1681526020016108c861ffff16815260200161111e61ffff1681526020016106db61ffff16815260200161109e61ffff168152602001610fdf61ffff16815260200161117261ffff1681526020016112da61ffff16815260200161077061ffff16815260200161064661ffff168152602001610e9361ffff16815260200161094e61ffff1681526020016110b361ffff16815260200161102461ffff168152602001610cdb61ffff1681526020016106d261ffff168152602001610af261ffff1681526020016110c461ffff168152602001610c0761ffff1681526020016106d461ffff168152602001610f4d61ffff16815260200161060d61ffff16815260200161012761ffff16815260200161088f61ffff168152602001610e2861ffff1681526020016102fb61ffff168152602001610d8d61ffff16815260200161072a61ffff16815260200161113261ffff168152602001610baf61ffff168152602001610def61ffff168152602001610acf61ffff16815260200161095961ffff1681526020016107dd61ffff1681526020016104ce61ffff168152602001610d9361ffff16815260200161034661ffff16815260200161049261ffff16815260200161082b61ffff16815260200161131261ffff16815260200161083661ffff168152602001610fde61ffff168152602001610efa61ffff168152602001610aa761ffff1681526020016106c561ffff1681526020016110a361ffff168152602001610dda61ffff16815260200160bf61ffff16815260200161011961ffff1681526020016103e761ffff16815260200161030e61ffff1681526020016104a961ffff168152602001610d1e61ffff1681526020016102e661ffff168152602001610a5561ffff168152602001610ba561ffff16815260200161026061ffff1681526020016106a861ffff168152602001610bf961ffff1681526020016103ae61ffff1681526020016112f861ffff168152602001610b2861ffff168152602001610bf361ffff16815260200160d761ffff16815260200161091461ffff16815260200161088c61ffff168152602001610e6161ffff1681526020016107a661ffff168152602001610f3461ffff16815260200161084161ffff1681526020016107b661ffff16815260200161017d61ffff16815260200161127861ffff16815260200161116661ffff168152602001610ed461ffff1681526020016102b461ffff16815260200160b361ffff16815260200161100161ffff16815260200161067d61ffff16815260200161107161ffff168152602001610ed061ffff16815260200161129561ffff16815260200161014e61ffff1681526020016110e861ffff168152602001610e9761ffff16815260200161129961ffff1681526020016107aa61ffff16815260200161026161ffff1681526020016107bf61ffff168152602001610f3e61ffff16815260200161067861ffff1681526020016104cf61ffff16815260200161115a61ffff16815260200161037461ffff168152602001610ebd61ffff1681526020016112eb61ffff16815260200161095261ffff168152602001610c1d61ffff168152602001610e7d61ffff16815260200161074761ffff16815260200161022661ffff16815260200161066161ffff16815260200161097f61ffff1681526020016106f261ffff168152602001610a1e61ffff16815260200161138661ffff168152602001607f61ffff168152602001610f2861ffff16815260200161095861ffff168152602001610a4e61ffff1681526020016112f261ffff16815260200161095661ffff168152602001610f3861ffff168152602001610b9561ffff16815260200161111d61ffff168152602001610a8c61ffff16815260200161069761ffff16815260200161121761ffff16815260200161054e61ffff16815260200161017361ffff168152602001610a9e61ffff168152602001610dbf61ffff168152602001610a2161ffff168152602001610a1a61ffff168152602001610e0e61ffff168152602001610f7b61ffff16815260200161092361ffff168152602001610fb861ffff16815260200161057a61ffff16815260200161058761ffff168152602001610a1161ffff168152602001610e8161ffff1681526020016102c561ffff16815260200161096261ffff168152602001610be861ffff1681526020016110ba61ffff16815260200161044861ffff16815260200161037961ffff16815260200161123661ffff168152602001610e9f61ffff16815260200161020261ffff1681526020016103f661ffff16815260200161092461ffff168152602001610fd061ffff16815260200161128d61ffff16815260200161014361ffff168152602001610d9661ffff16815260200161111461ffff168152602001610ff561ffff16815260200161102b61ffff168152602001610deb61ffff168152602001610bea61ffff16815260200161019561ffff16815260200161059261ffff1681526020016108d661ffff168152602001610c5061ffff1681526020016108f061ffff16815260200161025861ffff168152602001610d3161ffff1681526020016109d161ffff16815260200161041061ffff168152602001610e2d61ffff1681526020016112bd61ffff16815260200161088d61ffff16815260200161034261ffff16815260200161115761ffff16815260200161087161ffff168152602001610e9e61ffff16815260200161133c61ffff1681526020016104ac61ffff168152602001610ade61ffff16815260200161017261ffff1681526020016105bd61ffff168152602001610e1261ffff16815260200161121e61ffff16815260200161092c61ffff168152602001610be561ffff168152602001610b9861ffff16815260200161043761ffff1681526020016105ff61ffff16815260200161099c61ffff16815260200161023061ffff168152602001610e2c61ffff1681526020016101f461ffff168152602001610a0b61ffff168152602001610fd661ffff168152602001610bf161ffff1681526020016104e061ffff16815260200161051661ffff168152602001610a3761ffff16815260200161104161ffff1681526020016110e661ffff168152602001610e5861ffff1681526020016102a661ffff168152602001610eda61ffff16815260200161047161ffff16815260200161082461ffff168152602001610fe961ffff1681526020016110d761ffff16815260200161085561ffff1681526020016102bd61ffff16815260200161080861ffff16815260200161032e61ffff168152602001610a4b61ffff16815260200161020361ffff168152602001610dcb61ffff16815260200161127461ffff168152602001610d8661ffff16815260200161045961ffff16815260200161014461ffff168152602001610e2f61ffff168152602001610d3061ffff16815260200161084f61ffff16815260200161103861ffff16815260200161051e61ffff16815260200161061e61ffff16815260200161033561ffff16815260200161068261ffff168152602001610df261ffff1681526020016110ef61ffff168152602001610c7e61ffff16815260200161091061ffff168152602001610f8d61ffff16815260200161116561ffff168152602001610d7561ffff168152602001610a6261ffff1681526020016107c861ffff16815260200161045d61ffff16815260200161107961ffff1681526020016109ac61ffff168152602001603f61ffff16815260200161070861ffff168152602001610bdf61ffff16815260200161080361ffff16815260200161113961ffff168152602001610cb261ffff1681526020016110b261ffff168152602001610fb661ffff168152602001610ee261ffff168152602001610c3e61ffff16815260200161065261ffff16815260200160b661ffff16815260200161063461ffff168152602001610ee661ffff168152602001610b4361ffff168152602001610fbe61ffff1681526020016111ee61ffff168152602001610dee61ffff1681526020016103a261ffff16815260200161026961ffff1681526020016107f061ffff168152602001604661ffff16815260200161036a61ffff168152602001610d7161ffff1681526020016103ac61ffff16815260200161048661ffff168152602001610fa161ffff1681526020016112cc61ffff168152602001610fc661ffff16815260200161058a61ffff1681526020016112bf61ffff168152602001610de261ffff168152602001610db161ffff16815260200161069061ffff168152602001610ea661ffff168152602001610df961ffff16815260200161032561ffff16815260200161074161ffff168152602001610acc61ffff16815260200161034161ffff1681526020016101ce61ffff16815260200161043f61ffff16815260200161032161ffff168152602001610fa061ffff168152602001610c4761ffff1681526020016109f161ffff168152602001606861ffff16815260200161082361ffff16815260200161012561ffff16815260200161082561ffff1681526020016107d661ffff16815260200161106a61ffff1681526020016108bc61ffff16815260200161113461ffff16815260200160f661ffff168152602001610c6861ffff16815260200161031561ffff16815260200161061d61ffff168152602001610caf61ffff16815260200161057b61ffff16815260200161079061ffff16815260200161097161ffff1681526020016105ec61ffff1681526020016101e261ffff16815260200160f961ffff1681526020016112e061ffff168152602001610ddd61ffff1681526020016108d961ffff16815260200161014861ffff168152602001610af361ffff16815260200161101661ffff1681526020016107fb61ffff168152602001610eb061ffff16815260200161121361ffff16815260200161123261ffff16815260200161057e61ffff16815260200161107861ffff16815260200161130861ffff168152602001610dc561ffff168152602001610e5d61ffff16815260200161104561ffff16815260200161053861ffff16815260200161023a61ffff16815260200161133f61ffff168152602001610cd161ffff16815260200161120861ffff1681526020016107cb61ffff1681526020016106c061ffff1681526020016103eb61ffff168152602001610d6761ffff16815260200161129161ffff1681526020016112ed61ffff168152602001610b6b61ffff16815260200161084961ffff1681526020016101f761ffff16815260200160d361ffff1681526020016109c861ffff16815260200161074661ffff16815260200161058961ffff1681526020016108b661ffff168152602001610f4661ffff16815260200161124761ffff16815260200161069461ffff16815260200161036361ffff168152602001607c61ffff1681526020016112b461ffff16815260200161038061ffff168152602001610d1461ffff16815260200161024361ffff168152602001610bab61ffff16815260200161069661ffff1681526020016104be61ffff1681526020016101be61ffff168152602001610d2061ffff1681526020016112e661ffff168152602001610ef561ffff1681526020016103f861ffff16815260200161130e61ffff1681526020016103d161ffff1681526020016108f161ffff1681526020016101bf61ffff168152602001610c7261ffff168152602001610b4061ffff1681526020016103e661ffff16815260200161057d61ffff1681526020016111f961ffff16815260200161099b61ffff168152602001610fc761ffff1681526020016103bc61ffff16815260200161064561ffff1681526020016102f261ffff1681526020016103ff61ffff16815260200161113561ffff1681526020016110a661ffff16815260200161035561ffff16815260200161096061ffff168152602001610d7961ffff168152602001610e8c61ffff168152602001610e9a61ffff16815260200161020561ffff1681526020016103c561ffff16815260200161064461ffff1681526020016109e661ffff1681526020016105e761ffff1681526020016109ce61ffff168152602001610d5461ffff16815260200161078d61ffff16815260200161101561ffff1681526020016109f661ffff1681526020016101b261ffff168152602001610b5961ffff16815260200161061c61ffff168152602001610c4461ffff16815260200161057561ffff168152602001610fe161ffff16815260200161081f61ffff1681526020016111c961ffff1681526020016111e861ffff16815260200161060061ffff168152602001610b0661ffff168152602001610a9661ffff168152602001610b5661ffff1681526020016105ac61ffff168152602001606b61ffff168152602001610e6a61ffff16815260200161015161ffff168152602001610ae861ffff16815260200161122b61ffff16815260200161098361ffff16815260200161108c61ffff1681526020016111f661ffff168152602001610ea461ffff16815260200161120561ffff16815260200161057261ffff1681526020016107dc61ffff168152602001610a4961ffff16815260200161018461ffff16815260200161087a61ffff16815260200161136c61ffff16815260200161083f61ffff16815260200161132761ffff168152602001610ba461ffff1681526020016110f961ffff1681526020016112a961ffff168152602001610f7061ffff16815260200161109861ffff168152602001608c61ffff168152602001610f2361ffff168152602001610b0261ffff168152602001610ffa61ffff16815260200161131b61ffff1681526020016102da61ffff16815260200161112f61ffff168152602001610c0d61ffff1681526020016105f561ffff1681526020016111b361ffff168152602001610fc961ffff1681526020016103f361ffff168152602001610ea061ffff1681526020016112aa61ffff16815260200161092d61ffff16815260200161053761ffff1681526020016107b161ffff1681526020016103da61ffff1681526020016107a361ffff168152602001610b6f61ffff1681526020016103d661ffff16815260200161087361ffff16815260200161024d61ffff16815260200161099f61ffff1681526020016101b761ffff16815260200161109161ffff168152602001610dad61ffff16815260200161034d61ffff16815260200161069261ffff1681526020016106e261ffff168152602001610d0261ffff16815260200161133061ffff16815260200161088361ffff168152602001610d1d61ffff16815260200161065161ffff1681526020016106b261ffff16815260200161119161ffff168152602001610aec61ffff168152602001610d6961ffff168152602001610f9161ffff16815260200161026e61ffff168152602001610c3161ffff168152602001610f4361ffff16815260200161062561ffff168152602001610b6061ffff16815260200161072761ffff168152602001610d4761ffff16815260200161113c61ffff168152602001610f7361ffff16815260200161066961ffff168152602001610f8c61ffff1681526020016107c561ffff168152602001610f3561ffff1681526020016108ae61ffff1681526020016108e861ffff16815260200161074f61ffff168152602001609a61ffff1681526020016109d361ffff16815260200161126761ffff168152602001610fad61ffff16815260200161046d61ffff168152602001610a5a61ffff1681526020016105d061ffff168152602001610f8661ffff16815260200161041561ffff16815260200161068361ffff16815260200161112161ffff1681526020016106a061ffff16815260200161023c61ffff168152602001610a8d61ffff1681526020016101f961ffff1681526020016101f161ffff168152602001610f0f61ffff168152602001610f8861ffff168152602001610a9861ffff16815260200161035761ffff16815260200161064f61ffff168152602001610e5061ffff168152602001610aa261ffff16815260200161122461ffff16815260200161021161ffff1681526020016104aa61ffff1681526020016106b961ffff168152602001610af961ffff168152602001607b61ffff1681526020016112d261ffff1681526020016102d261ffff168152602001610cc361ffff168152602001610c9f61ffff168152602001610ea361ffff16815260200161028761ffff1681526020016110e261ffff16815260200161089b61ffff168152602001610d7261ffff1681526020016104e961ffff168152602001610a7f61ffff1681526020016110f761ffff16815260200161062a61ffff168152602001610a7361ffff1681526020016108ce61ffff1681526020016112e861ffff16815260200161062961ffff168152602001610a9761ffff168152602001610e8f61ffff16815260200161038961ffff168152602001610d7761ffff16815260200161122361ffff168152602001610b6461ffff16815260200161083461ffff168152602001610a3161ffff1681526020016102b161ffff16815260200161136a61ffff1681526020016103d761ffff168152602001610c9061ffff168152602001610cf561ffff168152602001610b3661ffff168152602001610dd461ffff1681526020016101ef61ffff168152602001610afc61ffff1681526020016105f961ffff1681526020016101a961ffff168152602001608461ffff168152602001610a4361ffff16815260200161029f61ffff16815260200161076861ffff16815260200161026861ffff16815260200161082c61ffff168152602001609f61ffff1681526020016109f461ffff168152602001610df761ffff1681526020016103ef61ffff168152602001610c3761ffff168152602001610ea561ffff1681526020016101e961ffff1681526020016109c161ffff1681526020016112c361ffff16815260200161024861ffff168152602001610d9561ffff1681526020016105a761ffff168152602001610b5c61ffff1681526020016103dd61ffff1681526020016111b161ffff168152602001610ad961ffff1681526020016107cd61ffff1681526020016111ce61ffff16815260200160aa61ffff168152602001610be461ffff168152602001610d8461ffff16815260200161045161ffff16815260200161115461ffff168152602001610a2361ffff16815260200161069861ffff1681526020016110f161ffff1681526020016103f161ffff1681526020016110ad61ffff1681526020016109ea61ffff16815260200161081261ffff168152602001610e0461ffff1681526020016108fa61ffff168152602001610a4261ffff168152602001610cd361ffff16815260200161070761ffff16815260200161071b61ffff16815260200161075061ffff1681526020016107ea61ffff168152602001610aa461ffff168152602001610e3461ffff1681526020016112cd61ffff1681526020016110d161ffff16815260200161108b61ffff1681526020016102fe61ffff16815260200161108661ffff168152602001610b5561ffff1681526020016109c761ffff16815260200161093f61ffff168152602001608e61ffff16815260200161085361ffff16815260200161111561ffff168152602001610c3461ffff1681526020016105e861ffff168152602001608161ffff1681526020016106d861ffff16815260200161027c61ffff16815260200161120e61ffff16815260200161126e61ffff1681526020016101ed61ffff16815260200161123361ffff16815260200161059061ffff16815260200161136761ffff16815260200161131761ffff16815260200161065c61ffff16815260200161133d61ffff168152602001610f3d61ffff1681526020016107f161ffff1681526020016101b961ffff168152602001610f5a61ffff16815260200161091561ffff1681526020016111bc61ffff1681526020016111a461ffff16815260200161114c61ffff168152602001610d4a61ffff168152602001610f5761ffff16815260200161064d61ffff1681526020016101b361ffff1681526020016108f461ffff168152602001610c4d61ffff16815260200160be61ffff168152602001610aa861ffff16815260200161038661ffff168152602001610d1b61ffff16815260200161082a61ffff16815260200161078f61ffff168152602001610e4161ffff16815260200161097061ffff16815260200161034361ffff16815260200161014261ffff168152602001610d6a61ffff16815260200161128361ffff1681526020016106d361ffff168152602001610c4061ffff16815260200161098861ffff168152602001606a61ffff16815260200160fa61ffff1681526020016107c261ffff1681526020016107fa61ffff16815260200161126361ffff168152602001610eea61ffff16815260200161096561ffff16815260200161126561ffff168152602001610c6161ffff16815260200161017561ffff168152602001610bc161ffff16815260200161098461ffff16815260200161036c61ffff168152602001609861ffff16815260200161049c61ffff16815260200161014661ffff168152602001610a3c61ffff1681526020016109a361ffff168152602001610e0361ffff1681526020016106bc61ffff16815260200161079a61ffff168152602001610cd861ffff168152602001610cd261ffff168152602001610fec61ffff168152602001610b3161ffff168152602001610e0161ffff16815260200161100461ffff16815260200161039f61ffff168152602001610b3b61ffff16815260200161135461ffff168152602001610f4761ffff1681526020016102a461ffff168152602001610e7f61ffff168152602001610dc361ffff16815260200161110061ffff16815260200161067661ffff16815260200161093761ffff168152602001610c9e61ffff1681526020016108a061ffff168152602001610ad461ffff168152602001610c8e61ffff1681526020016108c061ffff168152602001605061ffff16815260200161120a61ffff16815260200161115d61ffff168152602001610a0e61ffff168152602001610ff861ffff16815260200161106361ffff16815260200161050661ffff16815260200161047361ffff16815260200161019161ffff16815260200161023161ffff16815260200161111961ffff16815260200161137961ffff1681526020016110d361ffff16815260200161125e61ffff16815260200161048161ffff16815260200161135161ffff16815260200161058861ffff168152602001610ddc61ffff168152602001605861ffff168152602001610f3b61ffff168152602001604161ffff16815260200161024061ffff16815260200161052461ffff1681526020016107a861ffff16815260200161098e61ffff16815260200161124361ffff1681526020016102d661ffff16815260200161071361ffff168152602001610f9f61ffff168152602001610e9d61ffff16815260200161054a61ffff168152602001610d0161ffff1681526020016111c861ffff168152602001610d3961ffff16815260200161028f61ffff16815260200161112861ffff168152602001610fe761ffff16815260200161028a61ffff16815260200161132561ffff168152602001610a5261ffff1681526020016106fa61ffff168152602001610b0b61ffff168152602001610c1261ffff16815260200161128561ffff168152602001610f6861ffff168152602001610abf61ffff1681526020016110cd61ffff1681526020016110a761ffff16815260200161054161ffff16815260200161103461ffff16815260200161125061ffff16815260200161019261ffff16815260200161124d61ffff16815260200161031061ffff1681526020016110c661ffff16815260200161131861ffff16815260200161056661ffff16815260200161115661ffff16815260200161076261ffff168152602001610c5a61ffff168152602001610d3361ffff16815260200161130561ffff168152602001610bc261ffff16815260200161078a61ffff16815260200161054f61ffff168152602001610e5a61ffff168152602001610e4061ffff1681526020016105e561ffff16815260200160e761ffff1681526020016110ee61ffff168152602001610a9b61ffff1681526020016107ef61ffff16815260200161114161ffff168152602001610b4a61ffff168152602001610a6661ffff1681526020016103ee61ffff168152602001610d0361ffff168152602001610a7161ffff168152602001610bfa61ffff1681526020016110be61ffff16815260200161012061ffff1681526020016109c961ffff16815260200161043b61ffff168152602001610ace61ffff16815260200161106261ffff168152602001610e2361ffff1681526020016101ea61ffff16815260200161099061ffff168152602001606061ffff16815260200161073e61ffff16815260200161110b61ffff1681526020016111c761ffff16815260200161063b61ffff16815260200161075561ffff168152602001610c6b61ffff16815260200161045561ffff16815260200160b761ffff16815260200161016c61ffff1681526020016101dd61ffff16815260200161025161ffff1681526020016112a061ffff16815260200161062261ffff16815260200161104f61ffff168152602001610ab061ffff16815260200161057f61ffff16815260200161087261ffff16815260200161083d61ffff168152602001610a5c61ffff168152602001610a6461ffff16815260200161128b61ffff16815260200160d161ffff16815260200161084461ffff168152602001607761ffff1681526020016107b861ffff1681526020016104f761ffff16815260200161026b61ffff168152602001610d8a61ffff1681526020016104a761ffff16815260200161067761ffff16815260200161126b61ffff16815260200161098b61ffff168152602001610f9261ffff16815260200161087661ffff16815260200161063861ffff16815260200161054861ffff16815260200161132c61ffff168152602001610d7e61ffff1681526020016107ce61ffff16815260200161102161ffff168152602001610f9961ffff1681526020016101c561ffff16815260200161086e61ffff16815260200161058c61ffff168152602001610b8c61ffff16815260200161028661ffff16815260200161041d61ffff16815260200161070d61ffff168152602001610f3761ffff16815260200161134861ffff168152602001610bc561ffff16815260200161022461ffff168152602001610e5261ffff16815260200161042061ffff1681526020016108c161ffff1681526020016106b861ffff1681526020016103e161ffff16815260200161108561ffff16815260200160d461ffff16815260200161028b61ffff16815260200161080561ffff1681526020016105db61ffff16815260200161064161ffff168152602001610c9d61ffff168152602001610d8761ffff168152602001610ded61ffff168152602001610c9161ffff16815260200161095a61ffff168152602001610e5361ffff168152602001610d9a61ffff1681526020016103b061ffff16815260200161133661ffff16815260200161110161ffff1681526020016112d861ffff1681526020016103e961ffff168152602001610afb61ffff168152602001610c8961ffff1681526020016104de61ffff16815260200161081561ffff16815260200161078761ffff168152602001610a5361ffff1681526020016110c161ffff16815260200161136561ffff168152602001610b5061ffff16815260200161096161ffff168152602001610be261ffff168152602001610ff061ffff168152602001610fe561ffff16815260200161031361ffff16815260200161016d61ffff1681526020016104af61ffff16815260200161134c61ffff16815260200161043361ffff16815260200161011261ffff1681526020016102bf61ffff16815260200161110361ffff168152602001610c5461ffff16815260200161097561ffff168152602001610d9261ffff1681526020016109b261ffff1681526020016108ea61ffff16815260200161061761ffff1681526020016108eb61ffff168152602001610e2161ffff168152602001610e3761ffff16815260200161102661ffff168152602001610a7d61ffff16815260200161136261ffff16815260200161132f61ffff1681526020016112cb61ffff168152602001610f6061ffff168152602001610ae461ffff1681526020016110c861ffff1681526020016102cd61ffff168152602001610eef61ffff16815260200161033161ffff1681526020016107a161ffff1681526020016104ef61ffff1681526020016109bf61ffff168152602001610f5961ffff168152602001610f1861ffff168152602001610c6d61ffff16815260200160a861ffff16815260200161023861ffff168152602001610d8061ffff1681526020016108fb61ffff16815260200161064761ffff168152602001610fb161ffff168152602001610c1961ffff168152602001606e61ffff168152602001610fcb61ffff168152602001610c4361ffff16815260200161114d61ffff1681526020016105a961ffff16815260200161109b61ffff16815260200161126161ffff16815260200161013661ffff168152602001610fd361ffff16815260200161094d61ffff168152602001610ca761ffff1681526020016109e561ffff168152602001610ae161ffff16815260200160a261ffff16815260200161065b61ffff16815260200161066761ffff1681526020016101ab61ffff16815260200161011761ffff1681526020016112c561ffff1681526020016105a161ffff168152602001610d8e61ffff168152602001610ae761ffff1681526020016102dd61ffff16815260200161039661ffff16815260200161066e61ffff168152602001610c1b61ffff168152602001610a3661ffff16815260200161069361ffff16815260200161137f61ffff16815260200161037661ffff1681526020016105e261ffff168152602001610f9861ffff168152602001610c3661ffff16815260200161034461ffff168152602001610a8261ffff168152602001610bad61ffff1681526020016112f761ffff168152602001610c3261ffff16815260200161050861ffff168152602001610faa61ffff1681526020016103e561ffff1681526020016102e561ffff16815260200161117e61ffff16815260200161011c61ffff16815260200161013d61ffff16815260200161134461ffff168152602001610b9d61ffff168152602001610ad761ffff168152602001610c6261ffff16815260200161113a61ffff1681526020016103ec61ffff168152602001610bb961ffff16815260200161076d61ffff168152602001610bf261ffff1681526020016105f161ffff1681526020016107a561ffff168152602001610d3a61ffff168152602001610bb461ffff16815260200160d561ffff1681526020016109d961ffff1681526020016107d161ffff168152602001610d4661ffff168152602001610f1061ffff16815260200161076f61ffff16815260200161049961ffff1681526020016108b261ffff168152602001610f6161ffff16815260200161127361ffff1681526020016101ee61ffff16815260200161022b61ffff1681526020016104c661ffff1681526020016110ae61ffff1681526020016106b761ffff1681526020016112de61ffff168152602001610bc061ffff16815260200161116a61ffff168152602001610c1061ffff168152602001610dc261ffff16815260200161103661ffff1681526020016108b461ffff16815260200161110861ffff16815260200161089561ffff168152602001610c8f61ffff16815260200161084e61ffff168152602001610d1c61ffff16815260200161108961ffff16815260200161092a61ffff16815260200161077861ffff16815260200161019e61ffff168152602001610ab561ffff16815260200161113d61ffff16815260200161033c61ffff16815260200161125f61ffff16815260200161138061ffff16815260200160ee61ffff16815260200161125861ffff1681526020016110ff61ffff1681526020016109cb61ffff16815260200161120961ffff168152602001610de961ffff16815260200161086f61ffff168152602001610a1861ffff168152602001610f9b61ffff16815260200161088b61ffff168152602001610f7d61ffff16815260200161044a61ffff1681526020016112b561ffff16815260200161074261ffff16815260200161095d61ffff168152602001609261ffff168152602001610c2761ffff1681526020016102e761ffff16815260200161025961ffff16815260200161053461ffff16815260200161106661ffff16815260200161020d61ffff16815260200161131061ffff168152602001610a4d61ffff1681526020016108e661ffff1681526020016111b961ffff1681526020016109c361ffff16815260200161045c61ffff168152602001610daa61ffff16815260200161109961ffff16815260200161026d61ffff1681526020016104c861ffff16815260200161015561ffff1681526020016104c161ffff16815260200161056961ffff168152602001610e8d61ffff1681526020016106ad61ffff16815260200161137761ffff168152602001610cd061ffff168152602001610c6f61ffff168152602001610d6561ffff16815260200161136b61ffff16815260200161056261ffff168152602001610ad361ffff168152602001610b9661ffff16815260200161071261ffff168152602001610bae61ffff1681526020016107b361ffff1681526020016103bd61ffff168152602001610f5461ffff16815260200161071761ffff16815260200161093161ffff16815260200161127161ffff16815260200161040f61ffff1681526020016106ba61ffff168152602001610d8561ffff168152602001607d61ffff168152602001610d5961ffff16815260200161107661ffff1681526020016104d761ffff1681526020016101c961ffff16815260200161021461ffff168152602001610a3061ffff1681526020016106e361ffff168152602001610a8961ffff168152602001610a4f61ffff16815260200161070261ffff168152602001610c4561ffff16815260200161080e61ffff16815260200161079f61ffff16815260200160ce61ffff168152602001610a2261ffff16815260200161063f61ffff1681526020016101c661ffff16815260200161047f61ffff168152602001610cab61ffff168152602001610ce761ffff16815260200161020861ffff16815260200161127061ffff168152602001610d7861ffff1681526020016107e361ffff168152602001610d6061ffff16815260200161107e61ffff168152602001610aa561ffff16815260200161124f61ffff16815260200161084861ffff168152602001610f6a61ffff16815260200161074361ffff1681526020016105aa61ffff1681526020016110ec61ffff168152602001610a8861ffff1681526020016103d461ffff16815260200161017161ffff168152602001610bc461ffff16815260200161066061ffff1681526020016111f761ffff168152602001610a1461ffff1681526020016101d761ffff1681526020016108ca61ffff16815260200161129461ffff16815260200161027361ffff1681526020016111f461ffff168152602001610c3d61ffff168152602001610b3861ffff168152602001610aff61ffff168152602001610f7661ffff16815260200161123a61ffff16815260200160ad61ffff168152602001610a1961ffff16815260200161136e61ffff168152602001610eeb61ffff16815260200161011661ffff16815260200161046661ffff168152602001610e0c61ffff16815260200161047061ffff1681526020016110ea61ffff1681526020016110df61ffff16815260200161044161ffff16815260200161111761ffff168152602001610ab161ffff16815260200161092b61ffff168152602001610a9961ffff1681526020016105f861ffff16815260200161059461ffff1681526020016106f861ffff16815260200160b061ffff168152602001610aeb61ffff168152602001610e7a61ffff168152602001603861ffff168152602001610eca61ffff16815260200161096461ffff16815260200161111361ffff168152602001610a1b61ffff168152602001610ca961ffff168152602001610d9c61ffff1681526020016108e361ffff168152602001610f7761ffff16815260200161104961ffff16815260200161068461ffff1681526020016107da61ffff1681526020016107c661ffff16815260200161105d61ffff1681526020016102b261ffff168152602001610e0761ffff168152602001610ef661ffff16815260200161071661ffff168152602001610ff361ffff168152602001610ac661ffff16815260200160ff61ffff16815260200161081961ffff16815260200161010561ffff16815260200161055d61ffff1681526020016110b861ffff16815260200161048961ffff16815260200161098161ffff1681526020016111d661ffff168152602001610e4861ffff1681526020016110bc61ffff16815260200161027961ffff1681526020016108bd61ffff1681526020016107a061ffff16815260200161101c61ffff168152602001606f61ffff168152602001610d5361ffff1681526020016109e861ffff1681526020016107d561ffff168152602001610fd161ffff168152602001610da961ffff168152602001610b6661ffff1681526020016101cd61ffff16815260200161033261ffff16815260200161125b61ffff16815260200161093861ffff168152602001610cfe61ffff16815260200161126d61ffff1681526020016107cc61ffff168152602001604a61ffff16815260200160a361ffff16815260200161064061ffff16815260200161118061ffff16815260200161090a61ffff16815260200161060261ffff168152602001610c2a61ffff168152602001610e1661ffff168152602001610b5361ffff16815260200161047861ffff16815260200161102561ffff16815260200161034561ffff16815260200161074461ffff16815260200161079d61ffff16815260200161021d61ffff16815260200161072861ffff1681526020016107c061ffff168152602001610f0661ffff1681526020016104a561ffff1681526020016107f761ffff16815260200161102061ffff168152602001610d2461ffff168152602001610f9361ffff16815260200161086861ffff1681526020016107f461ffff16815260200161125d61ffff168152602001610f7e61ffff168152602001610bd961ffff1681526020016108e261ffff16815260200161011361ffff16815260200161134f61ffff1681526020016112a361ffff168152602001610fe361ffff16815260200161120261ffff16815260200161104661ffff16815260200161067f61ffff168152602001610d6e61ffff1681526020016106ab61ffff16815260200161071561ffff1681526020016101ca61ffff16815260200161112b61ffff16815260200161123f61ffff1681526020016110f061ffff16815260200161080761ffff16815260200161075461ffff1681526020016111c261ffff16815260200161048e61ffff168152602001610ed761ffff168152602001610de161ffff168152602001610c8061ffff16815260200161110261ffff16815260200160e861ffff16815260200161134061ffff16815260200161099761ffff168152602001610ac061ffff16815260200161016461ffff16815260200161075e61ffff168152602001610fcd61ffff16815260200161128c61ffff168152602001610dc661ffff16815260200161104361ffff168152602001610f8961ffff16815260200161043461ffff16815260200161117b61ffff16815260200161074c61ffff16815260200161082961ffff168152602001610a2061ffff1681526020016102d461ffff1681526020016112fa61ffff168152602001610ae261ffff16815260200161120461ffff1681526020016104ea61ffff16815260200161060c61ffff168152602001610ce661ffff168152602001610d2361ffff16815260200161062d61ffff16815260200161029661ffff1681526020016106cc61ffff16815260200160d261ffff1681526020016112a661ffff168152602001610be961ffff168152602001610b6861ffff16815260200161109061ffff16815260200161025e61ffff168152602001610ab761ffff16815260200161075a61ffff16815260200161041b61ffff168152602001610da161ffff1681526020016106ff61ffff16815260200161124861ffff168152602001610fd461ffff16815260200161084d61ffff16815260200160e461ffff168152602001610cef61ffff1681526020016104fa61ffff16815260200161031861ffff168152602001610ca361ffff168152602001606561ffff1681526020016111ff61ffff168152602001610ece61ffff16815260200161087d61ffff16815260200161081761ffff16815260200161119461ffff168152602001610dbb61ffff16815260200161098661ffff1681526020016108da61ffff168152602001610e0f61ffff168152602001610dfa61ffff168152602001610edc61ffff168152602001610a0461ffff1681526020016111ae61ffff16815260200160cd61ffff168152602001610ac461ffff16815260200161125961ffff1681526020016104d461ffff1681526020016102c161ffff1681526020016103f461ffff16815260200161083561ffff16815260200161119761ffff168152602001610fc161ffff16815260200161071161ffff1681526020016105a861ffff16815260200161097261ffff16815260200161132661ffff168152602001610e3961ffff168152602001610c2461ffff16815260200161060661ffff16815260200161133861ffff16815260200161028d61ffff1681526020016102d161ffff168152602001610c0661ffff168152602001610b0161ffff168152602001610fae61ffff168152602001610ba061ffff168152602001610ca861ffff16815260200161085e61ffff16815260200161088861ffff1681526020016112d161ffff1681526020016110f861ffff1681526020016102bb61ffff168152602001610ec561ffff168152602001610c3061ffff168152602001610d2161ffff16815260200161090061ffff16815260200161054261ffff16815260200161075761ffff1681526020016108b861ffff1681526020016111d361ffff168152602001610b7261ffff1681526020016109cc61ffff16815260200161018b61ffff16815260200161033061ffff168152602001610f8261ffff1681526020016103a361ffff16815260200161089e61ffff1681526020016110fc61ffff1681526020016101c261ffff168152602001610f7961ffff168152602001610ac561ffff1681526020016108aa61ffff1681526020016108e561ffff16815260200160a161ffff1681526020016104bb61ffff168152602001610dcc61ffff168152602001610ce561ffff16815260200161047561ffff1681526020016101f861ffff168152602001610cc561ffff1681526020016112a761ffff16815260200161031c61ffff1681526020016110a861ffff1681526020016111cf61ffff16815260200161078461ffff168152602001610a7b61ffff168152602001610bf461ffff168152602001610c0061ffff1681526020016106ed61ffff168152602001610aac61ffff1681526020016107f861ffff1681526020016107ae61ffff16815260200161072561ffff16815260200161119561ffff1681526020016102a061ffff168152602001610dc461ffff16815260200161030061ffff168152602001610fa461ffff168152602001610dae61ffff16815260200161044361ffff168152602001610e5b61ffff168152602001610a5161ffff168152602001610a9061ffff168152602001610a7e61ffff16815260200161025661ffff16815260200161075c61ffff168152602001610f0b61ffff16815260200161085d61ffff16815260200161099a61ffff16815260200161010261ffff1681526020016104dd61ffff16815260200161063361ffff16815260200160e361ffff168152602001610e1e61ffff1681526020016107a761ffff168152602001610e4c61ffff16815260200161092161ffff16815260200161078661ffff16815260200161079c61ffff16815260200161012d61ffff1681526020016105a361ffff16815260200161042661ffff16815260200161079461ffff16815260200161059761ffff168152602001610b0a61ffff16815260200161094161ffff16815260200161023e61ffff168152602001610bca61ffff16815260200161080661ffff168152602001610f1561ffff16815260200161138161ffff1681526020016104bd61ffff1681526020016106fe61ffff16815260200161033e61ffff16815260200161028c61ffff168152602001610dc161ffff16815260200161056561ffff168152602001610b4c61ffff16815260200161089661ffff168152602001610a6561ffff1681526020016101b061ffff168152602001610ec461ffff1681526020016108ad61ffff16815260200161034e61ffff168152602001610d4261ffff16815260200161127e61ffff168152602001610a0261ffff16815260200161028061ffff16815260200161012661ffff168152602001610ec861ffff16815260200161118761ffff168152602001610a2b61ffff16815260200161069a61ffff168152602001610e2e61ffff16815260200161118661ffff168152602001610ab661ffff168152602001610ab961ffff168152602001610c0161ffff168152602001610da761ffff168152602001610dfe61ffff16815260200161123d61ffff16815260200161073461ffff16815260200161093261ffff16815260200161020f61ffff168152602001610cff61ffff168152602001610d1a61ffff16815260200161063561ffff16815260200160ed61ffff1681526020016104d361ffff16815260200161085961ffff16815260200161101461ffff1681526020016111dc61ffff1681526020016105fe61ffff168152602001610a9361ffff1681526020016104fd61ffff16815260200161046c61ffff16815260200161102961ffff168152602001610f8361ffff16815260200161036f61ffff16815260200161028961ffff168152602001610f0a61ffff1681526020016107f561ffff168152602001610f7861ffff168152602001610f2461ffff16815260200161124161ffff16815260200161116b61ffff168152602001610b1e61ffff1681526020016101a861ffff168152602001610b7d61ffff16815260200161018261ffff168152602001610bbe61ffff168152602001610bd261ffff16815260200161094261ffff16815260200161010461ffff16815260200161089961ffff16815260200161116861ffff16815260200161092961ffff16815260200161103061ffff16815260200161064c61ffff168152602001610e4361ffff1681526020016109c061ffff168152602001610a4161ffff1681526020016105e361ffff1681526020016105bc61ffff168152602001610edb61ffff1681526020016107e661ffff16815260200161132061ffff16815260200161094b61ffff16815260200161097a61ffff1681526020016112fb61ffff16815260200161054661ffff168152602001610bee61ffff168152602001610f5661ffff168152602001608061ffff16815260200161076a61ffff168152602001610ef761ffff168152602001610e0061ffff168152602001610fbc61ffff1681526020016102a261ffff16815260200161112261ffff16815260200161031961ffff1681526020016111cd61ffff1681526020016102c061ffff16815260200161095161ffff1681526020016112e261ffff168152602001610e9661ffff16815260200161118861ffff168152602001610d9b61ffff168152602001610d1561ffff168152602001610e6461ffff1681526020016112bc61ffff16815260200161019761ffff16815260200161013a61ffff1681526020016108ef61ffff168152602001610a6f61ffff16815260200161039061ffff16815260200161092761ffff16815260200161020461ffff16815260200161123b61ffff16815260200161076561ffff16815260200161076661ffff16815260200161052761ffff16815260200161117461ffff1681526020016112d961ffff168152602001610ed261ffff168152602001610cf461ffff16815260200161015661ffff168152602001610c7861ffff16815260200161050161ffff168152602001610b3461ffff168152602001610f1461ffff1681526020016109db61ffff16815260200160fb61ffff168152602001610b7f61ffff16815260200161042361ffff168152602001610c5661ffff16815260200161130d61ffff1681526020016109c561ffff1681526020016112a161ffff16815260200161117961ffff16815260200161033d61ffff1681526020016101d361ffff168152602001610c5b61ffff16815260200161121d61ffff168152602001610a2f61ffff168152602001610fd561ffff168152602001610ae361ffff168152602001610b9961ffff16815260200161103f61ffff168152602001610db661ffff168152602001610e2261ffff168152602001610a0f61ffff16815260200161026461ffff168152602001609d61ffff168152602001610a1361ffff16815260200161054461ffff168152602001610b0761ffff16815260200161056e61ffff1681526020016111e461ffff16815260200161119361ffff1681526020016108cf61ffff168152602001610e8561ffff168152602001610d8f61ffff1681526020016101d661ffff168152602001610cb061ffff168152602001610b8d61ffff168152602001610f3061ffff16815260200161031a61ffff16815260200161109f61ffff16815260200161135361ffff16815260200161108061ffff16815260200161068e61ffff1681526020016110cc61ffff168152602001610eb561ffff16815260200161055961ffff16815260200161104761ffff16815260200161096761ffff168152602001605461ffff1681526020016109f061ffff16815260200161079e61ffff1681526020016104ee61ffff168152602001610b1a61ffff16815260200161086c61ffff168152602001610ec261ffff16815260200161039361ffff168152602001610fd261ffff1681526020016109f961ffff16815260200161040661ffff1681526020016108b361ffff1681526020016101e861ffff168152602001610b2c61ffff16815260200161029161ffff1681526020016111e061ffff16815260200161119c61ffff16815260200161093561ffff1681526020016106d661ffff16815260200161073961ffff168152602001610a4661ffff168152602001610c0461ffff16815260200161022a61ffff16815260200161022e61ffff168152602001610d7361ffff168152602001610ef961ffff168152602001610fb061ffff16815260200161030561ffff16815260200161070461ffff168152602001610cf961ffff168152602001607561ffff1681526020016111ca61ffff16815260200161074a61ffff168152602001610f1161ffff168152602001610e1961ffff16815260200161036461ffff16815260200161132a61ffff16815260200161088461ffff16815260200161057161ffff16815260200161037861ffff168152602001610a4561ffff168152602001610b8161ffff1681526020016105d261ffff168152602001610e8361ffff16815260200161113861ffff168152602001610f4861ffff1681526020016109f561ffff168152602001610cda61ffff168152602001610b1961ffff1681526020016104db61ffff168152602001610d2761ffff1681526020016106e061ffff16815260200160af61ffff16815260200161079661ffff16815260200161079161ffff16815260200161135b61ffff168152602001610de561ffff16815260200161104d61ffff1681526020016108cb61ffff16815260200161063d61ffff168152602001610d8161ffff16815260200161047461ffff168152602001610bb161ffff16815260200161128f61ffff168152602001610de061ffff16815260200161062f61ffff1681526020016104b761ffff168152602001610e5561ffff1681526020016110b761ffff16815260200161058361ffff168152602001610a2961ffff1681526020016105cc61ffff168152602001610b6361ffff168152602001610c3961ffff168152602001610d5061ffff16815260200161040861ffff16815260200161103b61ffff1681526020016104fc61ffff1681526020016109d761ffff168152602001610f2661ffff16815260200161124e61ffff168152602001610c4c61ffff168152602001610c1561ffff168152602001610cee61ffff168152602001610e8761ffff16815260200161047e61ffff16815260200161012f61ffff1681526020016102d061ffff168152602001610e9061ffff168152602001610f8761ffff168152602001610db561ffff1681526020016102f061ffff1681526020016104f861ffff16815260200161064a61ffff16815260200161101861ffff168152602001610b8761ffff1681526020016110c361ffff1681526020016111a661ffff16815260200161125761ffff1681526020016101fa61ffff1681526020016101ff61ffff16815260200161037a61ffff16815260200161099561ffff16815260200161053c61ffff16815260200161055461ffff16815260200161010e61ffff16815260200161096a61ffff16815260200161091e61ffff16815260200161080261ffff16815260200161076761ffff1681526020016108d161ffff16815260200161075f61ffff16815260200161122861ffff1681526020016108a161ffff168152602001610c3a61ffff168152602001610e1b61ffff16815260200161015f61ffff16815260200161028861ffff1681526020016102f461ffff16815260200161018d61ffff16815260200161105461ffff168152602001609361ffff168152602001610ed361ffff168152602001610c1361ffff16815260200161091b61ffff16815260200161068a61ffff16815260200161050361ffff1681526020016104b261ffff16815260200161071d61ffff168152602001610a0a61ffff16815260200161137161ffff168152602001610ee361ffff168152602001610f6e61ffff168152602001610aee61ffff1681526020016105c861ffff16815260200161113661ffff168152602001610a3261ffff16815260200161020c61ffff1681526020016110a461ffff1681526020016108e961ffff16815260200161047b61ffff16815260200161029561ffff16815260200161080a61ffff1681526020016108a761ffff16815260200161107561ffff1681526020016111b461ffff168152602001610e8861ffff16815260200161132861ffff16815260200161088061ffff16815260200161117661ffff168152602001610a2e61ffff16815260200161061361ffff168152602001610b8261ffff16815260200161110e61ffff16815260200161086361ffff16815260200161103a61ffff16815260200161091d61ffff16815260200161131161ffff168152602001610f5061ffff1681526020016105bb61ffff1681526020016110f561ffff168152602001610b3261ffff16815260200160ea61ffff168152602001610bde61ffff168152602001610fa261ffff16815260200161056d61ffff168152602001610e2761ffff16815260200160c161ffff168152602001610f9d61ffff168152602001610ea761ffff168152602001610aa161ffff16815260200161123861ffff1681526020016102cf61ffff1681526020016109fb61ffff1681526020016105ba61ffff168152602001610fb261ffff1681526020016105b961ffff168152602001610f8061ffff1681526020016101b561ffff1681526020016112ac61ffff16815260200161103561ffff1681526020016108b161ffff168152602001610bac61ffff16815260200161134661ffff168152602001610cdd61ffff168152602001610e7c61ffff168152602001610db461ffff16815260200161078561ffff168152602001610c8761ffff168152602001610a8161ffff168152602001610daf61ffff168152602001610b8f61ffff168152602001610ac961ffff16815260200161062461ffff168152602001610c9961ffff168152602001610f4961ffff16815260200161030861ffff168152602001610e1061ffff168152602001610e8b61ffff16815260200161133761ffff168152602001606361ffff168152602001610da661ffff16815260200161070661ffff16815260200161063a61ffff1681526020016101d561ffff168152602001610c6761ffff168152602001610b1161ffff1681526020016112c061ffff1681526020016110ca61ffff168152602001610c7c61ffff168152602001610ab861ffff168152602001610f6b61ffff168152602001610f6f61ffff1681526020016107d961ffff16815260200161089f61ffff16815260200161048461ffff16815260200161022c61ffff16815260200161092561ffff168152602001610bda61ffff1681526020016111c361ffff168152602001610ac161ffff1681526020016103a861ffff1681526020016106e461ffff16815260200161018a61ffff16815260200161103e61ffff168152602001610c8561ffff16815260200161107d61ffff1681526020016112c861ffff1681526020016110de61ffff1681526020016101f661ffff16815260200161057c61ffff16815260200161027161ffff1681526020016107a461ffff168152602001610be761ffff1681526020016110e461ffff168152602001610d5e61ffff16815260200161081161ffff16815260200161076c61ffff168152602001610a2461ffff16815260200160e961ffff168152602001610d9161ffff16815260200161091761ffff16815260200161090e61ffff1681526020016109b361ffff1681526020016112f961ffff16815260200161114361ffff168152602001610dd961ffff16815260200161057861ffff1681526020016101fc61ffff1681526020016109be61ffff168152602001610ea861ffff16815260200161054961ffff1681526020016104e261ffff16815260200161116461ffff1681526020016102c361ffff16815260200161054c61ffff16815260200161126861ffff16815260200161068b61ffff16815260200161127f61ffff16815260200161137261ffff16815260200161014d61ffff16815260200161100361ffff1681526020016106c661ffff16815260200161067e61ffff1681526020016109b761ffff168152602001603d61ffff16815260200161097761ffff1681526020016112b361ffff16815260200161035361ffff1681526020016108a261ffff1681526020016108d061ffff16815260200161099861ffff16815260200161099361ffff16815260200161022261ffff16815260200161089861ffff168152602001610bef61ffff168152602001610a9d61ffff168152602001610f9561ffff1681526020016101f061ffff16815260200161026a61ffff168152602001610bbb61ffff16815260200161059161ffff168152602001610fdd61ffff1681526020016104df61ffff16815260200161042b61ffff16815260200161114e61ffff16815260200161085f61ffff168152602001610e0d61ffff16815260200161076161ffff168152602001610d9861ffff168152602001610cc161ffff1681526020016110bf61ffff16815260200161028361ffff16815260200161028561ffff168152602001610cc661ffff16815260200161034f61ffff16815260200161070361ffff1681526020016102fc61ffff168152602001610edd61ffff168152602001610d0561ffff168152602001610b3a61ffff16815260200161073a61ffff16815260200161101961ffff168152602001610b8861ffff16815260200161029e61ffff1681526020016101df61ffff168152602001610d8c61ffff168152602001610b4261ffff1681526020016105eb61ffff16815260200161044561ffff168152602001610f5161ffff16815260200161137561ffff1681526020016101a061ffff16815260200161089761ffff16815260200161117561ffff16815260200161014061ffff168152602001610a8f61ffff1681526020016108fe61ffff16815260200160d861ffff16815260200160a661ffff168152602001605961ffff16815260200161017f61ffff1681526020016107ad61ffff16815260200161068961ffff1681526020016111eb61ffff1681526020016108d261ffff168152602001610dcf61ffff16815260200161105f61ffff1681526020016111d861ffff168152602001610d8361ffff16815260200161113361ffff16815260200161060561ffff168152602001610dbd61ffff16815260200161114b61ffff16815260200161077a61ffff168152602001610e9561ffff16815260200161052a61ffff1681526020016106f561ffff168152602001608561ffff16815260200161076e61ffff16815260200161042761ffff168152602001610e6861ffff1681526020016102ce61ffff16815260200161077e61ffff16815260200161105361ffff168152602001610a0861ffff16815260200161030a61ffff16815260200161034961ffff16815260200161089461ffff16815260200161043a61ffff16815260200161049761ffff16815260200161109c61ffff1681526020016109aa61ffff168152602001610cb161ffff16815260200161068d61ffff16815260200161124661ffff168152602001610b1761ffff16815260200161013761ffff1681526020016112c261ffff168152602001610e1861ffff1681526020016103fc61ffff168152602001610b6761ffff1681526020016101e761ffff16815260200161072661ffff16815260200161089c61ffff1681526020016105af61ffff168152602001610ca461ffff168152602001610d1f61ffff168152602001610d0f61ffff16815260200161079761ffff16815260200161112761ffff16815260200161123061ffff16815260200161037761ffff1681526020016102ba61ffff1681526020016107ab61ffff168152602001610b1d61ffff1681526020016104c461ffff1681526020016102b761ffff16815260200161062c61ffff16815260200161130a61ffff16815260200161132b61ffff16815260200161078161ffff16815260200161090261ffff16815260200161066561ffff16815260200161048861ffff1681526020016104a061ffff16815260200161025361ffff168152602001610aed61ffff168152602001610d4c61ffff168152602001610b9361ffff16815260200161042a61ffff16815260200160de61ffff16815260200161075861ffff16815260200161078b61ffff16815260200161090861ffff16815260200161110561ffff1681526020016106ee61ffff16815260200161042161ffff16815260200161034a61ffff1681526020016112e461ffff16815260200161090961ffff1681526020016112f061ffff168152602001610e2461ffff168152602001606d61ffff168152602001610ec661ffff16815260200160b261ffff168152602001610e1161ffff168152602001610b5d61ffff16815260200161118961ffff1681526020016106ac61ffff16815260200161083761ffff16815260200161074d61ffff168152602001610fb961ffff168152602001610f7461ffff1681526020016108d361ffff16815260200161088e61ffff168152602001610f3161ffff168152602001610b8961ffff16815260200161074961ffff1681526020016110b061ffff16815260200161100561ffff168152602001610f4161ffff16815260200161037361ffff16815260200161130761ffff168152602001609661ffff16815260200161132361ffff168152602001610cf161ffff16815260200160c461ffff168152602001610c0a61ffff16815260200161136361ffff168152602001610bf561ffff1681526020016104b961ffff168152602001610b7761ffff168152602001610a2861ffff16815260200161096861ffff1681526020016106d961ffff168152602001610a0661ffff1681526020016102d961ffff16815260200161048f61ffff168152602001610cd461ffff16815260200161129761ffff1681526020016102bc61ffff168152602001610b0f61ffff16815260200161125661ffff16815260200161066861ffff168152602001610b0961ffff168152602001610f4e61ffff16815260200161059961ffff168152602001607361ffff168152602001610fee61ffff168152602001610dd661ffff16815260200161052161ffff16815260200161093b61ffff16815260200161118361ffff1681526020016112c461ffff16815260200161065e61ffff168152602001610fda61ffff168152602001610f2a61ffff168152602001610e7061ffff168152602001610eae61ffff168152602001610f9061ffff16815260200161052d61ffff168152602001610e0861ffff16815260200161131a61ffff16815260200161137d61ffff16815260200161046e61ffff168152602001610e0961ffff168152602001610d1161ffff16815260200161114861ffff16815260200161136061ffff16815260200161098261ffff168152602001610f3661ffff1681526020016104f161ffff168152602001610dc861ffff16815260200161075b61ffff168152602001610a7c61ffff168152602001607961ffff168152602001610c8261ffff1681526020016111d461ffff16815260200161021561ffff168152602001610f0c61ffff16815260200161121961ffff16815260200161080f61ffff16815260200161033361ffff168152602001610c9c61ffff16815260200161069e61ffff16815260200161030b61ffff16815260200161026f61ffff16815260200161078061ffff16815260200161077c61ffff16815260200161030161ffff168152602001610a0561ffff168152602001610b4b61ffff16815260200160ec61ffff168152602001610a3f61ffff16815260200161123e61ffff1681526020016105d761ffff1681526020016109dc61ffff168152602001610ec061ffff168152602001607061ffff16815260200161047a61ffff168152602001610d7b61ffff16815260200161040161ffff16815260200161084661ffff16815260200161010661ffff16815260200161043261ffff16815260200161034b61ffff168152602001610e0261ffff16815260200161022761ffff168152602001610ce961ffff168152602001610de861ffff16815260200161123461ffff168152602001610b9761ffff168152602001610bc361ffff168152602001610b6961ffff16815260200161083361ffff1681526020016109e761ffff16815260200161085c61ffff16815260200161052361ffff168152602001610b4961ffff1681526020016103c461ffff16815260200161044b61ffff168152602001610f6461ffff1681526020016107b261ffff16815260200161122f61ffff168152602001610b2261ffff16815260200161049661ffff16815260200161062161ffff168152602001610c6961ffff1681526020016105ce61ffff16815260200161128461ffff16815260200161119b61ffff1681526020016105c961ffff16815260200161129261ffff168152602001610d4b61ffff168152602001610b6d61ffff16815260200161076b61ffff16815260200161084a61ffff168152602001610e4d61ffff1681526020016104ae61ffff1681526020016108f261ffff16815260200161129f61ffff168152602001610cd561ffff16815260200161013161ffff1681526020016111a261ffff16815260200161128261ffff1681526020016102b361ffff168152602001610b0c61ffff168152602001610aba61ffff1681526020016104cd61ffff1681526020016109a261ffff168152602001606661ffff16815260200161117361ffff16815260200161013961ffff168152602001610cf061ffff1681526020016103e061ffff16815260200161020a61ffff16815260200161028461ffff16815260200161050b61ffff1681526020016102e861ffff168152602001605b61ffff16815260200161039961ffff168152602001610d6f61ffff16815260200161012a61ffff168152602001610f9e61ffff16815260200160c361ffff168152602001610ec761ffff168152602001610afe61ffff1681526020016111ba61ffff1681526020016107d261ffff16815260200161078c61ffff1681526020016112d361ffff168152602001610b8e61ffff1681526020016106af61ffff1681526020016111d561ffff16815260200161022d61ffff168152602001610e6d61ffff16815260200161138761ffff16815260200161133561ffff16815260200161131d61ffff168152602001605761ffff16815260200161130c61ffff16815260200161055261ffff168152602001610f0d61ffff1681526020016104cb61ffff1681526020016103b561ffff1681526020016111a961ffff1681526020016102c961ffff168152602001610ab461ffff168152602001610a7061ffff168152602001610a3861ffff16815260200161015961ffff1681526020016107d361ffff16815260200161065961ffff168152602001610ccb61ffff1681526020016105ef61ffff16815260200160c961ffff16815260200161131f61ffff16815260200161116761ffff16815260200161013061ffff1681526020016101ba61ffff168152602001610a7661ffff168152602001610cd661ffff16815260200161134361ffff1681526020016107b761ffff168152602001610bec61ffff16815260200161097861ffff1681526020016109e461ffff1681526020016101fd61ffff16815260200161040b61ffff168152602001610f0961ffff1681526020016103a461ffff1681526020016104b461ffff16815260200161111a61ffff16815260200161045361ffff1681526020016105b161ffff16815260200161045f61ffff16815260200161094661ffff168152602001610d3d61ffff16815260200161123961ffff16815260200161135561ffff16815260200161064e61ffff1681526020016108a961ffff16815260200161108d61ffff168152602001604d61ffff16815260200161053d61ffff16815260200161081b61ffff16815260200161032361ffff168152602001610e1d61ffff168152602001610d9d61ffff16815260200161046961ffff1681526020016106de61ffff16815260200161106561ffff16815260200161104e61ffff168152602001610be661ffff168152602001610ea261ffff168152602001610abc61ffff16815260200161085461ffff1681526020016107ba61ffff1681526020016102c461ffff168152602001607661ffff1681526020016112bb61ffff16815260200160a961ffff16815260200160c061ffff168152602001604e61ffff168152602001610c2b61ffff16815260200161057761ffff16815260200161095c61ffff16815260200161018361ffff168152602001610d0e61ffff16815260200161049161ffff1681526020016109f861ffff168152602001610b4661ffff168152602001610f3261ffff16815260200161099461ffff16815260200161116d61ffff16815260200161115961ffff16815260200161137661ffff16815260200161022161ffff168152602001608f61ffff168152602001610f8a61ffff16815260200161013261ffff1681526020016110a961ffff1681526020016109ee61ffff1681526020016105c561ffff16815260200161042961ffff16815260200161098761ffff1681526020016112fd61ffff16815260200161027561ffff168152602001610a5861ffff16815260200161120b61ffff16815260200161016e61ffff16815260200161033761ffff16815260200161064b61ffff168152602001609761ffff168152602001610dea61ffff168152602001610afa61ffff168152602001610e7661ffff16815260200161110a61ffff168152602001610b4861ffff168152602001610d4d61ffff16815260200161114761ffff168152602001610c5f61ffff168152602001610ada61ffff16815260200161118b61ffff1681526020016101c761ffff16815260200161114561ffff16815260200161130361ffff168152602001610fb461ffff16815260200161079861ffff1681526020016107df61ffff16815260200161101761ffff16815260200161030461ffff168152602001610f6361ffff168152602001610ecf61ffff1681526020016110fe61ffff16815260200161103c61ffff168152602001609e61ffff1681526020016108fc61ffff16815260200161039561ffff1681526020016111d761ffff16815260200161052561ffff1681526020016103de61ffff16815260200161012c61ffff16815260200161036561ffff16815260200161109d61ffff16815260200161026261ffff1681526020016102b661ffff168152602001610c1461ffff16815260200161131461ffff16815260200161030761ffff168152602001610ff261ffff16815260200161032d61ffff16815260200161021861ffff168152602001610d8261ffff168152602001603961ffff168152602001610e2061ffff16815260200161058f61ffff168152602001610d0461ffff16815260200161041961ffff16815260200161137361ffff16815260200161011861ffff16815260200161087c61ffff16815260200161013f61ffff168152602001610f1f61ffff168152602001610b3361ffff168152602001610c6361ffff16815260200161016b61ffff168152602001610c8161ffff16815260200161113e61ffff16815260200161045661ffff168152602001610e3061ffff16815260200161032861ffff16815260200161035e61ffff168152602001610a1c61ffff16815260200161014b61ffff168152602001610a9461ffff1681526020016111a861ffff168152602001610c7461ffff168152602001610d4061ffff1681526020016103bb61ffff1681526020016101b661ffff168152602001610bc761ffff1681526020016112b261ffff16815260200161028161ffff168152602001610dac61ffff16815260200161038d61ffff168152602001610a5661ffff1681526020016109ad61ffff16815260200161126f61ffff168152602001610fc061ffff168152602001610ef861ffff16815260200161125a61ffff16815260200161046261ffff16815260200161091361ffff1681526020016107b061ffff16815260200161036961ffff1681526020016110fb61ffff1681526020016111fc61ffff168152602001610cc061ffff168152602001610e1461ffff168152602001610f3f61ffff16815260200161075d61ffff16815260200160a461ffff168152602001610d2e61ffff168152602001610ad661ffff16815260200161103961ffff168152602001610e9261ffff16815260200161050c61ffff1681526020016110b961ffff16815260200161128a61ffff168152602001610c0261ffff1681526020016105e461ffff16815260200161031e61ffff16815260200161011e61ffff1681526020016103ce61ffff16815260200161061661ffff16815260200161097e61ffff168152602001610bfe61ffff16815260200161027e61ffff16815260200161132961ffff16815260200161100061ffff16815260200161105c61ffff16815260200161063c61ffff1681526020016111be61ffff16815260200161080061ffff1681526020016101f561ffff168152602001610bb561ffff1681526020016106ca61ffff16815260200161022961ffff16815260200161137a61ffff168152602001610a5761ffff168152602001610fe661ffff16815260200161074b61ffff16815260200161011f61ffff16815260200161059c61ffff1681526020016110b161ffff16815260200161108f61ffff168152602001610a9561ffff16815260200161100f61ffff16815260200161136d61ffff1681526020016102f861ffff1681526020016105ae61ffff16815260200161083161ffff1681526020016107a261ffff16815260200161019a61ffff168152602001610f0061ffff168152602001605561ffff1681526020016105c261ffff1681526020016101d061ffff168152602001610b0861ffff1681526020016103b161ffff16815260200161116c61ffff1681526020016112e561ffff16815260200161093e61ffff16815260200161084761ffff16815260200161097b61ffff16815260200160c861ffff16815260200161041a61ffff16815260200161105a61ffff16815260200161048d61ffff16815260200160c661ffff168152602001609961ffff16815260200161017961ffff16815260200161039861ffff168152602001610d2261ffff1681526020016106a661ffff168152602001610aaf61ffff168152602001610e3561ffff1681526020016105a461ffff1681526020016104d061ffff16815260200161086461ffff16815260200161027b61ffff16815260200161073261ffff168152602001610c1a61ffff16815260200161084b61ffff16815260200161094361ffff16815260200160f361ffff16815260200161127c61ffff168152602001610b0461ffff16815260200161039d61ffff1681526020016101c361ffff1681526020016111a761ffff1681526020016107c961ffff168152602001610cb561ffff16815260200161121461ffff16815260200161090161ffff168152602001610b7361ffff16815260200161041861ffff168152602001610ac361ffff168152602001610d0661ffff1681526020016102f761ffff168152602001604061ffff1681526020016103ea61ffff1681526020016106e161ffff16815260200161019661ffff168152602001610e6661ffff16815260200161040e61ffff16815260200161138261ffff168152602001605d61ffff168152602001610be161ffff1681526020016103a561ffff16815260200161107a61ffff16815260200161038a61ffff16815260200161085661ffff16815260200161025f61ffff16815260200161085861ffff168152602001610fc561ffff16815260200161030261ffff168152602001609b61ffff168152602001610a6861ffff1681526020016104bf61ffff16815260200161070961ffff16815260200161019f61ffff168152602001610df561ffff16815260200161056061ffff168152602001610e3861ffff1681526020016105ea61ffff16815260200161093661ffff168152602001610b0561ffff16815260200161068661ffff16815260200161057961ffff1681526020016112ec61ffff1681526020016110d561ffff16815260200161118261ffff1681526020016112b161ffff16815260200161133261ffff16815260200161034861ffff168152602001610d2a61ffff1681526020016112e161ffff1681526020016112f461ffff1681526020016102ca61ffff16815260200161093d61ffff1681526020016103c761ffff16815260200161031f61ffff16815260200160d661ffff168152602001610d0a61ffff16815260200161080b61ffff16815260200161083b61ffff16815260200161130061ffff16815260200161108461ffff168152602001610d9461ffff1681526020016104c261ffff16815260200161046a61ffff168152602001610b9b61ffff16815260200161135261ffff16815260200161019061ffff1681526020016112a861ffff16815260200161109661ffff1681526020016111dd61ffff16815260200161023261ffff1681526020016101d261ffff1681526020016107af61ffff16815260200161021061ffff16815260200161033861ffff16815260200160fc61ffff168152602001610b1061ffff168152602001610acd61ffff1681526020016109ab61ffff168152602001610fd861ffff168152602001610b8461ffff16815260200161047261ffff168152602001610fbd61ffff16815260200161124261ffff1681526020016111b061ffff168152602001610d4e61ffff1681526020016109e161ffff168152602001610d9f61ffff16815260200161048c61ffff16815260200161067161ffff16815260200161023d61ffff168152602001610f0161ffff1681526020016109e061ffff16815260200161085a61ffff16815250600b906113476200e6b39291906200ec48565b5062030d40601160006101000a81548163ffffffff021916908363ffffffff160217905550601e601160046101000a81548161ffff021916908361ffff1602179055506001601160066101000a81548163ffffffff021916908363ffffffff1602179055506000601960006101000a81548160ff0219169083151502179055503480156200e74057600080fd5b5060405162014c3d38038062014c3d83398181016040528101906200e76691906200f066565b826040518060400160405280601081526020017f444746616d696c79476c617373426f78000000000000000000000000000000008152506040518060400160405280600181526020017f310000000000000000000000000000000000000000000000000000000000000081525081818d8d81600090805190602001906200e7ef9291906200ecf9565b5080600190805190602001906200e8089291906200ecf9565b5050506200e82b6200e81f6200eb7260201b60201c565b6200eb7a60201b60201c565b6040518060800160405280604f815260200162014bee604f91398051906020012082805190602001208280519060200120306200e86d6200ec4060201b60201c565b60001b6040516020016200e8869594939291906200f1c4565b60405160208183030381529060405280519060200120600881905550505050508073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1681525050506001600a8190555086601590805190602001906200e8fb9291906200ecf9565b508560188190555084601960016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555082600c60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600d60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555083600d60146101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555082600e60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081600f60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550806010819055506000601d6000600160ff16815260200190815260200160002060006101000a81548160ff021916908360028111156200ead8576200ead76200f221565b5b02179055506001601d6000600260ff16815260200190815260200160002060006101000a81548160ff021916908360028111156200eb1b576200eb1a6200f221565b5b02179055506002601d6000600360ff16815260200190815260200160002060006101000a81548160ff021916908360028111156200eb5e576200eb5d6200f221565b5b02179055505050505050505050506200f2b5565b600033905090565b6000600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600046905090565b82805482825590600052602060002090600f016010900481019282156200ece65791602002820160005b838211156200ecb457835183826101000a81548161ffff021916908361ffff16021790555092602001926002016020816001010492830192600103026200ec72565b80156200ece45782816101000a81549061ffff02191690556002016020816001010492830192600103026200ecb4565b505b5090506200ecf591906200ed8a565b5090565b8280546200ed07906200f27f565b90600052602060002090601f0160209004810192826200ed2b57600085556200ed77565b82601f106200ed4657805160ff19168380011785556200ed77565b828001600101855582156200ed77579182015b828111156200ed765782518255916020019190600101906200ed59565b5b5090506200ed8691906200ed8a565b5090565b5b808211156200eda55760008160009055506001016200ed8b565b5090565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6200ee12826200edc7565b810181811067ffffffffffffffff821117156200ee34576200ee336200edd8565b5b80604052505050565b60006200ee496200eda9565b90506200ee5782826200ee07565b919050565b600067ffffffffffffffff8211156200ee7a576200ee796200edd8565b5b6200ee85826200edc7565b9050602081019050919050565b60005b838110156200eeb25780820151818401526020810190506200ee95565b838111156200eec2576000848401525b50505050565b60006200eedf6200eed9846200ee5c565b6200ee3d565b9050828152602081018484840111156200eefe576200eefd6200edc2565b5b6200ef0b8482856200ee92565b509392505050565b600082601f8301126200ef2b576200ef2a6200edbd565b5b81516200ef3d8482602086016200eec8565b91505092915050565b6000819050919050565b6200ef5b816200ef46565b81146200ef6757600080fd5b50565b6000815190506200ef7b816200ef50565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006200efae826200ef81565b9050919050565b6200efc0816200efa1565b81146200efcc57600080fd5b50565b6000815190506200efe0816200efb5565b92915050565b600067ffffffffffffffff82169050919050565b6200f005816200efe6565b81146200f01157600080fd5b50565b6000815190506200f025816200effa565b92915050565b6000819050919050565b6200f040816200f02b565b81146200f04c57600080fd5b50565b6000815190506200f060816200f035565b92915050565b60008060008060008060008060006101208a8c0312156200f08c576200f08b6200edb3565b5b60008a015167ffffffffffffffff8111156200f0ad576200f0ac6200edb8565b5b6200f0bb8c828d016200ef13565b99505060208a015167ffffffffffffffff8111156200f0df576200f0de6200edb8565b5b6200f0ed8c828d016200ef13565b98505060408a015167ffffffffffffffff8111156200f111576200f1106200edb8565b5b6200f11f8c828d016200ef13565b97505060606200f1328c828d016200ef6a565b96505060806200f1458c828d016200efcf565b95505060a06200f1588c828d016200f014565b94505060c06200f16b8c828d016200efcf565b93505060e06200f17e8c828d016200efcf565b9250506101006200f1928c828d016200f04f565b9150509295985092959850929598565b6200f1ad816200f02b565b82525050565b6200f1be816200efa1565b82525050565b600060a0820190506200f1db60008301886200f1a2565b6200f1ea60208301876200f1a2565b6200f1f960408301866200f1a2565b6200f20860608301856200f1b3565b6200f21760808301846200f1a2565b9695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200f29857607f821691505b602082108114156200f2af576200f2ae6200f250565b5b50919050565b6080516159166200f2d86000396000818161125901526112ad01526159166000f3fe60806040526004361061023b5760003560e01c80636352211e1161012e57806395d89b41116100ab578063b88d4fde1161006f578063b88d4fde146108c3578063c87b56dd146108ec578063ca02c4e414610929578063e985e9c514610966578063f2fde38b146109a35761023b565b806395d89b41146107db578063a22cb46514610806578063a3422ee11461082f578063a3e56fa81461085a578063b76c632b146108855761023b565b80637579de8f116100f25780637579de8f146106f45780638a71bb2d1461071d5780638da5cb5b14610748578063944c9efa14610773578063955648371461079e5761023b565b80636352211e146105fd5780636981e6071461063a5780636f6745011461066357806370a08231146106a0578063715018a6146106dd5761023b565b80631fe543e3116101bc578063416fe85c11610180578063416fe85c1461051c57806342842e0e1461054557806355f804b31461056e5780635b2ec42f1461059757806361ba27da146105d45761023b565b80631fe543e31461042557806323b872dd1461044e578063241ec797146104775780632a47f799146104b45780632d0335ab146104df5761023b565b80630b74b0f3116102035780630b74b0f3146103395780630c53c51c146103625780630f16e8751461039257806318160ddd146103cf5780631c4695f4146103fa5761023b565b806301ffc9a71461024057806306fdde031461027d578063081812fc146102a8578063095ea7b3146102e557806309c1ba2e1461030e575b600080fd5b34801561024c57600080fd5b506102676004803603810190610262919061372f565b6109cc565b6040516102749190613777565b60405180910390f35b34801561028957600080fd5b50610292610aae565b60405161029f919061382b565b60405180910390f35b3480156102b457600080fd5b506102cf60048036038101906102ca9190613883565b610b40565b6040516102dc91906138f1565b60405180910390f35b3480156102f157600080fd5b5061030c60048036038101906103079190613938565b610bc5565b005b34801561031a57600080fd5b50610323610cdd565b604051610330919061399b565b60405180910390f35b34801561034557600080fd5b50610360600480360381019061035b91906139f0565b610cf7565b005b61037c60048036038101906103779190613bc1565b610ed8565b6040516103899190613cad565b60405180910390f35b34801561039e57600080fd5b506103b960048036038101906103b49190613883565b611201565b6040516103c69190613777565b60405180910390f35b3480156103db57600080fd5b506103e461122b565b6040516103f19190613cde565b60405180910390f35b34801561040657600080fd5b5061040f611231565b60405161041c91906138f1565b60405180910390f35b34801561043157600080fd5b5061044c60048036038101906104479190613dc1565b611257565b005b34801561045a57600080fd5b5061047560048036038101906104709190613e1d565b611317565b005b34801561048357600080fd5b5061049e60048036038101906104999190613883565b611377565b6040516104ab9190613ee7565b60405180910390f35b3480156104c057600080fd5b506104c9611397565b6040516104d69190613cde565b60405180910390f35b3480156104eb57600080fd5b5061050660048036038101906105019190613f02565b61139d565b6040516105139190613cde565b60405180910390f35b34801561052857600080fd5b50610543600480360381019061053e9190613f5b565b6113e6565b005b34801561055157600080fd5b5061056c60048036038101906105679190613e1d565b611566565b005b34801561057a57600080fd5b506105956004803603810190610590919061403c565b611586565b005b3480156105a357600080fd5b506105be60048036038101906105b99190613883565b61165f565b6040516105cb9190613777565b60405180910390f35b3480156105e057600080fd5b506105fb60048036038101906105f69190613883565b61167f565b005b34801561060957600080fd5b50610624600480360381019061061f9190613883565b611733565b60405161063191906138f1565b60405180910390f35b34801561064657600080fd5b50610661600480360381019061065c9190613883565b6117e5565b005b34801561066f57600080fd5b5061068a60048036038101906106859190614085565b611ad7565b6040516106979190613ee7565b60405180910390f35b3480156106ac57600080fd5b506106c760048036038101906106c29190613f02565b611af7565b6040516106d49190613cde565b60405180910390f35b3480156106e957600080fd5b506106f2611baf565b005b34801561070057600080fd5b5061071b600480360381019061071691906140b2565b611c66565b005b34801561072957600080fd5b50610732611f1b565b60405161073f9190613cde565b60405180910390f35b34801561075457600080fd5b5061075d611f21565b60405161076a91906138f1565b60405180910390f35b34801561077f57600080fd5b50610788611f4b565b6040516107959190613777565b60405180910390f35b3480156107aa57600080fd5b506107c560048036038101906107c09190613883565b611f5e565b6040516107d29190614101565b60405180910390f35b3480156107e757600080fd5b506107f0611f96565b6040516107fd919061382b565b60405180910390f35b34801561081257600080fd5b5061082d60048036038101906108289190613f5b565b612028565b005b34801561083b57600080fd5b5061084461203e565b60405161085191906138f1565b60405180910390f35b34801561086657600080fd5b5061086f612064565b60405161087c91906138f1565b60405180910390f35b34801561089157600080fd5b506108ac60048036038101906108a79190613883565b61208a565b6040516108ba92919061411c565b60405180910390f35b3480156108cf57600080fd5b506108ea60048036038101906108e59190614145565b61210f565b005b3480156108f857600080fd5b50610913600480360381019061090e9190613883565b612171565b604051610920919061382b565b60405180910390f35b34801561093557600080fd5b50610950600480360381019061094b9190613f02565b61220e565b60405161095d9190613777565b60405180910390f35b34801561097257600080fd5b5061098d600480360381019061098891906141c8565b61222e565b60405161099a9190613777565b60405180910390f35b3480156109af57600080fd5b506109ca60048036038101906109c59190613f02565b6122c2565b005b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610a9757507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610aa75750610aa6826123ba565b5b9050919050565b606060008054610abd90614237565b80601f0160208091040260200160405190810160405280929190818152602001828054610ae990614237565b8015610b365780601f10610b0b57610100808354040283529160200191610b36565b820191906000526020600020905b815481529060010190602001808311610b1957829003601f168201915b5050505050905090565b6000610b4b82612424565b610b8a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b81906142db565b60405180910390fd5b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610bd082611733565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610c41576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c3890614347565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610c60612490565b73ffffffffffffffffffffffffffffffffffffffff161480610c8f5750610c8e81610c89612490565b61222e565b5b610cce576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cc5906143d9565b60405180910390fd5b610cd88383612541565b505050565b600d60149054906101000a900467ffffffffffffffff1681565b610cff6125fa565b73ffffffffffffffffffffffffffffffffffffffff16610d1d611f21565b73ffffffffffffffffffffffffffffffffffffffff1614610d73576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d6a90614445565b60405180910390fd5b601960009054906101000a900460ff1615610dc3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dba906144b1565b60405180910390fd5b8061ffff16601381905550600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635d3b1d30601054600d60149054906101000a900467ffffffffffffffff16601160049054906101000a900461ffff16601160009054906101000a900463ffffffff16601160069054906101000a900463ffffffff166040518663ffffffff1660e01b8152600401610e7d9594939291906144ff565b602060405180830381600087803b158015610e9757600080fd5b505af1158015610eab573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ecf9190614567565b60148190555050565b60606000610ee586612602565b90506000357fffffffff00000000000000000000000000000000000000000000000000000000167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161415610f8c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f8390614606565b60405180910390fd5b60006040518060600160405280600960008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205481526020018973ffffffffffffffffffffffffffffffffffffffff16815260200188815250905061100d8882888888612626565b61104c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161104390614698565b60405180910390fd5b61109f6001600960008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461273590919063ffffffff16565b600960008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506000803073ffffffffffffffffffffffffffffffffffffffff16898b60405160200161110f92919061473c565b60405160208183030381529060405260405161112b9190614764565b6000604051808303816000865af19150503d8060008114611168576040519150601f19603f3d011682016040523d82523d6000602084013e61116d565b606091505b50915091508181906111b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111ac919061382b565b60405180910390fd5b507f5845892132946850460bff5a0083f71031bc5bf9aadcd40f1de79423eac9b10b8a338b6040516111e99392919061479c565b60405180910390a18094505050505095945050505050565b6000601b600083815260200190815260200160002060009054906101000a900460ff169050919050565b60175481565b600f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461130957337f00000000000000000000000000000000000000000000000000000000000000006040517f1cf993f40000000000000000000000000000000000000000000000000000000081526004016113009291906147da565b60405180910390fd5b611313828261274b565b5050565b611328611322612490565b826127a5565b611367576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161135e9061484f565b60405180910390fd5b611372838383612883565b505050565b601c6020528060005260406000206000915054906101000a900460ff1681565b61134781565b6000600960008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6113ee6125fa565b73ffffffffffffffffffffffffffffffffffffffff1661140c611f21565b73ffffffffffffffffffffffffffffffffffffffff1614611462576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161145990614445565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156114d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114c9906148bb565b60405180910390fd5b80601a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507f28498b2887c2a8668a9cf37cc647babb044c0ab0380b752baa6c5da9ca1d0b5f828260405161155a9291906148db565b60405180910390a15050565b6115818383836040518060200160405280600081525061210f565b505050565b61158e6125fa565b73ffffffffffffffffffffffffffffffffffffffff166115ac611f21565b73ffffffffffffffffffffffffffffffffffffffff1614611602576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115f990614445565b60405180910390fd5b80601590805190602001906116189291906135e0565b50601560405161162891906149a3565b60405180910390207f24a9152dc695ecc801ad580886331ee12d7aac0fa2ae341a5ae3c2ccae36cb4f60405160405180910390a250565b601b6020528060005260406000206000915054906101000a900460ff1681565b6116876125fa565b73ffffffffffffffffffffffffffffffffffffffff166116a5611f21565b73ffffffffffffffffffffffffffffffffffffffff16146116fb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116f290614445565b60405180910390fd5b806018819055506018547ec89f607338c43f69cf5b28786c5f2b43b2be84f09f4ad3bc93e97447de142760405160405180910390a250565b6000806002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156117dc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117d390614a2c565b60405180910390fd5b80915050919050565b6117f66117f0612490565b826127a5565b611835576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161182c9061484f565b60405180910390fd5b601960009054906101000a900460ff16611884576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161187b90614a98565b60405180910390fd5b601b600082815260200190815260200160002060009054906101000a900460ff16156118e5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118dc90614b04565b60405180910390fd5b6001601b600083815260200190815260200160002060006101000a81548160ff02191690831515021790555061191a81612aea565b6000600b80549050601254836013546119339190614b53565b61193d9190614bad565b6119479190614c32565b90506000600b828154811061195f5761195e614c63565b5b90600052602060002090601091828204019190066002029054906101000a900461ffff169050600060018261ffff16101580156119a15750604b8261ffff1611155b156119af57600290506119d5565b604c8261ffff16101580156119ca57506102ee8261ffff1611155b156119d457600190505b5b6000601960019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060008173ffffffffffffffffffffffffffffffffffffffff16633807aabd611a22612490565b866040518363ffffffff1660e01b8152600401611a40929190614ccd565b602060405180830381600087803b158015611a5a57600080fd5b505af1158015611a6e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a929190614567565b90507f636094fd65795f24380cbd1bb4b2587fd8d385720be2091b4cd9042af8722ecd868285604051611ac793929190614cf6565b60405180910390a1505050505050565b601d6020528060005260406000206000915054906101000a900460ff1681565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611b68576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b5f90614d9f565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b611bb76125fa565b73ffffffffffffffffffffffffffffffffffffffff16611bd5611f21565b73ffffffffffffffffffffffffffffffffffffffff1614611c2b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c2290614445565b60405180910390fd5b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c5d90614e0b565b60405180910390fd5b601a6000611c72612490565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1680611cfe5750611cc8612490565b73ffffffffffffffffffffffffffffffffffffffff16611ce6611f21565b73ffffffffffffffffffffffffffffffffffffffff16145b611d3d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d3490614e77565b60405180910390fd5b6002600a541415611d83576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d7a90614ee3565b60405180910390fd5b6002600a81905550600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611dfb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611df290614f4f565b60405180910390fd5b601960009054906101000a900460ff1615611e4b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e4290614fe1565b60405180910390fd5b611347611e638360175461273590919063ffffffff16565b1115611ea4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e9b9061504d565b60405180910390fd5b60005b82811015611f0e57611ec5600160175461273590919063ffffffff16565b601681905550611ee1600160175461273590919063ffffffff16565b601781905550611ef382601654612b3d565b611f0760018261273590919063ffffffff16565b9050611ea7565b506001600a819055505050565b60185481565b6000600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b601960009054906101000a900460ff1681565b600b8181548110611f6e57600080fd5b9060005260206000209060109182820401919006600202915054906101000a900461ffff1681565b606060018054611fa590614237565b80601f0160208091040260200160405190810160405280929190818152602001828054611fd190614237565b801561201e5780601f10611ff35761010080835404028352916020019161201e565b820191906000526020600020905b81548152906001019060200180831161200157829003601f168201915b5050505050905090565b61203a6120336125fa565b8383612b5b565b5050565b601960019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600080600083116120d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120c7906150b9565b60405180910390fd5b60006120fa60646120ec60185487612cc890919063ffffffff16565b612cde90919063ffffffff16565b905080612105611f21565b9250925050915091565b61212061211a612490565b836127a5565b61215f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121569061484f565b60405180910390fd5b61216b84848484612cf4565b50505050565b60606000601754141561218d57612186612d50565b9050612209565b61219682612424565b6121d5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121cc90615125565b60405180910390fd5b6121dd612d50565b6121e683612de2565b6040516020016121f7929190615176565b60405160208183030381529060405290505b919050565b601a6020528060005260406000206000915054906101000a900460ff1681565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6122ca6125fa565b73ffffffffffffffffffffffffffffffffffffffff166122e8611f21565b73ffffffffffffffffffffffffffffffffffffffff161461233e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161233590614445565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156123ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123a59061520c565b60405180910390fd5b6123b781612f43565b50565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b60008073ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b60003073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561253a57600080368080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509050600080369050905073ffffffffffffffffffffffffffffffffffffffff81830151169250505061253e565b3390505b90565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff166125b483611733565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600033905090565b6000808251141561261957600060e01b9050612621565b602082015190505b919050565b600080600161263c61263788613009565b613071565b8487876040516000815260200160405260405161265c949392919061523b565b6020604051602081039080840390855afa15801561267e573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156126fa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126f1906152cc565b60405180910390fd5b8673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161491505095945050505050565b600081836127439190614bad565b905092915050565b61278066038d7ea4c67fff8260008151811061276a57612769614c63565b5b60200260200101516130aa90919063ffffffff16565b6012819055506001601960006101000a81548160ff0219169083151502179055505050565b60006127b082612424565b6127ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127e69061535e565b60405180910390fd5b60006127fa83611733565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16148061286957508373ffffffffffffffffffffffffffffffffffffffff1661285184610b40565b73ffffffffffffffffffffffffffffffffffffffff16145b8061287a5750612879818561222e565b5b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff166128a382611733565b73ffffffffffffffffffffffffffffffffffffffff16146128f9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128f0906153f0565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612969576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161296090615482565b60405180910390fd5b6129748383836130c0565b61297f600082612541565b6001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546129cf91906154a2565b925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612a269190614bad565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4612ae58383836130c5565b505050565b612af3816130ca565b6000600660008381526020019081526020016000208054612b1390614237565b905014612b3a57600660008281526020019081526020016000206000612b399190613666565b5b50565b612b578282604051806020016040528060008152506131e7565b5050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415612bca576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612bc190615522565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051612cbb9190613777565b60405180910390a3505050565b60008183612cd69190614b53565b905092915050565b60008183612cec9190615542565b905092915050565b612cff848484612883565b612d0b84848484613242565b612d4a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d41906155e5565b60405180910390fd5b50505050565b606060158054612d5f90614237565b80601f0160208091040260200160405190810160405280929190818152602001828054612d8b90614237565b8015612dd85780601f10612dad57610100808354040283529160200191612dd8565b820191906000526020600020905b815481529060010190602001808311612dbb57829003601f168201915b5050505050905090565b60606000821415612e2a576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050612f3e565b600082905060005b60008214612e5c578080612e4590615605565b915050600a82612e559190615542565b9150612e32565b60008167ffffffffffffffff811115612e7857612e77613a27565b5b6040519080825280601f01601f191660200182016040528015612eaa5781602001600182028036833780820191505090505b5090505b60008514612f3757600182612ec391906154a2565b9150600a85612ed29190614c32565b6030612ede9190614bad565b60f81b818381518110612ef457612ef3614c63565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a85612f309190615542565b9450612eae565b8093505050505b919050565b6000600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600060405180608001604052806043815260200161589e604391398051906020012082600001518360200151846040015180519060200120604051602001613054949392919061564e565b604051602081830303815290604052805190602001209050919050565b600061307b6133d9565b8260405160200161308d929190615700565b604051602081830303815290604052805190602001209050919050565b600081836130b89190614c32565b905092915050565b505050565b505050565b60006130d582611733565b90506130e3816000846130c0565b6130ee600083612541565b6001600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461313e91906154a2565b925050819055506002600083815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905581600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46131e3816000846130c5565b5050565b6131f183836133e3565b6131fe6000848484613242565b61323d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613234906155e5565b60405180910390fd5b505050565b60006132638473ffffffffffffffffffffffffffffffffffffffff166135bd565b156133cc578373ffffffffffffffffffffffffffffffffffffffff1663150b7a0261328c6125fa565b8786866040518563ffffffff1660e01b81526004016132ae9493929190615737565b602060405180830381600087803b1580156132c857600080fd5b505af19250505080156132f957506040513d601f19601f820116820180604052508101906132f69190615798565b60015b61337c573d8060008114613329576040519150601f19603f3d011682016040523d82523d6000602084013e61332e565b606091505b50600081511415613374576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161336b906155e5565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149150506133d1565b600190505b949350505050565b6000600854905090565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415613453576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161344a90615811565b60405180910390fd5b61345c81612424565b1561349c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016134939061587d565b60405180910390fd5b6134a8600083836130c0565b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546134f89190614bad565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46135b9600083836130c5565b5050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b8280546135ec90614237565b90600052602060002090601f01602090048101928261360e5760008555613655565b82601f1061362757805160ff1916838001178555613655565b82800160010185558215613655579182015b82811115613654578251825591602001919060010190613639565b5b50905061366291906136a6565b5090565b50805461367290614237565b6000825580601f1061368457506136a3565b601f0160209004906000526020600020908101906136a291906136a6565b5b50565b5b808211156136bf5760008160009055506001016136a7565b5090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61370c816136d7565b811461371757600080fd5b50565b60008135905061372981613703565b92915050565b600060208284031215613745576137446136cd565b5b60006137538482850161371a565b91505092915050565b60008115159050919050565b6137718161375c565b82525050565b600060208201905061378c6000830184613768565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156137cc5780820151818401526020810190506137b1565b838111156137db576000848401525b50505050565b6000601f19601f8301169050919050565b60006137fd82613792565b613807818561379d565b93506138178185602086016137ae565b613820816137e1565b840191505092915050565b6000602082019050818103600083015261384581846137f2565b905092915050565b6000819050919050565b6138608161384d565b811461386b57600080fd5b50565b60008135905061387d81613857565b92915050565b600060208284031215613899576138986136cd565b5b60006138a78482850161386e565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006138db826138b0565b9050919050565b6138eb816138d0565b82525050565b600060208201905061390660008301846138e2565b92915050565b613915816138d0565b811461392057600080fd5b50565b6000813590506139328161390c565b92915050565b6000806040838503121561394f5761394e6136cd565b5b600061395d85828601613923565b925050602061396e8582860161386e565b9150509250929050565b600067ffffffffffffffff82169050919050565b61399581613978565b82525050565b60006020820190506139b0600083018461398c565b92915050565b600061ffff82169050919050565b6139cd816139b6565b81146139d857600080fd5b50565b6000813590506139ea816139c4565b92915050565b600060208284031215613a0657613a056136cd565b5b6000613a14848285016139db565b91505092915050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613a5f826137e1565b810181811067ffffffffffffffff82111715613a7e57613a7d613a27565b5b80604052505050565b6000613a916136c3565b9050613a9d8282613a56565b919050565b600067ffffffffffffffff821115613abd57613abc613a27565b5b613ac6826137e1565b9050602081019050919050565b82818337600083830152505050565b6000613af5613af084613aa2565b613a87565b905082815260208101848484011115613b1157613b10613a22565b5b613b1c848285613ad3565b509392505050565b600082601f830112613b3957613b38613a1d565b5b8135613b49848260208601613ae2565b91505092915050565b6000819050919050565b613b6581613b52565b8114613b7057600080fd5b50565b600081359050613b8281613b5c565b92915050565b600060ff82169050919050565b613b9e81613b88565b8114613ba957600080fd5b50565b600081359050613bbb81613b95565b92915050565b600080600080600060a08688031215613bdd57613bdc6136cd565b5b6000613beb88828901613923565b955050602086013567ffffffffffffffff811115613c0c57613c0b6136d2565b5b613c1888828901613b24565b9450506040613c2988828901613b73565b9350506060613c3a88828901613b73565b9250506080613c4b88828901613bac565b9150509295509295909350565b600081519050919050565b600082825260208201905092915050565b6000613c7f82613c58565b613c898185613c63565b9350613c998185602086016137ae565b613ca2816137e1565b840191505092915050565b60006020820190508181036000830152613cc78184613c74565b905092915050565b613cd88161384d565b82525050565b6000602082019050613cf36000830184613ccf565b92915050565b600067ffffffffffffffff821115613d1457613d13613a27565b5b602082029050602081019050919050565b600080fd5b6000613d3d613d3884613cf9565b613a87565b90508083825260208201905060208402830185811115613d6057613d5f613d25565b5b835b81811015613d895780613d75888261386e565b845260208401935050602081019050613d62565b5050509392505050565b600082601f830112613da857613da7613a1d565b5b8135613db8848260208601613d2a565b91505092915050565b60008060408385031215613dd857613dd76136cd565b5b6000613de68582860161386e565b925050602083013567ffffffffffffffff811115613e0757613e066136d2565b5b613e1385828601613d93565b9150509250929050565b600080600060608486031215613e3657613e356136cd565b5b6000613e4486828701613923565b9350506020613e5586828701613923565b9250506040613e668682870161386e565b9150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60038110613eb057613eaf613e70565b5b50565b6000819050613ec182613e9f565b919050565b6000613ed182613eb3565b9050919050565b613ee181613ec6565b82525050565b6000602082019050613efc6000830184613ed8565b92915050565b600060208284031215613f1857613f176136cd565b5b6000613f2684828501613923565b91505092915050565b613f388161375c565b8114613f4357600080fd5b50565b600081359050613f5581613f2f565b92915050565b60008060408385031215613f7257613f716136cd565b5b6000613f8085828601613923565b9250506020613f9185828601613f46565b9150509250929050565b600067ffffffffffffffff821115613fb657613fb5613a27565b5b613fbf826137e1565b9050602081019050919050565b6000613fdf613fda84613f9b565b613a87565b905082815260208101848484011115613ffb57613ffa613a22565b5b614006848285613ad3565b509392505050565b600082601f83011261402357614022613a1d565b5b8135614033848260208601613fcc565b91505092915050565b600060208284031215614052576140516136cd565b5b600082013567ffffffffffffffff8111156140705761406f6136d2565b5b61407c8482850161400e565b91505092915050565b60006020828403121561409b5761409a6136cd565b5b60006140a984828501613bac565b91505092915050565b600080604083850312156140c9576140c86136cd565b5b60006140d78582860161386e565b92505060206140e885828601613923565b9150509250929050565b6140fb816139b6565b82525050565b600060208201905061411660008301846140f2565b92915050565b60006040820190506141316000830185613ccf565b61413e60208301846138e2565b9392505050565b6000806000806080858703121561415f5761415e6136cd565b5b600061416d87828801613923565b945050602061417e87828801613923565b935050604061418f8782880161386e565b925050606085013567ffffffffffffffff8111156141b0576141af6136d2565b5b6141bc87828801613b24565b91505092959194509250565b600080604083850312156141df576141de6136cd565b5b60006141ed85828601613923565b92505060206141fe85828601613923565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061424f57607f821691505b6020821081141561426357614262614208565b5b50919050565b7f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860008201527f697374656e7420746f6b656e0000000000000000000000000000000000000000602082015250565b60006142c5602c8361379d565b91506142d082614269565b604082019050919050565b600060208201905081810360008301526142f4816142b8565b9050919050565b7f4552433732313a415050524f56414c5f544f5f43555252454e545f4f574e4552600082015250565b600061433160208361379d565b915061433c826142fb565b602082019050919050565b6000602082019050818103600083015261436081614324565b9050919050565b7f4552433732313a415050524f56455f43414c4c45525f4e4f545f4f574e45525f60008201527f4f525f415050524f5645445f464f525f414c4c00000000000000000000000000602082015250565b60006143c360338361379d565b91506143ce82614367565b604082019050919050565b600060208201905081810360008301526143f2816143b6565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b600061442f60208361379d565b915061443a826143f9565b602082019050919050565b6000602082019050818103600083015261445e81614422565b9050919050565b7f52455645414c5f50484153455f414c52454144595f494e495449415445440000600082015250565b600061449b601e8361379d565b91506144a682614465565b602082019050919050565b600060208201905081810360008301526144ca8161448e565b9050919050565b6144da81613b52565b82525050565b600063ffffffff82169050919050565b6144f9816144e0565b82525050565b600060a08201905061451460008301886144d1565b614521602083018761398c565b61452e60408301866140f2565b61453b60608301856144f0565b61454860808301846144f0565b9695505050505050565b60008151905061456181613857565b92915050565b60006020828403121561457d5761457c6136cd565b5b600061458b84828501614552565b91505092915050565b7f66756e6374696f6e5369676e61747572652063616e206e6f74206265206f662060008201527f657865637574654d6574615472616e73616374696f6e206d6574686f64000000602082015250565b60006145f0603d8361379d565b91506145fb82614594565b604082019050919050565b6000602082019050818103600083015261461f816145e3565b9050919050565b7f5369676e657220616e64207369676e617475726520646f206e6f74206d61746360008201527f6800000000000000000000000000000000000000000000000000000000000000602082015250565b600061468260218361379d565b915061468d82614626565b604082019050919050565b600060208201905081810360008301526146b181614675565b9050919050565b600081905092915050565b60006146ce82613c58565b6146d881856146b8565b93506146e88185602086016137ae565b80840191505092915050565b60008160601b9050919050565b600061470c826146f4565b9050919050565b600061471e82614701565b9050919050565b614736614731826138d0565b614713565b82525050565b600061474882856146c3565b91506147548284614725565b6014820191508190509392505050565b600061477082846146c3565b915081905092915050565b6000614786826138b0565b9050919050565b6147968161477b565b82525050565b60006060820190506147b160008301866138e2565b6147be602083018561478d565b81810360408301526147d08184613c74565b9050949350505050565b60006040820190506147ef60008301856138e2565b6147fc60208301846138e2565b9392505050565b7f43414c4c45525f4e4f545f415050524f56454400000000000000000000000000600082015250565b600061483960138361379d565b915061484482614803565b602082019050919050565b600060208201905081810360008301526148688161482c565b9050919050565b7f494e56414c49445f414444524553530000000000000000000000000000000000600082015250565b60006148a5600f8361379d565b91506148b08261486f565b602082019050919050565b600060208201905081810360008301526148d481614898565b9050919050565b60006040820190506148f060008301856138e2565b6148fd6020830184613768565b9392505050565b600081905092915050565b60008190508160005260206000209050919050565b6000815461493181614237565b61493b8186614904565b9450600182166000811461495657600181146149675761499a565b60ff1983168652818601935061499a565b6149708561490f565b60005b8381101561499257815481890152600182019150602081019050614973565b838801955050505b50505092915050565b60006149af8284614924565b915081905092915050565b7f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460008201527f656e7420746f6b656e0000000000000000000000000000000000000000000000602082015250565b6000614a1660298361379d565b9150614a21826149ba565b604082019050919050565b60006020820190508181036000830152614a4581614a09565b9050919050565b7f52455645414c5f50484153455f4e4f545f494e49544941544544000000000000600082015250565b6000614a82601a8361379d565b9150614a8d82614a4c565b602082019050919050565b60006020820190508181036000830152614ab181614a75565b9050919050565b7f424f585f414c52454144595f52455645414c4544000000000000000000000000600082015250565b6000614aee60148361379d565b9150614af982614ab8565b602082019050919050565b60006020820190508181036000830152614b1d81614ae1565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000614b5e8261384d565b9150614b698361384d565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615614ba257614ba1614b24565b5b828202905092915050565b6000614bb88261384d565b9150614bc38361384d565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115614bf857614bf7614b24565b5b828201905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000614c3d8261384d565b9150614c488361384d565b925082614c5857614c57614c03565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000819050919050565b6000614cb7614cb2614cad846139b6565b614c92565b61384d565b9050919050565b614cc781614c9c565b82525050565b6000604082019050614ce260008301856138e2565b614cef6020830184614cbe565b9392505050565b6000606082019050614d0b6000830186613ccf565b614d186020830185613ccf565b614d256040830184613ed8565b949350505050565b7f4552433732313a2062616c616e636520717565727920666f7220746865207a6560008201527f726f206164647265737300000000000000000000000000000000000000000000602082015250565b6000614d89602a8361379d565b9150614d9482614d2d565b604082019050919050565b60006020820190508181036000830152614db881614d7c565b9050919050565b7f43414e5f4e4f545f52454e4f554e43455f4f574e455253484950000000000000600082015250565b6000614df5601a8361379d565b9150614e0082614dbf565b602082019050919050565b60006020820190508181036000830152614e2481614de8565b9050919050565b7f554e415554484f52495a45445f41434345535300000000000000000000000000600082015250565b6000614e6160138361379d565b9150614e6c82614e2b565b602082019050919050565b60006020820190508181036000830152614e9081614e54565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000614ecd601f8361379d565b9150614ed882614e97565b602082019050919050565b60006020820190508181036000830152614efc81614ec0565b9050919050565b7f414444524553535f43414e5f4e4f545f42455f5a45524f000000000000000000600082015250565b6000614f3960178361379d565b9150614f4482614f03565b602082019050919050565b60006020820190508181036000830152614f6881614f2c565b9050919050565b7f5045524d495353494f4e5f44454e4945445f52455645414c5f50484153455f5360008201527f5441525445440000000000000000000000000000000000000000000000000000602082015250565b6000614fcb60268361379d565b9150614fd682614f6f565b604082019050919050565b60006020820190508181036000830152614ffa81614fbe565b9050919050565b7f4d41585f5055424c49435f535550504c595f5245414348454400000000000000600082015250565b600061503760198361379d565b915061504282615001565b602082019050919050565b600060208201905081810360008301526150668161502a565b9050919050565b7f50524943455f43414e5f4e4f545f42455f5a45524f0000000000000000000000600082015250565b60006150a360158361379d565b91506150ae8261506d565b602082019050919050565b600060208201905081810360008301526150d281615096565b9050919050565b7f544f4b454e5f444f45535f4e4f545f4558495354000000000000000000000000600082015250565b600061510f60148361379d565b915061511a826150d9565b602082019050919050565b6000602082019050818103600083015261513e81615102565b9050919050565b600061515082613792565b61515a8185614904565b935061516a8185602086016137ae565b80840191505092915050565b60006151828285615145565b915061518e8284615145565b91508190509392505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b60006151f660268361379d565b91506152018261519a565b604082019050919050565b60006020820190508181036000830152615225816151e9565b9050919050565b61523581613b88565b82525050565b600060808201905061525060008301876144d1565b61525d602083018661522c565b61526a60408301856144d1565b61527760608301846144d1565b95945050505050565b7f496e76616c6964207369676e6174757265000000000000000000000000000000600082015250565b60006152b660118361379d565b91506152c182615280565b602082019050919050565b600060208201905081810360008301526152e5816152a9565b9050919050565b7f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860008201527f697374656e7420746f6b656e0000000000000000000000000000000000000000602082015250565b6000615348602c8361379d565b9150615353826152ec565b604082019050919050565b600060208201905081810360008301526153778161533b565b9050919050565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b60006153da60258361379d565b91506153e58261537e565b604082019050919050565b60006020820190508181036000830152615409816153cd565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b600061546c60248361379d565b915061547782615410565b604082019050919050565b6000602082019050818103600083015261549b8161545f565b9050919050565b60006154ad8261384d565b91506154b88361384d565b9250828210156154cb576154ca614b24565b5b828203905092915050565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b600061550c60198361379d565b9150615517826154d6565b602082019050919050565b6000602082019050818103600083015261553b816154ff565b9050919050565b600061554d8261384d565b91506155588361384d565b92508261556857615567614c03565b5b828204905092915050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b60006155cf60328361379d565b91506155da82615573565b604082019050919050565b600060208201905081810360008301526155fe816155c2565b9050919050565b60006156108261384d565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561564357615642614b24565b5b600182019050919050565b600060808201905061566360008301876144d1565b6156706020830186613ccf565b61567d60408301856138e2565b61568a60608301846144d1565b95945050505050565b7f1901000000000000000000000000000000000000000000000000000000000000600082015250565b60006156c9600283614904565b91506156d482615693565b600282019050919050565b6000819050919050565b6156fa6156f582613b52565b6156df565b82525050565b600061570b826156bc565b915061571782856156e9565b60208201915061572782846156e9565b6020820191508190509392505050565b600060808201905061574c60008301876138e2565b61575960208301866138e2565b6157666040830185613ccf565b81810360608301526157788184613c74565b905095945050505050565b60008151905061579281613703565b92915050565b6000602082840312156157ae576157ad6136cd565b5b60006157bc84828501615783565b91505092915050565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b60006157fb60208361379d565b9150615806826157c5565b602082019050919050565b6000602082019050818103600083015261582a816157ee565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b6000615867601c8361379d565b915061587282615831565b602082019050919050565b600060208201905081810360008301526158968161585a565b905091905056fe4d6574615472616e73616374696f6e2875696e74323536206e6f6e63652c616464726573732066726f6d2c62797465732066756e6374696f6e5369676e617475726529a264697066735822122023eef793dde2f7dd3a2f472ea4e657bee39ab8e2a292fc8abb4264573353bf5464736f6c63430008090033454950373132446f6d61696e28737472696e67206e616d652c737472696e672076657273696f6e2c6164647265737320766572696679696e67436f6e74726163742c627974657333322073616c74290000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000eb6c5accafd8515c1b9e4c794bdc41532c5543ec0000000000000000000000000000000000000000000000000000000000000059000000000000000000000000271682deb8c4e0901d1a1550ad2e64d568e69909000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca9fe0eebf5e446e3c998ec9bb19951541aee00bb90ea201ae456421a2ded86805000000000000000000000000000000000000000000000000000000000000000e444746616d696c7920476c61737300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000074447474c41535300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002d68747470733a2f2f6e6674732e756e78642e636f6d2f6e6674732f646766616d696c792d676c617373626f782f00000000000000000000000000000000000000

Deployed Bytecode

0x60806040526004361061023b5760003560e01c80636352211e1161012e57806395d89b41116100ab578063b88d4fde1161006f578063b88d4fde146108c3578063c87b56dd146108ec578063ca02c4e414610929578063e985e9c514610966578063f2fde38b146109a35761023b565b806395d89b41146107db578063a22cb46514610806578063a3422ee11461082f578063a3e56fa81461085a578063b76c632b146108855761023b565b80637579de8f116100f25780637579de8f146106f45780638a71bb2d1461071d5780638da5cb5b14610748578063944c9efa14610773578063955648371461079e5761023b565b80636352211e146105fd5780636981e6071461063a5780636f6745011461066357806370a08231146106a0578063715018a6146106dd5761023b565b80631fe543e3116101bc578063416fe85c11610180578063416fe85c1461051c57806342842e0e1461054557806355f804b31461056e5780635b2ec42f1461059757806361ba27da146105d45761023b565b80631fe543e31461042557806323b872dd1461044e578063241ec797146104775780632a47f799146104b45780632d0335ab146104df5761023b565b80630b74b0f3116102035780630b74b0f3146103395780630c53c51c146103625780630f16e8751461039257806318160ddd146103cf5780631c4695f4146103fa5761023b565b806301ffc9a71461024057806306fdde031461027d578063081812fc146102a8578063095ea7b3146102e557806309c1ba2e1461030e575b600080fd5b34801561024c57600080fd5b506102676004803603810190610262919061372f565b6109cc565b6040516102749190613777565b60405180910390f35b34801561028957600080fd5b50610292610aae565b60405161029f919061382b565b60405180910390f35b3480156102b457600080fd5b506102cf60048036038101906102ca9190613883565b610b40565b6040516102dc91906138f1565b60405180910390f35b3480156102f157600080fd5b5061030c60048036038101906103079190613938565b610bc5565b005b34801561031a57600080fd5b50610323610cdd565b604051610330919061399b565b60405180910390f35b34801561034557600080fd5b50610360600480360381019061035b91906139f0565b610cf7565b005b61037c60048036038101906103779190613bc1565b610ed8565b6040516103899190613cad565b60405180910390f35b34801561039e57600080fd5b506103b960048036038101906103b49190613883565b611201565b6040516103c69190613777565b60405180910390f35b3480156103db57600080fd5b506103e461122b565b6040516103f19190613cde565b60405180910390f35b34801561040657600080fd5b5061040f611231565b60405161041c91906138f1565b60405180910390f35b34801561043157600080fd5b5061044c60048036038101906104479190613dc1565b611257565b005b34801561045a57600080fd5b5061047560048036038101906104709190613e1d565b611317565b005b34801561048357600080fd5b5061049e60048036038101906104999190613883565b611377565b6040516104ab9190613ee7565b60405180910390f35b3480156104c057600080fd5b506104c9611397565b6040516104d69190613cde565b60405180910390f35b3480156104eb57600080fd5b5061050660048036038101906105019190613f02565b61139d565b6040516105139190613cde565b60405180910390f35b34801561052857600080fd5b50610543600480360381019061053e9190613f5b565b6113e6565b005b34801561055157600080fd5b5061056c60048036038101906105679190613e1d565b611566565b005b34801561057a57600080fd5b506105956004803603810190610590919061403c565b611586565b005b3480156105a357600080fd5b506105be60048036038101906105b99190613883565b61165f565b6040516105cb9190613777565b60405180910390f35b3480156105e057600080fd5b506105fb60048036038101906105f69190613883565b61167f565b005b34801561060957600080fd5b50610624600480360381019061061f9190613883565b611733565b60405161063191906138f1565b60405180910390f35b34801561064657600080fd5b50610661600480360381019061065c9190613883565b6117e5565b005b34801561066f57600080fd5b5061068a60048036038101906106859190614085565b611ad7565b6040516106979190613ee7565b60405180910390f35b3480156106ac57600080fd5b506106c760048036038101906106c29190613f02565b611af7565b6040516106d49190613cde565b60405180910390f35b3480156106e957600080fd5b506106f2611baf565b005b34801561070057600080fd5b5061071b600480360381019061071691906140b2565b611c66565b005b34801561072957600080fd5b50610732611f1b565b60405161073f9190613cde565b60405180910390f35b34801561075457600080fd5b5061075d611f21565b60405161076a91906138f1565b60405180910390f35b34801561077f57600080fd5b50610788611f4b565b6040516107959190613777565b60405180910390f35b3480156107aa57600080fd5b506107c560048036038101906107c09190613883565b611f5e565b6040516107d29190614101565b60405180910390f35b3480156107e757600080fd5b506107f0611f96565b6040516107fd919061382b565b60405180910390f35b34801561081257600080fd5b5061082d60048036038101906108289190613f5b565b612028565b005b34801561083b57600080fd5b5061084461203e565b60405161085191906138f1565b60405180910390f35b34801561086657600080fd5b5061086f612064565b60405161087c91906138f1565b60405180910390f35b34801561089157600080fd5b506108ac60048036038101906108a79190613883565b61208a565b6040516108ba92919061411c565b60405180910390f35b3480156108cf57600080fd5b506108ea60048036038101906108e59190614145565b61210f565b005b3480156108f857600080fd5b50610913600480360381019061090e9190613883565b612171565b604051610920919061382b565b60405180910390f35b34801561093557600080fd5b50610950600480360381019061094b9190613f02565b61220e565b60405161095d9190613777565b60405180910390f35b34801561097257600080fd5b5061098d600480360381019061098891906141c8565b61222e565b60405161099a9190613777565b60405180910390f35b3480156109af57600080fd5b506109ca60048036038101906109c59190613f02565b6122c2565b005b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610a9757507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610aa75750610aa6826123ba565b5b9050919050565b606060008054610abd90614237565b80601f0160208091040260200160405190810160405280929190818152602001828054610ae990614237565b8015610b365780601f10610b0b57610100808354040283529160200191610b36565b820191906000526020600020905b815481529060010190602001808311610b1957829003601f168201915b5050505050905090565b6000610b4b82612424565b610b8a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b81906142db565b60405180910390fd5b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610bd082611733565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610c41576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c3890614347565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610c60612490565b73ffffffffffffffffffffffffffffffffffffffff161480610c8f5750610c8e81610c89612490565b61222e565b5b610cce576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cc5906143d9565b60405180910390fd5b610cd88383612541565b505050565b600d60149054906101000a900467ffffffffffffffff1681565b610cff6125fa565b73ffffffffffffffffffffffffffffffffffffffff16610d1d611f21565b73ffffffffffffffffffffffffffffffffffffffff1614610d73576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d6a90614445565b60405180910390fd5b601960009054906101000a900460ff1615610dc3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dba906144b1565b60405180910390fd5b8061ffff16601381905550600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635d3b1d30601054600d60149054906101000a900467ffffffffffffffff16601160049054906101000a900461ffff16601160009054906101000a900463ffffffff16601160069054906101000a900463ffffffff166040518663ffffffff1660e01b8152600401610e7d9594939291906144ff565b602060405180830381600087803b158015610e9757600080fd5b505af1158015610eab573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ecf9190614567565b60148190555050565b60606000610ee586612602565b90506000357fffffffff00000000000000000000000000000000000000000000000000000000167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161415610f8c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f8390614606565b60405180910390fd5b60006040518060600160405280600960008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205481526020018973ffffffffffffffffffffffffffffffffffffffff16815260200188815250905061100d8882888888612626565b61104c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161104390614698565b60405180910390fd5b61109f6001600960008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461273590919063ffffffff16565b600960008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506000803073ffffffffffffffffffffffffffffffffffffffff16898b60405160200161110f92919061473c565b60405160208183030381529060405260405161112b9190614764565b6000604051808303816000865af19150503d8060008114611168576040519150601f19603f3d011682016040523d82523d6000602084013e61116d565b606091505b50915091508181906111b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111ac919061382b565b60405180910390fd5b507f5845892132946850460bff5a0083f71031bc5bf9aadcd40f1de79423eac9b10b8a338b6040516111e99392919061479c565b60405180910390a18094505050505095945050505050565b6000601b600083815260200190815260200160002060009054906101000a900460ff169050919050565b60175481565b600f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b7f000000000000000000000000271682deb8c4e0901d1a1550ad2e64d568e6990973ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461130957337f000000000000000000000000271682deb8c4e0901d1a1550ad2e64d568e699096040517f1cf993f40000000000000000000000000000000000000000000000000000000081526004016113009291906147da565b60405180910390fd5b611313828261274b565b5050565b611328611322612490565b826127a5565b611367576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161135e9061484f565b60405180910390fd5b611372838383612883565b505050565b601c6020528060005260406000206000915054906101000a900460ff1681565b61134781565b6000600960008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6113ee6125fa565b73ffffffffffffffffffffffffffffffffffffffff1661140c611f21565b73ffffffffffffffffffffffffffffffffffffffff1614611462576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161145990614445565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156114d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114c9906148bb565b60405180910390fd5b80601a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507f28498b2887c2a8668a9cf37cc647babb044c0ab0380b752baa6c5da9ca1d0b5f828260405161155a9291906148db565b60405180910390a15050565b6115818383836040518060200160405280600081525061210f565b505050565b61158e6125fa565b73ffffffffffffffffffffffffffffffffffffffff166115ac611f21565b73ffffffffffffffffffffffffffffffffffffffff1614611602576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115f990614445565b60405180910390fd5b80601590805190602001906116189291906135e0565b50601560405161162891906149a3565b60405180910390207f24a9152dc695ecc801ad580886331ee12d7aac0fa2ae341a5ae3c2ccae36cb4f60405160405180910390a250565b601b6020528060005260406000206000915054906101000a900460ff1681565b6116876125fa565b73ffffffffffffffffffffffffffffffffffffffff166116a5611f21565b73ffffffffffffffffffffffffffffffffffffffff16146116fb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116f290614445565b60405180910390fd5b806018819055506018547ec89f607338c43f69cf5b28786c5f2b43b2be84f09f4ad3bc93e97447de142760405160405180910390a250565b6000806002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156117dc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117d390614a2c565b60405180910390fd5b80915050919050565b6117f66117f0612490565b826127a5565b611835576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161182c9061484f565b60405180910390fd5b601960009054906101000a900460ff16611884576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161187b90614a98565b60405180910390fd5b601b600082815260200190815260200160002060009054906101000a900460ff16156118e5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118dc90614b04565b60405180910390fd5b6001601b600083815260200190815260200160002060006101000a81548160ff02191690831515021790555061191a81612aea565b6000600b80549050601254836013546119339190614b53565b61193d9190614bad565b6119479190614c32565b90506000600b828154811061195f5761195e614c63565b5b90600052602060002090601091828204019190066002029054906101000a900461ffff169050600060018261ffff16101580156119a15750604b8261ffff1611155b156119af57600290506119d5565b604c8261ffff16101580156119ca57506102ee8261ffff1611155b156119d457600190505b5b6000601960019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060008173ffffffffffffffffffffffffffffffffffffffff16633807aabd611a22612490565b866040518363ffffffff1660e01b8152600401611a40929190614ccd565b602060405180830381600087803b158015611a5a57600080fd5b505af1158015611a6e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a929190614567565b90507f636094fd65795f24380cbd1bb4b2587fd8d385720be2091b4cd9042af8722ecd868285604051611ac793929190614cf6565b60405180910390a1505050505050565b601d6020528060005260406000206000915054906101000a900460ff1681565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611b68576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b5f90614d9f565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b611bb76125fa565b73ffffffffffffffffffffffffffffffffffffffff16611bd5611f21565b73ffffffffffffffffffffffffffffffffffffffff1614611c2b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c2290614445565b60405180910390fd5b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c5d90614e0b565b60405180910390fd5b601a6000611c72612490565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1680611cfe5750611cc8612490565b73ffffffffffffffffffffffffffffffffffffffff16611ce6611f21565b73ffffffffffffffffffffffffffffffffffffffff16145b611d3d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d3490614e77565b60405180910390fd5b6002600a541415611d83576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d7a90614ee3565b60405180910390fd5b6002600a81905550600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611dfb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611df290614f4f565b60405180910390fd5b601960009054906101000a900460ff1615611e4b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e4290614fe1565b60405180910390fd5b611347611e638360175461273590919063ffffffff16565b1115611ea4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e9b9061504d565b60405180910390fd5b60005b82811015611f0e57611ec5600160175461273590919063ffffffff16565b601681905550611ee1600160175461273590919063ffffffff16565b601781905550611ef382601654612b3d565b611f0760018261273590919063ffffffff16565b9050611ea7565b506001600a819055505050565b60185481565b6000600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b601960009054906101000a900460ff1681565b600b8181548110611f6e57600080fd5b9060005260206000209060109182820401919006600202915054906101000a900461ffff1681565b606060018054611fa590614237565b80601f0160208091040260200160405190810160405280929190818152602001828054611fd190614237565b801561201e5780601f10611ff35761010080835404028352916020019161201e565b820191906000526020600020905b81548152906001019060200180831161200157829003601f168201915b5050505050905090565b61203a6120336125fa565b8383612b5b565b5050565b601960019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600080600083116120d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120c7906150b9565b60405180910390fd5b60006120fa60646120ec60185487612cc890919063ffffffff16565b612cde90919063ffffffff16565b905080612105611f21565b9250925050915091565b61212061211a612490565b836127a5565b61215f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121569061484f565b60405180910390fd5b61216b84848484612cf4565b50505050565b60606000601754141561218d57612186612d50565b9050612209565b61219682612424565b6121d5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121cc90615125565b60405180910390fd5b6121dd612d50565b6121e683612de2565b6040516020016121f7929190615176565b60405160208183030381529060405290505b919050565b601a6020528060005260406000206000915054906101000a900460ff1681565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6122ca6125fa565b73ffffffffffffffffffffffffffffffffffffffff166122e8611f21565b73ffffffffffffffffffffffffffffffffffffffff161461233e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161233590614445565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156123ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123a59061520c565b60405180910390fd5b6123b781612f43565b50565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b60008073ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b60003073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561253a57600080368080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509050600080369050905073ffffffffffffffffffffffffffffffffffffffff81830151169250505061253e565b3390505b90565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff166125b483611733565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600033905090565b6000808251141561261957600060e01b9050612621565b602082015190505b919050565b600080600161263c61263788613009565b613071565b8487876040516000815260200160405260405161265c949392919061523b565b6020604051602081039080840390855afa15801561267e573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156126fa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126f1906152cc565b60405180910390fd5b8673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161491505095945050505050565b600081836127439190614bad565b905092915050565b61278066038d7ea4c67fff8260008151811061276a57612769614c63565b5b60200260200101516130aa90919063ffffffff16565b6012819055506001601960006101000a81548160ff0219169083151502179055505050565b60006127b082612424565b6127ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127e69061535e565b60405180910390fd5b60006127fa83611733565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16148061286957508373ffffffffffffffffffffffffffffffffffffffff1661285184610b40565b73ffffffffffffffffffffffffffffffffffffffff16145b8061287a5750612879818561222e565b5b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff166128a382611733565b73ffffffffffffffffffffffffffffffffffffffff16146128f9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128f0906153f0565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612969576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161296090615482565b60405180910390fd5b6129748383836130c0565b61297f600082612541565b6001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546129cf91906154a2565b925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612a269190614bad565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4612ae58383836130c5565b505050565b612af3816130ca565b6000600660008381526020019081526020016000208054612b1390614237565b905014612b3a57600660008281526020019081526020016000206000612b399190613666565b5b50565b612b578282604051806020016040528060008152506131e7565b5050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415612bca576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612bc190615522565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051612cbb9190613777565b60405180910390a3505050565b60008183612cd69190614b53565b905092915050565b60008183612cec9190615542565b905092915050565b612cff848484612883565b612d0b84848484613242565b612d4a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d41906155e5565b60405180910390fd5b50505050565b606060158054612d5f90614237565b80601f0160208091040260200160405190810160405280929190818152602001828054612d8b90614237565b8015612dd85780601f10612dad57610100808354040283529160200191612dd8565b820191906000526020600020905b815481529060010190602001808311612dbb57829003601f168201915b5050505050905090565b60606000821415612e2a576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050612f3e565b600082905060005b60008214612e5c578080612e4590615605565b915050600a82612e559190615542565b9150612e32565b60008167ffffffffffffffff811115612e7857612e77613a27565b5b6040519080825280601f01601f191660200182016040528015612eaa5781602001600182028036833780820191505090505b5090505b60008514612f3757600182612ec391906154a2565b9150600a85612ed29190614c32565b6030612ede9190614bad565b60f81b818381518110612ef457612ef3614c63565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a85612f309190615542565b9450612eae565b8093505050505b919050565b6000600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600060405180608001604052806043815260200161589e604391398051906020012082600001518360200151846040015180519060200120604051602001613054949392919061564e565b604051602081830303815290604052805190602001209050919050565b600061307b6133d9565b8260405160200161308d929190615700565b604051602081830303815290604052805190602001209050919050565b600081836130b89190614c32565b905092915050565b505050565b505050565b60006130d582611733565b90506130e3816000846130c0565b6130ee600083612541565b6001600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461313e91906154a2565b925050819055506002600083815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905581600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46131e3816000846130c5565b5050565b6131f183836133e3565b6131fe6000848484613242565b61323d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613234906155e5565b60405180910390fd5b505050565b60006132638473ffffffffffffffffffffffffffffffffffffffff166135bd565b156133cc578373ffffffffffffffffffffffffffffffffffffffff1663150b7a0261328c6125fa565b8786866040518563ffffffff1660e01b81526004016132ae9493929190615737565b602060405180830381600087803b1580156132c857600080fd5b505af19250505080156132f957506040513d601f19601f820116820180604052508101906132f69190615798565b60015b61337c573d8060008114613329576040519150601f19603f3d011682016040523d82523d6000602084013e61332e565b606091505b50600081511415613374576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161336b906155e5565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149150506133d1565b600190505b949350505050565b6000600854905090565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415613453576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161344a90615811565b60405180910390fd5b61345c81612424565b1561349c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016134939061587d565b60405180910390fd5b6134a8600083836130c0565b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546134f89190614bad565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46135b9600083836130c5565b5050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b8280546135ec90614237565b90600052602060002090601f01602090048101928261360e5760008555613655565b82601f1061362757805160ff1916838001178555613655565b82800160010185558215613655579182015b82811115613654578251825591602001919060010190613639565b5b50905061366291906136a6565b5090565b50805461367290614237565b6000825580601f1061368457506136a3565b601f0160209004906000526020600020908101906136a291906136a6565b5b50565b5b808211156136bf5760008160009055506001016136a7565b5090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61370c816136d7565b811461371757600080fd5b50565b60008135905061372981613703565b92915050565b600060208284031215613745576137446136cd565b5b60006137538482850161371a565b91505092915050565b60008115159050919050565b6137718161375c565b82525050565b600060208201905061378c6000830184613768565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156137cc5780820151818401526020810190506137b1565b838111156137db576000848401525b50505050565b6000601f19601f8301169050919050565b60006137fd82613792565b613807818561379d565b93506138178185602086016137ae565b613820816137e1565b840191505092915050565b6000602082019050818103600083015261384581846137f2565b905092915050565b6000819050919050565b6138608161384d565b811461386b57600080fd5b50565b60008135905061387d81613857565b92915050565b600060208284031215613899576138986136cd565b5b60006138a78482850161386e565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006138db826138b0565b9050919050565b6138eb816138d0565b82525050565b600060208201905061390660008301846138e2565b92915050565b613915816138d0565b811461392057600080fd5b50565b6000813590506139328161390c565b92915050565b6000806040838503121561394f5761394e6136cd565b5b600061395d85828601613923565b925050602061396e8582860161386e565b9150509250929050565b600067ffffffffffffffff82169050919050565b61399581613978565b82525050565b60006020820190506139b0600083018461398c565b92915050565b600061ffff82169050919050565b6139cd816139b6565b81146139d857600080fd5b50565b6000813590506139ea816139c4565b92915050565b600060208284031215613a0657613a056136cd565b5b6000613a14848285016139db565b91505092915050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613a5f826137e1565b810181811067ffffffffffffffff82111715613a7e57613a7d613a27565b5b80604052505050565b6000613a916136c3565b9050613a9d8282613a56565b919050565b600067ffffffffffffffff821115613abd57613abc613a27565b5b613ac6826137e1565b9050602081019050919050565b82818337600083830152505050565b6000613af5613af084613aa2565b613a87565b905082815260208101848484011115613b1157613b10613a22565b5b613b1c848285613ad3565b509392505050565b600082601f830112613b3957613b38613a1d565b5b8135613b49848260208601613ae2565b91505092915050565b6000819050919050565b613b6581613b52565b8114613b7057600080fd5b50565b600081359050613b8281613b5c565b92915050565b600060ff82169050919050565b613b9e81613b88565b8114613ba957600080fd5b50565b600081359050613bbb81613b95565b92915050565b600080600080600060a08688031215613bdd57613bdc6136cd565b5b6000613beb88828901613923565b955050602086013567ffffffffffffffff811115613c0c57613c0b6136d2565b5b613c1888828901613b24565b9450506040613c2988828901613b73565b9350506060613c3a88828901613b73565b9250506080613c4b88828901613bac565b9150509295509295909350565b600081519050919050565b600082825260208201905092915050565b6000613c7f82613c58565b613c898185613c63565b9350613c998185602086016137ae565b613ca2816137e1565b840191505092915050565b60006020820190508181036000830152613cc78184613c74565b905092915050565b613cd88161384d565b82525050565b6000602082019050613cf36000830184613ccf565b92915050565b600067ffffffffffffffff821115613d1457613d13613a27565b5b602082029050602081019050919050565b600080fd5b6000613d3d613d3884613cf9565b613a87565b90508083825260208201905060208402830185811115613d6057613d5f613d25565b5b835b81811015613d895780613d75888261386e565b845260208401935050602081019050613d62565b5050509392505050565b600082601f830112613da857613da7613a1d565b5b8135613db8848260208601613d2a565b91505092915050565b60008060408385031215613dd857613dd76136cd565b5b6000613de68582860161386e565b925050602083013567ffffffffffffffff811115613e0757613e066136d2565b5b613e1385828601613d93565b9150509250929050565b600080600060608486031215613e3657613e356136cd565b5b6000613e4486828701613923565b9350506020613e5586828701613923565b9250506040613e668682870161386e565b9150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60038110613eb057613eaf613e70565b5b50565b6000819050613ec182613e9f565b919050565b6000613ed182613eb3565b9050919050565b613ee181613ec6565b82525050565b6000602082019050613efc6000830184613ed8565b92915050565b600060208284031215613f1857613f176136cd565b5b6000613f2684828501613923565b91505092915050565b613f388161375c565b8114613f4357600080fd5b50565b600081359050613f5581613f2f565b92915050565b60008060408385031215613f7257613f716136cd565b5b6000613f8085828601613923565b9250506020613f9185828601613f46565b9150509250929050565b600067ffffffffffffffff821115613fb657613fb5613a27565b5b613fbf826137e1565b9050602081019050919050565b6000613fdf613fda84613f9b565b613a87565b905082815260208101848484011115613ffb57613ffa613a22565b5b614006848285613ad3565b509392505050565b600082601f83011261402357614022613a1d565b5b8135614033848260208601613fcc565b91505092915050565b600060208284031215614052576140516136cd565b5b600082013567ffffffffffffffff8111156140705761406f6136d2565b5b61407c8482850161400e565b91505092915050565b60006020828403121561409b5761409a6136cd565b5b60006140a984828501613bac565b91505092915050565b600080604083850312156140c9576140c86136cd565b5b60006140d78582860161386e565b92505060206140e885828601613923565b9150509250929050565b6140fb816139b6565b82525050565b600060208201905061411660008301846140f2565b92915050565b60006040820190506141316000830185613ccf565b61413e60208301846138e2565b9392505050565b6000806000806080858703121561415f5761415e6136cd565b5b600061416d87828801613923565b945050602061417e87828801613923565b935050604061418f8782880161386e565b925050606085013567ffffffffffffffff8111156141b0576141af6136d2565b5b6141bc87828801613b24565b91505092959194509250565b600080604083850312156141df576141de6136cd565b5b60006141ed85828601613923565b92505060206141fe85828601613923565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061424f57607f821691505b6020821081141561426357614262614208565b5b50919050565b7f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860008201527f697374656e7420746f6b656e0000000000000000000000000000000000000000602082015250565b60006142c5602c8361379d565b91506142d082614269565b604082019050919050565b600060208201905081810360008301526142f4816142b8565b9050919050565b7f4552433732313a415050524f56414c5f544f5f43555252454e545f4f574e4552600082015250565b600061433160208361379d565b915061433c826142fb565b602082019050919050565b6000602082019050818103600083015261436081614324565b9050919050565b7f4552433732313a415050524f56455f43414c4c45525f4e4f545f4f574e45525f60008201527f4f525f415050524f5645445f464f525f414c4c00000000000000000000000000602082015250565b60006143c360338361379d565b91506143ce82614367565b604082019050919050565b600060208201905081810360008301526143f2816143b6565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b600061442f60208361379d565b915061443a826143f9565b602082019050919050565b6000602082019050818103600083015261445e81614422565b9050919050565b7f52455645414c5f50484153455f414c52454144595f494e495449415445440000600082015250565b600061449b601e8361379d565b91506144a682614465565b602082019050919050565b600060208201905081810360008301526144ca8161448e565b9050919050565b6144da81613b52565b82525050565b600063ffffffff82169050919050565b6144f9816144e0565b82525050565b600060a08201905061451460008301886144d1565b614521602083018761398c565b61452e60408301866140f2565b61453b60608301856144f0565b61454860808301846144f0565b9695505050505050565b60008151905061456181613857565b92915050565b60006020828403121561457d5761457c6136cd565b5b600061458b84828501614552565b91505092915050565b7f66756e6374696f6e5369676e61747572652063616e206e6f74206265206f662060008201527f657865637574654d6574615472616e73616374696f6e206d6574686f64000000602082015250565b60006145f0603d8361379d565b91506145fb82614594565b604082019050919050565b6000602082019050818103600083015261461f816145e3565b9050919050565b7f5369676e657220616e64207369676e617475726520646f206e6f74206d61746360008201527f6800000000000000000000000000000000000000000000000000000000000000602082015250565b600061468260218361379d565b915061468d82614626565b604082019050919050565b600060208201905081810360008301526146b181614675565b9050919050565b600081905092915050565b60006146ce82613c58565b6146d881856146b8565b93506146e88185602086016137ae565b80840191505092915050565b60008160601b9050919050565b600061470c826146f4565b9050919050565b600061471e82614701565b9050919050565b614736614731826138d0565b614713565b82525050565b600061474882856146c3565b91506147548284614725565b6014820191508190509392505050565b600061477082846146c3565b915081905092915050565b6000614786826138b0565b9050919050565b6147968161477b565b82525050565b60006060820190506147b160008301866138e2565b6147be602083018561478d565b81810360408301526147d08184613c74565b9050949350505050565b60006040820190506147ef60008301856138e2565b6147fc60208301846138e2565b9392505050565b7f43414c4c45525f4e4f545f415050524f56454400000000000000000000000000600082015250565b600061483960138361379d565b915061484482614803565b602082019050919050565b600060208201905081810360008301526148688161482c565b9050919050565b7f494e56414c49445f414444524553530000000000000000000000000000000000600082015250565b60006148a5600f8361379d565b91506148b08261486f565b602082019050919050565b600060208201905081810360008301526148d481614898565b9050919050565b60006040820190506148f060008301856138e2565b6148fd6020830184613768565b9392505050565b600081905092915050565b60008190508160005260206000209050919050565b6000815461493181614237565b61493b8186614904565b9450600182166000811461495657600181146149675761499a565b60ff1983168652818601935061499a565b6149708561490f565b60005b8381101561499257815481890152600182019150602081019050614973565b838801955050505b50505092915050565b60006149af8284614924565b915081905092915050565b7f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460008201527f656e7420746f6b656e0000000000000000000000000000000000000000000000602082015250565b6000614a1660298361379d565b9150614a21826149ba565b604082019050919050565b60006020820190508181036000830152614a4581614a09565b9050919050565b7f52455645414c5f50484153455f4e4f545f494e49544941544544000000000000600082015250565b6000614a82601a8361379d565b9150614a8d82614a4c565b602082019050919050565b60006020820190508181036000830152614ab181614a75565b9050919050565b7f424f585f414c52454144595f52455645414c4544000000000000000000000000600082015250565b6000614aee60148361379d565b9150614af982614ab8565b602082019050919050565b60006020820190508181036000830152614b1d81614ae1565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000614b5e8261384d565b9150614b698361384d565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615614ba257614ba1614b24565b5b828202905092915050565b6000614bb88261384d565b9150614bc38361384d565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115614bf857614bf7614b24565b5b828201905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000614c3d8261384d565b9150614c488361384d565b925082614c5857614c57614c03565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000819050919050565b6000614cb7614cb2614cad846139b6565b614c92565b61384d565b9050919050565b614cc781614c9c565b82525050565b6000604082019050614ce260008301856138e2565b614cef6020830184614cbe565b9392505050565b6000606082019050614d0b6000830186613ccf565b614d186020830185613ccf565b614d256040830184613ed8565b949350505050565b7f4552433732313a2062616c616e636520717565727920666f7220746865207a6560008201527f726f206164647265737300000000000000000000000000000000000000000000602082015250565b6000614d89602a8361379d565b9150614d9482614d2d565b604082019050919050565b60006020820190508181036000830152614db881614d7c565b9050919050565b7f43414e5f4e4f545f52454e4f554e43455f4f574e455253484950000000000000600082015250565b6000614df5601a8361379d565b9150614e0082614dbf565b602082019050919050565b60006020820190508181036000830152614e2481614de8565b9050919050565b7f554e415554484f52495a45445f41434345535300000000000000000000000000600082015250565b6000614e6160138361379d565b9150614e6c82614e2b565b602082019050919050565b60006020820190508181036000830152614e9081614e54565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000614ecd601f8361379d565b9150614ed882614e97565b602082019050919050565b60006020820190508181036000830152614efc81614ec0565b9050919050565b7f414444524553535f43414e5f4e4f545f42455f5a45524f000000000000000000600082015250565b6000614f3960178361379d565b9150614f4482614f03565b602082019050919050565b60006020820190508181036000830152614f6881614f2c565b9050919050565b7f5045524d495353494f4e5f44454e4945445f52455645414c5f50484153455f5360008201527f5441525445440000000000000000000000000000000000000000000000000000602082015250565b6000614fcb60268361379d565b9150614fd682614f6f565b604082019050919050565b60006020820190508181036000830152614ffa81614fbe565b9050919050565b7f4d41585f5055424c49435f535550504c595f5245414348454400000000000000600082015250565b600061503760198361379d565b915061504282615001565b602082019050919050565b600060208201905081810360008301526150668161502a565b9050919050565b7f50524943455f43414e5f4e4f545f42455f5a45524f0000000000000000000000600082015250565b60006150a360158361379d565b91506150ae8261506d565b602082019050919050565b600060208201905081810360008301526150d281615096565b9050919050565b7f544f4b454e5f444f45535f4e4f545f4558495354000000000000000000000000600082015250565b600061510f60148361379d565b915061511a826150d9565b602082019050919050565b6000602082019050818103600083015261513e81615102565b9050919050565b600061515082613792565b61515a8185614904565b935061516a8185602086016137ae565b80840191505092915050565b60006151828285615145565b915061518e8284615145565b91508190509392505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b60006151f660268361379d565b91506152018261519a565b604082019050919050565b60006020820190508181036000830152615225816151e9565b9050919050565b61523581613b88565b82525050565b600060808201905061525060008301876144d1565b61525d602083018661522c565b61526a60408301856144d1565b61527760608301846144d1565b95945050505050565b7f496e76616c6964207369676e6174757265000000000000000000000000000000600082015250565b60006152b660118361379d565b91506152c182615280565b602082019050919050565b600060208201905081810360008301526152e5816152a9565b9050919050565b7f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860008201527f697374656e7420746f6b656e0000000000000000000000000000000000000000602082015250565b6000615348602c8361379d565b9150615353826152ec565b604082019050919050565b600060208201905081810360008301526153778161533b565b9050919050565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b60006153da60258361379d565b91506153e58261537e565b604082019050919050565b60006020820190508181036000830152615409816153cd565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b600061546c60248361379d565b915061547782615410565b604082019050919050565b6000602082019050818103600083015261549b8161545f565b9050919050565b60006154ad8261384d565b91506154b88361384d565b9250828210156154cb576154ca614b24565b5b828203905092915050565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b600061550c60198361379d565b9150615517826154d6565b602082019050919050565b6000602082019050818103600083015261553b816154ff565b9050919050565b600061554d8261384d565b91506155588361384d565b92508261556857615567614c03565b5b828204905092915050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b60006155cf60328361379d565b91506155da82615573565b604082019050919050565b600060208201905081810360008301526155fe816155c2565b9050919050565b60006156108261384d565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561564357615642614b24565b5b600182019050919050565b600060808201905061566360008301876144d1565b6156706020830186613ccf565b61567d60408301856138e2565b61568a60608301846144d1565b95945050505050565b7f1901000000000000000000000000000000000000000000000000000000000000600082015250565b60006156c9600283614904565b91506156d482615693565b600282019050919050565b6000819050919050565b6156fa6156f582613b52565b6156df565b82525050565b600061570b826156bc565b915061571782856156e9565b60208201915061572782846156e9565b6020820191508190509392505050565b600060808201905061574c60008301876138e2565b61575960208301866138e2565b6157666040830185613ccf565b81810360608301526157788184613c74565b905095945050505050565b60008151905061579281613703565b92915050565b6000602082840312156157ae576157ad6136cd565b5b60006157bc84828501615783565b91505092915050565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b60006157fb60208361379d565b9150615806826157c5565b602082019050919050565b6000602082019050818103600083015261582a816157ee565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b6000615867601c8361379d565b915061587282615831565b602082019050919050565b600060208201905081810360008301526158968161585a565b905091905056fe4d6574615472616e73616374696f6e2875696e74323536206e6f6e63652c616464726573732066726f6d2c62797465732066756e6374696f6e5369676e617475726529a264697066735822122023eef793dde2f7dd3a2f472ea4e657bee39ab8e2a292fc8abb4264573353bf5464736f6c63430008090033

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

0000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000eb6c5accafd8515c1b9e4c794bdc41532c5543ec0000000000000000000000000000000000000000000000000000000000000059000000000000000000000000271682deb8c4e0901d1a1550ad2e64d568e69909000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca9fe0eebf5e446e3c998ec9bb19951541aee00bb90ea201ae456421a2ded86805000000000000000000000000000000000000000000000000000000000000000e444746616d696c7920476c61737300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000074447474c41535300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002d68747470733a2f2f6e6674732e756e78642e636f6d2f6e6674732f646766616d696c792d676c617373626f782f00000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : _tokenName (string): DGFamily Glass
Arg [1] : _tokenSymbol (string): DGGLASS
Arg [2] : _baseURI1 (string): https://nfts.unxd.com/nfts/dgfamily-glassbox/
Arg [3] : _royaltyPercentage (uint256): 10
Arg [4] : _dgFamilyContractAddress (address): 0xEb6C5acCafD8515c1b9E4c794bDC41532C5543EC
Arg [5] : _subscriptionId (uint64): 89
Arg [6] : _vrfCoordinator (address): 0x271682DEB8C4E0901D1a1550aD2e64D568E69909
Arg [7] : _link (address): 0x514910771AF9Ca656af840dff83E8264EcF986CA
Arg [8] : _keyHash (bytes32): 0x9fe0eebf5e446e3c998ec9bb19951541aee00bb90ea201ae456421a2ded86805

-----Encoded View---------------
16 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000120
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000160
Arg [2] : 00000000000000000000000000000000000000000000000000000000000001a0
Arg [3] : 000000000000000000000000000000000000000000000000000000000000000a
Arg [4] : 000000000000000000000000eb6c5accafd8515c1b9e4c794bdc41532c5543ec
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000059
Arg [6] : 000000000000000000000000271682deb8c4e0901d1a1550ad2e64d568e69909
Arg [7] : 000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca
Arg [8] : 9fe0eebf5e446e3c998ec9bb19951541aee00bb90ea201ae456421a2ded86805
Arg [9] : 000000000000000000000000000000000000000000000000000000000000000e
Arg [10] : 444746616d696c7920476c617373000000000000000000000000000000000000
Arg [11] : 0000000000000000000000000000000000000000000000000000000000000007
Arg [12] : 4447474c41535300000000000000000000000000000000000000000000000000
Arg [13] : 000000000000000000000000000000000000000000000000000000000000002d
Arg [14] : 68747470733a2f2f6e6674732e756e78642e636f6d2f6e6674732f646766616d
Arg [15] : 696c792d676c617373626f782f00000000000000000000000000000000000000


Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.