// File: contracts/ecco.sol



// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/// @title: ecco
/// @author: manifold.xyz

import "./manifold/ERC721Creator.sol";

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//                                                                                                                                                                                                                //
//                                                                                                                                                                                                                //
//    PPPPPPPPPPPPPPPPPPPPPPPPPPPP5P5P55555555555555555555555555555555555555555555555555555555YY555YYYYYY55YJYG###&#BG5555555555555555555555555555555555555555555555555555555555555555555555555555555555555555    //
//    PPPPPPPPPPPPPPPPPPPPPPP55PPP55PP555555555555555555555555555555555555555555555555555555YYYYYYYYYYYJJJ???JJY555555YJJJJYYY555555Y55Y5555555555555555YYYYYYYYYY55555555555555555555555555555555555555555555    //
//    PPPPPPPPPPPPPPP5P55P55555555555555555555555555555555555555555555555555555555555555Y5YYYYYYYJ???7???JJJYYYYYYYJJJJJ??7777??JYY5555YY55YY5Y5555Y5YYYYY5YYYYYYY5555Y555555555555555555555555555555555555555    //
//    PPPPPPPPPPPPPPPPP55P5555555555555555555555555555555555555555555555555555555Y5YY5YYYYYYJJ??????JYY555PGBBBBBBBB##BBBBG5YJ?7!~~7?JYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY5Y5Y55555555555555555555555555555555555    //
//    PPPPPPPPPPPPPPPP5PP555555555555555555555555555555555555555555555555555555YYYYYYYYYJ????777??????JJJJJYYY55555PPPGBB######BP5J7!~7?JJYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY555Y555555555555555555555555555555    //
//    5PPPPPPPPPP55555P55555555555555555555555555555555555555555555555555555YYYYYYYYJ?????7777777???JJJJJJJJYYYYYYYYYJJJY55PGB##&&&#B5J?77??JJYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY555555555555555555555555555555    //
//    5PPPPPP5P5555555555555555555555555555555555555555555Y5Y55555555Y55555YYYYYYJ?7???777777777??JJY555PPGGGBGPPGPP55YYJJJJJYY5GB##&&#BPYJ????JYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY5Y5Y555Y555555555555555555555    //
//    5PPPPPP5555555555555555555555555555555555Y5Y55Y5555555YY5YY55555Y55YYYYYJ?77????777!!!7?JY55PGBBGGGGGGBBB######BBGPPP5YYYYY5PGB###&##G5YJJJJJYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY5Y555555555555555555555    //
//    5P55555555555555555555555555555555555555Y55YY5YYYYY5YYYY5Y5Y55555YYYYYJ77???????777?JY5PGGB##BBGPPPPPPPPP5YY55PG#####BGGP555Y5PGB######BP5YYJJYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY5YYY5Y55555555555555555    //
//    5555555555555555555555555555555555555Y555555555Y5YYYY55YYY5YY55YYYYYJ77??77??????JYY55PGB#&&##BBB#B#BBBBGP55YJ??YG####BBBGGP5YY5PGB######BP55Y?JYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY5YY55555555555555    //
//    555555555555555555555555555555555555555555Y55555555555Y55Y555YYYYYY?7?7!!??????JJJJJJYYPG#&##BGPPB###GPYYYY555YJJJ5GBBBB#BBP55Y?J5GGBB#&&#BGPPPJJYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY55555555555    //
//    55YY55YYY5555555555555555555555555555YY555YYYY5YY5555Y5YYYYYYYYYY?777!~7??77?JYYYJJJY5B######BPJJYPPPG5YYJJY5PGP5555GBBGB##BPP5YJJ5PPPBB####BGPPY?YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY55555555    //
//    5555Y55YJYYYYYYYYYYYYYYYYY555Y55555555Y5YYYY55YYYYYYYYYYYYYYYYYJ7!7!!7??7?JJYJJYYPPGGBG5YY5PB#BJ!JJPB#BBGPPP5GB#BGGPPGB##&####BGP55YYJJJJYPGBBGPG5?YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY5555    //
//    Y5555YJYJJJJJYYYYYYYYYYYYYYYYYYYYY555YYYYYYYYYYYYYYYYYYYYYYYYYJ7!!!7J?7?JJJ??JYPB##GPYJJJJJJ?Y55!~JPG####B##BB##&##GPPG#&&#&&#BP5PPPPPGPP5YY5PGPY5Y?YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY5555    //
//    Y55555J?JJ?J??JJJJ?JYYYYYYYYYYYYYYYYYYYYYYYY5YY555YYYYYYYYYYYJ7~~!?J???J???JYPGBGP5YJJJJJJ?7~^!JJJ?PP#######&#####BBGPGB&&#&&#BGGBBBBB####BGPPGBGJ!7JYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY5555    //
//    Y5555YYJ???????JJJ??JJYJYYYYYYYYYYYYYYYYYYYYY555YYYYYYYYYYYJ?!~~!?J??J???Y5PGGP5YYYJJJJ??77^^^?5P5P5&&&#######&##GGGBGB#&&&&######BGGGGPPPPPPPPGBB5J?JYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY5YY555    //
//    Y5555YJJJ?????7?JJJJ?JJ7J??JYJYYYYYYYYYYYYYYYYYYYY55555555YJ7!~!?JJ????J55P55YYYYJJJJ????7?JYY5YY5P5########BBBGGGGGBB#&&&####&###BPYJY55YYYY5PPPJGG5YJYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY5Y    //
//    Y55555YJJ?7?7777????77777777777??JYYYYYYYYYYYY55555YYYJJJYYYYYYY55555555555YYYYJJJ??????JJ5PGGGPPPGGGBBB#BBBP5PPGGBB##&&&&##BB#####BPY??J7^^7JY5Y7Y#G55YJYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY    //
//    Y55555YY??7777!77777777!!!!!~~!77JJJJYYYYYYYY5YYJ???????7777?????JJJJJJJJJJJJJ????????JJYY555G####B##BB####BP5PGBB#&&&&#P5PGB##BBBB##BP?7!~^!7?J?J5B&BPPYYJYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY    //
//    Y555YYYYYJ?777777!!!!!!!~~~^~^~7777?JYYYYYYYYYYYYJJJJJJJJJ?????7??????J?JJJJJJJJJJYY555P555PGBG5PG#&&#######BB###&&&&#GY?!!!!?P##BPG##GJ7!7J?77JGPJP##P55JYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY    //
//    Y55YYYYYYYY?7??77!7!!!!~^:::::^~!7??JJYYYYYYYYYYYYYYYYYJ7??JJJJJ????????JJJJYY55555PPPPP555YYJ????Y5#&&&&&&&&##&#####PP55J?7!~!?G#BPG##Y7!~!J?7?7!JPB&Y7PYJYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY    //
//    YYYYYYYJJJ????77!77777!~~^:::::^~7?JJJYYJJYYYYYYJYYYYYY~:^7J?777!~!7?????????????????JJY5PGGBBBBGGGGGB#&&&&&&&&#####P55PGPP5Y7!7?P#BPPB57~^.^7J?!?YPB##P5PJJYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY    //
//    YYYYYYYYJ?????777!77??7!~^::::::^!7?JJJJ?JJYYYYYYYYYYY?^^!J?!!~^..^!77?JJY55GGPPPPGGBB#&&&#BBGGPPPP5YY5PB#&&&#&###BBP5YYPBP55PY?JYBB5YP5Y?~..7YJJJ5GGB#B5PJJJJYYYJJJJJJYYYYJJYJYYJYYYYYYYYYYYYYYYYYYYYYY    //
//    YYYYYYYYYYYYJ???777??77~^:...:^^^!!7????77?JYJJJYYYYYY7~~?J?7~^:^~7?JJJYPG##&&&&&&&&&&&#####B#BBGPPP5YYY5PG###&&##BPP5YJYBB#G5#P5PBGYJY5P5J7~7J5555GGB#B5PYJJJJJJJJJJJJYJJYJJYYYJJJYYYYYYYYYYYYYYYYYYYYY    //
//    YYYYYYYYYYYYJ?77777777!~:.....::^~~~~!77!7??JJJJYYYYYJ!~7?J?!~::!??JJYPB##&&&&#&#####BGGBBGBBBBBBBBBGPP5YYY5PGGB##BP55YJ?YGB#5##BB#B5JJJ5PPY?JYGG5Y5GJPB5PYJJJJJJJJJJJJJJYJJJJJJJJJJYYYYYYYYYYYYYYYYYYYY    //
//    YYYYYYYYYYYYYJ????777!~~^:::::..^^~~~^~!!77??JJJYYYYY?~~?JJ7!^^!7JJYPG#########BBBGGGPPP55555555PPGGGGGPPJJ?JYYY5GBBP55YJ77?5GGGGBBBGYJJJ5P5Y7YGGYYPBYPBPPJJJJJJJJJJJJJJJJJJJJJJJJJJJYJYYYYYYYYYYYYYYYYY    //
//    YYYYYYYYYYYYYYYYYJ?777!!!^^^~^^::^^^^:^~!!!7??JJYYYYY?!!?YY7!^~7JY5GBB##BBBBBGPPP5YYYJYYJYYJJYYYJJJYYYYJYJ?777?JJJ5GGP55YYJ77?J5YPGBBPYJJJGG57JPGYYPB##GGPJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJYJYYYYYYYYYYYYYY    //
//    YYYYYYYYYYYJJJJJJJ?J??7!~~~~~~~~^^^^^::^^~~~7???JJYYY7!7JYJ7~~7?Y5GB#BBGPP55YJ??7?7777777777777777777777!7!77777?JJYGGPYYY5Y?7?JYYYPGBP5YYPGG5PGGY5GB##PP?JJJJJJJJJJJJJJJJJJJJJYJJJJJYJJJYYYYYYYYYYYYYYY    //
//    YYYYYYYYJYJJJJJJJ??????7!!~~~~~~!~^:::.:^^^~~!!7??JJY?7?YYJ7~!JYPBBBBGG5YJ?7777????????J?????????????7????????????JYYPGG5J?5PY?JJYJJYPBBGGGGGGBBPYP##B5Y5YJ??JJJJJJJJJJJJJJJJJJJJJJJJYJYYYYYYYYYYYYYYYYY    //
//    JYYYYYYJJJJJJJJJJJJ??????77!!!~^!~^^^.  :^^^^~!777??Y?7?5YJ7!?J5GBBBG5Y?????JJJJJ??????????????J????????????????????JYY5PP5Y5BPJYYYYY77YGB###BBB?7BBPY5Y?Y5Y???JJJJJJJJJJJJJJJJJJJJJJJJJYYYJYYYYYJYYYYYY    //
//    JYYYYJJJJJJJJJJJJJJJJJJ???????77!~^^:^^. :^:^!!!!!77?J7?5YJ77?YPBBGPYJ???JJJJ??????????????????????????????????????????J?JY55YPP?J5GBG?7?J?JPB#B5P#5JJJY5J?J5YJJJJYYYYYYJJY55PYJJJJJJJJYYJJJYYJYYJYYYYYY    //
//    JYYYJJJJJJJJJJJJJJJJJJJJJJJJJJJ??7!~^^^^:.::^^^^~~~!!Y??55Y?7J5GBGPJ???JJJJ????????????????????????????????????????????????JYYY55?75B#GJ?J?^~?5B#PY5?JJJJJJ?JJY55555555555555YJJJJJJJJJJJJJJJJJJJJYYYYYY    //
//    JYJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ?7!^^^^..:^^^::::^^7Y?555J?YPGBPY??JYYJ????77??????????????????????????????????????????????JYYYYJ7JPBG5JJ?!7YYJ?5YJJJJJJJJYYJJJYYYYYYYYYJJJJJJJJJJJJJJJJJJJJJJJJJJJYYY    //
//    JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ?!:^^^^..^^^:....::YJ5P5YJYPGG5JJJY5J?77777????7????????????7???????????????????????????????JYYYYJ?YGG5YJ7?JY7?GYJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJYJJ    //
//    JYJJJJJJJJJJJJJJJJJJJJJJJJJ????JJJ??7!!^.::..:^:::::..~PPG5YYYPGPYY555Y??!!!!7???7!777???????77??????????????????????????????????JYYYYJJ5GP5J!?J??GP?JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ    //
//    JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ???????77!~:..  .:::::..:5GG555J5GPYY5PYJJ!!~~!!7!!!!!!!???777!7?????????????????????????????????????JYJY5JYPPP??5YJPB?JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ    //
//    JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ??????77!!!:  ....::....7BBGP5J5GP55PGJJ?~~~^^~^.^~~^!7??77!!!???????????????????????????????????JJJJ?JYJPYYPG57JJYYGYJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ    //
//    JJJJJJJJJJJJJJJJJJJJJ??JJ?JJJJJJ???777!!!~^.. .....  ..^5#BP5YYGG55GGJ?!^^^::: .::.:^~!~~^^~7????77!7???????????????????????JJ?JJ?JJJ?JYJ55YPY7!~7JG5?JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ    //
//    JJJJJJJJJJJJJJJJJJJJJ?7???7??JJJ?7!~^~~~~^^:....  .  ...!G#BP5JPGGPBGJ?~:::..     ..:...::.!???77!!!??????????????JJ??????JJJJJJJJJJJJJJYYY55JJ7^7YGYJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ    //
//    JJJJJJJJJJJJJJJJJJJJJ??77???777!!!!~^::^::::.. .     ....JB#GPJJGGGBGJ?^.....     .......^^!?7~~!7??????????????JPJ????????JJJJJJJJ?JJJJ?J55Y555Y5GY?JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJYP5    //
//    JJJJJJJJJJJJJJJJJJJJJJJ??77777!!!~~~^:::......         .:^5##GP?YB55GJ?^......   ...::::^~~~^!77???????????????Y5PJ??????JJJJJJJJJJ?J?JJJ?J55YYYYYYJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJY5G#&    //
//    JJJJJJJJJJJJJJJJJJJJJJJJJJ??77!!~~^::::......        ....:~P#BG5!PG55J?~..........::^::^^^^~77^!??????????????J55P5???JJJJJJJJJJJJJJJJJJJJJ?JYYYYJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJYPPB    //
//    JJJJJJJJJJJJJJJJJJJJJJJJ?????!!!~~^^::::.....         . ..:^5BBGYJPP5J?7::........:::::^^!!^~~7??????????JYJJJJJYYYJ?7??JJJJJJJJJJJJJJJJJJJJJJJJ?JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJY5Y5    //
//    JJJJJJJJJJJJJJJJJJJJJJJJJ?7777~~~~^~^^^:.....             ..:JPGB5YPG?JJ^:.. .::::::^^^^~!!!7??????????Y5YJYY555555P5YJ???JJJJJJJJJJJ?JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJYY5P    //
//    JJJJJJJJJJJJJJJJJJJJJJJJJJ??77~~~!!!!!~^^::........   ........!YPGPYPYYY7^:..::^^^^~^^~^~77??????????Y5P5YYYJJJJYYYY5PPP5J?JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJY55YJJJJJJJYYJYPB#    //
//    JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ?7!~!7777!~~^::::................^?5GPY5P5Y7:::::::^~~!!~~!77???????JJ5P5YJJJJJJJJJJJ?J?J5PP5JJJJJJ??JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ5YYYJJJJJJY5P55GB#&    //
//    JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ7!???7777!~^^:::::::............:!J5PYYP5Y!^^^^^^~~^~~~!~~!????????PPYYJJJ???JJJJJJYJ????5BB5YJJJJ??????J??JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJYJJ5PY5JJY5PGBBBG#&    //
//    P5?JJJJJJJJJJJJJJJJJJJJJJJJJJJJJ?JJJJJ???7!~^::::::...............^7Y5YY55Y!^~~~~~~!~^~!77777777?J5P5J??77???????J?J??777?5BBP5J???J??JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJY55PB##BGPG##&&#BP5P&    //
//    PG5YYJJJJJJJJJJJJJJJ?J?JJJJJJJJJJJJJJ?????7~~^^^:::..............  .~?YYJY557~~~!!~!~~!7?777777?YYJ?77JY!77???????????77???5PGG5Y?JJJ?JJJJJJJ?JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJYP##&&&#&&&&####BYB#&#    //
//    GBGPP55YJJJJJJJJJJJ??JJJJJ??JJJJJJJ?J????777~~^^^^::::.......     ...:7JYJ5P5?!!!!!!!!7!7777!7J?!~~~~~~!!7?????????JJJ?JJ?JJJYGBG5?JJ?JJJJJJJJJJJJJJJJJJJJJJJJJJJJ?JJJJJJJJJJJJJYPG##&&&&########BPB&##P    //
//    ##BBBGGP5JJ?JJJJJJJJJJJ?JJJJJJJJJJJ??????7!!!!~~^~~^^:::......  .......~JYY5P5Y7!!~^^^^^^~!!!~~^~^^^^^~~!!7???????????JJJ?J??JYPB#5?JJJJJJJJJ?JJJJJJJJJJJJJJJJJJJJJJJJJ?JJ?JJ?J5GGBB&&#########BGB#&BP5P    //
//    GGGPB#BBGPJJ?JJJJJJJJJJJJJJJJJJJJJJJJJJ???7!!~~!~~~::::................ !J5Y5PPY?!^:.....:::^^^^^^^^^^^~!!!777?????J??JJ??J?!!!JPB#Y?JJJJJJJJJJJJJJJJJJJJJJJJJJJJJ??JJJJJJY55YPGBBB#&#########BBB#&GP5G#    //
//    BBBGB##BBGGG5YYYJJJJJJJJJJJJJJJJJJJJJ???77777!^^~^::...   ............. :YPP5PGGPY7~:.   :..::::::^^^^~~~!!777??J??JJJJJJJ?J77^^75BBY??????JJJJJJJJJJJ?JJJJJJJJJJJJJ??JPPPGBGGPY5GB##&&&#####BBB#BPGGBGP    //
//    ##&&#BB##GP5YJJJJYYJJJJJJJJJJJJJJJJJJJJJJ?777!~!~^::...   .....::......:?PBBP5G#BG5Y?!^:..  .:::::::^^~~~!77??JJ??????J?J??7777??7JBB5YYYYJJJJJJJJ?JJJJJJ??JJJ?JJ5YJ5PPG5PP55PPBB&&&&&#####BBGGB#GP55GBB    //
//    &&&&&###BGP55YJ?YP5JJJJJJJJJJJJJJJJJJJJ?J???7777^::::......  ..::::..^!JP####PPB##BGGPYJ?!~^:::::^^^~~~~!7?????????J??JJJ?J????7775BGPGBGGPP55YJJJJJJJJJJJJJJJJJYJYPGGP5Y5PPG#B#&##########BBGBGP555B#&&    //
//    #GB#GBBBBG555P55GBP5JJJJJJJJJJJJJJJJ??JJJJJJ???7!^^::........::^^^:~7YPB######5PB####B55YY55YJ??7!~~~~~~77?7???????J?J?JJ?JJJJ?77G&#P?JJ??5YYJJJJJJJJJJJJJYJJJJY55GGP5YY5B##B55555BB##########GB#B#&&&##    //
//    PPP5YJJYYYYY5YPPBBP555J???JJJJJJJJJ?7JJJJJJ???777!!!^^:::::.::~!7?JPB#&#######BYG####55P5BBPYGPP55YJ?7!777?7??????JJJ??JJJJJJJ?77#GJ??7JJYPPPPP55YYYYYJJJJJJJY5PPPP5PGPGB&#GYYYY55G########&####&&&&###B    //
//    GGBGP5YJYPYYY5GBBPY555JJJ??JJJJJJJJJJJJJJ????777!!!^~~^^:::^^!?YPB####&#&#####&P5B#&PPP5GGPYGBBBGGGPP5YJJ?????JJ?JJJ???JJJJY55Y?7YY?JJJJJJ5PPP555YYYJYJJJJYYYPGPP55BBBB###B5PPPGPGBBBBBGPG#&#########BBB    //
//    GG5555PPP5YY55BBG5JJJJJJYJJ??JJJJJJJJJJJ?????777~~~^^^::^~7?YPGGB########&&###&#BB#&GPPGBP5B####BBBBBBGPP5YYJJJJJJJJJJYYYYJYJJJJJ?!775Y5YY55555YYYYYYJYYYY5PPPPPYYGGGGB##BGGBG#GYY5PGBP5P####&&#####BGBB    //
//    GPPPPBBGGPGGPPGP5555PPYJJ??YYYYYYYY55YYJJ?7777777!!~^^~!J55G###GBB####&##&&#&&&BG&&G5BBBGP#&#############BBGG5YJJ55YYYYJYYYPPYY55JJ7!?JJJYYYYYYYYYYYYY555PP5555YPBGBBB#BBGGGP55YJY5PBBP#&#BGGGGGGGGGGGPP    //
//    GBBGGBGGGGBBBBBBBBBGGGP555YY55YYYYYYYYYJJJJ?7777^~~~!JPG#P5#G####B###&&###&&&#P~^7?^:~77!PGBB#######BBBBB#####BG5YYYY5PGB#&#G5PPYYJ?7!7?JYYYYYYYYYYY555P5P5555PB#######BGP5555YYYPP5PPPPPPPP5555PP5PP5Y5    //
//    BBBGGBBBBBBBBBBBBBBBGBBGGP5YYYYJYY55PPPPPGPPYYJY7^!?P##&&GG#G#PP########&&&BP7:::::.::. ..:^~~!!!!7???JY5PY555PGGBPP#&&#&#P5YYYYYYYYJ7!??JYYYYYYY55555555PPPPGBBBBGGPPGPYYY5555PPP55555555PPPPPPP5PPPPP5    //
//    B#BGGGGGGGGGBBBBBP5555PGPPP5555PGGGGGGGGGGGG55GB?JB##&#&#&&&&&GYPGB#&&##G5?~:..:::~!!!^.::::^~~!7?JJJYYYY55YJ?JYPB#B#####P555YY555YYYJ??JJYYYYJYYY555PPPPGGPP55YYYJYJJYYYYYYY555555PGGGGP55PGPGGGPPPPPPG    //
//    PPPPPP555555PPPP55YYJYYYYYY555PPPPP555PGGPPPGGGPJ##&&&#&&##&&&#B5YBGBGGY77!~^^:.:~7!!!7~^~!!77??J???J?JJYYJJ??5GGPPGGGBBYYJJJ?????????J7?JJJJJJJJYY5555YY55YYJJJJJJYYYYYYYYJYY5YY5PGGGGPPPPGPP5PPPPPGBB#    //
//    5YYYYYYYYYYYJJJ?J????777?????????????????????J??G&#&#&&&&&##BGP5???7JJJ?777!!~^::^!!!!!!!!!!~~!!~~!!!!7?77!7YGGPPPPPPPG?^^^^^^~~~~!~~~^:^~~!!!!!!77777777777777777??????J????JJYJYYY55555555P5PP5555555P    //
//    PGGGGGPPPGGPPP555555YYYYYYYYYJJJJJ?????7777~~~~?&##&&#B5YJ7777777!7???J??77~~~~~~~^^^^^^^::...........:::::!JY5P5PPGGGB7!!!!!!!~~~~~^^^:^^^^~!!!!!!!!!!!!!7!!!!!!!77777???????JJY555PGGBBBBB#BBBBBBBB###    //
//    5PPPPPPPPPPP5555555YYYJJ????????777!!!!!!~^^^^^P###BY7~^~!~~!7?77??77!J5YJ?7?Y555P55YJJ?777!!~^^^^^^^^^^^^^^:^~7JYY5PGBY!777!!!!!!!!~~~~~~~~~~~~~~~~!!!!!!!!!!!!!!!!7777??????JJJYYY5PGGGGGGBBBBBBB#####    //
//    Y555YYYJJJ?J?????????????????777?JJYY5J7!!77~!!G#&P77777??????J?777!~~~!!7Y55J?7?7??JJYYYY55Y5YJ?7777?JJ?????7!~~7Y5YYYY7~!!~~^^::::^^^^~~~!~!!77777??777???????JJ?????J?????J??JJJJYY5Y55PGGGBBBBBB####    //
//    PGPP555555YJ???JJJYJJJJYY555J???JY55YYJJJJ?7!!7B&57??777777777!!!~~~^~~^~!JJJJ77!!!~~~~!7JYYJYJJJJJJJ?????JJJY???77?YP5YJ::^^::...:^~!!7?JY5Y5PP5PPP55Y555P5PPP5YYYYYYJJJYJJYYYYYJYY5555Y555555PPPGGGGGG    //
//    BBBBBBBGGGGGPPGGGGGGP55PP55YYJ???777777???JJYYJBB????J????????????J????!?????????JJJJ??777!7777???JY55PP5YJYY555555YYP5YJ7^:::::^^~!!77???JYJYYY555YYYYY???7?JJYYY55YYYYYJJYPPBBBBBGGPGBGBBGGBBBBGGBBBBB    //
//    ####################BGGP5GBBBGPP5JJJYYYYYYYJJJJY7JJJYYYYYYYJJ??JJJ????7!??????JJYYY555P5YJJ?77!!7777?JJ5YYYYJ?YYY55P55555YYJ?????77?JYJJ?JJJ??77!7JYYP555555555PGBBBBBB####B#B##BB#######&#######BB#####    //
//    ######BBBB#######BBBBBBGGP55555YYJJJ????????????!???JJJJJJJ??7?7??777!~7?77?????J55P5JJJ?JJYYJ??7?????JJYY5YY55YYJYYJ5YY5555YJJYYJ?JJJJYY555YYYYY5Y5555Y5PPP55555555555PPPGBBBBBBB#############B####BBBB    //
//    BBBBBBBGG5YPPPGBBGBGGGGGPPP5PP5P555PPPPPPPP55YYY?7??77777???77777777!!~!777!777777?J5P5YYYJJJYYJJ????JJYJ55555YJ?????JJJYY5PPP555YJ?JJJ?JYYYYYJ?7???JYYY5YYYJJ777?JYPGB##########&####&##&#&&#&#&&&&&&##    //
//    BBBBBBBGG5PGBGGGPPPGGGPPPPP5555YYJYYY5P5PGGGGGGP5YYJ????J?7??777777!!7777777!7777777?JYYYYY5PPP55YJ?????JJJYY?7!!77??YJ555PPPGGGGPPPPPPP55PPPGGGGGBBBBGBGGGGGPP5PGGB###########&&####BPGGGBGPGGPGBBB####    //
//    GBBGGGGGGGPPPP5555PPP5555YYYY5YJ??JY555Y5555PPPYJJ?????J??J????7!77!!77!7777777!777777!!7?J5555PPPP5YJJ?JJ?JPGG5J7!^^~~7JYY5PG                                                                              //
//                                                                                                                                                                                                                //
//                                                                                                                                                                                                                //
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


contract ecco is ERC721Creator {
    constructor() ERC721Creator("ecco", "ecco") {}
}

// File: contracts/manifold/ERC721Creator.sol



// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/// @author: manifold.xyz

import "@openzeppelin/contracts/proxy/Proxy.sol";
import "@openzeppelin/contracts/utils/Address.sol";
import "@openzeppelin/contracts/utils/StorageSlot.sol";

contract ERC721Creator is Proxy {
    
    constructor(string memory name, string memory symbol) {
        assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256("eip1967.proxy.implementation")) - 1));
        StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = 0x5133522ea5A0494EcB83F26311A095DDD7a9D4b6;
        (bool success, ) = 0x5133522ea5A0494EcB83F26311A095DDD7a9D4b6.delegatecall(abi.encodeWithSignature("initialize(string,string)", name, symbol));
        require(success, "Initialization failed");
    }
        
    /**
     * @dev Storage slot with the address of the current implementation.
     * This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is
     * validated in the constructor.
     */
    bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;

    /**
     * @dev Returns the current implementation address.
     */
     function implementation() public view returns (address) {
        return _implementation();
    }

    function _implementation() internal override view returns (address) {
        return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;
    }    

}

// File: node_modules/@openzeppelin/contracts/proxy/Proxy.sol



// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)

pragma solidity ^0.8.0;

/**
 * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM
 * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to
 * be specified by overriding the virtual {_implementation} function.
 *
 * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a
 * different contract through the {_delegate} function.
 *
 * The success and return data of the delegated call will be returned back to the caller of the proxy.
 */
abstract contract Proxy {
    /**
     * @dev Delegates the current call to `implementation`.
     *
     * This function does not return to its internal call site, it will return directly to the external caller.
     */
    function _delegate(address implementation) internal virtual {
        assembly {
            // Copy msg.data. We take full control of memory in this inline assembly
            // block because it will not return to Solidity code. We overwrite the
            // Solidity scratch pad at memory position 0.
            calldatacopy(0, 0, calldatasize())

            // Call the implementation.
            // out and outsize are 0 because we don't know the size yet.
            let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)

            // Copy the returned data.
            returndatacopy(0, 0, returndatasize())

            switch result
            // delegatecall returns 0 on error.
            case 0 {
                revert(0, returndatasize())
            }
            default {
                return(0, returndatasize())
            }
        }
    }

    /**
     * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function
     * and {_fallback} should delegate.
     */
    function _implementation() internal view virtual returns (address);

    /**
     * @dev Delegates the current call to the address returned by `_implementation()`.
     *
     * This function does not return to its internal call site, it will return directly to the external caller.
     */
    function _fallback() internal virtual {
        _beforeFallback();
        _delegate(_implementation());
    }

    /**
     * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other
     * function in the contract matches the call data.
     */
    fallback() external payable virtual {
        _fallback();
    }

    /**
     * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data
     * is empty.
     */
    receive() external payable virtual {
        _fallback();
    }

    /**
     * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`
     * call, or as part of the Solidity `fallback` or `receive` functions.
     *
     * If overridden should call `super._beforeFallback()`.
     */
    function _beforeFallback() internal virtual {}
}

// File: node_modules/@openzeppelin/contracts/utils/Address.sol



// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.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
     *
     * Furthermore, `isContract` will also return true if the target contract within
     * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,
     * which only has an effect at the end of a transaction.
     * ====
     *
     * [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://consensys.net/diligence/blog/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.8.0/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 functionCallWithValue(target, data, 0, "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");
        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResultFromTarget(target, 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) {
        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResultFromTarget(target, 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) {
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
     *
     * _Available since v4.8._
     */
    function verifyCallResultFromTarget(
        address target,
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        if (success) {
            if (returndata.length == 0) {
                // only check isContract if the call was successful and the return data is empty
                // otherwise we already know that it was a contract
                require(isContract(target), "Address: call to non-contract");
            }
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    /**
     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason or 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 {
            _revert(returndata, errorMessage);
        }
    }

    function _revert(bytes memory returndata, string memory errorMessage) private pure {
        // 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
            /// @solidity memory-safe-assembly
            assembly {
                let returndata_size := mload(returndata)
                revert(add(32, returndata), returndata_size)
            }
        } else {
            revert(errorMessage);
        }
    }
}

// File: node_modules/@openzeppelin/contracts/utils/StorageSlot.sol



// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/StorageSlot.sol)
// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.

pragma solidity ^0.8.0;

/**
 * @dev Library for reading and writing primitive types to specific storage slots.
 *
 * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.
 * This library helps with reading and writing to such slots without the need for inline assembly.
 *
 * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.
 *
 * Example usage to set ERC1967 implementation slot:
 * ```solidity
 * contract ERC1967 {
 *     bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
 *
 *     function _getImplementation() internal view returns (address) {
 *         return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;
 *     }
 *
 *     function _setImplementation(address newImplementation) internal {
 *         require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract");
 *         StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
 *     }
 * }
 * ```
 *
 * _Available since v4.1 for `address`, `bool`, `bytes32`, `uint256`._
 * _Available since v4.9 for `string`, `bytes`._
 */
library StorageSlot {
    struct AddressSlot {
        address value;
    }

    struct BooleanSlot {
        bool value;
    }

    struct Bytes32Slot {
        bytes32 value;
    }

    struct Uint256Slot {
        uint256 value;
    }

    struct StringSlot {
        string value;
    }

    struct BytesSlot {
        bytes value;
    }

    /**
     * @dev Returns an `AddressSlot` with member `value` located at `slot`.
     */
    function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `BooleanSlot` with member `value` located at `slot`.
     */
    function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.
     */
    function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `Uint256Slot` with member `value` located at `slot`.
     */
    function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `StringSlot` with member `value` located at `slot`.
     */
    function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `StringSlot` representation of the string storage pointer `store`.
     */
    function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := store.slot
        }
    }

    /**
     * @dev Returns an `BytesSlot` with member `value` located at `slot`.
     */
    function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.
     */
    function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := store.slot
        }
    }
}