// File: contracts/NGAL.sol




// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/// @title: Noble Gallery
/// @author: manifold.xyz

import "./manifold/ERC1155Creator.sol";

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//                                                                                                                                                                                                                                                                                                                    //
//                                                                                                                                                                                                                                                                                                                    //
//                                              .:ddkOOOk:       .    .x00d..,.        .:cccllclccccc:',:cccc:'.                             .:ccc'    ...     ......................            ..:dkO00k:               ......;xOx,'ol,,::;;,';x0O000000OOd,.....',,;lkOOOOOOOOl......,;:cdO0000000000o.            //
//                           .cl,     ',.           ,xo,;l;      ,o,  .'lddc.           'dook0O0Ol,;,''..'''''....     .,'.........                  '::::::::::loooooooooddlcccccccc:,'.     ......'lxO00Oxl;..       .,;;'      .oOkxOOOOO00OOOOO0Oo;;;:ll;.           ',,,,,,''.         .;lccoooooooo:.           //
//                           .,,.    .co.           'dc..c:.... ..'.                    'xOOO00kl..'.                  .;lodkkOOkl,.                  ..........:kOkkxdooddo'                   .loldxkO00Ox:.         .cO0o.      cO0000OO0OO00O000Ol,,,,;;,.                                                        //
//                                    ..            .,.  ',''.....                      .d0OOO0Od'      ...             .,;,,,,:loo.                            ;k0OOkdoolcl'  .,.              .cdddddkkOkc.           'cll,     .cOOO00OOOO000OOOOOOOOOOOOO:                                                        //
//                                                                                      .oxkOkxxx:                             .'ld'                            ;kOOOkdoo;';'                         ..,oo.          ...'...     .:kOOOOOOOOOOO00OO00OOOOO0Oc                                                        //
//                                                                                       ...,....                ..              ;o.                            .;:lccooooll'                            ;l.            ..         .......'lxllk000OOOOOOOO0Oc                                                        //
//                               ....''''','''.  ..'''',.                                                                        ..                                  ,oddodo'                            .'.                                . .;:cdO0OOOOOO0Oc                                                        //
//                              .;:';llooodolol;';loolod:                                            ..            ..   ..                                           ,oodooo:'.......                                     .,.    ...',,,,,,,,,,;,;oOOOO00OO0Oc                                                        //
//                               ;ccoolldololoooooooolodl',c:;;'.                                    ..            .,..,;;,''''''.''.....                            'ooooodooooolllllccc,....   .                       .cko.   ..;kOOOOOOOOOOOOOOO0OOOOO00Oc                                                        //
//                               ;ccoolooclooooodxooolodxkO0000d.                                                ..lkxxkkOOOOOOOOOOOOOkdl.                           'looooooddolccccccc;.                                ...      ,k00000000000000000O00OO0Oc..                                                      //
//    ....                       ,;';lloocooooooddololodxkOO0O0d.                                                ;xO0O0kldOOOOO00O0OOOO0kl;'......                   .:ooodddxxo:''''''''..                                     .;.,k00OOO000000000000000000Odc;.                                                     //
//    ccc:.                      ..';;:c;':oxxxxxo:::::::oOOOOOxllooooooll,                                     .:xkO00OkkOOOOO0OO0xdk0000OOOOkxd:.          ..      ,oxxxxkOOOOOkkkkkkkkko.                                    .;';k00OOOOOO0OO000OO0000000000o.                                                     //
//                                  ','.  ,x00OOkl;:'.  .lxdk00OOO000000O0d'  .                                .,lxxO0OOOOO000OOO0OkxkOOOOOOOOO00o.   .....    .....'oOOOkkOOOOOOOOOOO00Oxo'                                       ,k0000OOOOOOOOOOOOOO00000000o.                                                     //
//         .,,.                     .;'   ;k0000kc:l,    ;dkOO00O0OOOO0OO0Oxlo;                     .cdlc;.   .cxxO000OOO000O0OO0O0000OOOOOOOO000k,   ,xxo,    ;xkkxdkOOOOOOOO0OOOOOO000Odl'                                       'dO0OOO0000000OOOOOOOOOO0000kollllc,,'                                             //
//          ..                            .,::;cddll,     ..,:coxOkddO0OO0OO0Oc                  .. .dk;.      cOOO000000000000O00OO00OOOOOOOOdokk,   ;k0k,    :O00kxk0OO00OO0OOOOOOOOO000x'                                        ,x0O00OOOOO0OOOOOO000OO00000000000OOl.                      ..            ..      //
//                                             .:oll,           .':xOOOOOOOkxkc                  '. .do..,,,'',lxxxxxkxxxxxxxkOOOO0OO0OOOOO00Oxdkk,   ,lld,    :O0O00OOO0O0000O0OOO0000000x'             ..                         'dkkkkkOOO0OOOOOOOkkOO00000000000000l.                     .cc.            .      //
//                                   ..        .:::dolc;'         'd00OO0OOxldd:;;,.    ... ........,c,.cdddllddooolloddollloodxk00OO0O0OOkl:ccc:c:,,,locdo;,,;dO0O00O0OOOOOOO000OO00OkO00x'       .....':;.......                   .....';lkOOxddddo:.;d0OO0000000klcxl.                    .;oo:.                  //
//              .'.                  ..        .cc;;lxkkd;'''''''';xOOOOOOOOOOOOO0O:    .. .lOkkOkkkd' .coodlodddoolloooodddddoxO000OOOolkd.     .lOOOOO0O0OOOOO00O00OOOOOOOOOO00OO00kxO00x'      'dkkkkkkkkkkkkkd:...                      'xOOxddddl' .d0O0kdxOxooc' ,,                     .:;;c'                  //
//             .,,.      ..          ;;..''.....ldlldxddoloxkkkxxkd:,,,:okOOOOO000Oo:;;;;;;:ccclccoxc. .:oodlodolooooooooodxdoddddddl:;;:oc.     .lO0O00OOO000OOO00OO0OOOOOOOOOOO0OOOdlloxkoccccccdO0OOOOOO0OOOOOOkxddol;.''..              .';;,,,cldc..oO00d..'.                        ......  ':,...              //
//        .;cc, .,.                  .',;';::oddxxxxO00kdodlcc'....    .;dOOOkkOOOO000000O0x'     ...  .:oddlodollooooolooodollc:c,.   ....,,,,,,,oO0OO00OOOO00OO0OO0OOOO0OO0OOOO0OOOocloxO00000000O00OOOOO0kc,;;;;;;;:;,,cllddoollc:;,,,'.         .oo..dOO0d.                           .,::'.   .':c;..            //
//        .dd;' ...                 . .',;oOOOOOkkkkOOOOOkd;.            ';'...':dkOOO00OO0k,     .,;,:cooddlodoooooooolddodddo;'..       .:llllllok00OO00OO00O0000OOOkOOO000OOOOOOOOOO0OOOOOOOOOOOOO0OOOOO0x'.''.          ;kOOOOOOOOOOOOd:;;,'.   .dl..oOOOd.                             ..;,  .;;'.               //
//        .dkc.              .........,dkO0OOOO00OkxxodkOOx:                    .;xO0OO0000O:     .:oooodxxdlodolooooollodc:;::,.                'cdxxxkO00OOkxkOkkkkxdxkkkOOOOOOOOOOOOOOOOOOOOOO0OOO0kodO00x'.;,           .',,,,,,cllx0000O00Ol. .;c.  .;:c:.         ',.                   ':. ,;.                 //
//       .:x0o.          .. ... .,clddxO0O0OO0OO0OxodlokO0Oc.     ..            .ck0O0O00O0O:     .:doodxxxdlodollloooc,co;.                       ....oOO0OOl.,:'...,odxxxkO0OOOOOOOOOOOOOOOOOOOOOOOOOOOO00x'                        .';;;;;;cd:   ..       ..   .;.  .ok,                   .:,.;.                  //
//       .,;:,.         .;.     .cxkOOkOOO000OOOOOdodoodk0Oc.                 .cxOO0OkOO0OOO;     .:oolododl:lollllllllcoo;.                       ...,dkkOOOc       .cdddxOOOOO0OOOOO0O00OOOO0OOOOOOxxxxxxxo.                                'l,           .cdddll:.  .dk,                    :oc:.                  //
//         .,.          .;. .:cloxO00OOOO00O0OOOOOkxxxxkO0Oc.               ';oOOOOOOOO0OO0k:..    ......... .........'lkdl:,;;'.                 .od,.c;.:xOc       .',;:oO00OOOOOOOkkkOOO0OOO0kc,,'........                               .''.''..     .,..lddxxkdcccdOk;                    .;:,                   //
//         ...          .;. ,dkO00O0OO00O0O0000000OOOO00OOOl.              .d000OO0O00O0OO0kc,'                       .oOxxddxd:.                 .;c'.cl,;xOo'...       .lOO00OOOOxddodkOOOOOO0x'            ..     .                      .''..'.             ...,lkdx0k;                                           //
//                      'c. 'x00O00OO00OO0O0OdlllxO0OOOO0OOxlc::'..        .:oxO0OO0OOO00O0O;                         .oOxxoodd:.                     .lOOOOOOkkkxl.     .lOOO00OOOkddddkOOOOOO0x'           .;,......                        ':'                   :llk0k, .'.                                       //
//                      .;. 'xOOOOOO0O000O00x,   ;xOOO0OOOOOkO0Okxd:,'.      .:ddxO0OO00000O:  .,.                    .o0Oo'....                      .lO00O0OO000O:     .lOO00OOOOOxddodxkOO0O0x' ,c.       ,ccccllc,..                       ..    .'.          ..::;x0k;.;'                                        //
//                          ..'''',od:;;;;;;,.   .lkOOO000O0000000OOOkc.       ..,looodkOOOkdllddc::;:;;;;,'.','......':lc'                           .lOOOOOOOOO0O:     .lOO00O00OOkkxxxkOO0OO0x' ..               .lko.                           .;:.          ..;;,x0Oc;'                                         //
//                                .c:      ..    .,,;cooooolccccc:;:c::l;.      ,l'    ..'''';okkkkkkkkkkkxo'..:oooooool,                             .lOOOOOO0OO0Oc......:ooooodkkkOOOO00OOO0OOx,                  .cko' . .                                       .;xO00kx;                                         //
//                             .. .c:      '.    ..                    'oo,     :d,          .;x0O00O000O00x'  .;::::lc:,....',,'.                    .lOOOOOOO0OOOkxxxxxoc;.   .''lO0O0OOOOOOOkol:::;,.             .....  .;c.  ;ol.                               ,kOlcxOc                                         //
//                             ..  ;,            ..     .........'......,;'.    ;d;           .,llcllcllcll:'...... .;'   ..,dOOx;                    .lOOOOOOO0OOOO0OOOOdoc.     .cO00O00OO0OOxlloodoc.                     :x' .l0x'    ....                       .cl..lOc       ..                                //
//                                    ........          ,lloddolodoolcc:.      .cxdc.     .lol,             .,,;;;,....     .',,:oc.         ..       .lOOOOOOOOOOOOOOOOkooc.  ....:xxxxxxxxxxxdlloollc.                     ;l.  :xo,....'...                         '..lOc                                         //
//                              .',,,;oddddddc.         .:ldxdolooloolol.      .oOkxlc:;::lk0Ok;                                .ll.       'lo;.      .lOOOOOOOOOOOOOO0Oxcll..'dOo. .............:l:;;;;,,,.                  .    ..cxxxo.                              .oOc                                         //
//                             .lkOkkOOOOOOOkxc.    ..  .looooooooloollc.      .d0kolloloxxkOOOl.           ...       .....';;;;:dl.    .  .;l;.      .lOOOOOOOOOOOOOOO0Okkxlcokxc..','..        ..       '' ........                ';;;,.                              .:c'     ...''.                              //
//                             .l0OkkO0OOOOOO0O:     .  ,oollodoooloolll:'     .dOOxxdxxxkOOkkkl.          .;l'      ;ooddxkOO00OOo.    .    ',.      .lOOOOOOOOOOOOOOO000O00OOOkx:,c::ol;.               ..,ooodooooc..ld:..,:'''.                                               ..;kd.                              //
//                             .lOkOOO0OO00OOOOl...;;;;,,,'.'',;;'''''''..     .d0OOOOOOOOOOOkxoll;..          .:ccccdkkOOOOOOOOOkd;   ',.    .,. ..  .lO00OOOOOOOOOOOOOO000OO0OOOdcooddol:.                ..;oxd;... ,x0x, ,kOOOdcccccccc::,..;;;;;;;;;'.''..                     :Ox'                              //
//           ....              .lOkOOO00OO0OOOO:.'coooll'                      .dOkxxxxxxxxxxxxdl;;ll,....     .''','''',;,''''';lxc..:xOo:;:;ldl::::;cxOO0000OOOOOOOOOOOOOOOOOOO0Oxooooollc:::.          .',;;cdxc...,lkddl.,k0O000O0000OOo,..;oododdodoooooo:.         ''         cOx'                              //
//                             .o0000O000000O0O: .......                 .,,,,,:oxdddooooooooooo, .;looldo'.''                   .,. .,,,,,,,;lxl;,,,,,,,lk0000OOOOOOOOOOOOOOOO00OOkdolooloddddocccccccccclddddddoodoldxxdc. ;k00O00OO0O00Oc   ;odoooooooolccc;.         ..         :kdc:'..                          //
//                              ,:::oO0000OO00O:                ..      'cddddddoooooooooooooddo;   'oOkkOo,''                                'l'        .oOOO0OO000OOOOOOOOOOO00OOOkxxddooooodddoddoododxkO000OkxkO0OkxkOl. ;kOOO000OO00OO:   ;ooodoooodl'                         ..'lkxo:.                         //
//                                  .;;:oO00OOO:                       .,lddooddddddddddddddddoooccclkOOOOOl'.                   ;:.  .',.    .,'...     .:odddkO000OO0OOOOOOOOOOOOOOO0OxdooddddddodddddodxkOO0OkxkO00OkkOc. .::ckOO0OO00kl:'. ;odoooooodl.                           .o000d'.                        //
//                       ..             ;kOO0OOo;.                      .cddoododdddddddddddddooxOOxdk00OOOOd,.         .:'   .  ..   .,;.     .:lll'    .cl:lolccdOO0OOOOOOO00OOOOOOO0OxdoooddoooodooddoodxOOOOOkxkxxxxkkl:;.  .lO000O00x;:l'.;odoooooodl.                           .o000Oxdl;c'                    //
//                                      ;kOOOOO0k;.                .,.  .cddoododdddddddddddddodxOOdlx0OO0OOOxl,.     .';c:'';:.              'oddol'      ...,.  .o0OOOOOOOOO0OOOOOOO0OxdoodddodddodoooodoxO0OOOOOOkxoldkkkk:   'ccccccc;.... ;odoooooodl.                           .okkOkxdxdo,                    //
//                                ..    .,,ckOO0Oxddddddolllll;.   ',.  .cdoooodddddoodooddoododxO000O0OOOkkOOOd.     .::::;;..'.              .lxol'     ',.     .lOkxkOOkkOOOOO00OOO0OxdooddddddddoooddooxOOO0OO0OOo;lxkxodo'  ..            ;oooodooodl.                            ...:lldddooc'                  //
//                                ..       .dOOOOOO000O0000000d.  ..    .cdddddddddododdddddooooxO000OOO0Oko;'..               ..     .         ;ol:'     ...      ;c'.':ccoO0O00OOOOO0OxdooddoododdoooooodxkOOOO00OOdldol:.;d:.      ..       ;ooooddoool.                       .'.     ,cd00000O;             .    //
//                .;;::::c:::::::::;.      .okkOO000000000OOO0o.',;;,'..';;,;cllllloo:,,,,,;oxxxkOO00OOOOOOl.                 .:;.               ...':c::c,              .;dO0OOOO00OO0OxdoodddddooooododddddxOOOxlcldool:. .,,;'..           .;ooooododdl.   .'                  ..      ':okkkkkx;           .cx    //
//                .ldooooooddddooddo:.     .oOOOkO0OO0000OOOO0o,cdddodool,  .;oxkkkko.     .lO00OxxkO0O0O0Oxc'.               .dkxolc::ccllc,,cllll,,ldoldc.          ..   ,x00OOOOO000Oxdooodddddoooodoooddddxxdccodddddo,   .,;,.           .;oodoodoodl.   ..                 .        .........;clc.       .;c    //
//                'ldodooooddooddddoc:;;;::cx0OkkOO00000000000kolc;,,,,cc..,c;ck0OO0d,      .ckOOOxdolclxO00ko;.       ..''.. .d0O00OklcoxkkkO00O0Ol;ldlld:.         .cc.  'x000OO0kodOOxdoooodddodddoodododdddc,;x0OOOOOkc. 'c,.              ;oooooooool.         .;llllllc::::,.;lll,           :O0k'         .    //
//              .;loddddddddddool,...':ok00OO00OOO0000000000000ko;.  ..;:,,ll,',,;;;,,;.      'lkO0Oc   .:dOOOOd;...   .;dkxd,.o0O0OOOOkkxxdlldkOOOl';o;',,''''''''.  ..   'x0OOOOOkodOOxdddoddddddoddooodddxxd' .oolxkOOkl..,,                ;odoooooodl.         .o000000000Oc  ;k0Ol.          :O0k'       ...    //
//              .:oododdddddddoo:.    .';:cxkxOOO0O0000000000000Okl'.  .   .         .;.        .;:;.     .oO0OkxxxdddooxOOkx,.oO00OOOO00O0Oddolodd:..;.  .lxocolcl;       .:xl;,',:okOOOkkkkkkxdooooooodddddxkl.'oookOOkxo;.,.   .:l,         ;odoooooodl.                                                           //
//                                                                                                                                                                                                                                                                                                                    //
//                                                                                                                                                                                                                                                                                                                    //
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


contract NGAL is ERC1155Creator {
    constructor() ERC1155Creator("Noble Gallery", "NGAL") {}
}

// File: contracts/manifold/ERC1155Creator.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 ERC1155Creator is Proxy {

    constructor(string memory name, string memory symbol) {
        assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256("eip1967.proxy.implementation")) - 1));
        StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = 0x6bf5ed59dE0E19999d264746843FF931c0133090;
        Address.functionDelegateCall(
            0x6bf5ed59dE0E19999d264746843FF931c0133090,
            abi.encodeWithSignature("initialize(string,string)", name, symbol)
        );
    }

    /**
     * @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.8.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 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.7.0) (utils/StorageSlot.sol)

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:
 * ```
 * 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`, and `uint256`._
 */
library StorageSlot {
    struct AddressSlot {
        address value;
    }

    struct BooleanSlot {
        bool value;
    }

    struct Bytes32Slot {
        bytes32 value;
    }

    struct Uint256Slot {
        uint256 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
        }
    }
}