{"matchId":"56639402","creationMatch":"match","runtimeMatch":"match","verifiedAt":"2026-10-21T02:23:55Z","creationBytecode":{"onchainBytecode":"0x608060405234801561000f575f5ffd5b5060408051602080820183525f8083528351918201909352918252906003610037838261012a565b506004610044828261012a565b505050600161005d61005a61006360201b60201c565b90565b556101e8565b7f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0090565b634e487b7160e01b5f52604160045260245ffd5b600181811c908216806100af57607f821691505b6020821081036100cd57634e487b7160e01b5f52602260045260245ffd5b50919050565b601f821115610125578282111561012557805f5260205f20601f840160051c60208510156100fe57505f5b90810190601f840160051c035f5b81811015610121575f8382015560010161010c565b5050505b505050565b81516001600160401b0381111561014357610143610087565b61015781610151845461009b565b846100d3565b6020601f821160018114610189575f83156101725750848201515b5f19600385901b1c1916600184901b1784556101e1565b5f84815260208120601f198516915b828110156101b85787850151825560209485019460019092019101610198565b50848210156101d557868401515f19600387901b60f8161c191681555b505060018360011b0184555b5050505050565b6153e7806101f55f395ff3fe608060405234801561000f575f5ffd5b5060043610610346575f3560e01c8063648da859116101be578063bc25cf77116100fe578063c5884ad11161009e578063ee39e7a011610079578063ee39e7a014610856578063f140a35a1461085e578063fc9654ab14610871578063fff6cae914610879575f5ffd5b8063c5884ad1146107dc578063d21220a71461080b578063dd62ed3e1461081e575f5ffd5b8063c245febc116100d9578063c245febc146107a0578063c45a0155146107ab578063c47f0027146107be578063c5700a02146107d1575f5ffd5b8063bc25cf7714610777578063bda39cad1461078a578063bf944dbc14610795575f5ffd5b806395d89b4111610169578063a1ac4d1311610144578063a1ac4d131461071d578063a9059cbb1461073e578063b84c824614610751578063b95d88f814610764575f5ffd5b806395d89b41146106ce5780639d63848a146106d65780639f767c88146106fc575f5ffd5b806378273aca1161019957806378273aca14610687578063883bdbfd1461069a57806389afcb44146106bb575f5ffd5b8063648da859146106255780636a6278421461064c57806370a082311461065f575f5ffd5b8063252c09d7116102895780633358095911610234578063485cc9551161020f578063485cc955146105da5780634983f2f5146105ed5780634d5a9f8a146105f95780635a76f25e1461061a575f5ffd5b80633358095914610569578063392f37e91461057c578063443cb4bc146105cf575f5ffd5b8063313ce56711610264578063313ce5671461053c57806332148f671461054b57806332c0defd1461055e575f5ffd5b8063252c09d7146104e157806325d2a3f3146105165780632dbfa73514610529575f5ffd5b8063119c4e9f116102f45780631a4211dc116102cf5780631a4211dc1461045a5780631df8c717146104a5578063205aabf1146104ad57806323b872dd146104ce575f5ffd5b8063119c4e9f1461041757806315a0ea6a1461042a57806318160ddd14610452575f5ffd5b8063095ea7b311610324578063095ea7b3146103a85780630dfe1681146103cb5780630ea099c1146103f6575f5ffd5b8063022c0d9f1461034a57806306fdde031461035f5780630902f1ac1461037d575b5f5ffd5b61035d61035836600461451c565b610881565b005b610367611049565b6040516103749190614581565b60405180910390f35b6203000b546203000c546203000d545b60408051938452602084019290925290820152606001610374565b6103bb6103b63660046145b6565b6110d9565b6040519015158152602001610374565b6007546103de906001600160a01b031681565b6040516001600160a01b039091168152602001610374565b6104096104043660046145e0565b6110f2565b604051908152602001610374565b61040961042536600461460e565b611175565b61043d610438366004614648565b611280565b60408051928352602083019190915201610374565b600254610409565b62030008546104809061ffff808216916201000081048216916401000000009091041683565b6040805161ffff94851681529284166020840152921691810191909152606001610374565b61038d6112d5565b6104096104bb366004614648565b620300136020525f908152604090205481565b6103bb6104dc366004614663565b61134c565b6104f46104ef3660046146a1565b611371565b6040805163ffffffff9094168452602084019290925290820152606001610374565b61043d610524366004614648565b6113ce565b61043d6105373660046146b8565b6114af565b60405160128152602001610374565b61035d6105593660046146e4565b61157c565b610409620300105481565b6009546103de906001600160a01b031681565b62030009546203000a546203000b546203000c546007546008546040805196875260208701959095529385019290925260608401526001600160a01b0390811660808401521660a082015260c001610374565b6104096203000b5481565b61035d6105e83660046146b8565b6115f0565b6104096402540be40081565b610409610607366004614648565b620300146020525f908152604090205481565b6104096203000c5481565b6104097f56325f535441424c45000000000000000000000000000000000000000000000081565b61040961065a366004614648565b611930565b61040961066d366004614648565b6001600160a01b03165f9081526020819052604090205490565b61035d610695366004614712565b611bc2565b6106ad6106a836600461473e565b611c8d565b6040516103749291906147e9565b61043d6106c9366004614648565b611cbb565b610367611fca565b600754600854604080516001600160a01b03938416815292909116602083015201610374565b61040961070a366004614648565b620300126020525f908152604090205481565b61040961072b366004614648565b620300156020525f908152604090205481565b6103bb61074c3660046145b6565b611fd9565b61035d61075f36600461480d565b611fe6565b6104096107723660046145e0565b6120b1565b61035d610785366004614648565b612249565b610409620300115481565b6104096203000e5481565b6104096203000f5481565b600a546103de906001600160a01b031681565b61035d6107cc36600461480d565b6123b6565b6104096203000d5481565b6103bb6107ea3660046146b8565b6203001660209081525f928352604080842090915290825290205460ff1681565b6008546103de906001600160a01b031681565b61040961082c3660046146b8565b6001600160a01b039182165f90815260016020908152604080832093909416825291909152205490565b610409612481565b61040961086c3660046145e0565b6124ca565b610409603c81565b61035d6125d6565b610889612729565b600a5f9054906101000a90046001600160a01b03166001600160a01b031663b187bd266040518163ffffffff1660e01b8152600401602060405180830381865afa1580156108d9573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108fd919061484c565b15610934576040517f1309a56300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84158015610940575083155b15610977576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6203000b546203000c5481871015806109905750808610155b156109c7576040517fbb55fd2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6007546008545f9182916001600160a01b0391821691908116908916821480610a015750806001600160a01b0316896001600160a01b0316145b15610a38576040517f290fa18800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8a15610a5257610a526001600160a01b0383168a8d612757565b8915610a6c57610a6c6001600160a01b0382168a8c612757565b8615610aed576040517f9a7bff790000000000000000000000000000000000000000000000000000000081526001600160a01b038a1690639a7bff7990610abf9033908f908f908e908e90600401614867565b5f604051808303815f87803b158015610ad6575f5ffd5b505af1158015610ae8573d5f5f3e3d5ffd5b505050505b6040516370a0823160e01b81523060048201526001600160a01b038316906370a0823190602401602060405180830381865afa158015610b2f573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b5391906148b3565b6040516370a0823160e01b81523060048201529094506001600160a01b038216906370a0823190602401602060405180830381865afa158015610b98573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610bbc91906148b3565b925050505f8985610bcd91906148f7565b8311610bd9575f610bed565b610be38a866148f7565b610bed90846148f7565b90505f610bfa8a866148f7565b8311610c06575f610c1a565b610c108a866148f7565b610c1a90846148f7565b905081158015610c28575080155b15610c5f576040517f098fb56100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051610100810182525f80825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810191909152610ca98c8461490a565b6fffffffffffffffffffffffffffffffff166040820152610cca8b8361490a565b6fffffffffffffffffffffffffffffffff1660608201526007546008546001600160a01b0391821691165f8080610d0388888e8e6127aa565b919450925090508715610d78575f612710610d1e858b61491d565b610d289190614961565b9050610d3381612863565b6fffffffffffffffffffffffffffffffff81168752612710610d55848b61491d565b610d5f9190614961565b6fffffffffffffffffffffffffffffffff1660c0880152505b8615610de9575f612710610d8c858a61491d565b610d969190614961565b9050610da181612910565b6fffffffffffffffffffffffffffffffff81166020880152612710610dc6848a61491d565b610dd09190614961565b6fffffffffffffffffffffffffffffffff1660e0880152505b8015610e195760408601516fffffffffffffffffffffffffffffffff908116608088015260608701511660a08701525b6040516370a0823160e01b81523060048201526001600160a01b038616906370a0823190602401602060405180830381865afa158015610e5b573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e7f91906148b3565b6040516370a0823160e01b8152306004820152909a506001600160a01b038516906370a0823190602401602060405180830381865afa158015610ec4573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ee891906148b3565b9850610ef48c8c6129b6565b610efe8b8b6129b6565b1015610f36576040517fa932492f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600a546040517f5310a4210000000000000000000000000000000000000000000000000000000081526001600160a01b0390911690635310a42190610f7f908990600401614974565b5f604051808303815f87803b158015610f96575f5ffd5b505af1158015610fa8573d5f5f3e3d5ffd5b50505050505050505050610fbe84848888612a5f565b60408051838152602081018390529081018c9052606081018b90526001600160a01b038a169033907fb3e2773606abfd36b5bd91394b3a54d1398336c65005baf7bf7a05efeffaf75b9060800160405180910390a350505050505061104260017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b5050505050565b60606005805461105890614a84565b80601f016020809104026020016040519081016040528092919081815260200182805461108490614a84565b80156110cf5780601f106110a6576101008083540402835291602001916110cf565b820191905f5260205f20905b8154815290600101906020018083116110b257829003601f168201915b5050505050905090565b5f336110e6818585612b44565b60019150505b92915050565b6203000b546203000c546007545f929190839081906001600160a01b03878116911614611120575f87611123565b865f5b915091505f611134838387876127aa565b505090506127108189611147919061491d565b6111519190614961565b61115b90896148f7565b975061116988888787612b51565b98975050505050505050565b6007545f90819081906001600160a01b03878116911614611197575f8761119a565b865f5b600a546040517fdf29d5bb0000000000000000000000000000000000000000000000000000000081523060048201525f602482015260448101849052606481018390526084810189905260a48101889052929450909250612710916001600160a01b039091169063df29d5bb9060c401602060405180830381865afa158015611225573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061124991906148b3565b611253908961491d565b61125d9190614961565b61126790886148f7565b965061127587878787612b51565b979650505050505050565b5f806001600160a01b0383166112c2576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6112cc3384612c93565b91509150915091565b6203000e546203000f54425f80806112fc6203000b546203000c546203000d549192909190565b925092509250838114611344575f61131482866148f7565b9050611320818561491d565b61132a908861490a565b9650611336818461491d565b611340908761490a565b9550505b505050909192565b5f33611359858285612dd0565b611364858585612e5f565b60019150505b9392505050565b5f808080600b8561ffff811061138957611389614ad5565b6040805160608101825260039290920292909201805463ffffffff16808352600182015460208401819052600290920154929093018290529197919650945092505050565b6001600160a01b0381165f908152620300146020908152604080832054620300158352818420549284905292205480156114a9576001600160a01b0384165f9081526203001260205260409020546203001054670de0b6b3a764000091611434916148f7565b61143e908361491d565b6114489190614961565b611452908461490a565b6001600160a01b0385165f9081526203001360205260409020546203001154919450670de0b6b3a76400009161148891906148f7565b611492908361491d565b61149c9190614961565b6114a6908361490a565b91505b50915091565b5f806001600160a01b0383166114f1576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336001600160a01b0385161480159061152f57506001600160a01b0384165f908152620300166020908152604080832033845290915290205460ff16155b15611566576040517fea8e4eb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6115708484612c93565b915091505b9250929050565b6203000854640100000000900461ffff165f611599600b84612eee565b90508161ffff168161ffff16146115eb576040805161ffff80851682528316602082015233917ff0b7b7d1cdf542f5660a7879f0cac17375fdcf984af4a6d499a9daedacb24c58910160405180910390a25b505050565b600a546001600160a01b031615611633576040517f154c51b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600a8054337fffffffffffffffffffffffff0000000000000000000000000000000000000000918216179091556008805482166001600160a01b03848116919091179091556007805490921690841617905560405182908290611695906144bd565b6001600160a01b03928316815291166020820152604001604051809103905ff0801580156116c5573d5f5f3e3d5ffd5b5060095f6101000a8154816001600160a01b0302191690836001600160a01b031602179055505f826001600160a01b03166395d89b416040518163ffffffff1660e01b81526004015f60405180830381865afa158015611727573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261174e9190810190614b2f565b90505f826001600160a01b03166395d89b416040518163ffffffff1660e01b81526004015f60405180830381865afa15801561178c573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526117b39190810190614b2f565b90506117bf8282613005565b6005906117cc9082614c39565b506117d78282613031565b6006906117e49082614c39565b50836001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611821573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118459190614cf4565b61185090600a614def565b6203000981905550826001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611894573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118b89190614cf4565b6118c390600a614def565b6203000a55600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000164263ffffffff161790556203000880547fffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ffff166401000100001790555b50505050565b5f611939612729565b6203000b546203000c546007546040516370a0823160e01b81523060048201525f916001600160a01b0316906370a0823190602401602060405180830381865afa158015611989573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119ad91906148b3565b6008546040516370a0823160e01b81523060048201529192505f916001600160a01b03909116906370a0823190602401602060405180830381865afa1580156119f8573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611a1c91906148b3565b90505f611a2985846148f7565b90505f611a3685846148f7565b90505f611a4260025490565b9050805f03611ac4576103e8611a60611a5b848661491d565b613046565b611a6a91906148f7565b9750611a7960016103e86131ab565b611a8383836131fc565b6103e8881015611abf576040517fd226f9d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611b31565b611af687611ad2838661491d565b611adc9190614961565b87611ae7848661491d565b611af19190614961565b6132bc565b9750875f03611b31576040517fd226f9d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611b3b89896131ab565b611b4785858989612a5f565b60408051848152602081018490526001600160a01b038b169133917f2f00e3cdd69a77be7ed215ec7b2a36784dd158f921fca79ac29deffa353fe6ee910160405180910390a350505050505050611bbd60017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b919050565b6001600160a01b038216611c02576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b335f81815262030016602090815260408083206001600160a01b0387168085529083529281902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001686151590811790915590519081529192917f63484c3756a6c7d95f131879210268006b60e58057de5db75f3a8c91c7869ebf910160405180910390a35050565b6060805f5f611c9a6112d5565b509092509050611cae600b878785856132cb565b9350935050509250929050565b5f5f611cc5612729565b6203000b546203000c546007546008546040516370a0823160e01b81523060048201526001600160a01b0392831692909116905f9083906370a0823190602401602060405180830381865afa158015611d20573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611d4491906148b3565b6040516370a0823160e01b81523060048201529091505f906001600160a01b038416906370a0823190602401602060405180830381865afa158015611d8b573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611daf91906148b3565b305f908152602081905260409020546002549192509080611dd0858461491d565b611dda9190614961565b995080611de7848461491d565b611df19190614961565b9850891580611dfe575088155b15611e35576040517f749383ad00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611e3f30836133e6565b611e536001600160a01b0387168c8c612757565b611e676001600160a01b0386168c8b612757565b6040516370a0823160e01b81523060048201526001600160a01b038716906370a0823190602401602060405180830381865afa158015611ea9573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611ecd91906148b3565b6040516370a0823160e01b81523060048201529094506001600160a01b038616906370a0823190602401602060405180830381865afa158015611f12573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f3691906148b3565b9250611f428484613433565b611f4e84848a8a612a5f565b604080518b8152602081018b90526001600160a01b038d169133917f5d624aa9c148153ab3446c1b154f660ee7701e549fe9b62dab7171b1c80e6fa2910160405180910390a35050505050505050611fc560017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b915091565b60606006805461105890614a84565b5f336110e6818585612e5f565b600a5f9054906101000a90046001600160a01b03166001600160a01b031663b782cc496040518163ffffffff1660e01b8152600401602060405180830381865afa158015612036573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061205a9190614dfd565b6001600160a01b0316336001600160a01b0316146120a4576040517f058a2da800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60066115eb828483614e18565b5f825f036120c057505f6110ec565b6203000b546203000c546007546001600160a01b038581169116146120e557806120e7565b815b851061211f576040517fbb55fd2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f61212c86868585613475565b9050805f03612140575f93505050506110ec565b6007545f9081906001600160a01b0388811691161461216057825f612163565b5f835b600a546040517f11896ad200000000000000000000000000000000000000000000000000000000815230600482015233602482015260448101849052606481018390526084810189905260a481018890529294509092505f916001600160a01b03909116906311896ad29060c401602060405180830381865afa1580156121ec573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061221091906148b3565b9050612232816122216001876148f7565b61222d846127106148f7565b6135ce565b61223c908561490a565b9998505050505050505050565b612251612729565b6007546008546203000b546040516370a0823160e01b81523060048201526001600160a01b0393841693909216915f919084906370a0823190602401602060405180830381865afa1580156122a8573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906122cc91906148b3565b6122d691906148f7565b905080156122f2576122f26001600160a01b0384168583612757565b6203000c546040516370a0823160e01b81523060048201525f91906001600160a01b038516906370a0823190602401602060405180830381865afa15801561233c573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061236091906148b3565b61236a91906148f7565b90508015612386576123866001600160a01b0384168683612757565b505050506123b360017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b50565b600a5f9054906101000a90046001600160a01b03166001600160a01b031663b782cc496040518163ffffffff1660e01b8152600401602060405180830381865afa158015612406573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061242a9190614dfd565b6001600160a01b0316336001600160a01b031614612474576040517f058a2da800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60056115eb828483614e18565b5f61248a612729565b61249c6203000b546203000c546129b6565b90506124c760017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b90565b6203000b546203000c546007545f929190839081906001600160a01b038781169116146124f8575f876124fb565b865f5b600a546040517fdf29d5bb0000000000000000000000000000000000000000000000000000000081523060048201525f602482015260448101849052606481018390526084810188905260a48101879052929450909250612710916001600160a01b039091169063df29d5bb9060c401602060405180830381865afa158015612586573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906125aa91906148b3565b6125b4908961491d565b6125be9190614961565b6125c890886148f7565b965061127587878686612b51565b6125de612729565b6002545f03612619576040517fbb55fd2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6007546040516370a0823160e01b81523060048201526126fe916001600160a01b0316906370a0823190602401602060405180830381865afa158015612661573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061268591906148b3565b6008546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa1580156126cb573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906126ef91906148b3565b6203000b546203000c54612a5f565b61272760017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b565b61273161367e565b60027f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b61276483838360016136e1565b6115eb576040517f5274afe70000000000000000000000000000000000000000000000000000000081526001600160a01b03841660048201526024015b60405180910390fd5b600a546040517fdb6b39b400000000000000000000000000000000000000000000000000000000815230600482015233602482015260448101869052606481018590526084810184905260a481018390525f91829182916001600160a01b03169063db6b39b49060c401606060405180830381865afa15801561282f573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906128539190614ed2565b9250925092509450945094915050565b805f0361286d5750565b60095460075461288a916001600160a01b03918216911683612757565b5f61289460025490565b6128a683670de0b6b3a764000061491d565b6128b09190614961565b905080156128d15780620300105f8282546128cb919061490a565b90915550505b604080518381525f602082015233917f112c256902bf554b6ed882d2936687aaeb4225e8cd5b51303c90ca6cf43a860291015b60405180910390a25050565b805f0361291a5750565b600954600854612937916001600160a01b03918216911683612757565b5f61294160025490565b61295383670de0b6b3a764000061491d565b61295d9190614961565b9050801561297e5780620300115f828254612978919061490a565b90915550505b604080515f81526020810184905233917f112c256902bf554b6ed882d2936687aaeb4225e8cd5b51303c90ca6cf43a86029101612904565b5f5f620300095484670de0b6b3a76400006129d1919061491d565b6129db9190614961565b90505f6203000a5484670de0b6b3a76400006129f7919061491d565b612a019190614961565b90505f612a178383670de0b6b3a76400006135ce565b90505f612a2d8384670de0b6b3a76400006135ce565b612a408586670de0b6b3a76400006135ce565b612a4a919061490a565b90506112758282670de0b6b3a76400006135ce565b6203000d5442905f90612a7290836148f7565b90505f81118015612a8257508315155b8015612a8d57508215155b15612ad657612a9c818561491d565b6203000e5f828254612aae919061490a565b90915550612abe9050818461491d565b6203000f5f828254612ad0919061490a565b90915550505b6203000e546203000f54612aee91600b91603c61375c565b6203000b8690556203000c8590556203000d82905560408051878152602081018790527fcf2aa50876cdfbb541206f89af0ee78d44a2abf8d328e37fa4917f982149848a910160405180910390a1505050505050565b6115eb838383600161391f565b5f5f612b5d84846129b6565b6203000954909150612b7785670de0b6b3a764000061491d565b612b819190614961565b6203000a54909450612b9b84670de0b6b3a764000061491d565b612ba59190614961565b6007549093505f9081906001600160a01b03888116911614612bc8578486612bcb565b85855b60075491935091506001600160a01b03888116911614612c0b576203000a54612bfc89670de0b6b3a764000061491d565b612c069190614961565b612c2c565b6203000954612c2289670de0b6b3a764000061491d565b612c2c9190614961565b97505f612c43612c3c848b61490a565b8584613a23565b612c4d90836148f7565b600754909150670de0b6b3a7640000906001600160a01b038a8116911614612c79576203000954612c7f565b6203000a545b612c89908361491d565b61223c9190614961565b5f5f612c9e84613b44565b50506001600160a01b0382165f908152620300146020908152604080832054620300159092529091205481151580612cd557505f81115b15611575576001600160a01b038481165f9081526203001460209081526040808320839055620300159091528082209190915560095490517f533cf5ce0000000000000000000000000000000000000000000000000000000081528583166004820152602481018590526044810184905291169063533cf5ce906064015f604051808303815f87803b158015612d69575f5ffd5b505af1158015612d7b573d5f5f3e3d5ffd5b505060408051858152602081018590526001600160a01b0380881694508816925033917fcd5e4f020ddad29434c2200a9edf2f8d7ec30f0d787f03b528ab7279aab0acbe910160405180910390a49250929050565b6001600160a01b038381165f908152600160209081526040808320938616835292905220545f1981101561192a5781811015612e51576040517ffb8f41b20000000000000000000000000000000000000000000000000000000081526001600160a01b038416600482015260248101829052604481018390526064016127a1565b61192a84848484035f61391f565b6001600160a01b038316612ea1576040517f96c6fd1e0000000000000000000000000000000000000000000000000000000081525f60048201526024016127a1565b6001600160a01b038216612ee3576040517fec442f050000000000000000000000000000000000000000000000000000000081525f60048201526024016127a1565b6115eb838383613cb0565b6202fffd8201545f9061ffff64010000000090910481169083168110612f155790506110ec565b805b8361ffff168161ffff161015612fc45760018561ffff808416908110612f3f57612f3f614ad5565b6003020180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff9290921691909117905560018561ffff838116908110612f8e57612f8e614ad5565b60030201600101819055506001855f018261ffff1661ffff8110612fb457612fb4614ad5565b6003020160020155600101612f17565b5050506202fffd9190910180547fffffffffffffffffffffffffffffffffffffffffffffffffffff0000ffffffff1664010000000061ffff84160217905590565b6060828260405160200161301a929190614f20565b604051602081830303815290604052905092915050565b6060828260405160200161301a929190614f81565b5f60018211613053575090565b81600170010000000000000000000000000000000082106130795760809190911c9060401b5b6801000000000000000082106130945760409190911c9060201b5b64010000000082106130ab5760209190911c9060101b5b6201000082106130c05760109190911c9060081b5b61010082106130d45760089190911c9060041b5b601082106130e75760049190911c9060021b5b600482106130f35760011b5b600302600190811c9081858161310b5761310b614934565b048201901c9050600181858161312357613123614934565b048201901c9050600181858161313b5761313b614934565b048201901c9050600181858161315357613153614934565b048201901c9050600181858161316b5761316b614934565b048201901c9050600181858161318357613183614934565b048201901c90506131a281858161319c5761319c614934565b04821190565b90039392505050565b6001600160a01b0382166131ed576040517fec442f050000000000000000000000000000000000000000000000000000000081525f60048201526024016127a1565b6131f85f8383613cb0565b5050565b6203000a5461321382670de0b6b3a764000061491d565b61321d9190614961565b620300095461323484670de0b6b3a764000061491d565b61323e9190614961565b14613275576040517f0a04d7fa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6402540be40061328583836129b6565b116131f8576040517f438d3ade00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f82821882841002821861136a565b60608042858067ffffffffffffffff8111156132e9576132e9614b02565b604051908082528060200260200182016040528015613312578160200160208202803683370190505b5093508067ffffffffffffffff81111561332e5761332e614b02565b604051908082528060200260200182016040528015613357578160200160208202803683370190505b5092505f5b818110156133d9576133978a848b8b8581811061337b5761337b614ad5565b90506020020160208101906133909190614fb2565b8a8a613ceb565b8683815181106133a9576133a9614ad5565b602002602001018684815181106133c2576133c2614ad5565b60209081029190910101919091525260010161335c565b5050509550959350505050565b6001600160a01b038216613428576040517f96c6fd1e0000000000000000000000000000000000000000000000000000000081525f60048201526024016127a1565b6131f8825f83613cb0565b61343d82826129b6565b5f036131f8576040517f7d06c0c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f5f61348184846129b6565b620300095490915061349b85670de0b6b3a764000061491d565b6134a59190614961565b6203000a549094506134bf84670de0b6b3a764000061491d565b6134c99190614961565b6007549093505f9081906001600160a01b038881169116146134ec5784866134ef565b85855b60075491935091505f9081906001600160a01b038a811691161461351c576203000a546203000954613527565b62030009546203000a545b90925090506135476135418b670de0b6b3a764000061491d565b83613d71565b9950838a10613582576040517fbb55fd2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f6135976135908c876148f7565b8786613a23565b90506135bf826135a786846148f7565b6135b1919061491d565b670de0b6b3a7640000613d71565b9b9a5050505050505050505050565b5f5f5f6135db8686613da5565b91509150815f036135ff578381816135f5576135f5614934565b049250505061136a565b818411613616576136166003851502601118613dc1565b5f848688095f868103871696879004966002600389028118808a02820302808a02820302808a02820302808a02820302808a02820302808a02909103029181900381900460010185841190960395909502919093039390930492909217029150509392505050565b6136aa5f60027f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00613dd2565b15612727576040517f3ee5aeb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517fa9059cbb000000000000000000000000000000000000000000000000000000005f8181526001600160a01b038616600452602485905291602083604481808b5af1925060015f51148316613750578383151615613744573d5f823e3d81fd5b5f873b113d1516831692505b60405250949350505050565b6202fffd840154429061ffff908116905f9087908390811061378057613780614ad5565b600302015463ffffffff90811684031690508381116137a15750505061192a565b6202fffd87015461ffff620100008204811691829164010000000090910416811080156137df57506137d4600183614fd5565b61ffff168461ffff16145b156137f2576137ef826001614fef565b90505b5f816137ff866001614fef565b6138099190615009565b905060405180606001604052808763ffffffff1681526020018a8152602001898152508a5f018261ffff1661ffff811061384557613845614ad5565b82516003919091029190910180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff909216919091178155602082015160018201556040909101516002909101556202fffd8a0180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff8381169190911790915583811690831614613913576202fffd8a0180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ffff166201000061ffff8516021790555b50505050505050505050565b6001600160a01b038416613961576040517fe602df050000000000000000000000000000000000000000000000000000000081525f60048201526024016127a1565b6001600160a01b0383166139a3576040517f94280d620000000000000000000000000000000000000000000000000000000081525f60048201526024016127a1565b6001600160a01b038085165f908152600160209081526040808320938716835292905220829055801561192a57826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92584604051613a1591815260200190565b60405180910390a350505050565b5f805b60ff811015613b11575f613a3a8685613dd9565b905084811015613ab4575f613a65613a5283886148f7565b670de0b6b3a764000061222d8a89613e3f565b9050805f03613aa25785613a8388613a7e88600161490a565b613dd9565b1115613a9e57613a9485600161490a565b935050505061136a565b5060015b613aac818661490a565b945050613b08565b5f613ac2613a5287846148f7565b9050805f03613afa5785821480613ae6575085613ae488613a7e6001896148f7565b105b15613af65784935050505061136a565b5060015b613b0481866148f7565b9450505b50600101613a26565b506040517f6eb5c82100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0381165f908152602081905260409020548015613c77576001600160a01b0382165f9081526203001260209081526040808320805462030013808552928520805462030010546203001154948190559490955282905593613bac85846148f7565b90505f613bb985846148f7565b90508115613c14575f670de0b6b3a7640000613bd5848a61491d565b613bdf9190614961565b6001600160a01b038a165f908152620300146020526040812080549293508392909190613c0d90849061490a565b9091555050505b8015613c6d575f670de0b6b3a7640000613c2e838a61491d565b613c389190614961565b6001600160a01b038a165f908152620300156020526040812080549293508392909190613c6690849061490a565b9091555050505b5050505050505050565b62030010546001600160a01b0383165f908152620300126020908152604080832093909355620300115462030013909152919020555050565b6001600160a01b03831615613cc857613cc883613b44565b6001600160a01b03821615613ce057613ce082613b44565b6115eb838383613ea6565b5f5f8463ffffffff165f03613d04575082905081613d67565b8486035f80613d168a8a858a8a613fe5565b915091508263ffffffff16815f015163ffffffff1603613d46578060200151816040015194509450505050613d67565b613d5e82825f015183602001518460400151876141bf565b90955093505050505b9550959350505050565b5f815f03613d8357613d836012613dc1565b816001840381613d9557613d95614934565b046001018315155b029392505050565b5f805f1983850993909202808410938190039390930393915050565b634e487b715f52806020526024601cfd5b5414919050565b5f5f613dee8484670de0b6b3a76400006135ce565b90505f613e048485670de0b6b3a76400006135ce565b613e178687670de0b6b3a76400006135ce565b613e21919061490a565b9050613e368282670de0b6b3a76400006135ce565b95945050505050565b5f5f613e548384670de0b6b3a76400006135ce565b90505f613e6a8586670de0b6b3a76400006135ce565b9050613e7f8186670de0b6b3a76400006135ce565b613e9c613e8d87600361491d565b84670de0b6b3a76400006135ce565b613e36919061490a565b6001600160a01b038316613ed0578060025f828254613ec5919061490a565b90915550613f599050565b6001600160a01b0383165f9081526020819052604090205481811015613f3b576040517fe450d38c0000000000000000000000000000000000000000000000000000000081526001600160a01b038516600482015260248101829052604481018390526064016127a1565b6001600160a01b0384165f9081526020819052604090209082900390555b6001600160a01b038216613f7557600280548290039055613f93565b6001600160a01b0382165f9081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051613fd891815260200190565b60405180910390a3505050565b61400c60405180606001604052805f63ffffffff1681526020015f81526020015f81525090565b61403360405180606001604052805f63ffffffff1681526020015f81526020015f81525090565b6202fffd87015461ffff9081169088908290811061405357614053614ad5565b6040805160608101825260039290920292909201805463ffffffff168083526001820154602084015260029091015492820192909252935061409790889088614240565b156140ee57825163ffffffff8088169116036140b65750819050613d67565b5f5f6140c5858a89898c6141bf565b6040805160608101825263ffffffff8c16815260208101939093528201529350613d6792505050565b6202fffd880154889062010000900461ffff1661410c836001614fef565b6141169190615009565b61ffff1661ffff811061412b5761412b614ad5565b6040805160608101825260039290920292909201805463ffffffff168083526001820154602084015260029091015492820192909252935061416f90889088614240565b6141a5576040517fc02e462000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6141b088888861430e565b92509250509550959350505050565b845160208601515f91829163ffffffff8289038116928603169083906141e590896148f7565b90505f8a60400151886141f891906148f7565b90506142058284866135ce565b8b60200151614214919061490a565b95506142218184866135ce565b8b60400151614230919061490a565b9450505050509550959350505050565b5f8363ffffffff168363ffffffff161115801561426957508363ffffffff168263ffffffff1611155b15614285578163ffffffff168363ffffffff161115905061136a565b5f8463ffffffff168463ffffffff16116142b3576142ae63ffffffff851664010000000061502c565b6142bb565b8363ffffffff165b64ffffffffff1690505f8563ffffffff168463ffffffff16116142f2576142ed63ffffffff851664010000000061502c565b6142fa565b8363ffffffff165b64ffffffffff169091111595945050505050565b61433560405180606001604052805f63ffffffff1681526020015f81526020015f81525090565b61435c60405180606001604052805f63ffffffff1681526020015f81526020015f81525090565b6202fffd85015461ffff62010000820481169187915f918491166001018161438657614386614934565b0690505f1961ffff84168201015b6002818301048361ffff861682816143ae576143ae614934565b0661ffff81106143c0576143c0614ad5565b6040805160608101825260039290920292909201805463ffffffff1682526001808201546020840152600290910154928201929092529750849061ffff87169083018161440f5761440f614934565b0661ffff811061442157614421614ad5565b6040805160608101825260039290920292909201805463ffffffff16825260018101546020830152600201549181019190915287519096505f90614467908b908b614240565b90505f6144788b8b8a5f0151614240565b90508180156144845750805b15614491575050506144b1565b81156144a2578260010194506144a9565b6001830393505b505050614394565b50505050935093915050565b6103688061504a83390190565b6001600160a01b03811681146123b3575f5ffd5b5f5f83601f8401126144ee575f5ffd5b50813567ffffffffffffffff811115614505575f5ffd5b602083019150836020828501011115611575575f5ffd5b5f5f5f5f5f60808688031215614530575f5ffd5b85359450602086013593506040860135614549816144ca565b9250606086013567ffffffffffffffff811115614564575f5ffd5b614570888289016144de565b969995985093965092949392505050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b5f5f604083850312156145c7575f5ffd5b82356145d2816144ca565b946020939093013593505050565b5f5f604083850312156145f1575f5ffd5b823591506020830135614603816144ca565b809150509250929050565b5f5f5f5f60808587031215614621575f5ffd5b843593506020850135614633816144ca565b93969395505050506040820135916060013590565b5f60208284031215614658575f5ffd5b813561136a816144ca565b5f5f5f60608486031215614675575f5ffd5b8335614680816144ca565b92506020840135614690816144ca565b929592945050506040919091013590565b5f602082840312156146b1575f5ffd5b5035919050565b5f5f604083850312156146c9575f5ffd5b82356146d4816144ca565b91506020830135614603816144ca565b5f602082840312156146f4575f5ffd5b813561ffff8116811461136a575f5ffd5b80151581146123b3575f5ffd5b5f5f60408385031215614723575f5ffd5b823561472e816144ca565b9150602083013561460381614705565b5f5f6020838503121561474f575f5ffd5b823567ffffffffffffffff811115614765575f5ffd5b8301601f81018513614775575f5ffd5b803567ffffffffffffffff81111561478b575f5ffd5b8560208260051b840101111561479f575f5ffd5b6020919091019590945092505050565b5f8151808452602084019350602083015f5b828110156147df5781518652602095860195909101906001016147c1565b5093949350505050565b604081525f6147fb60408301856147af565b8281036020840152613e3681856147af565b5f5f6020838503121561481e575f5ffd5b823567ffffffffffffffff811115614834575f5ffd5b614840858286016144de565b90969095509350505050565b5f6020828403121561485c575f5ffd5b815161136a81614705565b6001600160a01b038616815284602082015283604082015260806060820152816080820152818360a08301375f81830160a090810191909152601f909201601f19160101949350505050565b5f602082840312156148c3575f5ffd5b5051919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b818103818111156110ec576110ec6148ca565b808201808211156110ec576110ec6148ca565b80820281158282048414176110ec576110ec6148ca565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f8261496f5761496f614934565b500490565b5f610100820190506fffffffffffffffffffffffffffffffff83511682526fffffffffffffffffffffffffffffffff60208401511660208301526fffffffffffffffffffffffffffffffff604084015116604083015260608301516149ed60608401826fffffffffffffffffffffffffffffffff169052565b506080830151614a1160808401826fffffffffffffffffffffffffffffffff169052565b5060a0830151614a3560a08401826fffffffffffffffffffffffffffffffff169052565b5060c0830151614a5960c08401826fffffffffffffffffffffffffffffffff169052565b5060e0830151614a7d60e08401826fffffffffffffffffffffffffffffffff169052565b5092915050565b600181811c90821680614a9857607f821691505b602082108103614acf577f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b50919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f60208284031215614b3f575f5ffd5b815167ffffffffffffffff811115614b55575f5ffd5b8201601f81018413614b65575f5ffd5b805167ffffffffffffffff811115614b7f57614b7f614b02565b604051601f19603f601f19601f8501160116810181811067ffffffffffffffff82111715614baf57614baf614b02565b604052818152828201602001861015614bc6575f5ffd5b8160208401602083015e5f91810160200191909152949350505050565b601f8211156115eb57828211156115eb57805f5260205f20601f840160051c6020851015614c0e57505f5b90810190601f840160051c035f5b81811015614c31575f83820155600101614c1c565b505050505050565b815167ffffffffffffffff811115614c5357614c53614b02565b614c6781614c618454614a84565b84614be3565b6020601f821160018114614c99575f8315614c825750848201515b5f19600385901b1c1916600184901b178455611042565b5f84815260208120601f198516915b82811015614cc85787850151825560209485019460019092019101614ca8565b5084821015614ce557868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b5f60208284031215614d04575f5ffd5b815160ff8116811461136a575f5ffd5b6001815b6001841115614d4f57808504811115614d3357614d336148ca565b6001841615614d4157908102905b60019390931c928002614d18565b935093915050565b5f82614d65575060016110ec565b81614d7157505f6110ec565b8160018114614d875760028114614d9157614dad565b60019150506110ec565b60ff841115614da257614da26148ca565b50506001821b6110ec565b5060208310610133831016604e8410600b8410161715614dd0575081810a6110ec565b614ddc5f198484614d14565b805f1904821115613d9d57613d9d6148ca565b5f61136a60ff841683614d57565b5f60208284031215614e0d575f5ffd5b815161136a816144ca565b67ffffffffffffffff831115614e3057614e30614b02565b614e4483614e3e8354614a84565b83614be3565b5f601f841160018114614e75575f8515614e5e5750838201355b5f19600387901b1c1916600186901b178355611042565b5f83815260208120601f198716915b82811015614ea45786850135825560209485019460019092019101614e84565b5086821015614ec0575f1960f88860031b161c19848701351681555b505060018560011b0183555050505050565b5f5f5f60608486031215614ee4575f5ffd5b8351602085015160408601519194509250614efe81614705565b809150509250925092565b5f81518060208401855e5f93019283525090919050565b7f537461626c65563220414d4d202d20000000000000000000000000000000000081525f614f51600f830185614f09565b7f2f000000000000000000000000000000000000000000000000000000000000008152613e366001820185614f09565b7f73414d4d56322d0000000000000000000000000000000000000000000000000081525f614f516007830185614f09565b5f60208284031215614fc2575f5ffd5b813563ffffffff8116811461136a575f5ffd5b61ffff82811682821603908111156110ec576110ec6148ca565b61ffff81811683821601908111156110ec576110ec6148ca565b5f61ffff83168061501c5761501c614934565b8061ffff84160691505092915050565b64ffffffffff81811683821601908111156110ec576110ec6148ca56fe60e060405234801561000f575f5ffd5b5060405161036838038061036883398101604081905261002e91610064565b336080526001600160a01b0391821660a0521660c052610095565b80516001600160a01b038116811461005f575f5ffd5b919050565b5f5f60408385031215610075575f5ffd5b61007e83610049565b915061008c60208401610049565b90509250929050565b60805160a05160c0516102ab6100bd5f395f61011801525f60d101525f605a01526102ab5ff3fe608060405234801561000f575f5ffd5b5060043610610029575f3560e01c8063533cf5ce1461002d575b5f5ffd5b61004061003b36600461022b565b610042565b005b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146100b1576040517f6f61f64100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81156100f8576100f873ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168484610144565b801561013f5761013f73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168483610144565b505050565b61015183838360016101a3565b61013f576040517f5274afe700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8416600482015260240160405180910390fd5b6040517fa9059cbb000000000000000000000000000000000000000000000000000000005f81815273ffffffffffffffffffffffffffffffffffffffff8616600452602485905291602083604481808b5af1925060015f5114831661021f578383151615610213573d5f823e3d81fd5b5f873b113d1516831692505b60405250949350505050565b5f5f5f6060848603121561023d575f5ffd5b833573ffffffffffffffffffffffffffffffffffffffff81168114610260575f5ffd5b9560208501359550604090940135939250505056fea26469706673582212207519fe77d60fa2befaa943fe4f040b0f82abdb9264e6f95e7af68108cee501e564736f6c63430008240033a2646970667358221220c44780aa04b481bff35f6e43d6d561fdb2f8fde74b2f0d2839a586c497a0e40264736f6c63430008240033","recompiledBytecode":"0x608060405234801561000f575f5ffd5b5060408051602080820183525f8083528351918201909352918252906003610037838261012a565b506004610044828261012a565b505050600161005d61005a61006360201b60201c565b90565b556101e8565b7f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0090565b634e487b7160e01b5f52604160045260245ffd5b600181811c908216806100af57607f821691505b6020821081036100cd57634e487b7160e01b5f52602260045260245ffd5b50919050565b601f821115610125578282111561012557805f5260205f20601f840160051c60208510156100fe57505f5b90810190601f840160051c035f5b81811015610121575f8382015560010161010c565b5050505b505050565b81516001600160401b0381111561014357610143610087565b61015781610151845461009b565b846100d3565b6020601f821160018114610189575f83156101725750848201515b5f19600385901b1c1916600184901b1784556101e1565b5f84815260208120601f198516915b828110156101b85787850151825560209485019460019092019101610198565b50848210156101d557868401515f19600387901b60f8161c191681555b505060018360011b0184555b5050505050565b6153e7806101f55f395ff3fe608060405234801561000f575f5ffd5b5060043610610346575f3560e01c8063648da859116101be578063bc25cf77116100fe578063c5884ad11161009e578063ee39e7a011610079578063ee39e7a014610856578063f140a35a1461085e578063fc9654ab14610871578063fff6cae914610879575f5ffd5b8063c5884ad1146107dc578063d21220a71461080b578063dd62ed3e1461081e575f5ffd5b8063c245febc116100d9578063c245febc146107a0578063c45a0155146107ab578063c47f0027146107be578063c5700a02146107d1575f5ffd5b8063bc25cf7714610777578063bda39cad1461078a578063bf944dbc14610795575f5ffd5b806395d89b4111610169578063a1ac4d1311610144578063a1ac4d131461071d578063a9059cbb1461073e578063b84c824614610751578063b95d88f814610764575f5ffd5b806395d89b41146106ce5780639d63848a146106d65780639f767c88146106fc575f5ffd5b806378273aca1161019957806378273aca14610687578063883bdbfd1461069a57806389afcb44146106bb575f5ffd5b8063648da859146106255780636a6278421461064c57806370a082311461065f575f5ffd5b8063252c09d7116102895780633358095911610234578063485cc9551161020f578063485cc955146105da5780634983f2f5146105ed5780634d5a9f8a146105f95780635a76f25e1461061a575f5ffd5b80633358095914610569578063392f37e91461057c578063443cb4bc146105cf575f5ffd5b8063313ce56711610264578063313ce5671461053c57806332148f671461054b57806332c0defd1461055e575f5ffd5b8063252c09d7146104e157806325d2a3f3146105165780632dbfa73514610529575f5ffd5b8063119c4e9f116102f45780631a4211dc116102cf5780631a4211dc1461045a5780631df8c717146104a5578063205aabf1146104ad57806323b872dd146104ce575f5ffd5b8063119c4e9f1461041757806315a0ea6a1461042a57806318160ddd14610452575f5ffd5b8063095ea7b311610324578063095ea7b3146103a85780630dfe1681146103cb5780630ea099c1146103f6575f5ffd5b8063022c0d9f1461034a57806306fdde031461035f5780630902f1ac1461037d575b5f5ffd5b61035d61035836600461451c565b610881565b005b610367611049565b6040516103749190614581565b60405180910390f35b6203000b546203000c546203000d545b60408051938452602084019290925290820152606001610374565b6103bb6103b63660046145b6565b6110d9565b6040519015158152602001610374565b6007546103de906001600160a01b031681565b6040516001600160a01b039091168152602001610374565b6104096104043660046145e0565b6110f2565b604051908152602001610374565b61040961042536600461460e565b611175565b61043d610438366004614648565b611280565b60408051928352602083019190915201610374565b600254610409565b62030008546104809061ffff808216916201000081048216916401000000009091041683565b6040805161ffff94851681529284166020840152921691810191909152606001610374565b61038d6112d5565b6104096104bb366004614648565b620300136020525f908152604090205481565b6103bb6104dc366004614663565b61134c565b6104f46104ef3660046146a1565b611371565b6040805163ffffffff9094168452602084019290925290820152606001610374565b61043d610524366004614648565b6113ce565b61043d6105373660046146b8565b6114af565b60405160128152602001610374565b61035d6105593660046146e4565b61157c565b610409620300105481565b6009546103de906001600160a01b031681565b62030009546203000a546203000b546203000c546007546008546040805196875260208701959095529385019290925260608401526001600160a01b0390811660808401521660a082015260c001610374565b6104096203000b5481565b61035d6105e83660046146b8565b6115f0565b6104096402540be40081565b610409610607366004614648565b620300146020525f908152604090205481565b6104096203000c5481565b6104097f56325f535441424c45000000000000000000000000000000000000000000000081565b61040961065a366004614648565b611930565b61040961066d366004614648565b6001600160a01b03165f9081526020819052604090205490565b61035d610695366004614712565b611bc2565b6106ad6106a836600461473e565b611c8d565b6040516103749291906147e9565b61043d6106c9366004614648565b611cbb565b610367611fca565b600754600854604080516001600160a01b03938416815292909116602083015201610374565b61040961070a366004614648565b620300126020525f908152604090205481565b61040961072b366004614648565b620300156020525f908152604090205481565b6103bb61074c3660046145b6565b611fd9565b61035d61075f36600461480d565b611fe6565b6104096107723660046145e0565b6120b1565b61035d610785366004614648565b612249565b610409620300115481565b6104096203000e5481565b6104096203000f5481565b600a546103de906001600160a01b031681565b61035d6107cc36600461480d565b6123b6565b6104096203000d5481565b6103bb6107ea3660046146b8565b6203001660209081525f928352604080842090915290825290205460ff1681565b6008546103de906001600160a01b031681565b61040961082c3660046146b8565b6001600160a01b039182165f90815260016020908152604080832093909416825291909152205490565b610409612481565b61040961086c3660046145e0565b6124ca565b610409603c81565b61035d6125d6565b610889612729565b600a5f9054906101000a90046001600160a01b03166001600160a01b031663b187bd266040518163ffffffff1660e01b8152600401602060405180830381865afa1580156108d9573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108fd919061484c565b15610934576040517f1309a56300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84158015610940575083155b15610977576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6203000b546203000c5481871015806109905750808610155b156109c7576040517fbb55fd2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6007546008545f9182916001600160a01b0391821691908116908916821480610a015750806001600160a01b0316896001600160a01b0316145b15610a38576040517f290fa18800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8a15610a5257610a526001600160a01b0383168a8d612757565b8915610a6c57610a6c6001600160a01b0382168a8c612757565b8615610aed576040517f9a7bff790000000000000000000000000000000000000000000000000000000081526001600160a01b038a1690639a7bff7990610abf9033908f908f908e908e90600401614867565b5f604051808303815f87803b158015610ad6575f5ffd5b505af1158015610ae8573d5f5f3e3d5ffd5b505050505b6040516370a0823160e01b81523060048201526001600160a01b038316906370a0823190602401602060405180830381865afa158015610b2f573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b5391906148b3565b6040516370a0823160e01b81523060048201529094506001600160a01b038216906370a0823190602401602060405180830381865afa158015610b98573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610bbc91906148b3565b925050505f8985610bcd91906148f7565b8311610bd9575f610bed565b610be38a866148f7565b610bed90846148f7565b90505f610bfa8a866148f7565b8311610c06575f610c1a565b610c108a866148f7565b610c1a90846148f7565b905081158015610c28575080155b15610c5f576040517f098fb56100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051610100810182525f80825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810191909152610ca98c8461490a565b6fffffffffffffffffffffffffffffffff166040820152610cca8b8361490a565b6fffffffffffffffffffffffffffffffff1660608201526007546008546001600160a01b0391821691165f8080610d0388888e8e6127aa565b919450925090508715610d78575f612710610d1e858b61491d565b610d289190614961565b9050610d3381612863565b6fffffffffffffffffffffffffffffffff81168752612710610d55848b61491d565b610d5f9190614961565b6fffffffffffffffffffffffffffffffff1660c0880152505b8615610de9575f612710610d8c858a61491d565b610d969190614961565b9050610da181612910565b6fffffffffffffffffffffffffffffffff81166020880152612710610dc6848a61491d565b610dd09190614961565b6fffffffffffffffffffffffffffffffff1660e0880152505b8015610e195760408601516fffffffffffffffffffffffffffffffff908116608088015260608701511660a08701525b6040516370a0823160e01b81523060048201526001600160a01b038616906370a0823190602401602060405180830381865afa158015610e5b573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e7f91906148b3565b6040516370a0823160e01b8152306004820152909a506001600160a01b038516906370a0823190602401602060405180830381865afa158015610ec4573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ee891906148b3565b9850610ef48c8c6129b6565b610efe8b8b6129b6565b1015610f36576040517fa932492f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600a546040517f5310a4210000000000000000000000000000000000000000000000000000000081526001600160a01b0390911690635310a42190610f7f908990600401614974565b5f604051808303815f87803b158015610f96575f5ffd5b505af1158015610fa8573d5f5f3e3d5ffd5b50505050505050505050610fbe84848888612a5f565b60408051838152602081018390529081018c9052606081018b90526001600160a01b038a169033907fb3e2773606abfd36b5bd91394b3a54d1398336c65005baf7bf7a05efeffaf75b9060800160405180910390a350505050505061104260017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b5050505050565b60606005805461105890614a84565b80601f016020809104026020016040519081016040528092919081815260200182805461108490614a84565b80156110cf5780601f106110a6576101008083540402835291602001916110cf565b820191905f5260205f20905b8154815290600101906020018083116110b257829003601f168201915b5050505050905090565b5f336110e6818585612b44565b60019150505b92915050565b6203000b546203000c546007545f929190839081906001600160a01b03878116911614611120575f87611123565b865f5b915091505f611134838387876127aa565b505090506127108189611147919061491d565b6111519190614961565b61115b90896148f7565b975061116988888787612b51565b98975050505050505050565b6007545f90819081906001600160a01b03878116911614611197575f8761119a565b865f5b600a546040517fdf29d5bb0000000000000000000000000000000000000000000000000000000081523060048201525f602482015260448101849052606481018390526084810189905260a48101889052929450909250612710916001600160a01b039091169063df29d5bb9060c401602060405180830381865afa158015611225573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061124991906148b3565b611253908961491d565b61125d9190614961565b61126790886148f7565b965061127587878787612b51565b979650505050505050565b5f806001600160a01b0383166112c2576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6112cc3384612c93565b91509150915091565b6203000e546203000f54425f80806112fc6203000b546203000c546203000d549192909190565b925092509250838114611344575f61131482866148f7565b9050611320818561491d565b61132a908861490a565b9650611336818461491d565b611340908761490a565b9550505b505050909192565b5f33611359858285612dd0565b611364858585612e5f565b60019150505b9392505050565b5f808080600b8561ffff811061138957611389614ad5565b6040805160608101825260039290920292909201805463ffffffff16808352600182015460208401819052600290920154929093018290529197919650945092505050565b6001600160a01b0381165f908152620300146020908152604080832054620300158352818420549284905292205480156114a9576001600160a01b0384165f9081526203001260205260409020546203001054670de0b6b3a764000091611434916148f7565b61143e908361491d565b6114489190614961565b611452908461490a565b6001600160a01b0385165f9081526203001360205260409020546203001154919450670de0b6b3a76400009161148891906148f7565b611492908361491d565b61149c9190614961565b6114a6908361490a565b91505b50915091565b5f806001600160a01b0383166114f1576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336001600160a01b0385161480159061152f57506001600160a01b0384165f908152620300166020908152604080832033845290915290205460ff16155b15611566576040517fea8e4eb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6115708484612c93565b915091505b9250929050565b6203000854640100000000900461ffff165f611599600b84612eee565b90508161ffff168161ffff16146115eb576040805161ffff80851682528316602082015233917ff0b7b7d1cdf542f5660a7879f0cac17375fdcf984af4a6d499a9daedacb24c58910160405180910390a25b505050565b600a546001600160a01b031615611633576040517f154c51b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600a8054337fffffffffffffffffffffffff0000000000000000000000000000000000000000918216179091556008805482166001600160a01b03848116919091179091556007805490921690841617905560405182908290611695906144bd565b6001600160a01b03928316815291166020820152604001604051809103905ff0801580156116c5573d5f5f3e3d5ffd5b5060095f6101000a8154816001600160a01b0302191690836001600160a01b031602179055505f826001600160a01b03166395d89b416040518163ffffffff1660e01b81526004015f60405180830381865afa158015611727573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261174e9190810190614b2f565b90505f826001600160a01b03166395d89b416040518163ffffffff1660e01b81526004015f60405180830381865afa15801561178c573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526117b39190810190614b2f565b90506117bf8282613005565b6005906117cc9082614c39565b506117d78282613031565b6006906117e49082614c39565b50836001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611821573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118459190614cf4565b61185090600a614def565b6203000981905550826001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611894573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118b89190614cf4565b6118c390600a614def565b6203000a55600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000164263ffffffff161790556203000880547fffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ffff166401000100001790555b50505050565b5f611939612729565b6203000b546203000c546007546040516370a0823160e01b81523060048201525f916001600160a01b0316906370a0823190602401602060405180830381865afa158015611989573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119ad91906148b3565b6008546040516370a0823160e01b81523060048201529192505f916001600160a01b03909116906370a0823190602401602060405180830381865afa1580156119f8573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611a1c91906148b3565b90505f611a2985846148f7565b90505f611a3685846148f7565b90505f611a4260025490565b9050805f03611ac4576103e8611a60611a5b848661491d565b613046565b611a6a91906148f7565b9750611a7960016103e86131ab565b611a8383836131fc565b6103e8881015611abf576040517fd226f9d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611b31565b611af687611ad2838661491d565b611adc9190614961565b87611ae7848661491d565b611af19190614961565b6132bc565b9750875f03611b31576040517fd226f9d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611b3b89896131ab565b611b4785858989612a5f565b60408051848152602081018490526001600160a01b038b169133917f2f00e3cdd69a77be7ed215ec7b2a36784dd158f921fca79ac29deffa353fe6ee910160405180910390a350505050505050611bbd60017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b919050565b6001600160a01b038216611c02576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b335f81815262030016602090815260408083206001600160a01b0387168085529083529281902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001686151590811790915590519081529192917f63484c3756a6c7d95f131879210268006b60e58057de5db75f3a8c91c7869ebf910160405180910390a35050565b6060805f5f611c9a6112d5565b509092509050611cae600b878785856132cb565b9350935050509250929050565b5f5f611cc5612729565b6203000b546203000c546007546008546040516370a0823160e01b81523060048201526001600160a01b0392831692909116905f9083906370a0823190602401602060405180830381865afa158015611d20573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611d4491906148b3565b6040516370a0823160e01b81523060048201529091505f906001600160a01b038416906370a0823190602401602060405180830381865afa158015611d8b573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611daf91906148b3565b305f908152602081905260409020546002549192509080611dd0858461491d565b611dda9190614961565b995080611de7848461491d565b611df19190614961565b9850891580611dfe575088155b15611e35576040517f749383ad00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611e3f30836133e6565b611e536001600160a01b0387168c8c612757565b611e676001600160a01b0386168c8b612757565b6040516370a0823160e01b81523060048201526001600160a01b038716906370a0823190602401602060405180830381865afa158015611ea9573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611ecd91906148b3565b6040516370a0823160e01b81523060048201529094506001600160a01b038616906370a0823190602401602060405180830381865afa158015611f12573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f3691906148b3565b9250611f428484613433565b611f4e84848a8a612a5f565b604080518b8152602081018b90526001600160a01b038d169133917f5d624aa9c148153ab3446c1b154f660ee7701e549fe9b62dab7171b1c80e6fa2910160405180910390a35050505050505050611fc560017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b915091565b60606006805461105890614a84565b5f336110e6818585612e5f565b600a5f9054906101000a90046001600160a01b03166001600160a01b031663b782cc496040518163ffffffff1660e01b8152600401602060405180830381865afa158015612036573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061205a9190614dfd565b6001600160a01b0316336001600160a01b0316146120a4576040517f058a2da800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60066115eb828483614e18565b5f825f036120c057505f6110ec565b6203000b546203000c546007546001600160a01b038581169116146120e557806120e7565b815b851061211f576040517fbb55fd2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f61212c86868585613475565b9050805f03612140575f93505050506110ec565b6007545f9081906001600160a01b0388811691161461216057825f612163565b5f835b600a546040517f11896ad200000000000000000000000000000000000000000000000000000000815230600482015233602482015260448101849052606481018390526084810189905260a481018890529294509092505f916001600160a01b03909116906311896ad29060c401602060405180830381865afa1580156121ec573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061221091906148b3565b9050612232816122216001876148f7565b61222d846127106148f7565b6135ce565b61223c908561490a565b9998505050505050505050565b612251612729565b6007546008546203000b546040516370a0823160e01b81523060048201526001600160a01b0393841693909216915f919084906370a0823190602401602060405180830381865afa1580156122a8573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906122cc91906148b3565b6122d691906148f7565b905080156122f2576122f26001600160a01b0384168583612757565b6203000c546040516370a0823160e01b81523060048201525f91906001600160a01b038516906370a0823190602401602060405180830381865afa15801561233c573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061236091906148b3565b61236a91906148f7565b90508015612386576123866001600160a01b0384168683612757565b505050506123b360017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b50565b600a5f9054906101000a90046001600160a01b03166001600160a01b031663b782cc496040518163ffffffff1660e01b8152600401602060405180830381865afa158015612406573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061242a9190614dfd565b6001600160a01b0316336001600160a01b031614612474576040517f058a2da800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60056115eb828483614e18565b5f61248a612729565b61249c6203000b546203000c546129b6565b90506124c760017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b90565b6203000b546203000c546007545f929190839081906001600160a01b038781169116146124f8575f876124fb565b865f5b600a546040517fdf29d5bb0000000000000000000000000000000000000000000000000000000081523060048201525f602482015260448101849052606481018390526084810188905260a48101879052929450909250612710916001600160a01b039091169063df29d5bb9060c401602060405180830381865afa158015612586573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906125aa91906148b3565b6125b4908961491d565b6125be9190614961565b6125c890886148f7565b965061127587878686612b51565b6125de612729565b6002545f03612619576040517fbb55fd2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6007546040516370a0823160e01b81523060048201526126fe916001600160a01b0316906370a0823190602401602060405180830381865afa158015612661573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061268591906148b3565b6008546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa1580156126cb573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906126ef91906148b3565b6203000b546203000c54612a5f565b61272760017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b565b61273161367e565b60027f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b61276483838360016136e1565b6115eb576040517f5274afe70000000000000000000000000000000000000000000000000000000081526001600160a01b03841660048201526024015b60405180910390fd5b600a546040517fdb6b39b400000000000000000000000000000000000000000000000000000000815230600482015233602482015260448101869052606481018590526084810184905260a481018390525f91829182916001600160a01b03169063db6b39b49060c401606060405180830381865afa15801561282f573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906128539190614ed2565b9250925092509450945094915050565b805f0361286d5750565b60095460075461288a916001600160a01b03918216911683612757565b5f61289460025490565b6128a683670de0b6b3a764000061491d565b6128b09190614961565b905080156128d15780620300105f8282546128cb919061490a565b90915550505b604080518381525f602082015233917f112c256902bf554b6ed882d2936687aaeb4225e8cd5b51303c90ca6cf43a860291015b60405180910390a25050565b805f0361291a5750565b600954600854612937916001600160a01b03918216911683612757565b5f61294160025490565b61295383670de0b6b3a764000061491d565b61295d9190614961565b9050801561297e5780620300115f828254612978919061490a565b90915550505b604080515f81526020810184905233917f112c256902bf554b6ed882d2936687aaeb4225e8cd5b51303c90ca6cf43a86029101612904565b5f5f620300095484670de0b6b3a76400006129d1919061491d565b6129db9190614961565b90505f6203000a5484670de0b6b3a76400006129f7919061491d565b612a019190614961565b90505f612a178383670de0b6b3a76400006135ce565b90505f612a2d8384670de0b6b3a76400006135ce565b612a408586670de0b6b3a76400006135ce565b612a4a919061490a565b90506112758282670de0b6b3a76400006135ce565b6203000d5442905f90612a7290836148f7565b90505f81118015612a8257508315155b8015612a8d57508215155b15612ad657612a9c818561491d565b6203000e5f828254612aae919061490a565b90915550612abe9050818461491d565b6203000f5f828254612ad0919061490a565b90915550505b6203000e546203000f54612aee91600b91603c61375c565b6203000b8690556203000c8590556203000d82905560408051878152602081018790527fcf2aa50876cdfbb541206f89af0ee78d44a2abf8d328e37fa4917f982149848a910160405180910390a1505050505050565b6115eb838383600161391f565b5f5f612b5d84846129b6565b6203000954909150612b7785670de0b6b3a764000061491d565b612b819190614961565b6203000a54909450612b9b84670de0b6b3a764000061491d565b612ba59190614961565b6007549093505f9081906001600160a01b03888116911614612bc8578486612bcb565b85855b60075491935091506001600160a01b03888116911614612c0b576203000a54612bfc89670de0b6b3a764000061491d565b612c069190614961565b612c2c565b6203000954612c2289670de0b6b3a764000061491d565b612c2c9190614961565b97505f612c43612c3c848b61490a565b8584613a23565b612c4d90836148f7565b600754909150670de0b6b3a7640000906001600160a01b038a8116911614612c79576203000954612c7f565b6203000a545b612c89908361491d565b61223c9190614961565b5f5f612c9e84613b44565b50506001600160a01b0382165f908152620300146020908152604080832054620300159092529091205481151580612cd557505f81115b15611575576001600160a01b038481165f9081526203001460209081526040808320839055620300159091528082209190915560095490517f533cf5ce0000000000000000000000000000000000000000000000000000000081528583166004820152602481018590526044810184905291169063533cf5ce906064015f604051808303815f87803b158015612d69575f5ffd5b505af1158015612d7b573d5f5f3e3d5ffd5b505060408051858152602081018590526001600160a01b0380881694508816925033917fcd5e4f020ddad29434c2200a9edf2f8d7ec30f0d787f03b528ab7279aab0acbe910160405180910390a49250929050565b6001600160a01b038381165f908152600160209081526040808320938616835292905220545f1981101561192a5781811015612e51576040517ffb8f41b20000000000000000000000000000000000000000000000000000000081526001600160a01b038416600482015260248101829052604481018390526064016127a1565b61192a84848484035f61391f565b6001600160a01b038316612ea1576040517f96c6fd1e0000000000000000000000000000000000000000000000000000000081525f60048201526024016127a1565b6001600160a01b038216612ee3576040517fec442f050000000000000000000000000000000000000000000000000000000081525f60048201526024016127a1565b6115eb838383613cb0565b6202fffd8201545f9061ffff64010000000090910481169083168110612f155790506110ec565b805b8361ffff168161ffff161015612fc45760018561ffff808416908110612f3f57612f3f614ad5565b6003020180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff9290921691909117905560018561ffff838116908110612f8e57612f8e614ad5565b60030201600101819055506001855f018261ffff1661ffff8110612fb457612fb4614ad5565b6003020160020155600101612f17565b5050506202fffd9190910180547fffffffffffffffffffffffffffffffffffffffffffffffffffff0000ffffffff1664010000000061ffff84160217905590565b6060828260405160200161301a929190614f20565b604051602081830303815290604052905092915050565b6060828260405160200161301a929190614f81565b5f60018211613053575090565b81600170010000000000000000000000000000000082106130795760809190911c9060401b5b6801000000000000000082106130945760409190911c9060201b5b64010000000082106130ab5760209190911c9060101b5b6201000082106130c05760109190911c9060081b5b61010082106130d45760089190911c9060041b5b601082106130e75760049190911c9060021b5b600482106130f35760011b5b600302600190811c9081858161310b5761310b614934565b048201901c9050600181858161312357613123614934565b048201901c9050600181858161313b5761313b614934565b048201901c9050600181858161315357613153614934565b048201901c9050600181858161316b5761316b614934565b048201901c9050600181858161318357613183614934565b048201901c90506131a281858161319c5761319c614934565b04821190565b90039392505050565b6001600160a01b0382166131ed576040517fec442f050000000000000000000000000000000000000000000000000000000081525f60048201526024016127a1565b6131f85f8383613cb0565b5050565b6203000a5461321382670de0b6b3a764000061491d565b61321d9190614961565b620300095461323484670de0b6b3a764000061491d565b61323e9190614961565b14613275576040517f0a04d7fa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6402540be40061328583836129b6565b116131f8576040517f438d3ade00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f82821882841002821861136a565b60608042858067ffffffffffffffff8111156132e9576132e9614b02565b604051908082528060200260200182016040528015613312578160200160208202803683370190505b5093508067ffffffffffffffff81111561332e5761332e614b02565b604051908082528060200260200182016040528015613357578160200160208202803683370190505b5092505f5b818110156133d9576133978a848b8b8581811061337b5761337b614ad5565b90506020020160208101906133909190614fb2565b8a8a613ceb565b8683815181106133a9576133a9614ad5565b602002602001018684815181106133c2576133c2614ad5565b60209081029190910101919091525260010161335c565b5050509550959350505050565b6001600160a01b038216613428576040517f96c6fd1e0000000000000000000000000000000000000000000000000000000081525f60048201526024016127a1565b6131f8825f83613cb0565b61343d82826129b6565b5f036131f8576040517f7d06c0c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f5f61348184846129b6565b620300095490915061349b85670de0b6b3a764000061491d565b6134a59190614961565b6203000a549094506134bf84670de0b6b3a764000061491d565b6134c99190614961565b6007549093505f9081906001600160a01b038881169116146134ec5784866134ef565b85855b60075491935091505f9081906001600160a01b038a811691161461351c576203000a546203000954613527565b62030009546203000a545b90925090506135476135418b670de0b6b3a764000061491d565b83613d71565b9950838a10613582576040517fbb55fd2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f6135976135908c876148f7565b8786613a23565b90506135bf826135a786846148f7565b6135b1919061491d565b670de0b6b3a7640000613d71565b9b9a5050505050505050505050565b5f5f5f6135db8686613da5565b91509150815f036135ff578381816135f5576135f5614934565b049250505061136a565b818411613616576136166003851502601118613dc1565b5f848688095f868103871696879004966002600389028118808a02820302808a02820302808a02820302808a02820302808a02820302808a02909103029181900381900460010185841190960395909502919093039390930492909217029150509392505050565b6136aa5f60027f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00613dd2565b15612727576040517f3ee5aeb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517fa9059cbb000000000000000000000000000000000000000000000000000000005f8181526001600160a01b038616600452602485905291602083604481808b5af1925060015f51148316613750578383151615613744573d5f823e3d81fd5b5f873b113d1516831692505b60405250949350505050565b6202fffd840154429061ffff908116905f9087908390811061378057613780614ad5565b600302015463ffffffff90811684031690508381116137a15750505061192a565b6202fffd87015461ffff620100008204811691829164010000000090910416811080156137df57506137d4600183614fd5565b61ffff168461ffff16145b156137f2576137ef826001614fef565b90505b5f816137ff866001614fef565b6138099190615009565b905060405180606001604052808763ffffffff1681526020018a8152602001898152508a5f018261ffff1661ffff811061384557613845614ad5565b82516003919091029190910180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff909216919091178155602082015160018201556040909101516002909101556202fffd8a0180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff8381169190911790915583811690831614613913576202fffd8a0180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ffff166201000061ffff8516021790555b50505050505050505050565b6001600160a01b038416613961576040517fe602df050000000000000000000000000000000000000000000000000000000081525f60048201526024016127a1565b6001600160a01b0383166139a3576040517f94280d620000000000000000000000000000000000000000000000000000000081525f60048201526024016127a1565b6001600160a01b038085165f908152600160209081526040808320938716835292905220829055801561192a57826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92584604051613a1591815260200190565b60405180910390a350505050565b5f805b60ff811015613b11575f613a3a8685613dd9565b905084811015613ab4575f613a65613a5283886148f7565b670de0b6b3a764000061222d8a89613e3f565b9050805f03613aa25785613a8388613a7e88600161490a565b613dd9565b1115613a9e57613a9485600161490a565b935050505061136a565b5060015b613aac818661490a565b945050613b08565b5f613ac2613a5287846148f7565b9050805f03613afa5785821480613ae6575085613ae488613a7e6001896148f7565b105b15613af65784935050505061136a565b5060015b613b0481866148f7565b9450505b50600101613a26565b506040517f6eb5c82100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0381165f908152602081905260409020548015613c77576001600160a01b0382165f9081526203001260209081526040808320805462030013808552928520805462030010546203001154948190559490955282905593613bac85846148f7565b90505f613bb985846148f7565b90508115613c14575f670de0b6b3a7640000613bd5848a61491d565b613bdf9190614961565b6001600160a01b038a165f908152620300146020526040812080549293508392909190613c0d90849061490a565b9091555050505b8015613c6d575f670de0b6b3a7640000613c2e838a61491d565b613c389190614961565b6001600160a01b038a165f908152620300156020526040812080549293508392909190613c6690849061490a565b9091555050505b5050505050505050565b62030010546001600160a01b0383165f908152620300126020908152604080832093909355620300115462030013909152919020555050565b6001600160a01b03831615613cc857613cc883613b44565b6001600160a01b03821615613ce057613ce082613b44565b6115eb838383613ea6565b5f5f8463ffffffff165f03613d04575082905081613d67565b8486035f80613d168a8a858a8a613fe5565b915091508263ffffffff16815f015163ffffffff1603613d46578060200151816040015194509450505050613d67565b613d5e82825f015183602001518460400151876141bf565b90955093505050505b9550959350505050565b5f815f03613d8357613d836012613dc1565b816001840381613d9557613d95614934565b046001018315155b029392505050565b5f805f1983850993909202808410938190039390930393915050565b634e487b715f52806020526024601cfd5b5414919050565b5f5f613dee8484670de0b6b3a76400006135ce565b90505f613e048485670de0b6b3a76400006135ce565b613e178687670de0b6b3a76400006135ce565b613e21919061490a565b9050613e368282670de0b6b3a76400006135ce565b95945050505050565b5f5f613e548384670de0b6b3a76400006135ce565b90505f613e6a8586670de0b6b3a76400006135ce565b9050613e7f8186670de0b6b3a76400006135ce565b613e9c613e8d87600361491d565b84670de0b6b3a76400006135ce565b613e36919061490a565b6001600160a01b038316613ed0578060025f828254613ec5919061490a565b90915550613f599050565b6001600160a01b0383165f9081526020819052604090205481811015613f3b576040517fe450d38c0000000000000000000000000000000000000000000000000000000081526001600160a01b038516600482015260248101829052604481018390526064016127a1565b6001600160a01b0384165f9081526020819052604090209082900390555b6001600160a01b038216613f7557600280548290039055613f93565b6001600160a01b0382165f9081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051613fd891815260200190565b60405180910390a3505050565b61400c60405180606001604052805f63ffffffff1681526020015f81526020015f81525090565b61403360405180606001604052805f63ffffffff1681526020015f81526020015f81525090565b6202fffd87015461ffff9081169088908290811061405357614053614ad5565b6040805160608101825260039290920292909201805463ffffffff168083526001820154602084015260029091015492820192909252935061409790889088614240565b156140ee57825163ffffffff8088169116036140b65750819050613d67565b5f5f6140c5858a89898c6141bf565b6040805160608101825263ffffffff8c16815260208101939093528201529350613d6792505050565b6202fffd880154889062010000900461ffff1661410c836001614fef565b6141169190615009565b61ffff1661ffff811061412b5761412b614ad5565b6040805160608101825260039290920292909201805463ffffffff168083526001820154602084015260029091015492820192909252935061416f90889088614240565b6141a5576040517fc02e462000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6141b088888861430e565b92509250509550959350505050565b845160208601515f91829163ffffffff8289038116928603169083906141e590896148f7565b90505f8a60400151886141f891906148f7565b90506142058284866135ce565b8b60200151614214919061490a565b95506142218184866135ce565b8b60400151614230919061490a565b9450505050509550959350505050565b5f8363ffffffff168363ffffffff161115801561426957508363ffffffff168263ffffffff1611155b15614285578163ffffffff168363ffffffff161115905061136a565b5f8463ffffffff168463ffffffff16116142b3576142ae63ffffffff851664010000000061502c565b6142bb565b8363ffffffff165b64ffffffffff1690505f8563ffffffff168463ffffffff16116142f2576142ed63ffffffff851664010000000061502c565b6142fa565b8363ffffffff165b64ffffffffff169091111595945050505050565b61433560405180606001604052805f63ffffffff1681526020015f81526020015f81525090565b61435c60405180606001604052805f63ffffffff1681526020015f81526020015f81525090565b6202fffd85015461ffff62010000820481169187915f918491166001018161438657614386614934565b0690505f1961ffff84168201015b6002818301048361ffff861682816143ae576143ae614934565b0661ffff81106143c0576143c0614ad5565b6040805160608101825260039290920292909201805463ffffffff1682526001808201546020840152600290910154928201929092529750849061ffff87169083018161440f5761440f614934565b0661ffff811061442157614421614ad5565b6040805160608101825260039290920292909201805463ffffffff16825260018101546020830152600201549181019190915287519096505f90614467908b908b614240565b90505f6144788b8b8a5f0151614240565b90508180156144845750805b15614491575050506144b1565b81156144a2578260010194506144a9565b6001830393505b505050614394565b50505050935093915050565b6103688061504a83390190565b6001600160a01b03811681146123b3575f5ffd5b5f5f83601f8401126144ee575f5ffd5b50813567ffffffffffffffff811115614505575f5ffd5b602083019150836020828501011115611575575f5ffd5b5f5f5f5f5f60808688031215614530575f5ffd5b85359450602086013593506040860135614549816144ca565b9250606086013567ffffffffffffffff811115614564575f5ffd5b614570888289016144de565b969995985093965092949392505050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b5f5f604083850312156145c7575f5ffd5b82356145d2816144ca565b946020939093013593505050565b5f5f604083850312156145f1575f5ffd5b823591506020830135614603816144ca565b809150509250929050565b5f5f5f5f60808587031215614621575f5ffd5b843593506020850135614633816144ca565b93969395505050506040820135916060013590565b5f60208284031215614658575f5ffd5b813561136a816144ca565b5f5f5f60608486031215614675575f5ffd5b8335614680816144ca565b92506020840135614690816144ca565b929592945050506040919091013590565b5f602082840312156146b1575f5ffd5b5035919050565b5f5f604083850312156146c9575f5ffd5b82356146d4816144ca565b91506020830135614603816144ca565b5f602082840312156146f4575f5ffd5b813561ffff8116811461136a575f5ffd5b80151581146123b3575f5ffd5b5f5f60408385031215614723575f5ffd5b823561472e816144ca565b9150602083013561460381614705565b5f5f6020838503121561474f575f5ffd5b823567ffffffffffffffff811115614765575f5ffd5b8301601f81018513614775575f5ffd5b803567ffffffffffffffff81111561478b575f5ffd5b8560208260051b840101111561479f575f5ffd5b6020919091019590945092505050565b5f8151808452602084019350602083015f5b828110156147df5781518652602095860195909101906001016147c1565b5093949350505050565b604081525f6147fb60408301856147af565b8281036020840152613e3681856147af565b5f5f6020838503121561481e575f5ffd5b823567ffffffffffffffff811115614834575f5ffd5b614840858286016144de565b90969095509350505050565b5f6020828403121561485c575f5ffd5b815161136a81614705565b6001600160a01b038616815284602082015283604082015260806060820152816080820152818360a08301375f81830160a090810191909152601f909201601f19160101949350505050565b5f602082840312156148c3575f5ffd5b5051919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b818103818111156110ec576110ec6148ca565b808201808211156110ec576110ec6148ca565b80820281158282048414176110ec576110ec6148ca565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f8261496f5761496f614934565b500490565b5f610100820190506fffffffffffffffffffffffffffffffff83511682526fffffffffffffffffffffffffffffffff60208401511660208301526fffffffffffffffffffffffffffffffff604084015116604083015260608301516149ed60608401826fffffffffffffffffffffffffffffffff169052565b506080830151614a1160808401826fffffffffffffffffffffffffffffffff169052565b5060a0830151614a3560a08401826fffffffffffffffffffffffffffffffff169052565b5060c0830151614a5960c08401826fffffffffffffffffffffffffffffffff169052565b5060e0830151614a7d60e08401826fffffffffffffffffffffffffffffffff169052565b5092915050565b600181811c90821680614a9857607f821691505b602082108103614acf577f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b50919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f60208284031215614b3f575f5ffd5b815167ffffffffffffffff811115614b55575f5ffd5b8201601f81018413614b65575f5ffd5b805167ffffffffffffffff811115614b7f57614b7f614b02565b604051601f19603f601f19601f8501160116810181811067ffffffffffffffff82111715614baf57614baf614b02565b604052818152828201602001861015614bc6575f5ffd5b8160208401602083015e5f91810160200191909152949350505050565b601f8211156115eb57828211156115eb57805f5260205f20601f840160051c6020851015614c0e57505f5b90810190601f840160051c035f5b81811015614c31575f83820155600101614c1c565b505050505050565b815167ffffffffffffffff811115614c5357614c53614b02565b614c6781614c618454614a84565b84614be3565b6020601f821160018114614c99575f8315614c825750848201515b5f19600385901b1c1916600184901b178455611042565b5f84815260208120601f198516915b82811015614cc85787850151825560209485019460019092019101614ca8565b5084821015614ce557868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b5f60208284031215614d04575f5ffd5b815160ff8116811461136a575f5ffd5b6001815b6001841115614d4f57808504811115614d3357614d336148ca565b6001841615614d4157908102905b60019390931c928002614d18565b935093915050565b5f82614d65575060016110ec565b81614d7157505f6110ec565b8160018114614d875760028114614d9157614dad565b60019150506110ec565b60ff841115614da257614da26148ca565b50506001821b6110ec565b5060208310610133831016604e8410600b8410161715614dd0575081810a6110ec565b614ddc5f198484614d14565b805f1904821115613d9d57613d9d6148ca565b5f61136a60ff841683614d57565b5f60208284031215614e0d575f5ffd5b815161136a816144ca565b67ffffffffffffffff831115614e3057614e30614b02565b614e4483614e3e8354614a84565b83614be3565b5f601f841160018114614e75575f8515614e5e5750838201355b5f19600387901b1c1916600186901b178355611042565b5f83815260208120601f198716915b82811015614ea45786850135825560209485019460019092019101614e84565b5086821015614ec0575f1960f88860031b161c19848701351681555b505060018560011b0183555050505050565b5f5f5f60608486031215614ee4575f5ffd5b8351602085015160408601519194509250614efe81614705565b809150509250925092565b5f81518060208401855e5f93019283525090919050565b7f537461626c65563220414d4d202d20000000000000000000000000000000000081525f614f51600f830185614f09565b7f2f000000000000000000000000000000000000000000000000000000000000008152613e366001820185614f09565b7f73414d4d56322d0000000000000000000000000000000000000000000000000081525f614f516007830185614f09565b5f60208284031215614fc2575f5ffd5b813563ffffffff8116811461136a575f5ffd5b61ffff82811682821603908111156110ec576110ec6148ca565b61ffff81811683821601908111156110ec576110ec6148ca565b5f61ffff83168061501c5761501c614934565b8061ffff84160691505092915050565b64ffffffffff81811683821601908111156110ec576110ec6148ca56fe60e060405234801561000f575f5ffd5b5060405161036838038061036883398101604081905261002e91610064565b336080526001600160a01b0391821660a0521660c052610095565b80516001600160a01b038116811461005f575f5ffd5b919050565b5f5f60408385031215610075575f5ffd5b61007e83610049565b915061008c60208401610049565b90509250929050565b60805160a05160c0516102ab6100bd5f395f61011801525f60d101525f605a01526102ab5ff3fe608060405234801561000f575f5ffd5b5060043610610029575f3560e01c8063533cf5ce1461002d575b5f5ffd5b61004061003b36600461022b565b610042565b005b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146100b1576040517f6f61f64100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81156100f8576100f873ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168484610144565b801561013f5761013f73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168483610144565b505050565b61015183838360016101a3565b61013f576040517f5274afe700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8416600482015260240160405180910390fd5b6040517fa9059cbb000000000000000000000000000000000000000000000000000000005f81815273ffffffffffffffffffffffffffffffffffffffff8616600452602485905291602083604481808b5af1925060015f5114831661021f578383151615610213573d5f823e3d81fd5b5f873b113d1516831692505b60405250949350505050565b5f5f5f6060848603121561023d575f5ffd5b833573ffffffffffffffffffffffffffffffffffffffff81168114610260575f5ffd5b9560208501359550604090940135939250505056fea2646970667358221220eeabba3bd98e978db119b83233dcf1a15cbc1751f5b6fdcc907308b07b33330264736f6c63430008240033a2646970667358221220aa9bbd0570a5d863052798f5e72b7cb02066916c003643151160fd218424ee5f64736f6c63430008240033","sourceMap":"362:5174:8:-:0;;;;;;;;;;;;-1:-1:-1;1582:113:13;;;;;;;;;-1:-1:-1;1582:113:13;;;;;;;;;;;;;;;1648:5;:13;1582:113;1648:5;:13;:::i;:::-;-1:-1:-1;1671:7:13;:17;1681:7;1671;:17;:::i;:::-;;1582:113;;2365:1:19;2539:46;:29;:27;;;:29;;:::i;:::-;2822:4:20;2679:163;2539:46:19;:66;362:5174:8;;4636:127:19;1505:66;;4636:127::o;14::24:-;75:10;70:3;66:20;63:1;56:31;106:4;103:1;96:15;130:4;127:1;120:15;146:380;225:1;221:12;;;;268;;;289:61;;343:4;335:6;331:17;321:27;;289:61;396:2;388:6;385:14;365:18;362:38;359:161;;442:10;437:3;433:20;430:1;423:31;477:4;474:1;467:15;505:4;502:1;495:15;359:161;;146:380;;;:::o;657:692::-;759:2;754:3;751:11;748:595;;;796:10;791:3;788:19;785:548;;;848:5;845:1;838:16;896:4;893:1;883:18;961:2;949:10;945:19;942:1;938:27;1000:4;988:10;985:20;982:45;;;-1:-1:-1;1024:1:24;982:45;1063:23;;;;1133:2;1124:12;;1121:1;1117:20;1113:39;1178:1;1196:123;1210:2;1207:1;1204:9;1196:123;;;1299:1;1278:19;;;1271:30;1228:1;1221:9;1196:123;;;1200:3;;;785:548;657:692;;;:::o;1525:1299::-;1645:10;;-1:-1:-1;;;;;1667:30:24;;1664:56;;;1700:18;;:::i;:::-;1729:97;1819:6;1779:38;1811:4;1805:11;1779:38;:::i;:::-;1773:4;1729:97;:::i;:::-;1875:4;1906:2;1895:14;;1923:1;1918:649;;;;2611:1;2628:6;2625:89;;;-1:-1:-1;2680:19:24;;;2674:26;2625:89;-1:-1:-1;;1482:1:24;1478:11;;;1474:24;1470:29;1460:40;1506:1;1502:11;;;1457:57;2727:81;;1888:930;;1918:649;604:1;597:14;;;641:4;628:18;;-1:-1:-1;;1954:20:24;;;2072:222;2086:7;2083:1;2080:14;2072:222;;;2168:19;;;2162:26;2147:42;;2275:4;2260:20;;;;2228:1;2216:14;;;;2102:12;2072:222;;;2076:3;2322:6;2313:7;2310:19;2307:201;;;2383:19;;;2377:26;-1:-1:-1;;2466:1:24;2462:14;;;2478:3;2458:24;2454:37;2450:42;2435:58;2420:74;;2307:201;;;2554:1;2545:6;2542:1;2538:14;2534:22;2528:4;2521:36;1888:930;;;;1525:1299;;:::o;:::-;362:5174:8;;;;;;","linkReferences":{},"cborAuxdata":{"1":{"value":"0xa2646970667358221220aa9bbd0570a5d863052798f5e72b7cb02066916c003643151160fd218424ee5f64736f6c63430008240033","offset":21927},"2":{"value":"0xa2646970667358221220eeabba3bd98e978db119b83233dcf1a15cbc1751f5b6fdcc907308b07b33330264736f6c63430008240033","offset":21874}},"transformations":[{"id":"1","type":"replace","offset":21927,"reason":"cborAuxdata"},{"id":"2","type":"replace","offset":21874,"reason":"cborAuxdata"}],"transformationValues":{"cborAuxdata":{"1":"0xa2646970667358221220c44780aa04b481bff35f6e43d6d561fdb2f8fde74b2f0d2839a586c497a0e40264736f6c63430008240033","2":"0xa26469706673582212207519fe77d60fa2befaa943fe4f040b0f82abdb9264e6f95e7af68108cee501e564736f6c63430008240033"}}},"runtimeBytecode":{"onchainBytecode":"0x608060405234801561000f575f5ffd5b5060043610610346575f3560e01c8063648da859116101be578063bc25cf77116100fe578063c5884ad11161009e578063ee39e7a011610079578063ee39e7a014610856578063f140a35a1461085e578063fc9654ab14610871578063fff6cae914610879575f5ffd5b8063c5884ad1146107dc578063d21220a71461080b578063dd62ed3e1461081e575f5ffd5b8063c245febc116100d9578063c245febc146107a0578063c45a0155146107ab578063c47f0027146107be578063c5700a02146107d1575f5ffd5b8063bc25cf7714610777578063bda39cad1461078a578063bf944dbc14610795575f5ffd5b806395d89b4111610169578063a1ac4d1311610144578063a1ac4d131461071d578063a9059cbb1461073e578063b84c824614610751578063b95d88f814610764575f5ffd5b806395d89b41146106ce5780639d63848a146106d65780639f767c88146106fc575f5ffd5b806378273aca1161019957806378273aca14610687578063883bdbfd1461069a57806389afcb44146106bb575f5ffd5b8063648da859146106255780636a6278421461064c57806370a082311461065f575f5ffd5b8063252c09d7116102895780633358095911610234578063485cc9551161020f578063485cc955146105da5780634983f2f5146105ed5780634d5a9f8a146105f95780635a76f25e1461061a575f5ffd5b80633358095914610569578063392f37e91461057c578063443cb4bc146105cf575f5ffd5b8063313ce56711610264578063313ce5671461053c57806332148f671461054b57806332c0defd1461055e575f5ffd5b8063252c09d7146104e157806325d2a3f3146105165780632dbfa73514610529575f5ffd5b8063119c4e9f116102f45780631a4211dc116102cf5780631a4211dc1461045a5780631df8c717146104a5578063205aabf1146104ad57806323b872dd146104ce575f5ffd5b8063119c4e9f1461041757806315a0ea6a1461042a57806318160ddd14610452575f5ffd5b8063095ea7b311610324578063095ea7b3146103a85780630dfe1681146103cb5780630ea099c1146103f6575f5ffd5b8063022c0d9f1461034a57806306fdde031461035f5780630902f1ac1461037d575b5f5ffd5b61035d61035836600461451c565b610881565b005b610367611049565b6040516103749190614581565b60405180910390f35b6203000b546203000c546203000d545b60408051938452602084019290925290820152606001610374565b6103bb6103b63660046145b6565b6110d9565b6040519015158152602001610374565b6007546103de906001600160a01b031681565b6040516001600160a01b039091168152602001610374565b6104096104043660046145e0565b6110f2565b604051908152602001610374565b61040961042536600461460e565b611175565b61043d610438366004614648565b611280565b60408051928352602083019190915201610374565b600254610409565b62030008546104809061ffff808216916201000081048216916401000000009091041683565b6040805161ffff94851681529284166020840152921691810191909152606001610374565b61038d6112d5565b6104096104bb366004614648565b620300136020525f908152604090205481565b6103bb6104dc366004614663565b61134c565b6104f46104ef3660046146a1565b611371565b6040805163ffffffff9094168452602084019290925290820152606001610374565b61043d610524366004614648565b6113ce565b61043d6105373660046146b8565b6114af565b60405160128152602001610374565b61035d6105593660046146e4565b61157c565b610409620300105481565b6009546103de906001600160a01b031681565b62030009546203000a546203000b546203000c546007546008546040805196875260208701959095529385019290925260608401526001600160a01b0390811660808401521660a082015260c001610374565b6104096203000b5481565b61035d6105e83660046146b8565b6115f0565b6104096402540be40081565b610409610607366004614648565b620300146020525f908152604090205481565b6104096203000c5481565b6104097f56325f535441424c45000000000000000000000000000000000000000000000081565b61040961065a366004614648565b611930565b61040961066d366004614648565b6001600160a01b03165f9081526020819052604090205490565b61035d610695366004614712565b611bc2565b6106ad6106a836600461473e565b611c8d565b6040516103749291906147e9565b61043d6106c9366004614648565b611cbb565b610367611fca565b600754600854604080516001600160a01b03938416815292909116602083015201610374565b61040961070a366004614648565b620300126020525f908152604090205481565b61040961072b366004614648565b620300156020525f908152604090205481565b6103bb61074c3660046145b6565b611fd9565b61035d61075f36600461480d565b611fe6565b6104096107723660046145e0565b6120b1565b61035d610785366004614648565b612249565b610409620300115481565b6104096203000e5481565b6104096203000f5481565b600a546103de906001600160a01b031681565b61035d6107cc36600461480d565b6123b6565b6104096203000d5481565b6103bb6107ea3660046146b8565b6203001660209081525f928352604080842090915290825290205460ff1681565b6008546103de906001600160a01b031681565b61040961082c3660046146b8565b6001600160a01b039182165f90815260016020908152604080832093909416825291909152205490565b610409612481565b61040961086c3660046145e0565b6124ca565b610409603c81565b61035d6125d6565b610889612729565b600a5f9054906101000a90046001600160a01b03166001600160a01b031663b187bd266040518163ffffffff1660e01b8152600401602060405180830381865afa1580156108d9573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108fd919061484c565b15610934576040517f1309a56300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84158015610940575083155b15610977576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6203000b546203000c5481871015806109905750808610155b156109c7576040517fbb55fd2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6007546008545f9182916001600160a01b0391821691908116908916821480610a015750806001600160a01b0316896001600160a01b0316145b15610a38576040517f290fa18800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8a15610a5257610a526001600160a01b0383168a8d612757565b8915610a6c57610a6c6001600160a01b0382168a8c612757565b8615610aed576040517f9a7bff790000000000000000000000000000000000000000000000000000000081526001600160a01b038a1690639a7bff7990610abf9033908f908f908e908e90600401614867565b5f604051808303815f87803b158015610ad6575f5ffd5b505af1158015610ae8573d5f5f3e3d5ffd5b505050505b6040516370a0823160e01b81523060048201526001600160a01b038316906370a0823190602401602060405180830381865afa158015610b2f573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b5391906148b3565b6040516370a0823160e01b81523060048201529094506001600160a01b038216906370a0823190602401602060405180830381865afa158015610b98573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610bbc91906148b3565b925050505f8985610bcd91906148f7565b8311610bd9575f610bed565b610be38a866148f7565b610bed90846148f7565b90505f610bfa8a866148f7565b8311610c06575f610c1a565b610c108a866148f7565b610c1a90846148f7565b905081158015610c28575080155b15610c5f576040517f098fb56100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051610100810182525f80825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810191909152610ca98c8461490a565b6fffffffffffffffffffffffffffffffff166040820152610cca8b8361490a565b6fffffffffffffffffffffffffffffffff1660608201526007546008546001600160a01b0391821691165f8080610d0388888e8e6127aa565b919450925090508715610d78575f612710610d1e858b61491d565b610d289190614961565b9050610d3381612863565b6fffffffffffffffffffffffffffffffff81168752612710610d55848b61491d565b610d5f9190614961565b6fffffffffffffffffffffffffffffffff1660c0880152505b8615610de9575f612710610d8c858a61491d565b610d969190614961565b9050610da181612910565b6fffffffffffffffffffffffffffffffff81166020880152612710610dc6848a61491d565b610dd09190614961565b6fffffffffffffffffffffffffffffffff1660e0880152505b8015610e195760408601516fffffffffffffffffffffffffffffffff908116608088015260608701511660a08701525b6040516370a0823160e01b81523060048201526001600160a01b038616906370a0823190602401602060405180830381865afa158015610e5b573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e7f91906148b3565b6040516370a0823160e01b8152306004820152909a506001600160a01b038516906370a0823190602401602060405180830381865afa158015610ec4573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ee891906148b3565b9850610ef48c8c6129b6565b610efe8b8b6129b6565b1015610f36576040517fa932492f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600a546040517f5310a4210000000000000000000000000000000000000000000000000000000081526001600160a01b0390911690635310a42190610f7f908990600401614974565b5f604051808303815f87803b158015610f96575f5ffd5b505af1158015610fa8573d5f5f3e3d5ffd5b50505050505050505050610fbe84848888612a5f565b60408051838152602081018390529081018c9052606081018b90526001600160a01b038a169033907fb3e2773606abfd36b5bd91394b3a54d1398336c65005baf7bf7a05efeffaf75b9060800160405180910390a350505050505061104260017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b5050505050565b60606005805461105890614a84565b80601f016020809104026020016040519081016040528092919081815260200182805461108490614a84565b80156110cf5780601f106110a6576101008083540402835291602001916110cf565b820191905f5260205f20905b8154815290600101906020018083116110b257829003601f168201915b5050505050905090565b5f336110e6818585612b44565b60019150505b92915050565b6203000b546203000c546007545f929190839081906001600160a01b03878116911614611120575f87611123565b865f5b915091505f611134838387876127aa565b505090506127108189611147919061491d565b6111519190614961565b61115b90896148f7565b975061116988888787612b51565b98975050505050505050565b6007545f90819081906001600160a01b03878116911614611197575f8761119a565b865f5b600a546040517fdf29d5bb0000000000000000000000000000000000000000000000000000000081523060048201525f602482015260448101849052606481018390526084810189905260a48101889052929450909250612710916001600160a01b039091169063df29d5bb9060c401602060405180830381865afa158015611225573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061124991906148b3565b611253908961491d565b61125d9190614961565b61126790886148f7565b965061127587878787612b51565b979650505050505050565b5f806001600160a01b0383166112c2576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6112cc3384612c93565b91509150915091565b6203000e546203000f54425f80806112fc6203000b546203000c546203000d549192909190565b925092509250838114611344575f61131482866148f7565b9050611320818561491d565b61132a908861490a565b9650611336818461491d565b611340908761490a565b9550505b505050909192565b5f33611359858285612dd0565b611364858585612e5f565b60019150505b9392505050565b5f808080600b8561ffff811061138957611389614ad5565b6040805160608101825260039290920292909201805463ffffffff16808352600182015460208401819052600290920154929093018290529197919650945092505050565b6001600160a01b0381165f908152620300146020908152604080832054620300158352818420549284905292205480156114a9576001600160a01b0384165f9081526203001260205260409020546203001054670de0b6b3a764000091611434916148f7565b61143e908361491d565b6114489190614961565b611452908461490a565b6001600160a01b0385165f9081526203001360205260409020546203001154919450670de0b6b3a76400009161148891906148f7565b611492908361491d565b61149c9190614961565b6114a6908361490a565b91505b50915091565b5f806001600160a01b0383166114f1576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336001600160a01b0385161480159061152f57506001600160a01b0384165f908152620300166020908152604080832033845290915290205460ff16155b15611566576040517fea8e4eb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6115708484612c93565b915091505b9250929050565b6203000854640100000000900461ffff165f611599600b84612eee565b90508161ffff168161ffff16146115eb576040805161ffff80851682528316602082015233917ff0b7b7d1cdf542f5660a7879f0cac17375fdcf984af4a6d499a9daedacb24c58910160405180910390a25b505050565b600a546001600160a01b031615611633576040517f154c51b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600a8054337fffffffffffffffffffffffff0000000000000000000000000000000000000000918216179091556008805482166001600160a01b03848116919091179091556007805490921690841617905560405182908290611695906144bd565b6001600160a01b03928316815291166020820152604001604051809103905ff0801580156116c5573d5f5f3e3d5ffd5b5060095f6101000a8154816001600160a01b0302191690836001600160a01b031602179055505f826001600160a01b03166395d89b416040518163ffffffff1660e01b81526004015f60405180830381865afa158015611727573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261174e9190810190614b2f565b90505f826001600160a01b03166395d89b416040518163ffffffff1660e01b81526004015f60405180830381865afa15801561178c573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526117b39190810190614b2f565b90506117bf8282613005565b6005906117cc9082614c39565b506117d78282613031565b6006906117e49082614c39565b50836001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611821573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118459190614cf4565b61185090600a614def565b6203000981905550826001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611894573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118b89190614cf4565b6118c390600a614def565b6203000a55600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000164263ffffffff161790556203000880547fffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ffff166401000100001790555b50505050565b5f611939612729565b6203000b546203000c546007546040516370a0823160e01b81523060048201525f916001600160a01b0316906370a0823190602401602060405180830381865afa158015611989573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119ad91906148b3565b6008546040516370a0823160e01b81523060048201529192505f916001600160a01b03909116906370a0823190602401602060405180830381865afa1580156119f8573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611a1c91906148b3565b90505f611a2985846148f7565b90505f611a3685846148f7565b90505f611a4260025490565b9050805f03611ac4576103e8611a60611a5b848661491d565b613046565b611a6a91906148f7565b9750611a7960016103e86131ab565b611a8383836131fc565b6103e8881015611abf576040517fd226f9d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611b31565b611af687611ad2838661491d565b611adc9190614961565b87611ae7848661491d565b611af19190614961565b6132bc565b9750875f03611b31576040517fd226f9d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611b3b89896131ab565b611b4785858989612a5f565b60408051848152602081018490526001600160a01b038b169133917f2f00e3cdd69a77be7ed215ec7b2a36784dd158f921fca79ac29deffa353fe6ee910160405180910390a350505050505050611bbd60017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b919050565b6001600160a01b038216611c02576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b335f81815262030016602090815260408083206001600160a01b0387168085529083529281902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001686151590811790915590519081529192917f63484c3756a6c7d95f131879210268006b60e58057de5db75f3a8c91c7869ebf910160405180910390a35050565b6060805f5f611c9a6112d5565b509092509050611cae600b878785856132cb565b9350935050509250929050565b5f5f611cc5612729565b6203000b546203000c546007546008546040516370a0823160e01b81523060048201526001600160a01b0392831692909116905f9083906370a0823190602401602060405180830381865afa158015611d20573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611d4491906148b3565b6040516370a0823160e01b81523060048201529091505f906001600160a01b038416906370a0823190602401602060405180830381865afa158015611d8b573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611daf91906148b3565b305f908152602081905260409020546002549192509080611dd0858461491d565b611dda9190614961565b995080611de7848461491d565b611df19190614961565b9850891580611dfe575088155b15611e35576040517f749383ad00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611e3f30836133e6565b611e536001600160a01b0387168c8c612757565b611e676001600160a01b0386168c8b612757565b6040516370a0823160e01b81523060048201526001600160a01b038716906370a0823190602401602060405180830381865afa158015611ea9573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611ecd91906148b3565b6040516370a0823160e01b81523060048201529094506001600160a01b038616906370a0823190602401602060405180830381865afa158015611f12573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f3691906148b3565b9250611f428484613433565b611f4e84848a8a612a5f565b604080518b8152602081018b90526001600160a01b038d169133917f5d624aa9c148153ab3446c1b154f660ee7701e549fe9b62dab7171b1c80e6fa2910160405180910390a35050505050505050611fc560017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b915091565b60606006805461105890614a84565b5f336110e6818585612e5f565b600a5f9054906101000a90046001600160a01b03166001600160a01b031663b782cc496040518163ffffffff1660e01b8152600401602060405180830381865afa158015612036573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061205a9190614dfd565b6001600160a01b0316336001600160a01b0316146120a4576040517f058a2da800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60066115eb828483614e18565b5f825f036120c057505f6110ec565b6203000b546203000c546007546001600160a01b038581169116146120e557806120e7565b815b851061211f576040517fbb55fd2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f61212c86868585613475565b9050805f03612140575f93505050506110ec565b6007545f9081906001600160a01b0388811691161461216057825f612163565b5f835b600a546040517f11896ad200000000000000000000000000000000000000000000000000000000815230600482015233602482015260448101849052606481018390526084810189905260a481018890529294509092505f916001600160a01b03909116906311896ad29060c401602060405180830381865afa1580156121ec573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061221091906148b3565b9050612232816122216001876148f7565b61222d846127106148f7565b6135ce565b61223c908561490a565b9998505050505050505050565b612251612729565b6007546008546203000b546040516370a0823160e01b81523060048201526001600160a01b0393841693909216915f919084906370a0823190602401602060405180830381865afa1580156122a8573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906122cc91906148b3565b6122d691906148f7565b905080156122f2576122f26001600160a01b0384168583612757565b6203000c546040516370a0823160e01b81523060048201525f91906001600160a01b038516906370a0823190602401602060405180830381865afa15801561233c573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061236091906148b3565b61236a91906148f7565b90508015612386576123866001600160a01b0384168683612757565b505050506123b360017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b50565b600a5f9054906101000a90046001600160a01b03166001600160a01b031663b782cc496040518163ffffffff1660e01b8152600401602060405180830381865afa158015612406573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061242a9190614dfd565b6001600160a01b0316336001600160a01b031614612474576040517f058a2da800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60056115eb828483614e18565b5f61248a612729565b61249c6203000b546203000c546129b6565b90506124c760017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b90565b6203000b546203000c546007545f929190839081906001600160a01b038781169116146124f8575f876124fb565b865f5b600a546040517fdf29d5bb0000000000000000000000000000000000000000000000000000000081523060048201525f602482015260448101849052606481018390526084810188905260a48101879052929450909250612710916001600160a01b039091169063df29d5bb9060c401602060405180830381865afa158015612586573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906125aa91906148b3565b6125b4908961491d565b6125be9190614961565b6125c890886148f7565b965061127587878686612b51565b6125de612729565b6002545f03612619576040517fbb55fd2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6007546040516370a0823160e01b81523060048201526126fe916001600160a01b0316906370a0823190602401602060405180830381865afa158015612661573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061268591906148b3565b6008546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa1580156126cb573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906126ef91906148b3565b6203000b546203000c54612a5f565b61272760017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b565b61273161367e565b60027f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b61276483838360016136e1565b6115eb576040517f5274afe70000000000000000000000000000000000000000000000000000000081526001600160a01b03841660048201526024015b60405180910390fd5b600a546040517fdb6b39b400000000000000000000000000000000000000000000000000000000815230600482015233602482015260448101869052606481018590526084810184905260a481018390525f91829182916001600160a01b03169063db6b39b49060c401606060405180830381865afa15801561282f573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906128539190614ed2565b9250925092509450945094915050565b805f0361286d5750565b60095460075461288a916001600160a01b03918216911683612757565b5f61289460025490565b6128a683670de0b6b3a764000061491d565b6128b09190614961565b905080156128d15780620300105f8282546128cb919061490a565b90915550505b604080518381525f602082015233917f112c256902bf554b6ed882d2936687aaeb4225e8cd5b51303c90ca6cf43a860291015b60405180910390a25050565b805f0361291a5750565b600954600854612937916001600160a01b03918216911683612757565b5f61294160025490565b61295383670de0b6b3a764000061491d565b61295d9190614961565b9050801561297e5780620300115f828254612978919061490a565b90915550505b604080515f81526020810184905233917f112c256902bf554b6ed882d2936687aaeb4225e8cd5b51303c90ca6cf43a86029101612904565b5f5f620300095484670de0b6b3a76400006129d1919061491d565b6129db9190614961565b90505f6203000a5484670de0b6b3a76400006129f7919061491d565b612a019190614961565b90505f612a178383670de0b6b3a76400006135ce565b90505f612a2d8384670de0b6b3a76400006135ce565b612a408586670de0b6b3a76400006135ce565b612a4a919061490a565b90506112758282670de0b6b3a76400006135ce565b6203000d5442905f90612a7290836148f7565b90505f81118015612a8257508315155b8015612a8d57508215155b15612ad657612a9c818561491d565b6203000e5f828254612aae919061490a565b90915550612abe9050818461491d565b6203000f5f828254612ad0919061490a565b90915550505b6203000e546203000f54612aee91600b91603c61375c565b6203000b8690556203000c8590556203000d82905560408051878152602081018790527fcf2aa50876cdfbb541206f89af0ee78d44a2abf8d328e37fa4917f982149848a910160405180910390a1505050505050565b6115eb838383600161391f565b5f5f612b5d84846129b6565b6203000954909150612b7785670de0b6b3a764000061491d565b612b819190614961565b6203000a54909450612b9b84670de0b6b3a764000061491d565b612ba59190614961565b6007549093505f9081906001600160a01b03888116911614612bc8578486612bcb565b85855b60075491935091506001600160a01b03888116911614612c0b576203000a54612bfc89670de0b6b3a764000061491d565b612c069190614961565b612c2c565b6203000954612c2289670de0b6b3a764000061491d565b612c2c9190614961565b97505f612c43612c3c848b61490a565b8584613a23565b612c4d90836148f7565b600754909150670de0b6b3a7640000906001600160a01b038a8116911614612c79576203000954612c7f565b6203000a545b612c89908361491d565b61223c9190614961565b5f5f612c9e84613b44565b50506001600160a01b0382165f908152620300146020908152604080832054620300159092529091205481151580612cd557505f81115b15611575576001600160a01b038481165f9081526203001460209081526040808320839055620300159091528082209190915560095490517f533cf5ce0000000000000000000000000000000000000000000000000000000081528583166004820152602481018590526044810184905291169063533cf5ce906064015f604051808303815f87803b158015612d69575f5ffd5b505af1158015612d7b573d5f5f3e3d5ffd5b505060408051858152602081018590526001600160a01b0380881694508816925033917fcd5e4f020ddad29434c2200a9edf2f8d7ec30f0d787f03b528ab7279aab0acbe910160405180910390a49250929050565b6001600160a01b038381165f908152600160209081526040808320938616835292905220545f1981101561192a5781811015612e51576040517ffb8f41b20000000000000000000000000000000000000000000000000000000081526001600160a01b038416600482015260248101829052604481018390526064016127a1565b61192a84848484035f61391f565b6001600160a01b038316612ea1576040517f96c6fd1e0000000000000000000000000000000000000000000000000000000081525f60048201526024016127a1565b6001600160a01b038216612ee3576040517fec442f050000000000000000000000000000000000000000000000000000000081525f60048201526024016127a1565b6115eb838383613cb0565b6202fffd8201545f9061ffff64010000000090910481169083168110612f155790506110ec565b805b8361ffff168161ffff161015612fc45760018561ffff808416908110612f3f57612f3f614ad5565b6003020180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff9290921691909117905560018561ffff838116908110612f8e57612f8e614ad5565b60030201600101819055506001855f018261ffff1661ffff8110612fb457612fb4614ad5565b6003020160020155600101612f17565b5050506202fffd9190910180547fffffffffffffffffffffffffffffffffffffffffffffffffffff0000ffffffff1664010000000061ffff84160217905590565b6060828260405160200161301a929190614f20565b604051602081830303815290604052905092915050565b6060828260405160200161301a929190614f81565b5f60018211613053575090565b81600170010000000000000000000000000000000082106130795760809190911c9060401b5b6801000000000000000082106130945760409190911c9060201b5b64010000000082106130ab5760209190911c9060101b5b6201000082106130c05760109190911c9060081b5b61010082106130d45760089190911c9060041b5b601082106130e75760049190911c9060021b5b600482106130f35760011b5b600302600190811c9081858161310b5761310b614934565b048201901c9050600181858161312357613123614934565b048201901c9050600181858161313b5761313b614934565b048201901c9050600181858161315357613153614934565b048201901c9050600181858161316b5761316b614934565b048201901c9050600181858161318357613183614934565b048201901c90506131a281858161319c5761319c614934565b04821190565b90039392505050565b6001600160a01b0382166131ed576040517fec442f050000000000000000000000000000000000000000000000000000000081525f60048201526024016127a1565b6131f85f8383613cb0565b5050565b6203000a5461321382670de0b6b3a764000061491d565b61321d9190614961565b620300095461323484670de0b6b3a764000061491d565b61323e9190614961565b14613275576040517f0a04d7fa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6402540be40061328583836129b6565b116131f8576040517f438d3ade00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f82821882841002821861136a565b60608042858067ffffffffffffffff8111156132e9576132e9614b02565b604051908082528060200260200182016040528015613312578160200160208202803683370190505b5093508067ffffffffffffffff81111561332e5761332e614b02565b604051908082528060200260200182016040528015613357578160200160208202803683370190505b5092505f5b818110156133d9576133978a848b8b8581811061337b5761337b614ad5565b90506020020160208101906133909190614fb2565b8a8a613ceb565b8683815181106133a9576133a9614ad5565b602002602001018684815181106133c2576133c2614ad5565b60209081029190910101919091525260010161335c565b5050509550959350505050565b6001600160a01b038216613428576040517f96c6fd1e0000000000000000000000000000000000000000000000000000000081525f60048201526024016127a1565b6131f8825f83613cb0565b61343d82826129b6565b5f036131f8576040517f7d06c0c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f5f61348184846129b6565b620300095490915061349b85670de0b6b3a764000061491d565b6134a59190614961565b6203000a549094506134bf84670de0b6b3a764000061491d565b6134c99190614961565b6007549093505f9081906001600160a01b038881169116146134ec5784866134ef565b85855b60075491935091505f9081906001600160a01b038a811691161461351c576203000a546203000954613527565b62030009546203000a545b90925090506135476135418b670de0b6b3a764000061491d565b83613d71565b9950838a10613582576040517fbb55fd2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f6135976135908c876148f7565b8786613a23565b90506135bf826135a786846148f7565b6135b1919061491d565b670de0b6b3a7640000613d71565b9b9a5050505050505050505050565b5f5f5f6135db8686613da5565b91509150815f036135ff578381816135f5576135f5614934565b049250505061136a565b818411613616576136166003851502601118613dc1565b5f848688095f868103871696879004966002600389028118808a02820302808a02820302808a02820302808a02820302808a02820302808a02909103029181900381900460010185841190960395909502919093039390930492909217029150509392505050565b6136aa5f60027f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00613dd2565b15612727576040517f3ee5aeb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517fa9059cbb000000000000000000000000000000000000000000000000000000005f8181526001600160a01b038616600452602485905291602083604481808b5af1925060015f51148316613750578383151615613744573d5f823e3d81fd5b5f873b113d1516831692505b60405250949350505050565b6202fffd840154429061ffff908116905f9087908390811061378057613780614ad5565b600302015463ffffffff90811684031690508381116137a15750505061192a565b6202fffd87015461ffff620100008204811691829164010000000090910416811080156137df57506137d4600183614fd5565b61ffff168461ffff16145b156137f2576137ef826001614fef565b90505b5f816137ff866001614fef565b6138099190615009565b905060405180606001604052808763ffffffff1681526020018a8152602001898152508a5f018261ffff1661ffff811061384557613845614ad5565b82516003919091029190910180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff909216919091178155602082015160018201556040909101516002909101556202fffd8a0180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff8381169190911790915583811690831614613913576202fffd8a0180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ffff166201000061ffff8516021790555b50505050505050505050565b6001600160a01b038416613961576040517fe602df050000000000000000000000000000000000000000000000000000000081525f60048201526024016127a1565b6001600160a01b0383166139a3576040517f94280d620000000000000000000000000000000000000000000000000000000081525f60048201526024016127a1565b6001600160a01b038085165f908152600160209081526040808320938716835292905220829055801561192a57826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92584604051613a1591815260200190565b60405180910390a350505050565b5f805b60ff811015613b11575f613a3a8685613dd9565b905084811015613ab4575f613a65613a5283886148f7565b670de0b6b3a764000061222d8a89613e3f565b9050805f03613aa25785613a8388613a7e88600161490a565b613dd9565b1115613a9e57613a9485600161490a565b935050505061136a565b5060015b613aac818661490a565b945050613b08565b5f613ac2613a5287846148f7565b9050805f03613afa5785821480613ae6575085613ae488613a7e6001896148f7565b105b15613af65784935050505061136a565b5060015b613b0481866148f7565b9450505b50600101613a26565b506040517f6eb5c82100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0381165f908152602081905260409020548015613c77576001600160a01b0382165f9081526203001260209081526040808320805462030013808552928520805462030010546203001154948190559490955282905593613bac85846148f7565b90505f613bb985846148f7565b90508115613c14575f670de0b6b3a7640000613bd5848a61491d565b613bdf9190614961565b6001600160a01b038a165f908152620300146020526040812080549293508392909190613c0d90849061490a565b9091555050505b8015613c6d575f670de0b6b3a7640000613c2e838a61491d565b613c389190614961565b6001600160a01b038a165f908152620300156020526040812080549293508392909190613c6690849061490a565b9091555050505b5050505050505050565b62030010546001600160a01b0383165f908152620300126020908152604080832093909355620300115462030013909152919020555050565b6001600160a01b03831615613cc857613cc883613b44565b6001600160a01b03821615613ce057613ce082613b44565b6115eb838383613ea6565b5f5f8463ffffffff165f03613d04575082905081613d67565b8486035f80613d168a8a858a8a613fe5565b915091508263ffffffff16815f015163ffffffff1603613d46578060200151816040015194509450505050613d67565b613d5e82825f015183602001518460400151876141bf565b90955093505050505b9550959350505050565b5f815f03613d8357613d836012613dc1565b816001840381613d9557613d95614934565b046001018315155b029392505050565b5f805f1983850993909202808410938190039390930393915050565b634e487b715f52806020526024601cfd5b5414919050565b5f5f613dee8484670de0b6b3a76400006135ce565b90505f613e048485670de0b6b3a76400006135ce565b613e178687670de0b6b3a76400006135ce565b613e21919061490a565b9050613e368282670de0b6b3a76400006135ce565b95945050505050565b5f5f613e548384670de0b6b3a76400006135ce565b90505f613e6a8586670de0b6b3a76400006135ce565b9050613e7f8186670de0b6b3a76400006135ce565b613e9c613e8d87600361491d565b84670de0b6b3a76400006135ce565b613e36919061490a565b6001600160a01b038316613ed0578060025f828254613ec5919061490a565b90915550613f599050565b6001600160a01b0383165f9081526020819052604090205481811015613f3b576040517fe450d38c0000000000000000000000000000000000000000000000000000000081526001600160a01b038516600482015260248101829052604481018390526064016127a1565b6001600160a01b0384165f9081526020819052604090209082900390555b6001600160a01b038216613f7557600280548290039055613f93565b6001600160a01b0382165f9081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051613fd891815260200190565b60405180910390a3505050565b61400c60405180606001604052805f63ffffffff1681526020015f81526020015f81525090565b61403360405180606001604052805f63ffffffff1681526020015f81526020015f81525090565b6202fffd87015461ffff9081169088908290811061405357614053614ad5565b6040805160608101825260039290920292909201805463ffffffff168083526001820154602084015260029091015492820192909252935061409790889088614240565b156140ee57825163ffffffff8088169116036140b65750819050613d67565b5f5f6140c5858a89898c6141bf565b6040805160608101825263ffffffff8c16815260208101939093528201529350613d6792505050565b6202fffd880154889062010000900461ffff1661410c836001614fef565b6141169190615009565b61ffff1661ffff811061412b5761412b614ad5565b6040805160608101825260039290920292909201805463ffffffff168083526001820154602084015260029091015492820192909252935061416f90889088614240565b6141a5576040517fc02e462000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6141b088888861430e565b92509250509550959350505050565b845160208601515f91829163ffffffff8289038116928603169083906141e590896148f7565b90505f8a60400151886141f891906148f7565b90506142058284866135ce565b8b60200151614214919061490a565b95506142218184866135ce565b8b60400151614230919061490a565b9450505050509550959350505050565b5f8363ffffffff168363ffffffff161115801561426957508363ffffffff168263ffffffff1611155b15614285578163ffffffff168363ffffffff161115905061136a565b5f8463ffffffff168463ffffffff16116142b3576142ae63ffffffff851664010000000061502c565b6142bb565b8363ffffffff165b64ffffffffff1690505f8563ffffffff168463ffffffff16116142f2576142ed63ffffffff851664010000000061502c565b6142fa565b8363ffffffff165b64ffffffffff169091111595945050505050565b61433560405180606001604052805f63ffffffff1681526020015f81526020015f81525090565b61435c60405180606001604052805f63ffffffff1681526020015f81526020015f81525090565b6202fffd85015461ffff62010000820481169187915f918491166001018161438657614386614934565b0690505f1961ffff84168201015b6002818301048361ffff861682816143ae576143ae614934565b0661ffff81106143c0576143c0614ad5565b6040805160608101825260039290920292909201805463ffffffff1682526001808201546020840152600290910154928201929092529750849061ffff87169083018161440f5761440f614934565b0661ffff811061442157614421614ad5565b6040805160608101825260039290920292909201805463ffffffff16825260018101546020830152600201549181019190915287519096505f90614467908b908b614240565b90505f6144788b8b8a5f0151614240565b90508180156144845750805b15614491575050506144b1565b81156144a2578260010194506144a9565b6001830393505b505050614394565b50505050935093915050565b6103688061504a83390190565b6001600160a01b03811681146123b3575f5ffd5b5f5f83601f8401126144ee575f5ffd5b50813567ffffffffffffffff811115614505575f5ffd5b602083019150836020828501011115611575575f5ffd5b5f5f5f5f5f60808688031215614530575f5ffd5b85359450602086013593506040860135614549816144ca565b9250606086013567ffffffffffffffff811115614564575f5ffd5b614570888289016144de565b969995985093965092949392505050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b5f5f604083850312156145c7575f5ffd5b82356145d2816144ca565b946020939093013593505050565b5f5f604083850312156145f1575f5ffd5b823591506020830135614603816144ca565b809150509250929050565b5f5f5f5f60808587031215614621575f5ffd5b843593506020850135614633816144ca565b93969395505050506040820135916060013590565b5f60208284031215614658575f5ffd5b813561136a816144ca565b5f5f5f60608486031215614675575f5ffd5b8335614680816144ca565b92506020840135614690816144ca565b929592945050506040919091013590565b5f602082840312156146b1575f5ffd5b5035919050565b5f5f604083850312156146c9575f5ffd5b82356146d4816144ca565b91506020830135614603816144ca565b5f602082840312156146f4575f5ffd5b813561ffff8116811461136a575f5ffd5b80151581146123b3575f5ffd5b5f5f60408385031215614723575f5ffd5b823561472e816144ca565b9150602083013561460381614705565b5f5f6020838503121561474f575f5ffd5b823567ffffffffffffffff811115614765575f5ffd5b8301601f81018513614775575f5ffd5b803567ffffffffffffffff81111561478b575f5ffd5b8560208260051b840101111561479f575f5ffd5b6020919091019590945092505050565b5f8151808452602084019350602083015f5b828110156147df5781518652602095860195909101906001016147c1565b5093949350505050565b604081525f6147fb60408301856147af565b8281036020840152613e3681856147af565b5f5f6020838503121561481e575f5ffd5b823567ffffffffffffffff811115614834575f5ffd5b614840858286016144de565b90969095509350505050565b5f6020828403121561485c575f5ffd5b815161136a81614705565b6001600160a01b038616815284602082015283604082015260806060820152816080820152818360a08301375f81830160a090810191909152601f909201601f19160101949350505050565b5f602082840312156148c3575f5ffd5b5051919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b818103818111156110ec576110ec6148ca565b808201808211156110ec576110ec6148ca565b80820281158282048414176110ec576110ec6148ca565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f8261496f5761496f614934565b500490565b5f610100820190506fffffffffffffffffffffffffffffffff83511682526fffffffffffffffffffffffffffffffff60208401511660208301526fffffffffffffffffffffffffffffffff604084015116604083015260608301516149ed60608401826fffffffffffffffffffffffffffffffff169052565b506080830151614a1160808401826fffffffffffffffffffffffffffffffff169052565b5060a0830151614a3560a08401826fffffffffffffffffffffffffffffffff169052565b5060c0830151614a5960c08401826fffffffffffffffffffffffffffffffff169052565b5060e0830151614a7d60e08401826fffffffffffffffffffffffffffffffff169052565b5092915050565b600181811c90821680614a9857607f821691505b602082108103614acf577f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b50919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f60208284031215614b3f575f5ffd5b815167ffffffffffffffff811115614b55575f5ffd5b8201601f81018413614b65575f5ffd5b805167ffffffffffffffff811115614b7f57614b7f614b02565b604051601f19603f601f19601f8501160116810181811067ffffffffffffffff82111715614baf57614baf614b02565b604052818152828201602001861015614bc6575f5ffd5b8160208401602083015e5f91810160200191909152949350505050565b601f8211156115eb57828211156115eb57805f5260205f20601f840160051c6020851015614c0e57505f5b90810190601f840160051c035f5b81811015614c31575f83820155600101614c1c565b505050505050565b815167ffffffffffffffff811115614c5357614c53614b02565b614c6781614c618454614a84565b84614be3565b6020601f821160018114614c99575f8315614c825750848201515b5f19600385901b1c1916600184901b178455611042565b5f84815260208120601f198516915b82811015614cc85787850151825560209485019460019092019101614ca8565b5084821015614ce557868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b5f60208284031215614d04575f5ffd5b815160ff8116811461136a575f5ffd5b6001815b6001841115614d4f57808504811115614d3357614d336148ca565b6001841615614d4157908102905b60019390931c928002614d18565b935093915050565b5f82614d65575060016110ec565b81614d7157505f6110ec565b8160018114614d875760028114614d9157614dad565b60019150506110ec565b60ff841115614da257614da26148ca565b50506001821b6110ec565b5060208310610133831016604e8410600b8410161715614dd0575081810a6110ec565b614ddc5f198484614d14565b805f1904821115613d9d57613d9d6148ca565b5f61136a60ff841683614d57565b5f60208284031215614e0d575f5ffd5b815161136a816144ca565b67ffffffffffffffff831115614e3057614e30614b02565b614e4483614e3e8354614a84565b83614be3565b5f601f841160018114614e75575f8515614e5e5750838201355b5f19600387901b1c1916600186901b178355611042565b5f83815260208120601f198716915b82811015614ea45786850135825560209485019460019092019101614e84565b5086821015614ec0575f1960f88860031b161c19848701351681555b505060018560011b0183555050505050565b5f5f5f60608486031215614ee4575f5ffd5b8351602085015160408601519194509250614efe81614705565b809150509250925092565b5f81518060208401855e5f93019283525090919050565b7f537461626c65563220414d4d202d20000000000000000000000000000000000081525f614f51600f830185614f09565b7f2f000000000000000000000000000000000000000000000000000000000000008152613e366001820185614f09565b7f73414d4d56322d0000000000000000000000000000000000000000000000000081525f614f516007830185614f09565b5f60208284031215614fc2575f5ffd5b813563ffffffff8116811461136a575f5ffd5b61ffff82811682821603908111156110ec576110ec6148ca565b61ffff81811683821601908111156110ec576110ec6148ca565b5f61ffff83168061501c5761501c614934565b8061ffff84160691505092915050565b64ffffffffff81811683821601908111156110ec576110ec6148ca56fe60e060405234801561000f575f5ffd5b5060405161036838038061036883398101604081905261002e91610064565b336080526001600160a01b0391821660a0521660c052610095565b80516001600160a01b038116811461005f575f5ffd5b919050565b5f5f60408385031215610075575f5ffd5b61007e83610049565b915061008c60208401610049565b90509250929050565b60805160a05160c0516102ab6100bd5f395f61011801525f60d101525f605a01526102ab5ff3fe608060405234801561000f575f5ffd5b5060043610610029575f3560e01c8063533cf5ce1461002d575b5f5ffd5b61004061003b36600461022b565b610042565b005b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146100b1576040517f6f61f64100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81156100f8576100f873ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168484610144565b801561013f5761013f73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168483610144565b505050565b61015183838360016101a3565b61013f576040517f5274afe700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8416600482015260240160405180910390fd5b6040517fa9059cbb000000000000000000000000000000000000000000000000000000005f81815273ffffffffffffffffffffffffffffffffffffffff8616600452602485905291602083604481808b5af1925060015f5114831661021f578383151615610213573d5f823e3d81fd5b5f873b113d1516831692505b60405250949350505050565b5f5f5f6060848603121561023d575f5ffd5b833573ffffffffffffffffffffffffffffffffffffffff81168114610260575f5ffd5b9560208501359550604090940135939250505056fea26469706673582212207519fe77d60fa2befaa943fe4f040b0f82abdb9264e6f95e7af68108cee501e564736f6c63430008240033a2646970667358221220c44780aa04b481bff35f6e43d6d561fdb2f8fde74b2f0d2839a586c497a0e40264736f6c63430008240033","recompiledBytecode":"0x608060405234801561000f575f5ffd5b5060043610610346575f3560e01c8063648da859116101be578063bc25cf77116100fe578063c5884ad11161009e578063ee39e7a011610079578063ee39e7a014610856578063f140a35a1461085e578063fc9654ab14610871578063fff6cae914610879575f5ffd5b8063c5884ad1146107dc578063d21220a71461080b578063dd62ed3e1461081e575f5ffd5b8063c245febc116100d9578063c245febc146107a0578063c45a0155146107ab578063c47f0027146107be578063c5700a02146107d1575f5ffd5b8063bc25cf7714610777578063bda39cad1461078a578063bf944dbc14610795575f5ffd5b806395d89b4111610169578063a1ac4d1311610144578063a1ac4d131461071d578063a9059cbb1461073e578063b84c824614610751578063b95d88f814610764575f5ffd5b806395d89b41146106ce5780639d63848a146106d65780639f767c88146106fc575f5ffd5b806378273aca1161019957806378273aca14610687578063883bdbfd1461069a57806389afcb44146106bb575f5ffd5b8063648da859146106255780636a6278421461064c57806370a082311461065f575f5ffd5b8063252c09d7116102895780633358095911610234578063485cc9551161020f578063485cc955146105da5780634983f2f5146105ed5780634d5a9f8a146105f95780635a76f25e1461061a575f5ffd5b80633358095914610569578063392f37e91461057c578063443cb4bc146105cf575f5ffd5b8063313ce56711610264578063313ce5671461053c57806332148f671461054b57806332c0defd1461055e575f5ffd5b8063252c09d7146104e157806325d2a3f3146105165780632dbfa73514610529575f5ffd5b8063119c4e9f116102f45780631a4211dc116102cf5780631a4211dc1461045a5780631df8c717146104a5578063205aabf1146104ad57806323b872dd146104ce575f5ffd5b8063119c4e9f1461041757806315a0ea6a1461042a57806318160ddd14610452575f5ffd5b8063095ea7b311610324578063095ea7b3146103a85780630dfe1681146103cb5780630ea099c1146103f6575f5ffd5b8063022c0d9f1461034a57806306fdde031461035f5780630902f1ac1461037d575b5f5ffd5b61035d61035836600461451c565b610881565b005b610367611049565b6040516103749190614581565b60405180910390f35b6203000b546203000c546203000d545b60408051938452602084019290925290820152606001610374565b6103bb6103b63660046145b6565b6110d9565b6040519015158152602001610374565b6007546103de906001600160a01b031681565b6040516001600160a01b039091168152602001610374565b6104096104043660046145e0565b6110f2565b604051908152602001610374565b61040961042536600461460e565b611175565b61043d610438366004614648565b611280565b60408051928352602083019190915201610374565b600254610409565b62030008546104809061ffff808216916201000081048216916401000000009091041683565b6040805161ffff94851681529284166020840152921691810191909152606001610374565b61038d6112d5565b6104096104bb366004614648565b620300136020525f908152604090205481565b6103bb6104dc366004614663565b61134c565b6104f46104ef3660046146a1565b611371565b6040805163ffffffff9094168452602084019290925290820152606001610374565b61043d610524366004614648565b6113ce565b61043d6105373660046146b8565b6114af565b60405160128152602001610374565b61035d6105593660046146e4565b61157c565b610409620300105481565b6009546103de906001600160a01b031681565b62030009546203000a546203000b546203000c546007546008546040805196875260208701959095529385019290925260608401526001600160a01b0390811660808401521660a082015260c001610374565b6104096203000b5481565b61035d6105e83660046146b8565b6115f0565b6104096402540be40081565b610409610607366004614648565b620300146020525f908152604090205481565b6104096203000c5481565b6104097f56325f535441424c45000000000000000000000000000000000000000000000081565b61040961065a366004614648565b611930565b61040961066d366004614648565b6001600160a01b03165f9081526020819052604090205490565b61035d610695366004614712565b611bc2565b6106ad6106a836600461473e565b611c8d565b6040516103749291906147e9565b61043d6106c9366004614648565b611cbb565b610367611fca565b600754600854604080516001600160a01b03938416815292909116602083015201610374565b61040961070a366004614648565b620300126020525f908152604090205481565b61040961072b366004614648565b620300156020525f908152604090205481565b6103bb61074c3660046145b6565b611fd9565b61035d61075f36600461480d565b611fe6565b6104096107723660046145e0565b6120b1565b61035d610785366004614648565b612249565b610409620300115481565b6104096203000e5481565b6104096203000f5481565b600a546103de906001600160a01b031681565b61035d6107cc36600461480d565b6123b6565b6104096203000d5481565b6103bb6107ea3660046146b8565b6203001660209081525f928352604080842090915290825290205460ff1681565b6008546103de906001600160a01b031681565b61040961082c3660046146b8565b6001600160a01b039182165f90815260016020908152604080832093909416825291909152205490565b610409612481565b61040961086c3660046145e0565b6124ca565b610409603c81565b61035d6125d6565b610889612729565b600a5f9054906101000a90046001600160a01b03166001600160a01b031663b187bd266040518163ffffffff1660e01b8152600401602060405180830381865afa1580156108d9573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108fd919061484c565b15610934576040517f1309a56300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84158015610940575083155b15610977576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6203000b546203000c5481871015806109905750808610155b156109c7576040517fbb55fd2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6007546008545f9182916001600160a01b0391821691908116908916821480610a015750806001600160a01b0316896001600160a01b0316145b15610a38576040517f290fa18800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8a15610a5257610a526001600160a01b0383168a8d612757565b8915610a6c57610a6c6001600160a01b0382168a8c612757565b8615610aed576040517f9a7bff790000000000000000000000000000000000000000000000000000000081526001600160a01b038a1690639a7bff7990610abf9033908f908f908e908e90600401614867565b5f604051808303815f87803b158015610ad6575f5ffd5b505af1158015610ae8573d5f5f3e3d5ffd5b505050505b6040516370a0823160e01b81523060048201526001600160a01b038316906370a0823190602401602060405180830381865afa158015610b2f573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b5391906148b3565b6040516370a0823160e01b81523060048201529094506001600160a01b038216906370a0823190602401602060405180830381865afa158015610b98573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610bbc91906148b3565b925050505f8985610bcd91906148f7565b8311610bd9575f610bed565b610be38a866148f7565b610bed90846148f7565b90505f610bfa8a866148f7565b8311610c06575f610c1a565b610c108a866148f7565b610c1a90846148f7565b905081158015610c28575080155b15610c5f576040517f098fb56100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051610100810182525f80825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810191909152610ca98c8461490a565b6fffffffffffffffffffffffffffffffff166040820152610cca8b8361490a565b6fffffffffffffffffffffffffffffffff1660608201526007546008546001600160a01b0391821691165f8080610d0388888e8e6127aa565b919450925090508715610d78575f612710610d1e858b61491d565b610d289190614961565b9050610d3381612863565b6fffffffffffffffffffffffffffffffff81168752612710610d55848b61491d565b610d5f9190614961565b6fffffffffffffffffffffffffffffffff1660c0880152505b8615610de9575f612710610d8c858a61491d565b610d969190614961565b9050610da181612910565b6fffffffffffffffffffffffffffffffff81166020880152612710610dc6848a61491d565b610dd09190614961565b6fffffffffffffffffffffffffffffffff1660e0880152505b8015610e195760408601516fffffffffffffffffffffffffffffffff908116608088015260608701511660a08701525b6040516370a0823160e01b81523060048201526001600160a01b038616906370a0823190602401602060405180830381865afa158015610e5b573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e7f91906148b3565b6040516370a0823160e01b8152306004820152909a506001600160a01b038516906370a0823190602401602060405180830381865afa158015610ec4573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ee891906148b3565b9850610ef48c8c6129b6565b610efe8b8b6129b6565b1015610f36576040517fa932492f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600a546040517f5310a4210000000000000000000000000000000000000000000000000000000081526001600160a01b0390911690635310a42190610f7f908990600401614974565b5f604051808303815f87803b158015610f96575f5ffd5b505af1158015610fa8573d5f5f3e3d5ffd5b50505050505050505050610fbe84848888612a5f565b60408051838152602081018390529081018c9052606081018b90526001600160a01b038a169033907fb3e2773606abfd36b5bd91394b3a54d1398336c65005baf7bf7a05efeffaf75b9060800160405180910390a350505050505061104260017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b5050505050565b60606005805461105890614a84565b80601f016020809104026020016040519081016040528092919081815260200182805461108490614a84565b80156110cf5780601f106110a6576101008083540402835291602001916110cf565b820191905f5260205f20905b8154815290600101906020018083116110b257829003601f168201915b5050505050905090565b5f336110e6818585612b44565b60019150505b92915050565b6203000b546203000c546007545f929190839081906001600160a01b03878116911614611120575f87611123565b865f5b915091505f611134838387876127aa565b505090506127108189611147919061491d565b6111519190614961565b61115b90896148f7565b975061116988888787612b51565b98975050505050505050565b6007545f90819081906001600160a01b03878116911614611197575f8761119a565b865f5b600a546040517fdf29d5bb0000000000000000000000000000000000000000000000000000000081523060048201525f602482015260448101849052606481018390526084810189905260a48101889052929450909250612710916001600160a01b039091169063df29d5bb9060c401602060405180830381865afa158015611225573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061124991906148b3565b611253908961491d565b61125d9190614961565b61126790886148f7565b965061127587878787612b51565b979650505050505050565b5f806001600160a01b0383166112c2576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6112cc3384612c93565b91509150915091565b6203000e546203000f54425f80806112fc6203000b546203000c546203000d549192909190565b925092509250838114611344575f61131482866148f7565b9050611320818561491d565b61132a908861490a565b9650611336818461491d565b611340908761490a565b9550505b505050909192565b5f33611359858285612dd0565b611364858585612e5f565b60019150505b9392505050565b5f808080600b8561ffff811061138957611389614ad5565b6040805160608101825260039290920292909201805463ffffffff16808352600182015460208401819052600290920154929093018290529197919650945092505050565b6001600160a01b0381165f908152620300146020908152604080832054620300158352818420549284905292205480156114a9576001600160a01b0384165f9081526203001260205260409020546203001054670de0b6b3a764000091611434916148f7565b61143e908361491d565b6114489190614961565b611452908461490a565b6001600160a01b0385165f9081526203001360205260409020546203001154919450670de0b6b3a76400009161148891906148f7565b611492908361491d565b61149c9190614961565b6114a6908361490a565b91505b50915091565b5f806001600160a01b0383166114f1576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336001600160a01b0385161480159061152f57506001600160a01b0384165f908152620300166020908152604080832033845290915290205460ff16155b15611566576040517fea8e4eb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6115708484612c93565b915091505b9250929050565b6203000854640100000000900461ffff165f611599600b84612eee565b90508161ffff168161ffff16146115eb576040805161ffff80851682528316602082015233917ff0b7b7d1cdf542f5660a7879f0cac17375fdcf984af4a6d499a9daedacb24c58910160405180910390a25b505050565b600a546001600160a01b031615611633576040517f154c51b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600a8054337fffffffffffffffffffffffff0000000000000000000000000000000000000000918216179091556008805482166001600160a01b03848116919091179091556007805490921690841617905560405182908290611695906144bd565b6001600160a01b03928316815291166020820152604001604051809103905ff0801580156116c5573d5f5f3e3d5ffd5b5060095f6101000a8154816001600160a01b0302191690836001600160a01b031602179055505f826001600160a01b03166395d89b416040518163ffffffff1660e01b81526004015f60405180830381865afa158015611727573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261174e9190810190614b2f565b90505f826001600160a01b03166395d89b416040518163ffffffff1660e01b81526004015f60405180830381865afa15801561178c573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526117b39190810190614b2f565b90506117bf8282613005565b6005906117cc9082614c39565b506117d78282613031565b6006906117e49082614c39565b50836001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611821573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118459190614cf4565b61185090600a614def565b6203000981905550826001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611894573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118b89190614cf4565b6118c390600a614def565b6203000a55600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000164263ffffffff161790556203000880547fffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ffff166401000100001790555b50505050565b5f611939612729565b6203000b546203000c546007546040516370a0823160e01b81523060048201525f916001600160a01b0316906370a0823190602401602060405180830381865afa158015611989573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119ad91906148b3565b6008546040516370a0823160e01b81523060048201529192505f916001600160a01b03909116906370a0823190602401602060405180830381865afa1580156119f8573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611a1c91906148b3565b90505f611a2985846148f7565b90505f611a3685846148f7565b90505f611a4260025490565b9050805f03611ac4576103e8611a60611a5b848661491d565b613046565b611a6a91906148f7565b9750611a7960016103e86131ab565b611a8383836131fc565b6103e8881015611abf576040517fd226f9d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611b31565b611af687611ad2838661491d565b611adc9190614961565b87611ae7848661491d565b611af19190614961565b6132bc565b9750875f03611b31576040517fd226f9d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611b3b89896131ab565b611b4785858989612a5f565b60408051848152602081018490526001600160a01b038b169133917f2f00e3cdd69a77be7ed215ec7b2a36784dd158f921fca79ac29deffa353fe6ee910160405180910390a350505050505050611bbd60017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b919050565b6001600160a01b038216611c02576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b335f81815262030016602090815260408083206001600160a01b0387168085529083529281902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001686151590811790915590519081529192917f63484c3756a6c7d95f131879210268006b60e58057de5db75f3a8c91c7869ebf910160405180910390a35050565b6060805f5f611c9a6112d5565b509092509050611cae600b878785856132cb565b9350935050509250929050565b5f5f611cc5612729565b6203000b546203000c546007546008546040516370a0823160e01b81523060048201526001600160a01b0392831692909116905f9083906370a0823190602401602060405180830381865afa158015611d20573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611d4491906148b3565b6040516370a0823160e01b81523060048201529091505f906001600160a01b038416906370a0823190602401602060405180830381865afa158015611d8b573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611daf91906148b3565b305f908152602081905260409020546002549192509080611dd0858461491d565b611dda9190614961565b995080611de7848461491d565b611df19190614961565b9850891580611dfe575088155b15611e35576040517f749383ad00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611e3f30836133e6565b611e536001600160a01b0387168c8c612757565b611e676001600160a01b0386168c8b612757565b6040516370a0823160e01b81523060048201526001600160a01b038716906370a0823190602401602060405180830381865afa158015611ea9573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611ecd91906148b3565b6040516370a0823160e01b81523060048201529094506001600160a01b038616906370a0823190602401602060405180830381865afa158015611f12573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f3691906148b3565b9250611f428484613433565b611f4e84848a8a612a5f565b604080518b8152602081018b90526001600160a01b038d169133917f5d624aa9c148153ab3446c1b154f660ee7701e549fe9b62dab7171b1c80e6fa2910160405180910390a35050505050505050611fc560017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b915091565b60606006805461105890614a84565b5f336110e6818585612e5f565b600a5f9054906101000a90046001600160a01b03166001600160a01b031663b782cc496040518163ffffffff1660e01b8152600401602060405180830381865afa158015612036573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061205a9190614dfd565b6001600160a01b0316336001600160a01b0316146120a4576040517f058a2da800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60066115eb828483614e18565b5f825f036120c057505f6110ec565b6203000b546203000c546007546001600160a01b038581169116146120e557806120e7565b815b851061211f576040517fbb55fd2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f61212c86868585613475565b9050805f03612140575f93505050506110ec565b6007545f9081906001600160a01b0388811691161461216057825f612163565b5f835b600a546040517f11896ad200000000000000000000000000000000000000000000000000000000815230600482015233602482015260448101849052606481018390526084810189905260a481018890529294509092505f916001600160a01b03909116906311896ad29060c401602060405180830381865afa1580156121ec573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061221091906148b3565b9050612232816122216001876148f7565b61222d846127106148f7565b6135ce565b61223c908561490a565b9998505050505050505050565b612251612729565b6007546008546203000b546040516370a0823160e01b81523060048201526001600160a01b0393841693909216915f919084906370a0823190602401602060405180830381865afa1580156122a8573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906122cc91906148b3565b6122d691906148f7565b905080156122f2576122f26001600160a01b0384168583612757565b6203000c546040516370a0823160e01b81523060048201525f91906001600160a01b038516906370a0823190602401602060405180830381865afa15801561233c573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061236091906148b3565b61236a91906148f7565b90508015612386576123866001600160a01b0384168683612757565b505050506123b360017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b50565b600a5f9054906101000a90046001600160a01b03166001600160a01b031663b782cc496040518163ffffffff1660e01b8152600401602060405180830381865afa158015612406573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061242a9190614dfd565b6001600160a01b0316336001600160a01b031614612474576040517f058a2da800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60056115eb828483614e18565b5f61248a612729565b61249c6203000b546203000c546129b6565b90506124c760017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b90565b6203000b546203000c546007545f929190839081906001600160a01b038781169116146124f8575f876124fb565b865f5b600a546040517fdf29d5bb0000000000000000000000000000000000000000000000000000000081523060048201525f602482015260448101849052606481018390526084810188905260a48101879052929450909250612710916001600160a01b039091169063df29d5bb9060c401602060405180830381865afa158015612586573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906125aa91906148b3565b6125b4908961491d565b6125be9190614961565b6125c890886148f7565b965061127587878686612b51565b6125de612729565b6002545f03612619576040517fbb55fd2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6007546040516370a0823160e01b81523060048201526126fe916001600160a01b0316906370a0823190602401602060405180830381865afa158015612661573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061268591906148b3565b6008546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa1580156126cb573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906126ef91906148b3565b6203000b546203000c54612a5f565b61272760017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b565b61273161367e565b60027f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b61276483838360016136e1565b6115eb576040517f5274afe70000000000000000000000000000000000000000000000000000000081526001600160a01b03841660048201526024015b60405180910390fd5b600a546040517fdb6b39b400000000000000000000000000000000000000000000000000000000815230600482015233602482015260448101869052606481018590526084810184905260a481018390525f91829182916001600160a01b03169063db6b39b49060c401606060405180830381865afa15801561282f573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906128539190614ed2565b9250925092509450945094915050565b805f0361286d5750565b60095460075461288a916001600160a01b03918216911683612757565b5f61289460025490565b6128a683670de0b6b3a764000061491d565b6128b09190614961565b905080156128d15780620300105f8282546128cb919061490a565b90915550505b604080518381525f602082015233917f112c256902bf554b6ed882d2936687aaeb4225e8cd5b51303c90ca6cf43a860291015b60405180910390a25050565b805f0361291a5750565b600954600854612937916001600160a01b03918216911683612757565b5f61294160025490565b61295383670de0b6b3a764000061491d565b61295d9190614961565b9050801561297e5780620300115f828254612978919061490a565b90915550505b604080515f81526020810184905233917f112c256902bf554b6ed882d2936687aaeb4225e8cd5b51303c90ca6cf43a86029101612904565b5f5f620300095484670de0b6b3a76400006129d1919061491d565b6129db9190614961565b90505f6203000a5484670de0b6b3a76400006129f7919061491d565b612a019190614961565b90505f612a178383670de0b6b3a76400006135ce565b90505f612a2d8384670de0b6b3a76400006135ce565b612a408586670de0b6b3a76400006135ce565b612a4a919061490a565b90506112758282670de0b6b3a76400006135ce565b6203000d5442905f90612a7290836148f7565b90505f81118015612a8257508315155b8015612a8d57508215155b15612ad657612a9c818561491d565b6203000e5f828254612aae919061490a565b90915550612abe9050818461491d565b6203000f5f828254612ad0919061490a565b90915550505b6203000e546203000f54612aee91600b91603c61375c565b6203000b8690556203000c8590556203000d82905560408051878152602081018790527fcf2aa50876cdfbb541206f89af0ee78d44a2abf8d328e37fa4917f982149848a910160405180910390a1505050505050565b6115eb838383600161391f565b5f5f612b5d84846129b6565b6203000954909150612b7785670de0b6b3a764000061491d565b612b819190614961565b6203000a54909450612b9b84670de0b6b3a764000061491d565b612ba59190614961565b6007549093505f9081906001600160a01b03888116911614612bc8578486612bcb565b85855b60075491935091506001600160a01b03888116911614612c0b576203000a54612bfc89670de0b6b3a764000061491d565b612c069190614961565b612c2c565b6203000954612c2289670de0b6b3a764000061491d565b612c2c9190614961565b97505f612c43612c3c848b61490a565b8584613a23565b612c4d90836148f7565b600754909150670de0b6b3a7640000906001600160a01b038a8116911614612c79576203000954612c7f565b6203000a545b612c89908361491d565b61223c9190614961565b5f5f612c9e84613b44565b50506001600160a01b0382165f908152620300146020908152604080832054620300159092529091205481151580612cd557505f81115b15611575576001600160a01b038481165f9081526203001460209081526040808320839055620300159091528082209190915560095490517f533cf5ce0000000000000000000000000000000000000000000000000000000081528583166004820152602481018590526044810184905291169063533cf5ce906064015f604051808303815f87803b158015612d69575f5ffd5b505af1158015612d7b573d5f5f3e3d5ffd5b505060408051858152602081018590526001600160a01b0380881694508816925033917fcd5e4f020ddad29434c2200a9edf2f8d7ec30f0d787f03b528ab7279aab0acbe910160405180910390a49250929050565b6001600160a01b038381165f908152600160209081526040808320938616835292905220545f1981101561192a5781811015612e51576040517ffb8f41b20000000000000000000000000000000000000000000000000000000081526001600160a01b038416600482015260248101829052604481018390526064016127a1565b61192a84848484035f61391f565b6001600160a01b038316612ea1576040517f96c6fd1e0000000000000000000000000000000000000000000000000000000081525f60048201526024016127a1565b6001600160a01b038216612ee3576040517fec442f050000000000000000000000000000000000000000000000000000000081525f60048201526024016127a1565b6115eb838383613cb0565b6202fffd8201545f9061ffff64010000000090910481169083168110612f155790506110ec565b805b8361ffff168161ffff161015612fc45760018561ffff808416908110612f3f57612f3f614ad5565b6003020180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff9290921691909117905560018561ffff838116908110612f8e57612f8e614ad5565b60030201600101819055506001855f018261ffff1661ffff8110612fb457612fb4614ad5565b6003020160020155600101612f17565b5050506202fffd9190910180547fffffffffffffffffffffffffffffffffffffffffffffffffffff0000ffffffff1664010000000061ffff84160217905590565b6060828260405160200161301a929190614f20565b604051602081830303815290604052905092915050565b6060828260405160200161301a929190614f81565b5f60018211613053575090565b81600170010000000000000000000000000000000082106130795760809190911c9060401b5b6801000000000000000082106130945760409190911c9060201b5b64010000000082106130ab5760209190911c9060101b5b6201000082106130c05760109190911c9060081b5b61010082106130d45760089190911c9060041b5b601082106130e75760049190911c9060021b5b600482106130f35760011b5b600302600190811c9081858161310b5761310b614934565b048201901c9050600181858161312357613123614934565b048201901c9050600181858161313b5761313b614934565b048201901c9050600181858161315357613153614934565b048201901c9050600181858161316b5761316b614934565b048201901c9050600181858161318357613183614934565b048201901c90506131a281858161319c5761319c614934565b04821190565b90039392505050565b6001600160a01b0382166131ed576040517fec442f050000000000000000000000000000000000000000000000000000000081525f60048201526024016127a1565b6131f85f8383613cb0565b5050565b6203000a5461321382670de0b6b3a764000061491d565b61321d9190614961565b620300095461323484670de0b6b3a764000061491d565b61323e9190614961565b14613275576040517f0a04d7fa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6402540be40061328583836129b6565b116131f8576040517f438d3ade00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f82821882841002821861136a565b60608042858067ffffffffffffffff8111156132e9576132e9614b02565b604051908082528060200260200182016040528015613312578160200160208202803683370190505b5093508067ffffffffffffffff81111561332e5761332e614b02565b604051908082528060200260200182016040528015613357578160200160208202803683370190505b5092505f5b818110156133d9576133978a848b8b8581811061337b5761337b614ad5565b90506020020160208101906133909190614fb2565b8a8a613ceb565b8683815181106133a9576133a9614ad5565b602002602001018684815181106133c2576133c2614ad5565b60209081029190910101919091525260010161335c565b5050509550959350505050565b6001600160a01b038216613428576040517f96c6fd1e0000000000000000000000000000000000000000000000000000000081525f60048201526024016127a1565b6131f8825f83613cb0565b61343d82826129b6565b5f036131f8576040517f7d06c0c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f5f61348184846129b6565b620300095490915061349b85670de0b6b3a764000061491d565b6134a59190614961565b6203000a549094506134bf84670de0b6b3a764000061491d565b6134c99190614961565b6007549093505f9081906001600160a01b038881169116146134ec5784866134ef565b85855b60075491935091505f9081906001600160a01b038a811691161461351c576203000a546203000954613527565b62030009546203000a545b90925090506135476135418b670de0b6b3a764000061491d565b83613d71565b9950838a10613582576040517fbb55fd2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f6135976135908c876148f7565b8786613a23565b90506135bf826135a786846148f7565b6135b1919061491d565b670de0b6b3a7640000613d71565b9b9a5050505050505050505050565b5f5f5f6135db8686613da5565b91509150815f036135ff578381816135f5576135f5614934565b049250505061136a565b818411613616576136166003851502601118613dc1565b5f848688095f868103871696879004966002600389028118808a02820302808a02820302808a02820302808a02820302808a02820302808a02909103029181900381900460010185841190960395909502919093039390930492909217029150509392505050565b6136aa5f60027f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00613dd2565b15612727576040517f3ee5aeb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517fa9059cbb000000000000000000000000000000000000000000000000000000005f8181526001600160a01b038616600452602485905291602083604481808b5af1925060015f51148316613750578383151615613744573d5f823e3d81fd5b5f873b113d1516831692505b60405250949350505050565b6202fffd840154429061ffff908116905f9087908390811061378057613780614ad5565b600302015463ffffffff90811684031690508381116137a15750505061192a565b6202fffd87015461ffff620100008204811691829164010000000090910416811080156137df57506137d4600183614fd5565b61ffff168461ffff16145b156137f2576137ef826001614fef565b90505b5f816137ff866001614fef565b6138099190615009565b905060405180606001604052808763ffffffff1681526020018a8152602001898152508a5f018261ffff1661ffff811061384557613845614ad5565b82516003919091029190910180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff909216919091178155602082015160018201556040909101516002909101556202fffd8a0180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff8381169190911790915583811690831614613913576202fffd8a0180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ffff166201000061ffff8516021790555b50505050505050505050565b6001600160a01b038416613961576040517fe602df050000000000000000000000000000000000000000000000000000000081525f60048201526024016127a1565b6001600160a01b0383166139a3576040517f94280d620000000000000000000000000000000000000000000000000000000081525f60048201526024016127a1565b6001600160a01b038085165f908152600160209081526040808320938716835292905220829055801561192a57826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92584604051613a1591815260200190565b60405180910390a350505050565b5f805b60ff811015613b11575f613a3a8685613dd9565b905084811015613ab4575f613a65613a5283886148f7565b670de0b6b3a764000061222d8a89613e3f565b9050805f03613aa25785613a8388613a7e88600161490a565b613dd9565b1115613a9e57613a9485600161490a565b935050505061136a565b5060015b613aac818661490a565b945050613b08565b5f613ac2613a5287846148f7565b9050805f03613afa5785821480613ae6575085613ae488613a7e6001896148f7565b105b15613af65784935050505061136a565b5060015b613b0481866148f7565b9450505b50600101613a26565b506040517f6eb5c82100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0381165f908152602081905260409020548015613c77576001600160a01b0382165f9081526203001260209081526040808320805462030013808552928520805462030010546203001154948190559490955282905593613bac85846148f7565b90505f613bb985846148f7565b90508115613c14575f670de0b6b3a7640000613bd5848a61491d565b613bdf9190614961565b6001600160a01b038a165f908152620300146020526040812080549293508392909190613c0d90849061490a565b9091555050505b8015613c6d575f670de0b6b3a7640000613c2e838a61491d565b613c389190614961565b6001600160a01b038a165f908152620300156020526040812080549293508392909190613c6690849061490a565b9091555050505b5050505050505050565b62030010546001600160a01b0383165f908152620300126020908152604080832093909355620300115462030013909152919020555050565b6001600160a01b03831615613cc857613cc883613b44565b6001600160a01b03821615613ce057613ce082613b44565b6115eb838383613ea6565b5f5f8463ffffffff165f03613d04575082905081613d67565b8486035f80613d168a8a858a8a613fe5565b915091508263ffffffff16815f015163ffffffff1603613d46578060200151816040015194509450505050613d67565b613d5e82825f015183602001518460400151876141bf565b90955093505050505b9550959350505050565b5f815f03613d8357613d836012613dc1565b816001840381613d9557613d95614934565b046001018315155b029392505050565b5f805f1983850993909202808410938190039390930393915050565b634e487b715f52806020526024601cfd5b5414919050565b5f5f613dee8484670de0b6b3a76400006135ce565b90505f613e048485670de0b6b3a76400006135ce565b613e178687670de0b6b3a76400006135ce565b613e21919061490a565b9050613e368282670de0b6b3a76400006135ce565b95945050505050565b5f5f613e548384670de0b6b3a76400006135ce565b90505f613e6a8586670de0b6b3a76400006135ce565b9050613e7f8186670de0b6b3a76400006135ce565b613e9c613e8d87600361491d565b84670de0b6b3a76400006135ce565b613e36919061490a565b6001600160a01b038316613ed0578060025f828254613ec5919061490a565b90915550613f599050565b6001600160a01b0383165f9081526020819052604090205481811015613f3b576040517fe450d38c0000000000000000000000000000000000000000000000000000000081526001600160a01b038516600482015260248101829052604481018390526064016127a1565b6001600160a01b0384165f9081526020819052604090209082900390555b6001600160a01b038216613f7557600280548290039055613f93565b6001600160a01b0382165f9081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051613fd891815260200190565b60405180910390a3505050565b61400c60405180606001604052805f63ffffffff1681526020015f81526020015f81525090565b61403360405180606001604052805f63ffffffff1681526020015f81526020015f81525090565b6202fffd87015461ffff9081169088908290811061405357614053614ad5565b6040805160608101825260039290920292909201805463ffffffff168083526001820154602084015260029091015492820192909252935061409790889088614240565b156140ee57825163ffffffff8088169116036140b65750819050613d67565b5f5f6140c5858a89898c6141bf565b6040805160608101825263ffffffff8c16815260208101939093528201529350613d6792505050565b6202fffd880154889062010000900461ffff1661410c836001614fef565b6141169190615009565b61ffff1661ffff811061412b5761412b614ad5565b6040805160608101825260039290920292909201805463ffffffff168083526001820154602084015260029091015492820192909252935061416f90889088614240565b6141a5576040517fc02e462000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6141b088888861430e565b92509250509550959350505050565b845160208601515f91829163ffffffff8289038116928603169083906141e590896148f7565b90505f8a60400151886141f891906148f7565b90506142058284866135ce565b8b60200151614214919061490a565b95506142218184866135ce565b8b60400151614230919061490a565b9450505050509550959350505050565b5f8363ffffffff168363ffffffff161115801561426957508363ffffffff168263ffffffff1611155b15614285578163ffffffff168363ffffffff161115905061136a565b5f8463ffffffff168463ffffffff16116142b3576142ae63ffffffff851664010000000061502c565b6142bb565b8363ffffffff165b64ffffffffff1690505f8563ffffffff168463ffffffff16116142f2576142ed63ffffffff851664010000000061502c565b6142fa565b8363ffffffff165b64ffffffffff169091111595945050505050565b61433560405180606001604052805f63ffffffff1681526020015f81526020015f81525090565b61435c60405180606001604052805f63ffffffff1681526020015f81526020015f81525090565b6202fffd85015461ffff62010000820481169187915f918491166001018161438657614386614934565b0690505f1961ffff84168201015b6002818301048361ffff861682816143ae576143ae614934565b0661ffff81106143c0576143c0614ad5565b6040805160608101825260039290920292909201805463ffffffff1682526001808201546020840152600290910154928201929092529750849061ffff87169083018161440f5761440f614934565b0661ffff811061442157614421614ad5565b6040805160608101825260039290920292909201805463ffffffff16825260018101546020830152600201549181019190915287519096505f90614467908b908b614240565b90505f6144788b8b8a5f0151614240565b90508180156144845750805b15614491575050506144b1565b81156144a2578260010194506144a9565b6001830393505b505050614394565b50505050935093915050565b6103688061504a83390190565b6001600160a01b03811681146123b3575f5ffd5b5f5f83601f8401126144ee575f5ffd5b50813567ffffffffffffffff811115614505575f5ffd5b602083019150836020828501011115611575575f5ffd5b5f5f5f5f5f60808688031215614530575f5ffd5b85359450602086013593506040860135614549816144ca565b9250606086013567ffffffffffffffff811115614564575f5ffd5b614570888289016144de565b969995985093965092949392505050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b5f5f604083850312156145c7575f5ffd5b82356145d2816144ca565b946020939093013593505050565b5f5f604083850312156145f1575f5ffd5b823591506020830135614603816144ca565b809150509250929050565b5f5f5f5f60808587031215614621575f5ffd5b843593506020850135614633816144ca565b93969395505050506040820135916060013590565b5f60208284031215614658575f5ffd5b813561136a816144ca565b5f5f5f60608486031215614675575f5ffd5b8335614680816144ca565b92506020840135614690816144ca565b929592945050506040919091013590565b5f602082840312156146b1575f5ffd5b5035919050565b5f5f604083850312156146c9575f5ffd5b82356146d4816144ca565b91506020830135614603816144ca565b5f602082840312156146f4575f5ffd5b813561ffff8116811461136a575f5ffd5b80151581146123b3575f5ffd5b5f5f60408385031215614723575f5ffd5b823561472e816144ca565b9150602083013561460381614705565b5f5f6020838503121561474f575f5ffd5b823567ffffffffffffffff811115614765575f5ffd5b8301601f81018513614775575f5ffd5b803567ffffffffffffffff81111561478b575f5ffd5b8560208260051b840101111561479f575f5ffd5b6020919091019590945092505050565b5f8151808452602084019350602083015f5b828110156147df5781518652602095860195909101906001016147c1565b5093949350505050565b604081525f6147fb60408301856147af565b8281036020840152613e3681856147af565b5f5f6020838503121561481e575f5ffd5b823567ffffffffffffffff811115614834575f5ffd5b614840858286016144de565b90969095509350505050565b5f6020828403121561485c575f5ffd5b815161136a81614705565b6001600160a01b038616815284602082015283604082015260806060820152816080820152818360a08301375f81830160a090810191909152601f909201601f19160101949350505050565b5f602082840312156148c3575f5ffd5b5051919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b818103818111156110ec576110ec6148ca565b808201808211156110ec576110ec6148ca565b80820281158282048414176110ec576110ec6148ca565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f8261496f5761496f614934565b500490565b5f610100820190506fffffffffffffffffffffffffffffffff83511682526fffffffffffffffffffffffffffffffff60208401511660208301526fffffffffffffffffffffffffffffffff604084015116604083015260608301516149ed60608401826fffffffffffffffffffffffffffffffff169052565b506080830151614a1160808401826fffffffffffffffffffffffffffffffff169052565b5060a0830151614a3560a08401826fffffffffffffffffffffffffffffffff169052565b5060c0830151614a5960c08401826fffffffffffffffffffffffffffffffff169052565b5060e0830151614a7d60e08401826fffffffffffffffffffffffffffffffff169052565b5092915050565b600181811c90821680614a9857607f821691505b602082108103614acf577f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b50919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f60208284031215614b3f575f5ffd5b815167ffffffffffffffff811115614b55575f5ffd5b8201601f81018413614b65575f5ffd5b805167ffffffffffffffff811115614b7f57614b7f614b02565b604051601f19603f601f19601f8501160116810181811067ffffffffffffffff82111715614baf57614baf614b02565b604052818152828201602001861015614bc6575f5ffd5b8160208401602083015e5f91810160200191909152949350505050565b601f8211156115eb57828211156115eb57805f5260205f20601f840160051c6020851015614c0e57505f5b90810190601f840160051c035f5b81811015614c31575f83820155600101614c1c565b505050505050565b815167ffffffffffffffff811115614c5357614c53614b02565b614c6781614c618454614a84565b84614be3565b6020601f821160018114614c99575f8315614c825750848201515b5f19600385901b1c1916600184901b178455611042565b5f84815260208120601f198516915b82811015614cc85787850151825560209485019460019092019101614ca8565b5084821015614ce557868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b5f60208284031215614d04575f5ffd5b815160ff8116811461136a575f5ffd5b6001815b6001841115614d4f57808504811115614d3357614d336148ca565b6001841615614d4157908102905b60019390931c928002614d18565b935093915050565b5f82614d65575060016110ec565b81614d7157505f6110ec565b8160018114614d875760028114614d9157614dad565b60019150506110ec565b60ff841115614da257614da26148ca565b50506001821b6110ec565b5060208310610133831016604e8410600b8410161715614dd0575081810a6110ec565b614ddc5f198484614d14565b805f1904821115613d9d57613d9d6148ca565b5f61136a60ff841683614d57565b5f60208284031215614e0d575f5ffd5b815161136a816144ca565b67ffffffffffffffff831115614e3057614e30614b02565b614e4483614e3e8354614a84565b83614be3565b5f601f841160018114614e75575f8515614e5e5750838201355b5f19600387901b1c1916600186901b178355611042565b5f83815260208120601f198716915b82811015614ea45786850135825560209485019460019092019101614e84565b5086821015614ec0575f1960f88860031b161c19848701351681555b505060018560011b0183555050505050565b5f5f5f60608486031215614ee4575f5ffd5b8351602085015160408601519194509250614efe81614705565b809150509250925092565b5f81518060208401855e5f93019283525090919050565b7f537461626c65563220414d4d202d20000000000000000000000000000000000081525f614f51600f830185614f09565b7f2f000000000000000000000000000000000000000000000000000000000000008152613e366001820185614f09565b7f73414d4d56322d0000000000000000000000000000000000000000000000000081525f614f516007830185614f09565b5f60208284031215614fc2575f5ffd5b813563ffffffff8116811461136a575f5ffd5b61ffff82811682821603908111156110ec576110ec6148ca565b61ffff81811683821601908111156110ec576110ec6148ca565b5f61ffff83168061501c5761501c614934565b8061ffff84160691505092915050565b64ffffffffff81811683821601908111156110ec576110ec6148ca56fe60e060405234801561000f575f5ffd5b5060405161036838038061036883398101604081905261002e91610064565b336080526001600160a01b0391821660a0521660c052610095565b80516001600160a01b038116811461005f575f5ffd5b919050565b5f5f60408385031215610075575f5ffd5b61007e83610049565b915061008c60208401610049565b90509250929050565b60805160a05160c0516102ab6100bd5f395f61011801525f60d101525f605a01526102ab5ff3fe608060405234801561000f575f5ffd5b5060043610610029575f3560e01c8063533cf5ce1461002d575b5f5ffd5b61004061003b36600461022b565b610042565b005b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146100b1576040517f6f61f64100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81156100f8576100f873ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168484610144565b801561013f5761013f73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168483610144565b505050565b61015183838360016101a3565b61013f576040517f5274afe700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8416600482015260240160405180910390fd5b6040517fa9059cbb000000000000000000000000000000000000000000000000000000005f81815273ffffffffffffffffffffffffffffffffffffffff8616600452602485905291602083604481808b5af1925060015f5114831661021f578383151615610213573d5f823e3d81fd5b5f873b113d1516831692505b60405250949350505050565b5f5f5f6060848603121561023d575f5ffd5b833573ffffffffffffffffffffffffffffffffffffffff81168114610260575f5ffd5b9560208501359550604090940135939250505056fea2646970667358221220eeabba3bd98e978db119b83233dcf1a15cbc1751f5b6fdcc907308b07b33330264736f6c63430008240033a2646970667358221220aa9bbd0570a5d863052798f5e72b7cb02066916c003643151160fd218424ee5f64736f6c63430008240033","sourceMap":"362:5174:8:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5112:3053:6;;;;;;:::i;:::-;;:::i;:::-;;24340:84;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;22002:214;22131:8;;22157;;22193:18;;22002:214;;;;1999:25:24;;;2055:2;2040:18;;2033:34;;;;2083:18;;;2076:34;1987:2;1972:18;22002:214:6;1797:319:24;3902:186:13;;;;;;:::i;:::-;;:::i;:::-;;;2658:14:24;;2651:22;2633:41;;2621:2;2606:18;3902:186:13;2493:187:24;2027:21:6;;;;;-1:-1:-1;;;;;2027:21:6;;;;;;-1:-1:-1;;;;;2849:55:24;;;2831:74;;2819:2;2804:18;2027:21:6;2685:226:24;22816:523:6;;;;;;:::i;:::-;;:::i;:::-;;;3434:25:24;;;3422:2;3407:18;22816:523:6;3288:177:24;20705:496:6;;;;;;:::i;:::-;;:::i;4006:183::-;;;;;;:::i;:::-;;:::i;:::-;;;;4509:25:24;;;4565:2;4550:18;;4543:34;;;;4482:18;4006:183:6;4335:248:24;2803:97:13;2881:12;;2803:97;;2301:53:6;;;;;;;;;;;;;;;;;;;;;;;;;;;4814:6:24;4802:19;;;4784:38;;4858:19;;;4853:2;4838:18;;4831:47;4914:19;;4894:18;;;4887:47;;;;4772:2;4757:18;2301:53:6;4588:352:24;21229:745:6;;;:::i;3009:47::-;;;;;;:::i;:::-;;;;;;;;;;;;;;4680:244:13;;;;;;:::i;:::-;;:::i;20331:346:6:-;;;;;;:::i;:::-;;:::i;:::-;;;;5919:10:24;5907:23;;;5889:42;;5962:2;5947:18;;5940:34;;;;5990:18;;;5983:34;5877:2;5862:18;20331:346:6;5689:334:24;19162:402:6;;;;;;:::i;:::-;;:::i;4217:298::-;;;;;;:::i;:::-;;:::i;2688:82:13:-;;;2761:2;6563:36:24;;6551:2;6536:18;2688:82:13;6421:184:24;12027:433:6;;;;;;:::i;:::-;;:::i;2835:21::-;;;;;;2125:23;;;;;-1:-1:-1;;;;;2125:23:6;;;19592:211;19739:10;;19751;;19763:8;;19773;;19783:6;;19791;;19592:211;;;7174:25:24;;;7230:2;7215:18;;7208:34;;;;7258:18;;;7251:34;;;;7316:2;7301:18;;7294:34;-1:-1:-1;;;;;19783:6:6;;;7359:3:24;7344:19;;7337:84;19791:6:6;7452:3:24;7437:19;;7430:84;7161:3;7146:19;19592:211:6;6887:633:24;2540:23:6;;;;;;11337:582;;;;;;:::i;:::-;;:::i;437:44:8:-;;473:8;437:44;;3085:45:6;;;;;;:::i;:::-;;;;;;;;;;;;;;2591:23;;;;;;510:47:8;;;;;9477:1162:6;;;;;;:::i;:::-;;:::i;2933:116:13:-;;;;;;:::i;:::-;-1:-1:-1;;;;;3024:18:13;2998:7;3024:18;;;;;;;;;;;;2933:116;3734:244:6;;;;;;:::i;:::-;;:::i;19952:351::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;8236:1213::-;;;;;;:::i;:::-;;:::i;24428:88::-;;;:::i;19831:93::-;19904:6;;19912;;19831:93;;;-1:-1:-1;;;;;19904:6:6;;;9900:74:24;;19912:6:6;;;;10005:2:24;9990:18;;9983:83;9873:18;19831:93:6;9726:346:24;2934:47:6;;;;;;:::i;:::-;;;;;;;;;;;;;;3158:45;;;;;;:::i;:::-;;;;;;;;;;;;;;3244:178:13;;;;;;:::i;:::-;;:::i;4863:176:6:-;;;;;;:::i;:::-;;:::i;23367:969::-;;;;;;:::i;:::-;;:::i;10667:396::-;;;;;;:::i;:::-;;:::i;2884:21::-;;;;;;2704:37;;;;;;2769;;;;;;2176:22;;;;;-1:-1:-1;;;;;2176:22:6;;;4667:168;;;;;;:::i;:::-;;:::i;2642:33::-;;;;;;3231:97;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;2076:21;;;;;-1:-1:-1;;;;;2076:21:6;;;3455:140:13;;;;;;:::i;:::-;-1:-1:-1;;;;;3561:18:13;;;3535:7;3561:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;3455:140;4543:96:6;;;:::i;22244:544::-;;;;;;:::i;:::-;;:::i;1345:47::-;;1383:9;1345:47;;11091:218;;;:::i;5112:3053::-;3023:21:19;:19;:21::i;:::-;5244:7:6::1;;;;;;;;;-1:-1:-1::0;;;;;5244:7:6::1;-1:-1:-1::0;;;;;5231:30:6::1;;:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5227:55;;;5272:10;;;;;;;;;;;;;;5227:55;5292:15:::0;;:34;::::1;;;-1:-1:-1::0;5311:15:6;;5292:34:::1;5288:73;;;5335:26;;;;;;;;;;;;;;5288:73;5409:8;::::0;5419::::1;::::0;5438:23;;::::1;;::::0;:50:::1;;;5479:9;5465:10;:23;;5438:50;5434:86;;;5497:23;;;;;;;;;;;;;;5434:86;5680:6;::::0;5688::::1;::::0;5527:17:::1;::::0;;;-1:-1:-1;;;;;5680:6:6;;::::1;::::0;5688;;::::1;::::0;5707:13;::::1;::::0;::::1;::::0;:30:::1;;;5730:7;-1:-1:-1::0;;;;;5724:13:6::1;:2;-1:-1:-1::0;;;;;5724:13:6::1;;5707:30;5703:54;;;5746:11;;;;;;;;;;;;;;5703:54;5769:14:::0;;5765:64:::1;;5785:44;-1:-1:-1::0;;;;;5785:28:6;::::1;5814:2:::0;5818:10;5785:28:::1;:44::i;:::-;5875:14:::0;;5871:64:::1;;5891:44;-1:-1:-1::0;;;;;5891:28:6;::::1;5920:2:::0;5924:10;5891:28:::1;:44::i;:::-;5981:15:::0;;5977:83:::1;;5998:62;::::0;;;;-1:-1:-1;;;;;5998:20:6;::::1;::::0;::::1;::::0;:62:::1;::::0;6019:10:::1;::::0;6031;;6043;;6055:4;;;;5998:62:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5977:83;6114:40;::::0;-1:-1:-1;;;6114:40:6;;6148:4:::1;6114:40;::::0;::::1;2831:74:24::0;-1:-1:-1;;;;;6114:25:6;::::1;::::0;::::1;::::0;2804:18:24;;6114:40:6::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6174;::::0;-1:-1:-1;;;6174:40:6;;6208:4:::1;6174:40;::::0;::::1;2831:74:24::0;6102:52:6;;-1:-1:-1;;;;;;6174:25:6;::::1;::::0;::::1;::::0;2804:18:24;;6174:40:6::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6162:52;;5573:648;;6226:17;6270:10;6258:9;:22;;;;:::i;:::-;6246:9;:34;:77;;6322:1;6246:77;;;6296:22;6308:10:::0;6296:9;:22:::1;:::i;:::-;6283:36;::::0;:9;:36:::1;:::i;:::-;6226:97:::0;-1:-1:-1;6329:17:6::1;6361:22;6373:10:::0;6361:9;:22:::1;:::i;:::-;6349:9;:34;:77;;6425:1;6349:77;;;6399:22;6411:10:::0;6399:9;:22:::1;:::i;:::-;6386:36;::::0;:9;:36:::1;:::i;:::-;6329:97:::0;-1:-1:-1;6436:14:6;;:32;::::1;;;-1:-1:-1::0;6454:14:6;;6436:32:::1;6432:70;;;6477:25;;;;;;;;;;;;;;6432:70;-1:-1:-1::0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6716:22:6::1;6728:10:::0;6716:9;:22:::1;:::i;:::-;6688:51;;:17;::::0;::::1;:51:::0;6775:22:::1;6787:10:::0;6775:9;:22:::1;:::i;:::-;6747:51;;:17;::::0;::::1;:51:::0;6844:6:::1;::::0;6852::::1;::::0;-1:-1:-1;;;;;6844:6:6;;::::1;::::0;6852::::1;6807:15;::::0;;6971:55:::1;6983:9:::0;6994;7005;7016;6971:11:::1;:55::i;:::-;6924:102:::0;;-1:-1:-1;6924:102:6;-1:-1:-1;6924:102:6;-1:-1:-1;7038:13:6;;7034:238:::1;;7063:19;1606:6;7086:16;7098:4:::0;7086:9;:16:::1;:::i;:::-;7085:29;;;;:::i;:::-;7063:51;;7124:21;7133:11;7124:8;:21::i;:::-;7155:37;::::0;::::1;::::0;;1606:6:::1;7231:19;7243:7:::0;7231:9;:19:::1;:::i;:::-;7230:32;;;;:::i;:::-;7202:61;;:17;::::0;::::1;:61:::0;-1:-1:-1;7034:238:6::1;7283:13:::0;;7279:238:::1;;7308:19;1606:6;7331:16;7343:4:::0;7331:9;:16:::1;:::i;:::-;7330:29;;;;:::i;:::-;7308:51;;7369:21;7378:11;7369:8;:21::i;:::-;7400:37;::::0;::::1;:14;::::0;::::1;:37:::0;1606:6:::1;7476:19;7488:7:::0;7476:9;:19:::1;:::i;:::-;7475:32;;;;:::i;:::-;7447:61;;:17;::::0;::::1;:61:::0;-1:-1:-1;7279:238:6::1;7528:6;7524:121;;;7569:17;::::0;::::1;::::0;7546:40:::1;::::0;;::::1;:20;::::0;::::1;:40:::0;7619:17:::1;::::0;::::1;::::0;7596:40:::1;:20;::::0;::::1;:40:::0;7524:121:::1;7728:40;::::0;-1:-1:-1;;;7728:40:6;;7762:4:::1;7728:40;::::0;::::1;2831:74:24::0;-1:-1:-1;;;;;7728:25:6;::::1;::::0;::::1;::::0;2804:18:24;;7728:40:6::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;7788;::::0;-1:-1:-1;;;7788:40:6;;7822:4:::1;7788:40;::::0;::::1;2831:74:24::0;7716:52:6;;-1:-1:-1;;;;;;7788:25:6;::::1;::::0;::::1;::::0;2804:18:24;;7788:40:6::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;7776:52;;7928:24;7931:9;7942;7928:2;:24::i;:::-;7901;7904:9;7915;7901:2;:24::i;:::-;:51;7897:67;;;7961:3;;;;;;;;;;;;;;7897:67;7985:7;::::0;7972:47:::1;::::0;;;;-1:-1:-1;;;;;7985:7:6;;::::1;::::0;7972:36:::1;::::0;:47:::1;::::0;8009:9;;7972:47:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6508:1518;;;;;;8032:51;8040:9;8051;8062;8073;8032:7;:51::i;:::-;8094:66;::::0;;14085:25:24;;;14141:2;14126:18;;14119:34;;;14169:18;;;14162:34;;;14227:2;14212:18;;14205:34;;;-1:-1:-1;;;;;8094:66:6;::::1;::::0;8099:10:::1;::::0;8094:66:::1;::::0;14072:3:24;14057:19;8094:66:6::1;;;;;;;5221:2944;;;;;;3065:20:19::0;2365:1;1505:66;3972:62;3749:292::o;3065:20::-;5112:3053:6;;;;;:::o;24340:84::-;24386:13;24414:5;24407:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24340:84;:::o;3902:186:13:-;3975:4;735:10:17;4029:31:13;735:10:17;4045:7:13;4054:5;4029:8;:31::i;:::-;4077:4;4070:11;;;3902:186;;;;;:::o;22816:523:6:-;22965:8;;22975;;23044:6;;22908:7;;22965:8;22975;22908:7;;;;-1:-1:-1;;;;;23033:17:6;;;23044:6;;23033:17;:67;;23087:1;23091:8;23033:67;;;23054:8;23072:1;23033:67;22990:110;;;;23107:12;23125:57;23137:10;23149;23161:9;23172;23125:11;:57::i;:::-;23106:76;;;;1606:6;23251:4;23240:8;:15;;;;:::i;:::-;23239:28;;;;:::i;:::-;23227:40;;;;:::i;:::-;;;23280:54;23294:8;23304:7;23313:9;23324;23280:13;:54::i;:::-;23273:61;22816:523;-1:-1:-1;;;;;;;;22816:523:6:o;20705:496::-;20912:6;;20843:7;;;;;;-1:-1:-1;;;;;20901:17:6;;;20912:6;;20901:17;:67;;20955:1;20959:8;20901:67;;;20922:8;20940:1;20901:67;21019:7;;21006:105;;;;;21047:4;21006:105;;;14979:74:24;21019:7:6;15069:18:24;;;15062:83;15161:18;;;15154:34;;;15204:18;;;15197:34;;;15247:19;;;15240:35;;;15291:19;;;15284:35;;;20858:110:6;;-1:-1:-1;20858:110:6;;-1:-1:-1;1606:6:6;;-1:-1:-1;;;;;21019:7:6;;;;21006:32;;14951:19:24;;21006:105:6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;20987:124;;:8;:124;:::i;:::-;20986:143;;;;:::i;:::-;20974:155;;;;:::i;:::-;;;21142:54;21156:8;21166:7;21175:9;21186;21142:13;:54::i;:::-;21135:61;20705:496;-1:-1:-1;;;;;;;20705:496:6:o;4006:183::-;4063:7;;-1:-1:-1;;;;;4091:24:6;;4087:50;;4124:13;;;;;;;;;;;;;;4087:50;4150:34;4161:10;4173;4150;:34::i;:::-;4143:41;;;;4006:183;;;:::o;21229:745::-;21444:22;;21493;;21402:15;21297:26;;;21688:13;22131:8;;22157;;22193:18;;22131:8;;22157;;22193:18;22002:214;21688:13;21618:83;;;;;;21734:14;21711:19;:37;21707:263;;21799:19;21821:36;21838:19;21821:14;:36;:::i;:::-;21799:58;-1:-1:-1;21887:23:6;21799:58;21887:9;:23;:::i;:::-;21865:45;;;;:::i;:::-;;-1:-1:-1;21940:23:6;21952:11;21940:9;:23;:::i;:::-;21918:45;;;;:::i;:::-;;;21750:220;21707:263;21379:595;;;21229:745;;;:::o;4680:244:13:-;4767:4;735:10:17;4823:37:13;4839:4;735:10:17;4854:5:13;4823:15;:37::i;:::-;4870:26;4880:4;4886:2;4890:5;4870:9;:26::i;:::-;4913:4;4906:11;;;4680:244;;;;;;:::o;20331:346:6:-;20404:16;;;;20531:17;20562:6;20531:38;;;;;;;:::i;:::-;20486:83;;;;;;;;20531:38;;;;;;;;;20486:83;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;20486:83:6;-1:-1:-1;20331:346:6;-1:-1:-1;;;20331:346:6:o;19162:402::-;-1:-1:-1;;;;;19277:20:6;;19224:16;19277:20;;;:10;:20;;;;;;;;;19314:10;:20;;;;;;3024:18:13;;;;;;;19390:13:6;;19386:174;;-1:-1:-1;;;;;19448:22:6;;;;;;:12;:22;;;;;;19439:6;;19475:4;;19439:31;;;:::i;:::-;19426:45;;:9;:45;:::i;:::-;19425:54;;;;:::i;:::-;19413:66;;;;:::i;:::-;-1:-1:-1;;;;;19522:22:6;;;;;;:12;:22;;;;;;19513:6;;19413:66;;-1:-1:-1;19549:4:6;;19513:31;;19522:22;19513:31;:::i;:::-;19500:45;;:9;:45;:::i;:::-;19499:54;;;;:::i;:::-;19487:66;;;;:::i;:::-;;;19386:174;19260:304;19162:402;;;:::o;4217:298::-;4292:7;;-1:-1:-1;;;;;4320:24:6;;4316:50;;4353:13;;;;;;;;;;;;;;4316:50;4376:10;-1:-1:-1;;;;;4376:22:6;;;;;;:65;;-1:-1:-1;;;;;;4403:26:6;;;;;;:16;:26;;;;;;;;4430:10;4403:38;;;;;;;;;;4402:39;4376:65;4372:93;;;4450:15;;;;;;;;;;;;;;4372:93;4478:32;4489:8;4499:10;4478;:32::i;:::-;4471:39;;;;4217:298;;;;;;:::o;12027:433::-;12155:33;;;;;;;12122:30;12227:51;12155:17;12250:27;12227:22;:51::i;:::-;12194:84;;12315:23;12288:50;;:23;:50;;;12284:172;;12353:96;;;15719:6:24;15707:19;;;15689:38;;15763:19;;15758:2;15743:18;;15736:47;12388:10:6;;12353:96;;15662:18:24;12353:96:6;;;;;;;12284:172;12116:344;;12027:433;:::o;11337:582::-;11410:7;;-1:-1:-1;;;;;11410:7:6;:21;11406:53;;11440:19;;;;;;;;;;;;;;11406:53;11465:7;:20;;11475:10;11465:20;;;;;;;;11500:6;11491:37;;;;-1:-1:-1;;;;;11491:37:6;;;;;;;;;;11492:6;11491:37;;;;;;;;;;;11553:30;;11491:37;;;;11553:30;;;:::i;:::-;-1:-1:-1;;;;;9918:55:24;;;9900:74;;10010:55;;10005:2;9990:18;;9983:83;9888:2;9873:18;11553:30:6;;;;;;;;;;;;;;;;;;;;;;;11534:8;;:50;;;;;-1:-1:-1;;;;;11534:50:6;;;;;-1:-1:-1;;;;;11534:50:6;;;;;;11590:21;11620:7;-1:-1:-1;;;;;11614:21:6;;:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;11614:23:6;;;;;;;;;;;;:::i;:::-;11590:47;;11643:21;11673:7;-1:-1:-1;;;;;11667:21:6;;:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;11667:23:6;;;;;;;;;;;;:::i;:::-;11643:47;;11704:27;11714:7;11723;11704:9;:27::i;:::-;11696:5;;:35;;:5;:35;:::i;:::-;;11747:29;11759:7;11768;11747:11;:29::i;:::-;11737:7;;:39;;:7;:39;:::i;:::-;;11808:7;-1:-1:-1;;;;;11802:23:6;;:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;11796:31;;:2;:31;:::i;:::-;11783:10;:44;;;;11858:7;-1:-1:-1;;;;;11852:23:6;;:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;11846:31;;:2;:31;:::i;:::-;11833:10;:44;11884:17;1908:56:5;;;;1948:15;1908:56;;;;;1970:16;:20;;1996:24;;;;;;11884:30:6;11400:519;;11337:582;;:::o;9477:1162::-;9534:17;3023:21:19;:19;:21::i;:::-;9601:8:6::1;::::0;9611::::1;::::0;9653:6:::1;::::0;9646:39:::1;::::0;-1:-1:-1;;;9646:39:6;;9679:4:::1;9646:39;::::0;::::1;2831:74:24::0;9560:17:6::1;::::0;-1:-1:-1;;;;;9653:6:6::1;::::0;9646:24:::1;::::0;2804:18:24;;9646:39:6::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;9718:6;::::0;9711:39:::1;::::0;-1:-1:-1;;;9711:39:6;;9744:4:::1;9711:39;::::0;::::1;2831:74:24::0;9626:59:6;;-1:-1:-1;9691:17:6::1;::::0;-1:-1:-1;;;;;9718:6:6;;::::1;::::0;9711:24:::1;::::0;2804:18:24;;9711:39:6::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;9691:59:::0;-1:-1:-1;9756:16:6::1;9775:21;9787:9:::0;9775;:21:::1;:::i;:::-;9756:40:::0;-1:-1:-1;9802:16:6::1;9821:21;9833:9:::0;9821;:21:::1;:::i;:::-;9802:40;;9849:20;9872:13;2881:12:13::0;;;2803:97;9872:13:6::1;9849:36;;9973:12;9989:1;9973:17:::0;9969:531:::1;;1490:7;10012:30;10022:19;10033:8:::0;10022;:19:::1;:::i;:::-;10012:9;:30::i;:::-;:51;;;;:::i;:::-;10000:63;;10071:37;10085:1;1490:7;10071:5;:37::i;:::-;10195:35;10211:8;10221;10195:15;:35::i;:::-;1490:7;10242:9;:30;10238:72;;;10281:29;;;;;;;;;;;;;;10238:72;9969:531;;;10343:86;10380:9:::0;10353:23:::1;10364:12:::0;10353:8;:23:::1;:::i;:::-;10352:37;;;;:::i;:::-;10419:9:::0;10392:23:::1;10403:12:::0;10392:8;:23:::1;:::i;:::-;10391:37;;;;:::i;:::-;10343:8;:86::i;:::-;10331:98;;10441:9;10454:1;10441:14:::0;10437:56:::1;;10464:29;;;;;;;;;;;;;;10437:56;10505:20;10511:2;10515:9;10505:5;:20::i;:::-;10532:51;10540:9;10551;10562;10573;10532:7;:51::i;:::-;10594:40;::::0;;4509:25:24;;;4565:2;4550:18;;4543:34;;;-1:-1:-1;;;;;10594:40:6;::::1;::::0;10599:10:::1;::::0;10594:40:::1;::::0;4482:18:24;10594:40:6::1;;;;;;;9553:1086;;;;;;;3065:20:19::0;2365:1;1505:66;3972:62;3749:292::o;3065:20::-;9477:1162:6;;;:::o;3734:244::-;-1:-1:-1;;;;;3813:23:6;;3809:49;;3845:13;;;;;;;;;;;;;;3809:49;3881:10;3864:28;;;;:16;:28;;;;;;;;-1:-1:-1;;;;;3864:39:6;;;;;;;;;;;;:51;;;;;;;;;;;;;3926:47;;2633:41:24;;;3864:39:6;;3881:10;3926:47;;2606:18:24;3926:47:6;;;;;;;3734:244;;:::o;19952:351::-;20036:37;20075;20123:14;20139;20158:25;:23;:25::i;:::-;-1:-1:-1;20122:61:6;;-1:-1:-1;20122:61:6;-1:-1:-1;20243:55:6;:17;20269:12;;20122:61;;20243:25;:55::i;:::-;20236:62;;;;;;19952:351;;;;;:::o;8236:1213::-;8293:15;8310;3023:21:19;:19;:21::i;:::-;8375:8:6::1;::::0;8385::::1;::::0;8438:6:::1;::::0;8446::::1;::::0;8479:40:::1;::::0;-1:-1:-1;;;8479:40:6;;8513:4:::1;8479:40;::::0;::::1;2831:74:24::0;-1:-1:-1;;;;;8438:6:6;;::::1;::::0;8446;;::::1;::::0;8334:17:::1;::::0;8438:6;;8479:25:::1;::::0;2804:18:24;;8479:40:6::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8545;::::0;-1:-1:-1;;;8545:40:6;;8579:4:::1;8545:40;::::0;::::1;2831:74:24::0;8459:60:6;;-1:-1:-1;8525:17:6::1;::::0;-1:-1:-1;;;;;8545:25:6;::::1;::::0;::::1;::::0;2804:18:24;;8545:40:6::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8630:4;8591:18;3024::13::0;;;;;;;;;;;2881:12;;8525:60:6;;-1:-1:-1;3024:18:13;2881:12;8774:22:6::1;8787:9:::0;3024:18:13;8774:22:6::1;:::i;:::-;8773:39;;;;:::i;:::-;8763:49:::0;-1:-1:-1;8903:12:6;8877:22:::1;8890:9:::0;8877:10;:22:::1;:::i;:::-;8876:39;;;;:::i;:::-;8866:49:::0;-1:-1:-1;8973:12:6;;;:28:::1;;-1:-1:-1::0;8989:12:6;;8973:28:::1;8969:70;;;9010:29;;;;;;;;;;;;;;8969:70;9045:32;9059:4;9066:10;9045:5;:32::i;:::-;9083:41;-1:-1:-1::0;;;;;9083:28:6;::::1;9112:2:::0;9116:7;9083:28:::1;:41::i;:::-;9130;-1:-1:-1::0;;;;;9130:28:6;::::1;9159:2:::0;9163:7;9130:28:::1;:41::i;:::-;9189:40;::::0;-1:-1:-1;;;9189:40:6;;9223:4:::1;9189:40;::::0;::::1;2831:74:24::0;-1:-1:-1;;;;;9189:25:6;::::1;::::0;::::1;::::0;2804:18:24;;9189:40:6::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;9247;::::0;-1:-1:-1;;;9247:40:6;;9281:4:::1;9247:40;::::0;::::1;2831:74:24::0;9177:52:6;;-1:-1:-1;;;;;;9247:25:6;::::1;::::0;::::1;::::0;2804:18:24;;9247:40:6::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;9235:52;;9294:43;9316:9;9327;9294:21;:43::i;:::-;9344:51;9352:9;9363;9374;9385;9344:7;:51::i;:::-;9406:38;::::0;;4509:25:24;;;4565:2;4550:18;;4543:34;;;-1:-1:-1;;;;;9406:38:6;::::1;::::0;9411:10:::1;::::0;9406:38:::1;::::0;4482:18:24;9406:38:6::1;;;;;;;8327:1122;;;;;;;;3065:20:19::0;2365:1;1505:66;3972:62;3749:292::o;3065:20::-;8236:1213:6;;;:::o;24428:88::-;24476:13;24504:7;24497:14;;;;;:::i;3244:178:13:-;3313:4;735:10:17;3367:27:13;735:10:17;3384:2:13;3388:5;3367:9;:27::i;4863:176:6:-;4954:7;;;;;;;;;-1:-1:-1;;;;;4954:7:6;-1:-1:-1;;;;;4941:31:6;;:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;4927:47:6;:10;-1:-1:-1;;;;;4927:47:6;;4923:87;;4983:27;;;;;;;;;;;;;;4923:87;5016:7;:18;5026:8;;5016:7;:18;:::i;23367:969::-;23460:7;23479:9;23492:1;23479:14;23475:28;;-1:-1:-1;23502:1:6;23495:8;;23475:28;23551:8;;23561;;23606:6;;-1:-1:-1;;;;;23594:18:6;;;23606:6;;23594:18;:42;;23627:9;23594:42;;;23615:9;23594:42;23580:9;:57;23576:93;;23646:23;;;;;;;;;;;;;;23576:93;23676:25;23704:55;23717:9;23728:8;23738:9;23749;23704:12;:55::i;:::-;23676:83;;23928:17;23949:1;23928:22;23924:36;;23959:1;23952:8;;;;;;;23924:36;24028:6;;23968:18;;;;-1:-1:-1;;;;;24016:18:6;;;24028:6;;24016:18;:86;;24072:17;24099:1;24016:86;;;24046:1;24050:17;24016:86;24142:7;;24129:112;;;;;24177:4;24129:112;;;14979:74:24;24184:10:6;15069:18:24;;;15062:83;15161:18;;;15154:34;;;15204:18;;;15197:34;;;15247:19;;;15240:35;;;15291:19;;;15284:35;;;23967:135:6;;-1:-1:-1;23967:135:6;;-1:-1:-1;24108:12:6;;-1:-1:-1;;;;;24142:7:6;;;;24129:39;;14951:19:24;;24129:112:6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;24108:133;-1:-1:-1;24274:57:6;24108:133;24292:21;24312:1;24292:17;:21;:::i;:::-;24315:15;24326:4;1606:6;24315:15;:::i;:::-;24274:11;:57::i;:::-;24254:77;;:17;:77;:::i;:::-;24247:84;23367:969;-1:-1:-1;;;;;;;;;23367:969:6:o;10667:396::-;3023:21:19;:19;:21::i;:::-;10759:6:6::1;::::0;10767::::1;::::0;10842:8:::1;::::0;10799:40:::1;::::0;-1:-1:-1;;;10799:40:6;;10833:4:::1;10799:40;::::0;::::1;2831:74:24::0;-1:-1:-1;;;;;10759:6:6;;::::1;::::0;10767;;::::1;::::0;10722:15:::1;::::0;10842:8;10759:6;;10799:25:::1;::::0;2804:18:24;;10799:40:6::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:51;;;;:::i;:::-;10780:70:::0;-1:-1:-1;10860:12:6;;10856:60:::1;;10874:42;-1:-1:-1::0;;;;;10874:28:6;::::1;10903:2:::0;10907:8;10874:28:::1;:42::i;:::-;10984:8;::::0;10941:40:::1;::::0;-1:-1:-1;;;10941:40:6;;10975:4:::1;10941:40;::::0;::::1;2831:74:24::0;10922:16:6::1;::::0;10984:8;-1:-1:-1;;;;;10941:25:6;::::1;::::0;::::1;::::0;2804:18:24;;10941:40:6::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:51;;;;:::i;:::-;10922:70:::0;-1:-1:-1;11002:12:6;;10998:60:::1;;11016:42;-1:-1:-1::0;;;;;11016:28:6;::::1;11045:2:::0;11049:8;11016:28:::1;:42::i;:::-;10715:348;;;;3065:20:19::0;2365:1;1505:66;3972:62;3749:292::o;3065:20::-;10667:396:6;:::o;4667:168::-;4754:7;;;;;;;;;-1:-1:-1;;;;;4754:7:6;-1:-1:-1;;;;;4741:31:6;;:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;4727:47:6;:10;-1:-1:-1;;;;;4727:47:6;;4723:87;;4783:27;;;;;;;;;;;;;;4723:87;4816:5;:14;4824:6;;4816:5;:14;:::i;4543:96::-;4590:7;3023:21:19;:19;:21::i;:::-;4612:22:6::1;4615:8;;4625;;4612:2;:22::i;:::-;4605:29;;3065:20:19::0;2365:1;1505:66;3972:62;3749:292::o;3065:20::-;4543:96:6;:::o;22244:544::-;22381:8;;22391;;22460:6;;22324:7;;22381:8;22391;22324:7;;;;-1:-1:-1;;;;;22449:17:6;;;22460:6;;22449:17;:67;;22503:1;22507:8;22449:67;;;22470:8;22488:1;22449:67;22606:7;;22593:105;;;;;22634:4;22593:105;;;14979:74:24;22606:7:6;15069:18:24;;;15062:83;15161:18;;;15154:34;;;15204:18;;;15197:34;;;15247:19;;;15240:35;;;15291:19;;;15284:35;;;22406:110:6;;-1:-1:-1;22406:110:6;;-1:-1:-1;1606:6:6;;-1:-1:-1;;;;;22606:7:6;;;;22593:32;;14951:19:24;;22593:105:6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;22574:124;;:8;:124;:::i;:::-;22573:143;;;;:::i;:::-;22561:155;;;;:::i;:::-;;;22729:54;22743:8;22753:7;22762:9;22773;22729:13;:54::i;11091:218::-;3023:21:19;:19;:21::i;:::-;2881:12:13;;11156:1:6::1;11139:18:::0;11135:54:::1;;11166:23;;;;;;;;;;;;;;11135:54;11210:6;::::0;11203:39:::1;::::0;-1:-1:-1;;;11203:39:6;;11236:4:::1;11203:39;::::0;::::1;2831:74:24::0;11195:109:6::1;::::0;-1:-1:-1;;;;;11210:6:6::1;::::0;11203:24:::1;::::0;2804:18:24;;11203:39:6::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;11251:6;::::0;11244:39:::1;::::0;-1:-1:-1;;;11244:39:6;;11277:4:::1;11244:39;::::0;::::1;2831:74:24::0;-1:-1:-1;;;;;11251:6:6;;::::1;::::0;11244:24:::1;::::0;2804:18:24;;11244:39:6::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;11285:8;;11295;;11195:7;:109::i;:::-;3065:20:19::0;2365:1;1505:66;3972:62;3749:292::o;3065:20::-;11091:218:6:o;3749:292:19:-;3872:25;:23;:25::i;:::-;2407:1;1505:66;3972:62;3749:292::o;1219:204:16:-;1306:37;1320:5;1327:2;1331:5;1338:4;1306:13;:37::i;:::-;1301:116;;1366:40;;;;;-1:-1:-1;;;;;2849:55:24;;1366:40:16;;;2831:74:24;2804:18;;1366:40:16;;;;;;;;16669:352:6;16928:7;;16915:101;;;;;16952:4;16915:101;;;14979:74:24;16959:10:6;15069:18:24;;;15062:83;15161:18;;;15154:34;;;15204:18;;;15197:34;;;15247:19;;;15240:35;;;15291:19;;;15284:35;;;16811:12:6;;;;;;-1:-1:-1;;;;;16928:7:6;;16915:28;;14951:19:24;;16915:101:6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;16908:108;;;;;;16669:352;;;;;;;;:::o;13312:402::-;13415:6;13425:1;13415:11;13411:24;;13312:402;:::o;13411:24::-;13468:8;;13447:6;;13440:45;;-1:-1:-1;;;;;13447:6:6;;;;13468:8;13478:6;13440:27;:45::i;:::-;13528:14;13563:13;2881:12:13;;;2803:97;13563:13:6;13546;:6;13555:4;13546:13;:::i;:::-;13545:31;;;;:::i;:::-;13528:48;-1:-1:-1;13629:10:6;;13625:47;;13659:6;13649;;:16;;;;;;;:::i;:::-;;;;-1:-1:-1;;13625:47:6;13682:27;;;4509:25:24;;;13707:1:6;4565:2:24;4550:18;;4543:34;13687:10:6;;13682:27;;4482:18:24;13682:27:6;;;;;;;;13355:359;13312:402;:::o;13751:322::-;13854:6;13864:1;13854:11;13850:24;;13751:322;:::o;13850:24::-;13907:8;;13886:6;;13879:45;;-1:-1:-1;;;;;13886:6:6;;;;13907:8;13917:6;13879:27;:45::i;:::-;13930:14;13965:13;2881:12:13;;;2803:97;13965:13:6;13948;:6;13957:4;13948:13;:::i;:::-;13947:31;;;;:::i;:::-;13930:48;-1:-1:-1;13988:10:6;;13984:47;;14018:6;14008;;:16;;;;;;;:::i;:::-;;;;-1:-1:-1;;13984:47:6;14041:27;;;14058:1;4509:25:24;;4565:2;4550:18;;4543:34;;;14046:10:6;;14041:27;;4482:18:24;14041:27:6;4335:248:24;2189:387:8;2257:7;2272:16;2305:10;;2292:2;2297:4;2292:9;;;;:::i;:::-;2291:24;;;;:::i;:::-;2272:43;;2321:16;2354:10;;2341:2;2346:4;2341:9;;;;:::i;:::-;2340:24;;;;:::i;:::-;2321:43;;2370:10;2383:37;2395:8;2405;2415:4;2383:11;:37::i;:::-;2370:50;;2426:10;2479:37;2491:8;2501;2511:4;2479:11;:37::i;:::-;2439;2451:8;2461;2471:4;2439:11;:37::i;:::-;:77;;;;:::i;:::-;2426:90;;2529:25;2541:2;2545;2549:4;2529:11;:25::i;16000:615:6:-;16191:18;;16131:15;;16106:22;;16174:35;;16131:15;16174:35;:::i;:::-;16152:57;;16233:1;16219:11;:15;:33;;;;-1:-1:-1;16238:14:6;;;16219:33;:51;;;;-1:-1:-1;16256:14:6;;;16219:51;16215:178;;;16306:23;16318:11;16306:9;:23;:::i;:::-;16280:22;;:49;;;;;;;:::i;:::-;;;;-1:-1:-1;16363:23:6;;-1:-1:-1;16375:11:6;16363:9;:23;:::i;:::-;16337:22;;:49;;;;;;;:::i;:::-;;;;-1:-1:-1;;16215:178:6;16423:22;;16447;;16399:84;;:17;;1383:9;16399:23;:84::i;:::-;16490:8;:19;;;16515:8;:19;;;16540:18;:35;;;16586:24;;;4509:25:24;;;4565:2;4550:18;;4543:34;;;16586:24:6;;4482:18:24;16586:24:6;;;;;;;16100:515;;16000:615;;;;:::o;8630:128:13:-;8714:37;8723:5;8730:7;8739:5;8746:4;8714:8;:37::i;585:699:8:-;735:7;750:16;769:24;772:9;783;769:2;:24::i;:::-;832:10;;750:43;;-1:-1:-1;812:16:8;:9;824:4;812:16;:::i;:::-;811:31;;;;:::i;:::-;881:10;;799:43;;-1:-1:-1;861:16:8;:9;873:4;861:16;:::i;:::-;860:31;;;;:::i;:::-;950:6;;848:43;;-1:-1:-1;898:17:8;;;;-1:-1:-1;;;;;938:18:8;;;950:6;;938:18;:68;;985:9;996;938:68;;;960:9;971;938:68;1036:6;;897:109;;-1:-1:-1;897:109:8;-1:-1:-1;;;;;;1024:18:8;;;1036:6;;1024:18;:86;;1100:10;;1080:16;:9;1092:4;1080:16;:::i;:::-;1079:31;;;;:::i;:::-;1024:86;;;1066:10;;1046:16;:9;1058:4;1046:16;:::i;:::-;1045:31;;;;:::i;:::-;1012:98;-1:-1:-1;1116:18:8;1149:49;1155:21;1167:9;1012:98;1155:21;:::i;:::-;1178:8;1188:9;1149:5;:49::i;:::-;1137:61;;:9;:61;:::i;:::-;1238:6;;1116:82;;-1:-1:-1;1275:4:8;;-1:-1:-1;;;;;1226:18:8;;;1238:6;;1226:18;:44;;1260:10;;1226:44;;;1247:10;;1226:44;1212:59;;:10;:59;:::i;:::-;1211:68;;;;:::i;12703:572:6:-;12779:17;12798;12823:20;12834:8;12823:10;:20::i;:::-;-1:-1:-1;;;;;;;12862:20:6;;;;;;:10;:20;;;;;;;;;12900:10;:20;;;;;;;12931:13;;;;:30;;;12960:1;12948:9;:13;12931:30;12927:344;;;-1:-1:-1;;;;;12978:20:6;;;;;;;:10;:20;;;;;;;;12971:27;;;13013:10;:20;;;;;;13006:27;;;;13051:8;;13042:99;;;;;24144:55:24;;;13042:99:6;;;24126:74:24;24216:18;;;24209:34;;;24259:18;;;24252:34;;;13051:8:6;;;13042:31;;24099:18:24;;13042:99:6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;13155:109:6;;;4509:25:24;;;4565:2;4550:18;;4543:34;;;-1:-1:-1;;;;;13155:109:6;;;;-1:-1:-1;13155:109:6;;;-1:-1:-1;13170:10:6;;13155:109;;4482:18:24;13155:109:6;;;;;;;12703:572;;;;;:::o;10321:476:13:-;-1:-1:-1;;;;;3561:18:13;;;10420:24;3561:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;-1:-1:-1;;10486:36:13;;10482:309;;;10561:5;10542:16;:24;10538:130;;;10593:60;;;;;-1:-1:-1;;;;;24144:55:24;;10593:60:13;;;24126:74:24;24216:18;;;24209:34;;;24259:18;;;24252:34;;;24099:18;;10593:60:13;23924:368:24;10538:130:13;10709:57;10718:5;10725:7;10753:5;10734:16;:24;10760:5;10709:8;:57::i;5297:300::-;-1:-1:-1;;;;;5380:18:13;;5376:86;;5421:30;;;;;5448:1;5421:30;;;2831:74:24;2804:18;;5421:30:13;2685:226:24;5376:86:13;-1:-1:-1;;;;;5475:16:13;;5471:86;;5514:32;;;;;5543:1;5514:32;;;2831:74:24;2804:18;;5514:32:13;2685:226:24;5471:86:13;5566:24;5574:4;5580:2;5584:5;5566:7;:24::i;4026:435:5:-;4136:20;;;;4104:6;;4136:20;;;;;;;;4166:17;;;-1:-1:-1;4162:38:5;;4192:8;-1:-1:-1;4185:15:5;;4162:38;4223:8;4206:199;4238:5;4233:10;;:2;:10;;;4206:199;;;4293:1;4259:4;:21;;;;;;;;;;;:::i;:::-;;;;:35;;;;;;;;;;;;;;;-1:-1:-1;4302:4:5;:21;;;;;;;;;;;:::i;:::-;;;;:40;;:44;;;;4397:1;4354:4;:17;;4372:2;4354:21;;;;;;;;;:::i;:::-;;;;:40;;:44;4245:4;;4206:199;;;-1:-1:-1;;;4410:20:5;;;;;:28;;;;;;;;;;;;;4026:435::o;3042:200:8:-;3141:13;3212:8;3227;3176:60;;;;;;;;;:::i;:::-;;;;;;;;;;;;;3162:75;;3042:200;;;;:::o;3269:194::-;3370:13;3433:8;3448;3405:52;;;;;;;;;:::i;20859:5181:22:-;20907:7;21025:1;21020;:6;21016:53;;-1:-1:-1;21053:1:22;20859:5181::o;21016:53::-;22009:1;22037;22064:8;22057:16;;22053:92;;22100:3;22093:10;;;;;22128:2;22121:9;22053:92;22169:7;22162:2;:15;22158:90;;22204:2;22197:9;;;;;22231:2;22224:9;22158:90;22272:7;22265:2;:15;22261:90;;22307:2;22300:9;;;;;22334:2;22327:9;22261:90;22375:7;22368:2;:15;22364:89;;22410:2;22403:9;;;;;22437:1;22430:8;22364:89;22477:6;22470:2;:14;22466:87;;22511:1;22504:8;;;;;22537:1;22530:8;22466:87;22577:6;22570:2;:14;22566:87;;22611:1;22604:8;;;;;22637:1;22630:8;22566:87;22677:6;22670:2;:14;22666:61;;22711:1;22704:8;22666:61;23153:1;:6;23164:1;23152:13;;;;;25063:1;23152:13;25063:6;;;;:::i;:::-;;25058:2;:11;25057:18;;25052:23;;25183:1;25176:2;25172:1;:6;;;;;:::i;:::-;;25167:2;:11;25166:18;;25161:23;;25294:1;25287:2;25283:1;:6;;;;;:::i;:::-;;25278:2;:11;25277:18;;25272:23;;25403:1;25396:2;25392:1;:6;;;;;:::i;:::-;;25387:2;:11;25386:18;;25381:23;;25513:1;25506:2;25502:1;:6;;;;;:::i;:::-;;25497:2;:11;25496:18;;25491:23;;25623:1;25616:2;25612:1;:6;;;;;:::i;:::-;;25607:2;:11;25606:18;;25601:23;;25995:28;26020:2;26016:1;:6;;;;;:::i;:::-;;26011:11;;;34792:145:23;25995:28:22;25990:33;;;20859:5181;-1:-1:-1;;;20859:5181:22:o;7362:208:13:-;-1:-1:-1;;;;;7432:21:13;;7428:91;;7476:32;;;;;7505:1;7476:32;;;2831:74:24;2804:18;;7476:32:13;2685:226:24;7428:91:13;7528:35;7544:1;7548:7;7557:5;7528:7;:35::i;:::-;7362:208;;:::o;2603:259:8:-;2751:10;;2732:15;:8;2743:4;2732:15;:::i;:::-;2731:30;;;;:::i;:::-;2717:10;;2698:15;:8;2709:4;2698:15;:::i;:::-;2697:30;;;;:::i;:::-;:64;2693:95;;2770:18;;;;;;;;;;;;;;2693:95;473:8;2798:22;2801:8;2811;2798:2;:22::i;:::-;:35;2794:63;;2842:15;;;;;;;;;;;;;;5633:111:22;5691:7;5328:5;;;5725;;;5327:36;5322:42;;5717:20;5087:294;8875:672:5;9063:37;;9169:15;9209:12;;9257:22;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;9257:22:5;;9234:45;;9322:7;9308:22;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;9308:22:5;;9285:45;;9341:10;9336:207;9358:7;9353:2;:12;9336:207;;;9444:92;9458:4;9464:5;9471:12;;9484:2;9471:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;9489:22;9513;9444:13;:92::i;:::-;9382:20;9403:2;9382:24;;;;;;;;:::i;:::-;;;;;;9408:20;9429:2;9408:24;;;;;;;;:::i;:::-;;;;;;;;;;9381:155;;;;;9367:4;;9336:207;;;;9141:406;;8875:672;;;;;;;;:::o;7888:206:13:-;-1:-1:-1;;;;;7958:21:13;;7954:89;;8002:30;;;;;8029:1;8002:30;;;2831:74:24;2804:18;;8002:30:13;2685:226:24;7954:89:13;8052:35;8060:7;8077:1;8081:5;8052:7;:35::i;2889:126:8:-;2977:10;2980:2;2984;2977;:10::i;:::-;2991:1;2977:15;2973:37;;3001:9;;;;;;;;;;;;;;1311:851;1462:7;1477:16;1496:24;1499:9;1510;1496:2;:24::i;:::-;1559:10;;1477:43;;-1:-1:-1;1539:16:8;:9;1551:4;1539:16;:::i;:::-;1538:31;;;;:::i;:::-;1608:10;;1526:43;;-1:-1:-1;1588:16:8;:9;1600:4;1588:16;:::i;:::-;1587:31;;;;:::i;:::-;1681:6;;1575:43;;-1:-1:-1;1625:19:8;;;;-1:-1:-1;;;;;1668:19:8;;;1681:6;;1668:19;:69;;1716:9;1727;1668:69;;;1691:9;1702;1668:69;1808:6;;1624:113;;-1:-1:-1;1624:113:8;-1:-1:-1;1744:20:8;;;;-1:-1:-1;;;;;1795:19:8;;;1808:6;;1795:19;:73;;1845:10;;1857;;1795:73;;;1818:10;;1830;;1795:73;1743:125;;-1:-1:-1;1743:125:8;-1:-1:-1;1887:45:8;1900:17;:10;1913:4;1900:17;:::i;:::-;1919:12;1887;:45::i;:::-;1874:58;;1956:11;1942:10;:25;1938:61;;1976:23;;;;;;;;;;;;;;1938:61;2005:21;2029:53;2035:24;2049:10;2035:11;:24;:::i;:::-;2061:8;2071:10;2029:5;:53::i;:::-;2005:77;-1:-1:-1;2095:62:8;2139:11;2109:26;2125:10;2005:77;2109:26;:::i;:::-;2108:42;;;;:::i;:::-;2152:4;2095:12;:62::i;:::-;2088:69;1311:851;-1:-1:-1;;;;;;;;;;;1311:851:8:o;7296:3683:22:-;7378:14;7429:12;7443:11;7458:12;7465:1;7468;7458:6;:12::i;:::-;7428:42;;;;7552:4;7560:1;7552:9;7548:365;;7887:11;7881:3;:17;;;;;:::i;:::-;;7874:24;;;;;;7548:365;8038:4;8023:11;:19;8019:142;;8062:84;5328:5;8082:16;;5327:36;940:4:18;5322:42:22;8062:11;:84::i;:::-;8413:17;8564:11;8561:1;8558;8551:25;8956:12;8986:15;;;8971:31;;9121:22;;;;;9854:1;9835;:15;;9834:21;;10087;;;10083:25;;10072:36;10157:21;;;10153:25;;10142:36;10229:21;;;10225:25;;10214:36;10300:21;;;10296:25;;10285:36;10373:21;;;10369:25;;10358:36;10447:21;;;10443:25;;;10432:36;9363:12;;;;9359:23;;;9384:1;9355:31;8676:18;;;8666:29;;;9470:11;;;;8719:19;;;;9214:14;;;;9463:18;;;;10922:13;;-1:-1:-1;;7296:3683:22;;;;;:::o;3586:157:19:-;3648:25;4537:4;2407:1;1505:66;4560:46;4543:96:6;3648:25:19;3644:93;;;3696:30;;;;;;;;;;;;;;8373:1244:16;8600:4;8594:11;8509:24;8467:12;8618:22;;;-1:-1:-1;;;;;8666:24:16;;8660:4;8653:38;8711:4;8704:19;;;8467:12;8787:4;8467:12;8775:4;8467:12;;8759:5;8752;8747:45;8736:56;;9004:1;8997:4;8991:11;8988:18;8979:7;8975:32;8965:606;;9136:6;9126:7;9119:15;9115:28;9112:165;;;9192:16;9186:4;9181:3;9166:43;9242:16;9237:3;9230:29;9112:165;9553:1;9545:5;9533:18;9530:25;9511:16;9504:24;9500:56;9491:7;9487:70;9476:81;;8965:606;9591:4;9584:17;-1:-1:-1;8373:1244:16;;-1:-1:-1;;;;8373:1244:16:o;2546:1153:5:-;2785:10;;;;2747:15;;2785:10;;;;;2715:22;;2785:4;;:10;;2878:25;;;;;;:::i;:::-;;;;:35;;;;;2860:53;;2845:68;;-1:-1:-1;2929:27:5;;;2925:40;;2958:7;;;;;2925:40;2992:16;;;;;;;;;;;;;3227:20;;;;;:35;-1:-1:-1;3227:65:5;;;;-1:-1:-1;3276:16:5;3291:1;3276:12;:16;:::i;:::-;3266:26;;:6;:26;;;3227:65;3223:120;;;3320:16;:12;3335:1;3320:16;:::i;:::-;3302:34;;3223:120;3348:16;3382:15;3368:10;:6;3377:1;3368:10;:::i;:::-;3367:30;;;;:::i;:::-;3348:49;;3434:155;;;;;;;;3465:15;3434:155;;;;;;3508:23;3434:155;;;;3559:23;3434:155;;;3403:4;:17;;3421:9;3403:28;;;;;;;;;:::i;:::-;:186;;:28;;;;;;;;;:186;;;;;;;;;;;;;;;;;;-1:-1:-1;3403:186:5;;;;;;;;;;;;;3595:10;;;:22;;;;;;;;;;;;;;;3627:31;;;;;;;3623:71;;3660:16;;;:34;;;;;;;;;;;;3623:71;2709:990;;;;;;2546:1153;;;;:::o;9607:432:13:-;-1:-1:-1;;;;;9719:19:13;;9715:89;;9761:32;;;;;9790:1;9761:32;;;2831:74:24;2804:18;;9761:32:13;2685:226:24;9715:89:13;-1:-1:-1;;;;;9817:21:13;;9813:90;;9861:31;;;;;9889:1;9861:31;;;2831:74:24;2804:18;;9861:31:13;2685:226:24;9813:90:13;-1:-1:-1;;;;;9912:18:13;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;:35;;;9957:76;;;;10007:7;-1:-1:-1;;;;;9991:31:13;10000:5;-1:-1:-1;;;;;9991:31:13;;10016:5;9991:31;;;;3434:25:24;;3422:2;3407:18;;3288:177;9991:31:13;;;;;;;;9607:432;;;;:::o;4072:1462:8:-;4152:7;;4167:1332;4193:3;4188:2;:8;4167:1332;;;4212:17;4232:11;4235:3;4240:2;4232;:11::i;:::-;4212:31;;4267:8;4255:9;:20;4251:1242;;;4458:11;4472:52;4484:20;4495:9;4484:8;:20;:::i;:::-;4506:4;4512:11;4515:3;4520:2;4512;:11::i;4472:52::-;4458:66;;4538:3;4545:1;4538:8;4534:265;;4582:8;4564:15;4567:3;4572:6;:2;4577:1;4572:6;:::i;:::-;4564:2;:15::i;:::-;:26;4560:210;;;4751:6;:2;4756:1;4751:6;:::i;:::-;4744:13;;;;;;;4560:210;-1:-1:-1;4787:1:8;4534:265;4813:8;4818:3;4813:2;:8;:::i;:::-;4808:13;;4277:553;4251:1242;;;4846:11;4860:52;4872:20;4884:8;4872:9;:20;:::i;4860:52::-;4846:66;;4926:3;4933:1;4926:8;4922:540;;4965:8;4952:9;:21;:51;;;-1:-1:-1;4995:8:8;4977:15;4980:3;4985:6;4990:1;4985:2;:6;:::i;4977:15::-;:26;4952:51;4948:485;;;5418:2;5411:9;;;;;;;4948:485;-1:-1:-1;5450:1:8;4922:540;5476:8;5481:3;5476:2;:8;:::i;:::-;5471:13;;4836:657;4251:1242;-1:-1:-1;4198:4:8;;4167:1332;;;;5511:18;;;;;;;;;;;;;;14277:1160:6;-1:-1:-1;;;;;3024:18:13;;14331:17:6;3024:18:13;;;;;;;;;;;14414:13:6;;14410:1023;;-1:-1:-1;;;;;14461:23:6;;14437:21;14461:23;;;:12;:23;;;;;;;;;;14558:12;:23;;;;;;;;14607:6;;14681;;14695:33;;;;14787:23;;;;:33;;;14461:23;14846;14461;14607:6;14846:23;:::i;:::-;14828:41;-1:-1:-1;14935:15:6;14953:23;14963:13;14953:7;:23;:::i;:::-;14935:41;-1:-1:-1;14988:11:6;;14984:172;;15011:14;15052:4;15029:19;15041:7;15029:9;:19;:::i;:::-;15028:28;;;;:::i;:::-;-1:-1:-1;;;;;15116:21:6;;;;;;:10;:21;;;;;:31;;15011:45;;-1:-1:-1;15011:45:6;;15116:21;;;:31;;15011:45;;15116:31;:::i;:::-;;;;-1:-1:-1;;;14984:172:6;15167:11;;15163:122;;15190:14;15231:4;15208:19;15220:7;15208:9;:19;:::i;:::-;15207:28;;;;:::i;:::-;-1:-1:-1;;;;;15245:21:6;;;;;;:10;:21;;;;;:31;;15190:45;;-1:-1:-1;15190:45:6;;15245:21;;;:31;;15190:45;;15245:31;:::i;:::-;;;;-1:-1:-1;;;15163:122:6;14429:862;;;;;;7362:208:13;;:::o;14410:1023:6:-;15331:6;;-1:-1:-1;;;;;15305:23:6;;;;;;:12;:23;;;;;;;;:32;;;;15420:6;;15394:12;:23;;;;;;:32;14325:1112;14277:1160;:::o;18752:207::-;-1:-1:-1;;;;;18839:18:6;;;18835:40;;18859:16;18870:4;18859:10;:16::i;:::-;-1:-1:-1;;;;;18885:16:6;;;18881:36;;18903:14;18914:2;18903:10;:14::i;:::-;18923:31;18937:4;18943:2;18947:6;18923:13;:31::i;7340:921:5:-;7540:27;7569;7608:11;:16;;7623:1;7608:16;7604:92;;-1:-1:-1;7642:22:5;;-1:-1:-1;7666:22:5;7634:55;;7604:92;7749:19;;;7701:14;;7852:97;7880:4;7749:5;:19;7902:22;7926;7852:27;:97::i;:::-;7780:169;;;;7983:7;7959:31;;:10;:20;;;:31;;;7955:121;;8008:10;:29;;;8039:10;:29;;;8000:69;;;;;;;;;7955:121;8126:130;8146:11;8159:10;:20;;;8181:10;:29;;;8212:10;:29;;;8243:7;8126:12;:130::i;:::-;8081:175;;-1:-1:-1;8081:175:5;-1:-1:-1;;;;7340:921:5;;;;;;;;;:::o;6269:704:22:-;6331:7;6354:1;6359;6354:6;6350:150;;6454:35;1035:4:18;6454:11:22;:35::i;:::-;6950:1;6945;6941;:5;6940:11;;;;;:::i;:::-;;6954:1;6940:15;6930:5;;;6914:22;:42;;6269:704;-1:-1:-1;;;6269:704:22:o;1027:550::-;1088:12;;-1:-1:-1;;1471:1:22;1468;1461:20;1501:9;;;;1549:11;;;1535:12;;;;1531:30;;;;;1027:550;-1:-1:-1;;1027:550:22:o;1776:194:18:-;1881:10;1875:4;1868:24;1918:4;1912;1905:18;1949:4;1943;1936:18;4560:46:19;:52;:63;;4479:151;-1:-1:-1;4479:151:19:o;3467:230:8:-;3526:7;3541:10;3554:26;3566:3;3571:2;3575:4;3554:11;:26::i;:::-;3541:39;;3586:10;3629:25;3641:2;3645;3649:4;3629:11;:25::i;:::-;3599:27;3611:3;3616;3621:4;3599:11;:27::i;:::-;:55;;;;:::i;:::-;3586:68;;3667:25;3679:2;3683;3687:4;3667:11;:25::i;:::-;3660:32;3467:230;-1:-1:-1;;;;;3467:230:8:o;3701:284::-;3760:7;3775:17;3795:25;3807:2;3811;3815:4;3795:11;:25::i;:::-;3775:45;;3826:18;3847:27;3859:3;3864;3869:4;3847:11;:27::i;:::-;3826:48;;3927:34;3939:10;3951:3;3956:4;3927:11;:34::i;:::-;3887:37;3899:7;3903:3;3899:1;:7;:::i;:::-;3908:9;3919:4;3887:11;:37::i;:::-;:74;;;;:::i;5912:1107:13:-;-1:-1:-1;;;;;6001:18:13;;5997:540;;6153:5;6137:12;;:21;;;;;;;:::i;:::-;;;;-1:-1:-1;5997:540:13;;-1:-1:-1;5997:540:13;;-1:-1:-1;;;;;6211:15:13;;6189:19;6211:15;;;;;;;;;;;6244:19;;;6240:115;;;6290:50;;;;;-1:-1:-1;;;;;24144:55:24;;6290:50:13;;;24126:74:24;24216:18;;;24209:34;;;24259:18;;;24252:34;;;24099:18;;6290:50:13;23924:368:24;6240:115:13;-1:-1:-1;;;;;6475:15:13;;:9;:15;;;;;;;;;;6493:19;;;;6475:37;;5997:540;-1:-1:-1;;;;;6551:16:13;;6547:425;;6714:12;:21;;;;;;;6547:425;;;-1:-1:-1;;;;;6925:13:13;;:9;:13;;;;;;;;;;:22;;;;;;6547:425;7002:2;-1:-1:-1;;;;;6987:25:13;6996:4;-1:-1:-1;;;;;6987:25:13;;7006:5;6987:25;;;;3434::24;;3422:2;3407:18;;3288:177;6987:25:13;;;;;;;;5912:1107;;;:::o;5242:1164:5:-;5452:30;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;5452:30:5;5484:29;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;5484:29:5;5537:10;;;;;;;;;:4;;:10;;5567:25;;;;;;:::i;:::-;5553:39;;;;;;;;5567:25;;;;;;;;;5553:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;5620:43:5;;5625:5;;5655:7;5620:4;:43::i;:::-;5616:569;;;5777:21;;:32;;;;;;;5773:71;;-1:-1:-1;5819:11:5;;-1:-1:-1;5811:33:5;;5773:71;5853:23;5878;5913:89;5926:11;5939:5;5946:22;5970;5994:7;5913:12;:89::i;:::-;6031:107;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;6146:32:5;;-1:-1:-1;;;6146:32:5;5616:569;6237:16;;;;;;;;;;;6223:10;:6;6232:1;6223:10;:::i;:::-;6222:31;;;;:::i;:::-;6204:50;;;;;;;;;:::i;:::-;6190:64;;;;;;;;6204:50;;;;;;;;;6190:64;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;6285:43:5;;6290:5;;6320:7;6285:4;:43::i;:::-;6280:73;;6337:16;;;;;;;;;;;;;;6280:73;6366:35;6380:4;6386:5;6393:7;6366:13;:35::i;:::-;6359:42;;;;;5242:1164;;;;;;;;:::o;11215:992::-;11633:21;;11794:30;;;;11424:27;;;;11607:48;11615:39;;;11607:48;;;11698:31;;11690:40;;11424:27;;11767:57;;:24;:57;:::i;:::-;11742:82;;11830:22;11882:11;:30;;;11855:24;:57;;;;:::i;:::-;11830:82;;11979:78;11991:14;12007:24;12033:23;11979:11;:78::i;:::-;11946:11;:30;;;:111;;;;:::i;:::-;11918:139;;12124:78;12136:14;12152:24;12178:23;12124:11;:78::i;:::-;12091:11;:30;;;:111;;;;:::i;:::-;12063:139;;11482:725;;;;11215:992;;;;;;;;:::o;9843:290::-;9916:4;9938:5;9932:11;;:2;:11;;;;:26;;;;;9953:5;9947:11;;:2;:11;;;;9932:26;9928:47;;;9973:2;9967:8;;:2;:8;;;;9960:15;;;;9928:47;9982:18;10008:5;10003:10;;:2;:10;;;:30;;10021:12;;;;10026:7;10021:12;:::i;:::-;10003:30;;;10016:2;10003:30;;;9982:51;;;;10039:18;10065:5;10060:10;;:2;:10;;;:30;;10078:12;;;;10083:7;10078:12;:::i;:::-;10060:30;;;10073:2;10060:30;;;10039:51;;10104:24;;;;;9843:290;-1:-1:-1;;;;;9843:290:5:o;12551:963::-;12674:30;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;12674:30:5;12706:29;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;12706:29:5;12765:16;;;;;;;;;;;:4;;12743:19;;12765:16;;12893:10;;12885:23;12765:16;12884:40;;;;:::i;:::-;;;-1:-1:-1;;;12970:17:5;;;;;:21;13022:482;13070:1;13059:7;;;13058:13;13095:12;13108:17;;;13058:13;13108:17;;;;;:::i;:::-;;13095:31;;;;;;;:::i;:::-;13081:45;;;;;;;;13095:31;;;;;;;;;13081:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;13149:12:5;;13162:23;;;;13163:6;;13162:23;;;;;:::i;:::-;;13149:37;;;;;;;:::i;:::-;13136:50;;;;;;;;13149:37;;;;;;;;;13136:50;;;;;;;;;;;;;;;;;;;;;;;;13238:21;;13136:50;;-1:-1:-1;;;13226:43:5;;13231:5;;13261:7;13226:4;:43::i;:::-;13196:73;;13279:27;13309:42;13314:5;13321:7;13330:10;:20;;;13309:4;:42::i;:::-;13279:72;;13365:22;:48;;;;;13391:22;13365:48;13361:59;;;13415:5;;;;;13361:59;13434:22;13430:65;;;13463:2;13468:1;13463:6;13458:11;;13430:65;;;13494:1;13489:2;:6;13484:11;;13430:65;13035:469;;;13022:482;;;12853:657;;12737:777;;12551:963;;;;;;:::o;-1:-1:-1:-;;;;;;;;:::o;14:154:24:-;-1:-1:-1;;;;;93:5:24;89:54;82:5;79:65;69:93;;158:1;155;148:12;173:347;224:8;234:6;288:3;281:4;273:6;269:17;265:27;255:55;;306:1;303;296:12;255:55;-1:-1:-1;329:20:24;;372:18;361:30;;358:50;;;404:1;401;394:12;358:50;441:4;433:6;429:17;417:29;;493:3;486:4;477:6;469;465:19;461:30;458:39;455:59;;;510:1;507;500:12;525:785;622:6;630;638;646;654;707:3;695:9;686:7;682:23;678:33;675:53;;;724:1;721;714:12;675:53;769:23;;;-1:-1:-1;889:2:24;874:18;;861:32;;-1:-1:-1;971:2:24;956:18;;943:32;984:33;943:32;984:33;:::i;:::-;1036:7;-1:-1:-1;1094:2:24;1079:18;;1066:32;1121:18;1110:30;;1107:50;;;1153:1;1150;1143:12;1107:50;1192:58;1242:7;1233:6;1222:9;1218:22;1192:58;:::i;:::-;525:785;;;;-1:-1:-1;525:785:24;;-1:-1:-1;1269:8:24;;1166:84;525:785;-1:-1:-1;;;525:785:24:o;1315:477::-;1464:2;1453:9;1446:21;1427:4;1496:6;1490:13;1539:6;1534:2;1523:9;1519:18;1512:34;1598:6;1593:2;1585:6;1581:15;1576:2;1565:9;1561:18;1555:50;1654:1;1649:2;1640:6;1629:9;1625:22;1621:31;1614:42;1783:2;-1:-1:-1;;1708:2:24;1700:6;1696:15;1692:88;1681:9;1677:104;1673:113;1665:121;;;1315:477;;;;:::o;2121:367::-;2189:6;2197;2250:2;2238:9;2229:7;2225:23;2221:32;2218:52;;;2266:1;2263;2256:12;2218:52;2305:9;2292:23;2324:31;2349:5;2324:31;:::i;:::-;2374:5;2452:2;2437:18;;;;2424:32;;-1:-1:-1;;;2121:367:24:o;2916:::-;2984:6;2992;3045:2;3033:9;3024:7;3020:23;3016:32;3013:52;;;3061:1;3058;3051:12;3013:52;3106:23;;;-1:-1:-1;3205:2:24;3190:18;;3177:32;3218:33;3177:32;3218:33;:::i;:::-;3270:7;3260:17;;;2916:367;;;;;:::o;3470:608::-;3556:6;3564;3572;3580;3633:3;3621:9;3612:7;3608:23;3604:33;3601:53;;;3650:1;3647;3640:12;3601:53;3695:23;;;-1:-1:-1;3794:2:24;3779:18;;3766:32;3807:33;3766:32;3807:33;:::i;:::-;3470:608;;3859:7;;-1:-1:-1;;;;3939:2:24;3924:18;;3911:32;;4042:2;4027:18;4014:32;;3470:608::o;4083:247::-;4142:6;4195:2;4183:9;4174:7;4170:23;4166:32;4163:52;;;4211:1;4208;4201:12;4163:52;4250:9;4237:23;4269:31;4294:5;4269:31;:::i;4945:508::-;5022:6;5030;5038;5091:2;5079:9;5070:7;5066:23;5062:32;5059:52;;;5107:1;5104;5097:12;5059:52;5146:9;5133:23;5165:31;5190:5;5165:31;:::i;:::-;5215:5;-1:-1:-1;5272:2:24;5257:18;;5244:32;5285:33;5244:32;5285:33;:::i;:::-;4945:508;;5337:7;;-1:-1:-1;;;5417:2:24;5402:18;;;;5389:32;;4945:508::o;5458:226::-;5517:6;5570:2;5558:9;5549:7;5545:23;5541:32;5538:52;;;5586:1;5583;5576:12;5538:52;-1:-1:-1;5631:23:24;;5458:226;-1:-1:-1;5458:226:24:o;6028:388::-;6096:6;6104;6157:2;6145:9;6136:7;6132:23;6128:32;6125:52;;;6173:1;6170;6163:12;6125:52;6212:9;6199:23;6231:31;6256:5;6231:31;:::i;:::-;6281:5;-1:-1:-1;6338:2:24;6323:18;;6310:32;6351:33;6310:32;6351:33;:::i;6610:272::-;6668:6;6721:2;6709:9;6700:7;6696:23;6692:32;6689:52;;;6737:1;6734;6727:12;6689:52;6776:9;6763:23;6826:6;6819:5;6815:18;6808:5;6805:29;6795:57;;6848:1;6845;6838:12;7707:118;7793:5;7786:13;7779:21;7772:5;7769:32;7759:60;;7815:1;7812;7805:12;7830:382;7895:6;7903;7956:2;7944:9;7935:7;7931:23;7927:32;7924:52;;;7972:1;7969;7962:12;7924:52;8011:9;7998:23;8030:31;8055:5;8030:31;:::i;:::-;8080:5;-1:-1:-1;8137:2:24;8122:18;;8109:32;8150:30;8109:32;8150:30;:::i;8217:609::-;8302:6;8310;8363:2;8351:9;8342:7;8338:23;8334:32;8331:52;;;8379:1;8376;8369:12;8331:52;8419:9;8406:23;8452:18;8444:6;8441:30;8438:50;;;8484:1;8481;8474:12;8438:50;8507:22;;8560:4;8552:13;;8548:27;-1:-1:-1;8538:55:24;;8589:1;8586;8579:12;8538:55;8629:2;8616:16;8655:18;8647:6;8644:30;8641:50;;;8687:1;8684;8677:12;8641:50;8740:7;8735:2;8725:6;8722:1;8718:14;8714:2;8710:23;8706:32;8703:45;8700:65;;;8761:1;8758;8751:12;8700:65;8792:2;8784:11;;;;;8814:6;;-1:-1:-1;8217:609:24;-1:-1:-1;;;8217:609:24:o;8831:420::-;8884:3;8922:5;8916:12;8949:6;8944:3;8937:19;8981:4;8976:3;8972:14;8965:21;;9020:4;9013:5;9009:16;9043:1;9053:173;9067:6;9064:1;9061:13;9053:173;;;9128:13;;9116:26;;9171:4;9162:14;;;;9199:17;;;;9089:1;9082:9;9053:173;;;-1:-1:-1;9242:3:24;;8831:420;-1:-1:-1;;;;8831:420:24:o;9256:465::-;9513:2;9502:9;9495:21;9476:4;9539:56;9591:2;9580:9;9576:18;9568:6;9539:56;:::i;:::-;9643:9;9635:6;9631:22;9626:2;9615:9;9611:18;9604:50;9671:44;9708:6;9700;9671:44;:::i;10077:410::-;10148:6;10156;10209:2;10197:9;10188:7;10184:23;10180:32;10177:52;;;10225:1;10222;10215:12;10177:52;10265:9;10252:23;10298:18;10290:6;10287:30;10284:50;;;10330:1;10327;10320:12;10284:50;10369:58;10419:7;10410:6;10399:9;10395:22;10369:58;:::i;:::-;10446:8;;10343:84;;-1:-1:-1;10077:410:24;-1:-1:-1;;;;10077:410:24:o;10492:245::-;10559:6;10612:2;10600:9;10591:7;10587:23;10583:32;10580:52;;;10628:1;10625;10618:12;10580:52;10660:9;10654:16;10679:28;10701:5;10679:28;:::i;10742:714::-;-1:-1:-1;;;;;10987:6:24;10983:55;10972:9;10965:74;11075:6;11070:2;11059:9;11055:18;11048:34;11118:6;11113:2;11102:9;11098:18;11091:34;11161:3;11156:2;11145:9;11141:18;11134:31;11202:6;11196:3;11185:9;11181:19;11174:35;11260:6;11252;11246:3;11235:9;11231:19;11218:49;11317:1;11287:22;;;11311:3;11283:32;;;11276:43;;;;11371:2;11359:15;;;-1:-1:-1;;11355:88:24;11340:104;11336:114;;10742:714;-1:-1:-1;;;;10742:714:24:o;11461:230::-;11531:6;11584:2;11572:9;11563:7;11559:23;11555:32;11552:52;;;11600:1;11597;11590:12;11552:52;-1:-1:-1;11645:16:24;;11461:230;-1:-1:-1;11461:230:24:o;11696:184::-;11748:77;11745:1;11738:88;11845:4;11842:1;11835:15;11869:4;11866:1;11859:15;11885:128;11952:9;;;11973:11;;;11970:37;;;11987:18;;:::i;12018:125::-;12083:9;;;12104:10;;;12101:36;;;12117:18;;:::i;12148:168::-;12221:9;;;12252;;12269:15;;;12263:22;;12249:37;12239:71;;12290:18;;:::i;12321:184::-;12373:77;12370:1;12363:88;12470:4;12467:1;12460:15;12494:4;12491:1;12484:15;12510:120;12550:1;12576;12566:35;;12581:18;;:::i;:::-;-1:-1:-1;12615:9:24;;12510:120::o;12759:1090::-;12911:4;12953:3;12942:9;12938:19;12930:27;;13003:34;12994:6;12988:13;12984:54;12973:9;12966:73;13107:34;13099:4;13091:6;13087:17;13081:24;13077:65;13070:4;13059:9;13055:20;13048:95;13211:34;13203:4;13195:6;13191:17;13185:24;13181:65;13174:4;13163:9;13159:20;13152:95;13294:4;13286:6;13282:17;13276:24;13309:54;13357:4;13346:9;13342:20;13328:12;12712:34;12701:46;12689:59;;12635:119;13309:54;;13412:4;13404:6;13400:17;13394:24;13427:56;13477:4;13466:9;13462:20;13446:14;12712:34;12701:46;12689:59;;12635:119;13427:56;;13532:4;13524:6;13520:17;13514:24;13547:56;13597:4;13586:9;13582:20;13566:14;12712:34;12701:46;12689:59;;12635:119;13547:56;;13652:4;13644:6;13640:17;13634:24;13667:56;13717:4;13706:9;13702:20;13686:14;12712:34;12701:46;12689:59;;12635:119;13667:56;;13772:4;13764:6;13760:17;13754:24;13787:56;13837:4;13826:9;13822:20;13806:14;12712:34;12701:46;12689:59;;12635:119;13787:56;;12759:1090;;;;:::o;14250:437::-;14329:1;14325:12;;;;14372;;;14393:61;;14447:4;14439:6;14435:17;14425:27;;14393:61;14500:2;14492:6;14489:14;14469:18;14466:38;14463:218;;14537:77;14534:1;14527:88;14638:4;14635:1;14628:15;14666:4;14663:1;14656:15;14463:218;;14250:437;;;:::o;15330:184::-;15382:77;15379:1;15372:88;15479:4;15476:1;15469:15;15503:4;15500:1;15493:15;15794:184;15846:77;15843:1;15836:88;15943:4;15940:1;15933:15;15967:4;15964:1;15957:15;15983:1053;16063:6;16116:2;16104:9;16095:7;16091:23;16087:32;16084:52;;;16132:1;16129;16122:12;16084:52;16165:9;16159:16;16198:18;16190:6;16187:30;16184:50;;;16230:1;16227;16220:12;16184:50;16253:22;;16306:4;16298:13;;16294:27;-1:-1:-1;16284:55:24;;16335:1;16332;16325:12;16284:55;16368:2;16362:9;16394:18;16386:6;16383:30;16380:56;;;16416:18;;:::i;:::-;16465:2;16459:9;-1:-1:-1;;16607:2:24;-1:-1:-1;;16531:4:24;16523:6;16519:17;16515:90;16511:99;16507:172;16499:6;16495:185;16746:6;16734:10;16731:22;16710:18;16698:10;16695:34;16692:62;16689:88;;;16757:18;;:::i;:::-;16793:2;16786:22;16817;;;16858:15;;;16875:2;16854:24;16851:37;-1:-1:-1;16848:57:24;;;16901:1;16898;16891:12;16848:57;16950:6;16945:2;16941;16937:11;16932:2;16924:6;16920:15;16914:43;17003:1;16977:19;;;16998:2;16973:28;16966:39;;;;16981:6;15983:1053;-1:-1:-1;;;;15983:1053:24:o;17167:692::-;17269:2;17264:3;17261:11;17258:595;;;17306:10;17301:3;17298:19;17295:548;;;17358:5;17355:1;17348:16;17406:4;17403:1;17393:18;17471:2;17459:10;17455:19;17452:1;17448:27;17510:4;17498:10;17495:20;17492:45;;;-1:-1:-1;17534:1:24;17492:45;17573:23;;;;17643:2;17634:12;;17631:1;17627:20;17623:39;17688:1;17706:123;17720:2;17717:1;17714:9;17706:123;;;17809:1;17788:19;;;17781:30;17738:1;17731:9;17706:123;;;17710:3;;;17167:692;;;:::o;18095:1418::-;18221:3;18215:10;18248:18;18240:6;18237:30;18234:56;;;18270:18;;:::i;:::-;18299:97;18389:6;18349:38;18381:4;18375:11;18349:38;:::i;:::-;18343:4;18299:97;:::i;:::-;18445:4;18476:2;18465:14;;18493:1;18488:768;;;;19300:1;19317:6;19314:89;;;-1:-1:-1;19369:19:24;;;19363:26;19314:89;-1:-1:-1;;17992:1:24;17988:11;;;17984:84;17980:89;17970:100;18076:1;18072:11;;;17967:117;19416:81;;18458:1049;;18488:768;17114:1;17107:14;;;17151:4;17138:18;;-1:-1:-1;;18524:79:24;;;18701:222;18715:7;18712:1;18709:14;18701:222;;;18797:19;;;18791:26;18776:42;;18904:4;18889:20;;;;18857:1;18845:14;;;;18731:12;18701:222;;;18705:3;18951:6;18942:7;18939:19;18936:261;;;19012:19;;;19006:26;-1:-1:-1;;19095:1:24;19091:14;;;19107:3;19087:24;19083:97;19079:102;19064:118;19049:134;;18936:261;-1:-1:-1;;;;19243:1:24;19227:14;;;19223:22;19210:36;;-1:-1:-1;18095:1418:24:o;19518:273::-;19586:6;19639:2;19627:9;19618:7;19614:23;19610:32;19607:52;;;19655:1;19652;19645:12;19607:52;19687:9;19681:16;19737:4;19730:5;19726:16;19719:5;19716:27;19706:55;;19757:1;19754;19747:12;19796:375;19884:1;19902:5;19916:249;19937:1;19927:8;19924:15;19916:249;;;19987:4;19982:3;19978:14;19972:4;19969:24;19966:50;;;19996:18;;:::i;:::-;20046:1;20036:8;20032:16;20029:49;;;20060:16;;;;20029:49;20143:1;20139:16;;;;;20099:15;;19916:249;;;19796:375;;;;;;:::o;20176:1022::-;20225:5;20255:8;20245:80;;-1:-1:-1;20296:1:24;20310:5;;20245:80;20344:4;20334:76;;-1:-1:-1;20381:1:24;20395:5;;20334:76;20426:4;20444:1;20439:59;;;;20512:1;20507:174;;;;20419:262;;20439:59;20469:1;20460:10;;20483:5;;;20507:174;20544:3;20534:8;20531:17;20528:43;;;20551:18;;:::i;:::-;-1:-1:-1;;20607:1:24;20593:16;;20666:5;;20419:262;;20765:2;20755:8;20752:16;20746:3;20740:4;20737:13;20733:36;20727:2;20717:8;20714:16;20709:2;20703:4;20700:12;20696:35;20693:77;20690:203;;;-1:-1:-1;20802:19:24;;;20878:5;;20690:203;20925:102;-1:-1:-1;;20950:8:24;20944:4;20925:102;:::i;:::-;21123:6;-1:-1:-1;;21051:79:24;21042:7;21039:92;21036:118;;;21134:18;;:::i;21203:140::-;21261:5;21290:47;21331:4;21321:8;21317:19;21311:4;21290:47;:::i;21348:251::-;21418:6;21471:2;21459:9;21450:7;21446:23;21442:32;21439:52;;;21487:1;21484;21477:12;21439:52;21519:9;21513:16;21538:31;21563:5;21538:31;:::i;21604:1317::-;21728:18;21723:3;21720:27;21717:53;;;21750:18;;:::i;:::-;21779:94;21869:3;21829:38;21861:4;21855:11;21829:38;:::i;:::-;21823:4;21779:94;:::i;:::-;21899:1;21924:2;21919:3;21916:11;21941:1;21936:727;;;;22707:1;22724:3;22721:93;;;-1:-1:-1;22780:19:24;;;22767:33;22721:93;-1:-1:-1;;17992:1:24;17988:11;;;17984:84;17980:89;17970:100;18076:1;18072:11;;;17967:117;22827:78;;21909:1006;;21936:727;17114:1;17107:14;;;17151:4;17138:18;;-1:-1:-1;;21972:76:24;;;22146:229;22160:7;22157:1;22154:14;22146:229;;;22249:19;;;22236:33;22221:49;;22356:4;22341:20;;;;22309:1;22297:14;;;;22176:12;22146:229;;;22150:3;22403;22394:7;22391:16;22388:219;;;-1:-1:-1;;22517:3:24;22511;22508:1;22504:11;22500:21;22496:94;22492:99;22479:9;22474:3;22470:19;22457:33;22453:139;22445:6;22438:155;22388:219;;;22650:1;22644:3;22641:1;22637:11;22633:19;22627:4;22620:33;21909:1006;;21604:1317;;;:::o;22926:471::-;23011:6;23019;23027;23080:2;23068:9;23059:7;23055:23;23051:32;23048:52;;;23096:1;23093;23086:12;23048:52;23141:16;;23247:2;23232:18;;23226:25;23322:2;23307:18;;23301:25;23141:16;;-1:-1:-1;23226:25:24;-1:-1:-1;23335:30:24;23301:25;23335:30;:::i;:::-;23384:7;23374:17;;;22926:471;;;;;:::o;24297:212::-;24339:3;24377:5;24371:12;24421:6;24414:4;24407:5;24403:16;24398:3;24392:36;24483:1;24447:16;;24472:13;;;-1:-1:-1;24447:16:24;;24297:212;-1:-1:-1;24297:212:24:o;24514:570::-;24925:17;24920:3;24913:30;24895:3;24962:39;24997:2;24992:3;24988:12;24980:6;24962:39;:::i;:::-;25021:3;25017:2;25010:15;25041:37;25075:1;25071:2;25067:10;25059:6;25041:37;:::i;25089:561::-;25500:9;25495:3;25488:22;25470:3;25529:38;25564:1;25559:3;25555:11;25547:6;25529:38;:::i;25655:276::-;25713:6;25766:2;25754:9;25745:7;25741:23;25737:32;25734:52;;;25782:1;25779;25772:12;25734:52;25821:9;25808:23;25871:10;25864:5;25860:22;25853:5;25850:33;25840:61;;25897:1;25894;25887:12;25936:158;26029:6;26022:14;;;26006;;;26002:35;;26049:16;;26046:42;;;26068:18;;:::i;26099:155::-;26190:6;26167:14;;;26183;;;26163:35;;26210:15;;26207:41;;;26228:18;;:::i;26259:162::-;26290:1;26324:6;26321:1;26317:14;26350:3;26340:37;;26357:18;;:::i;:::-;26411:3;26402:6;26399:1;26395:14;26391:24;26386:29;;;26259:162;;;;:::o;26426:173::-;26523:12;26494:20;;;26516;;;26490:47;;26549:21;;26546:47;;;26573:18;;:::i","linkReferences":{},"cborAuxdata":{"1":{"value":"0xa2646970667358221220aa9bbd0570a5d863052798f5e72b7cb02066916c003643151160fd218424ee5f64736f6c63430008240033","offset":21426},"2":{"value":"0xa2646970667358221220eeabba3bd98e978db119b83233dcf1a15cbc1751f5b6fdcc907308b07b33330264736f6c63430008240033","offset":21373}},"immutableReferences":{},"transformations":[{"id":"1","type":"replace","offset":21426,"reason":"cborAuxdata"},{"id":"2","type":"replace","offset":21373,"reason":"cborAuxdata"}],"transformationValues":{"cborAuxdata":{"1":"0xa2646970667358221220c44780aa04b481bff35f6e43d6d561fdb2f8fde74b2f0d2839a586c497a0e40264736f6c63430008240033","2":"0xa26469706673582212207519fe77d60fa2befaa943fe4f040b0f82abdb9264e6f95e7af68108cee501e564736f6c63430008240033"}}},"deployment":{"transactionHash":"0x8912530e5ae81a9efd09bccb0d8c15430a0cf52df5a50a724285fc2d73339985","blockNumber":"52880012","transactionIndex":"60","deployer":"0xCaF2C1251465C90D91A16b2288D9d6389f836A0E"},"sources":{"V3/src/pools/StablePool.sol":{"content":"// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity 0.8.36;\n\nimport {Math} from '@openzeppelin/contracts/utils/math/Math.sol';\n\nimport {IPool} from 'V3/interfaces/pools/IPool.sol';\nimport {IStablePool} from 'V3/interfaces/pools/IStablePool.sol';\n\nimport {Pool} from 'V3/pools/Pool.sol';\n\n/// @title StablePool\n/// @notice Aerodrome V2 stable-swap pool.\ncontract StablePool is Pool, IStablePool {\n  /// @inheritdoc IStablePool\n  uint256 public constant MINIMUM_K = 10 ** 10;\n\n  /// @inheritdoc IPool\n  bytes32 public constant POOL_TYPE = 'V2_STABLE';\n\n  /// @inheritdoc Pool\n  function _getAmountOut(\n    uint256 _amountIn,\n    address _tokenIn,\n    uint256 _reserve0,\n    uint256 _reserve1\n  ) internal view override returns (uint256) {\n    uint256 _targetK = _k(_reserve0, _reserve1);\n    _reserve0 = (_reserve0 * 1e18) / _decimals0;\n    _reserve1 = (_reserve1 * 1e18) / _decimals1;\n    (uint256 _reserveA, uint256 _reserveB) = _tokenIn == token0 ? (_reserve0, _reserve1) : (_reserve1, _reserve0);\n    _amountIn = _tokenIn == token0 ? (_amountIn * 1e18) / _decimals0 : (_amountIn * 1e18) / _decimals1;\n    uint256 _amountOut = _reserveB - _getY(_amountIn + _reserveA, _targetK, _reserveB);\n    return (_amountOut * (_tokenIn == token0 ? _decimals1 : _decimals0)) / 1e18;\n  }\n\n  /// @inheritdoc Pool\n  function _getAmountIn(\n    uint256 _amountOut,\n    address _tokenOut,\n    uint256 _reserve0,\n    uint256 _reserve1\n  ) internal view override returns (uint256) {\n    uint256 _targetK = _k(_reserve0, _reserve1);\n    _reserve0 = (_reserve0 * 1e18) / _decimals0;\n    _reserve1 = (_reserve1 * 1e18) / _decimals1;\n    (uint256 _reserveOut, uint256 _reserveIn) = _tokenOut == token0 ? (_reserve0, _reserve1) : (_reserve1, _reserve0);\n    (uint256 _decimalsOut, uint256 _decimalsIn) =\n      _tokenOut == token0 ? (_decimals0, _decimals1) : (_decimals1, _decimals0);\n    _amountOut = Math.ceilDiv(_amountOut * 1e18, _decimalsOut);\n    if (_amountOut >= _reserveOut) revert InsufficientLiquidity();\n    uint256 _newReserveIn = _getY(_reserveOut - _amountOut, _targetK, _reserveIn);\n    return Math.ceilDiv((_newReserveIn - _reserveIn) * _decimalsIn, 1e18);\n  }\n\n  /// @inheritdoc Pool\n  function _k(uint256 _x, uint256 _y) internal view override returns (uint256) {\n    uint256 _scaledX = (_x * 1e18) / _decimals0;\n    uint256 _scaledY = (_y * 1e18) / _decimals1;\n    uint256 _a = Math.mulDiv(_scaledX, _scaledY, 1e18);\n    uint256 _b = Math.mulDiv(_scaledX, _scaledX, 1e18) + Math.mulDiv(_scaledY, _scaledY, 1e18);\n    return Math.mulDiv(_a, _b, 1e18); // x^3*y + y^3*x\n  }\n\n  /// @inheritdoc Pool\n  function _mintValidation(uint256 _amount0, uint256 _amount1) internal view override {\n    if ((_amount0 * 1e18) / _decimals0 != (_amount1 * 1e18) / _decimals1) revert DepositsNotEqual();\n    if (_k(_amount0, _amount1) <= MINIMUM_K) revert BelowMinimumK();\n  }\n\n  /// @inheritdoc Pool\n  function _kThresholdValidation(uint256 _x, uint256 _y) internal view override {\n    if (_k(_x, _y) == 0) revert KIsZero();\n  }\n\n  /// @inheritdoc Pool\n  function _poolName(string memory _symbol0, string memory _symbol1) internal pure override returns (string memory) {\n    return string(abi.encodePacked('StableV2 AMM - ', _symbol0, '/', _symbol1));\n  }\n\n  /// @inheritdoc Pool\n  function _poolSymbol(string memory _symbol0, string memory _symbol1) internal pure override returns (string memory) {\n    return string(abi.encodePacked('sAMMV2-', _symbol0, '/', _symbol1));\n  }\n\n  function _f(uint256 _x0, uint256 _y) private pure returns (uint256) {\n    uint256 _a = Math.mulDiv(_x0, _y, 1e18);\n    uint256 _b = Math.mulDiv(_x0, _x0, 1e18) + Math.mulDiv(_y, _y, 1e18);\n    return Math.mulDiv(_a, _b, 1e18);\n  }\n\n  function _d(uint256 _x0, uint256 _y) private pure returns (uint256) {\n    uint256 _ySquared = Math.mulDiv(_y, _y, 1e18);\n    uint256 _x0Squared = Math.mulDiv(_x0, _x0, 1e18);\n    return Math.mulDiv(3 * _x0, _ySquared, 1e18) + Math.mulDiv(_x0Squared, _x0, 1e18); // 3*x0*y^2 + x0^3\n  }\n\n  /// @dev Use Newton-Raphson to approximate the solution to `x^3*y + y^3*x >= k`.\n  function _getY(uint256 _x0, uint256 _targetK, uint256 _y) private pure returns (uint256) {\n    for (uint256 _i = 0; _i < 255; _i++) {\n      uint256 _currentK = _f(_x0, _y);\n      if (_currentK < _targetK) {\n        // dy == 0 means _d(_x0, _y) is too large compare to (_targetK - _currentK) and the rounding error\n        // screwed us. In this case, we need to increase y by 1\n        uint256 _dy = Math.mulDiv(_targetK - _currentK, 1e18, _d(_x0, _y));\n        if (_dy == 0) {\n          if (_f(_x0, _y + 1) > _targetK) {\n            // If _f(_x0, _y + 1) > _targetK, then we are close to the correct answer.\n            // There's no closer answer than y + 1\n            return _y + 1;\n          }\n          _dy = 1;\n        }\n        _y = _y + _dy;\n      } else {\n        uint256 _dy = Math.mulDiv(_currentK - _targetK, 1e18, _d(_x0, _y));\n        if (_dy == 0) {\n          if (_currentK == _targetK || _f(_x0, _y - 1) < _targetK) {\n            // Likewise, if _currentK == _targetK, we found the correct answer.\n            // If _f(_x0, _y - 1) < _targetK, then we are close to the correct answer.\n            // There's no closer answer than \"y\"\n            // It's worth mentioning that we need to find y where f(x0, y) >= _targetK\n            // As a result, we can't return y - 1 even it's closer to the correct answer\n            return _y;\n          }\n          _dy = 1;\n        }\n        _y = _y - _dy;\n      }\n    }\n    revert CannotCalculateY();\n  }\n}\n"},"node_modules/@openzeppelin/contracts/utils/math/Math.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.6.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.20;\n\nimport {Panic} from \"../Panic.sol\";\nimport {SafeCast} from \"./SafeCast.sol\";\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n    enum Rounding {\n        Floor, // Toward negative infinity\n        Ceil, // Toward positive infinity\n        Trunc, // Toward zero\n        Expand // Away from zero\n    }\n\n    /**\n     * @dev Return the 512-bit addition of two uint256.\n     *\n     * The result is stored in two 256 variables such that sum = high * 2²⁵⁶ + low.\n     */\n    function add512(uint256 a, uint256 b) internal pure returns (uint256 high, uint256 low) {\n        assembly (\"memory-safe\") {\n            low := add(a, b)\n            high := lt(low, a)\n        }\n    }\n\n    /**\n     * @dev Return the 512-bit multiplication of two uint256.\n     *\n     * The result is stored in two 256 variables such that product = high * 2²⁵⁶ + low.\n     */\n    function mul512(uint256 a, uint256 b) internal pure returns (uint256 high, uint256 low) {\n        // 512-bit multiply [high low] = x * y. Compute the product mod 2²⁵⁶ and mod 2²⁵⁶ - 1, then use\n        // the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n        // variables such that product = high * 2²⁵⁶ + low.\n        assembly (\"memory-safe\") {\n            let mm := mulmod(a, b, not(0))\n            low := mul(a, b)\n            high := sub(sub(mm, low), lt(mm, low))\n        }\n    }\n\n    /**\n     * @dev Returns the addition of two unsigned integers, with a success flag (no overflow).\n     */\n    function tryAdd(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n        unchecked {\n            uint256 c = a + b;\n            success = c >= a;\n            result = c * SafeCast.toUint(success);\n        }\n    }\n\n    /**\n     * @dev Returns the subtraction of two unsigned integers, with a success flag (no overflow).\n     */\n    function trySub(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n        unchecked {\n            uint256 c = a - b;\n            success = c <= a;\n            result = c * SafeCast.toUint(success);\n        }\n    }\n\n    /**\n     * @dev Returns the multiplication of two unsigned integers, with a success flag (no overflow).\n     */\n    function tryMul(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n        unchecked {\n            uint256 c = a * b;\n            assembly (\"memory-safe\") {\n                // Only true when the multiplication doesn't overflow\n                // (c / a == b) || (a == 0)\n                success := or(eq(div(c, a), b), iszero(a))\n            }\n            // equivalent to: success ? c : 0\n            result = c * SafeCast.toUint(success);\n        }\n    }\n\n    /**\n     * @dev Returns the division of two unsigned integers, with a success flag (no division by zero).\n     */\n    function tryDiv(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n        unchecked {\n            success = b > 0;\n            assembly (\"memory-safe\") {\n                // The `DIV` opcode returns zero when the denominator is 0.\n                result := div(a, b)\n            }\n        }\n    }\n\n    /**\n     * @dev Returns the remainder of dividing two unsigned integers, with a success flag (no division by zero).\n     */\n    function tryMod(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n        unchecked {\n            success = b > 0;\n            assembly (\"memory-safe\") {\n                // The `MOD` opcode returns zero when the denominator is 0.\n                result := mod(a, b)\n            }\n        }\n    }\n\n    /**\n     * @dev Unsigned saturating addition, bounds to `2²⁵⁶ - 1` instead of overflowing.\n     */\n    function saturatingAdd(uint256 a, uint256 b) internal pure returns (uint256) {\n        (bool success, uint256 result) = tryAdd(a, b);\n        return ternary(success, result, type(uint256).max);\n    }\n\n    /**\n     * @dev Unsigned saturating subtraction, bounds to zero instead of overflowing.\n     */\n    function saturatingSub(uint256 a, uint256 b) internal pure returns (uint256) {\n        (, uint256 result) = trySub(a, b);\n        return result;\n    }\n\n    /**\n     * @dev Unsigned saturating multiplication, bounds to `2²⁵⁶ - 1` instead of overflowing.\n     */\n    function saturatingMul(uint256 a, uint256 b) internal pure returns (uint256) {\n        (bool success, uint256 result) = tryMul(a, b);\n        return ternary(success, result, type(uint256).max);\n    }\n\n    /**\n     * @dev Branchless ternary evaluation for `condition ? a : b`. Gas costs are constant.\n     *\n     * IMPORTANT: This function may reduce bytecode size and consume less gas when used standalone.\n     * However, the compiler may optimize Solidity ternary operations (i.e. `condition ? a : b`) to only compute\n     * one branch when needed, making this function more expensive.\n     */\n    function ternary(bool condition, uint256 a, uint256 b) internal pure returns (uint256) {\n        unchecked {\n            // branchless ternary works because:\n            // b ^ (a ^ b) == a\n            // b ^ 0 == b\n            return b ^ ((a ^ b) * SafeCast.toUint(condition));\n        }\n    }\n\n    /**\n     * @dev Returns the largest of two numbers.\n     */\n    function max(uint256 a, uint256 b) internal pure returns (uint256) {\n        return ternary(a > b, a, b);\n    }\n\n    /**\n     * @dev Returns the smallest of two numbers.\n     */\n    function min(uint256 a, uint256 b) internal pure returns (uint256) {\n        return ternary(a < b, a, b);\n    }\n\n    /**\n     * @dev Returns the average of two numbers. The result is rounded towards\n     * zero.\n     */\n    function average(uint256 a, uint256 b) internal pure returns (uint256) {\n        unchecked {\n            // (a + b) / 2 can overflow.\n            return (a & b) + (a ^ b) / 2;\n        }\n    }\n\n    /**\n     * @dev Returns the ceiling of the division of two numbers.\n     *\n     * This differs from standard division with `/` in that it rounds towards infinity instead\n     * of rounding towards zero.\n     */\n    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n        if (b == 0) {\n            // Guarantee the same behavior as in a regular Solidity division.\n            Panic.panic(Panic.DIVISION_BY_ZERO);\n        }\n\n        // The following calculation ensures accurate ceiling division without overflow.\n        // Since a is non-zero, (a - 1) / b will not overflow.\n        // The largest possible result occurs when (a - 1) / b is type(uint256).max,\n        // but the largest value we can obtain is type(uint256).max - 1, which happens\n        // when a = type(uint256).max and b = 1.\n        unchecked {\n            return SafeCast.toUint(a > 0) * ((a - 1) / b + 1);\n        }\n    }\n\n    /**\n     * @dev Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or\n     * denominator == 0.\n     *\n     * Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) with further edits by\n     * Uniswap Labs also under MIT license.\n     */\n    function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n        unchecked {\n            (uint256 high, uint256 low) = mul512(x, y);\n\n            // Handle non-overflow cases, 256 by 256 division.\n            if (high == 0) {\n                // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n                // The surrounding unchecked block does not change this fact.\n                // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n                return low / denominator;\n            }\n\n            // Make sure the result is less than 2²⁵⁶. Also prevents denominator == 0.\n            if (denominator <= high) {\n                Panic.panic(ternary(denominator == 0, Panic.DIVISION_BY_ZERO, Panic.UNDER_OVERFLOW));\n            }\n\n            ///////////////////////////////////////////////\n            // 512 by 256 division.\n            ///////////////////////////////////////////////\n\n            // Make division exact by subtracting the remainder from [high low].\n            uint256 remainder;\n            assembly (\"memory-safe\") {\n                // Compute remainder using mulmod.\n                remainder := mulmod(x, y, denominator)\n\n                // Subtract 256 bit number from 512 bit number.\n                high := sub(high, gt(remainder, low))\n                low := sub(low, remainder)\n            }\n\n            // Factor powers of two out of denominator and compute largest power of two divisor of denominator.\n            // Always >= 1. See https://cs.stackexchange.com/q/138556/92363.\n\n            uint256 twos = denominator & (0 - denominator);\n            assembly (\"memory-safe\") {\n                // Divide denominator by twos.\n                denominator := div(denominator, twos)\n\n                // Divide [high low] by twos.\n                low := div(low, twos)\n\n                // Flip twos such that it is 2²⁵⁶ / twos. If twos is zero, then it becomes one.\n                twos := add(div(sub(0, twos), twos), 1)\n            }\n\n            // Shift in bits from high into low.\n            low |= high * twos;\n\n            // Invert denominator mod 2²⁵⁶. Now that denominator is an odd number, it has an inverse modulo 2²⁵⁶ such\n            // that denominator * inv ≡ 1 mod 2²⁵⁶. Compute the inverse by starting with a seed that is correct for\n            // four bits. That is, denominator * inv ≡ 1 mod 2⁴.\n            uint256 inverse = (3 * denominator) ^ 2;\n\n            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also\n            // works in modular arithmetic, doubling the correct bits in each step.\n            inverse *= 2 - denominator * inverse; // inverse mod 2⁸\n            inverse *= 2 - denominator * inverse; // inverse mod 2¹⁶\n            inverse *= 2 - denominator * inverse; // inverse mod 2³²\n            inverse *= 2 - denominator * inverse; // inverse mod 2⁶⁴\n            inverse *= 2 - denominator * inverse; // inverse mod 2¹²⁸\n            inverse *= 2 - denominator * inverse; // inverse mod 2²⁵⁶\n\n            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n            // This will give us the correct result modulo 2²⁵⁶. Since the preconditions guarantee that the outcome is\n            // less than 2²⁵⁶, this is the final result. We don't need to compute the high bits of the result and high\n            // is no longer required.\n            result = low * inverse;\n            return result;\n        }\n    }\n\n    /**\n     * @dev Calculates x * y / denominator with full precision, following the selected rounding direction.\n     */\n    function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n        return mulDiv(x, y, denominator) + SafeCast.toUint(unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0);\n    }\n\n    /**\n     * @dev Calculates floor(x * y >> n) with full precision. Throws if result overflows a uint256.\n     */\n    function mulShr(uint256 x, uint256 y, uint8 n) internal pure returns (uint256 result) {\n        unchecked {\n            (uint256 high, uint256 low) = mul512(x, y);\n            if (high >= 1 << n) {\n                Panic.panic(Panic.UNDER_OVERFLOW);\n            }\n            return (high << (256 - n)) | (low >> n);\n        }\n    }\n\n    /**\n     * @dev Calculates x * y >> n with full precision, following the selected rounding direction.\n     */\n    function mulShr(uint256 x, uint256 y, uint8 n, Rounding rounding) internal pure returns (uint256) {\n        return mulShr(x, y, n) + SafeCast.toUint(unsignedRoundsUp(rounding) && mulmod(x, y, 1 << n) > 0);\n    }\n\n    /**\n     * @dev Calculate the modular multiplicative inverse of a number in Z/nZ.\n     *\n     * If n is a prime, then Z/nZ is a field. In that case all elements are inversible, except 0.\n     * If n is not a prime, then Z/nZ is not a field, and some elements might not be inversible.\n     *\n     * If the input value is not inversible, 0 is returned.\n     *\n     * NOTE: If you know for sure that n is (big) a prime, it may be cheaper to use Fermat's little theorem and get the\n     * inverse using `Math.modExp(a, n - 2, n)`. See {invModPrime}.\n     */\n    function invMod(uint256 a, uint256 n) internal pure returns (uint256) {\n        unchecked {\n            if (n == 0) return 0;\n\n            // The inverse modulo is calculated using the Extended Euclidean Algorithm (iterative version)\n            // Used to compute integers x and y such that: ax + ny = gcd(a, n).\n            // When the gcd is 1, then the inverse of a modulo n exists and it's x.\n            // ax + ny = 1\n            // ax = 1 + (-y)n\n            // ax ≡ 1 (mod n) # x is the inverse of a modulo n\n\n            // If the remainder is 0 the gcd is n right away.\n            uint256 remainder = a % n;\n            uint256 gcd = n;\n\n            // Therefore the initial coefficients are:\n            // ax + ny = gcd(a, n) = n\n            // 0a + 1n = n\n            int256 x = 0;\n            int256 y = 1;\n\n            while (remainder != 0) {\n                uint256 quotient = gcd / remainder;\n\n                (gcd, remainder) = (\n                    // The old remainder is the next gcd to try.\n                    remainder,\n                    // Compute the next remainder.\n                    // Can't overflow given that (a % gcd) * (gcd // (a % gcd)) <= gcd\n                    // where gcd is at most n (capped to type(uint256).max)\n                    gcd - remainder * quotient\n                );\n\n                (x, y) = (\n                    // Increment the coefficient of a.\n                    y,\n                    // Decrement the coefficient of n.\n                    // Can overflow, but the result is casted to uint256 so that the\n                    // next value of y is \"wrapped around\" to a value between 0 and n - 1.\n                    x - y * int256(quotient)\n                );\n            }\n\n            if (gcd != 1) return 0; // No inverse exists.\n            return ternary(x < 0, n - uint256(-x), uint256(x)); // Wrap the result if it's negative.\n        }\n    }\n\n    /**\n     * @dev Variant of {invMod}. More efficient, but only works if `p` is known to be a prime greater than `2`.\n     *\n     * From https://en.wikipedia.org/wiki/Fermat%27s_little_theorem[Fermat's little theorem], we know that if p is\n     * prime, then `a**(p-1) ≡ 1 mod p`. As a consequence, we have `a * a**(p-2) ≡ 1 mod p`, which means that\n     * `a**(p-2)` is the modular multiplicative inverse of a in Fp.\n     *\n     * NOTE: this function does NOT check that `p` is a prime greater than `2`.\n     */\n    function invModPrime(uint256 a, uint256 p) internal view returns (uint256) {\n        unchecked {\n            return Math.modExp(a, p - 2, p);\n        }\n    }\n\n    /**\n     * @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m)\n     *\n     * Requirements:\n     * - modulus can't be zero\n     * - underlying staticcall to precompile must succeed\n     *\n     * IMPORTANT: The result is only valid if the underlying call succeeds. When using this function, make\n     * sure the chain you're using it on supports the precompiled contract for modular exponentiation\n     * at address 0x05 as specified in https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise,\n     * the underlying function will succeed given the lack of a revert, but the result may be incorrectly\n     * interpreted as 0.\n     */\n    function modExp(uint256 b, uint256 e, uint256 m) internal view returns (uint256) {\n        (bool success, uint256 result) = tryModExp(b, e, m);\n        if (!success) {\n            Panic.panic(Panic.DIVISION_BY_ZERO);\n        }\n        return result;\n    }\n\n    /**\n     * @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m).\n     * It includes a success flag indicating if the operation succeeded. Operation will be marked as failed if trying\n     * to operate modulo 0 or if the underlying precompile reverted.\n     *\n     * IMPORTANT: The result is only valid if the success flag is true. When using this function, make sure the chain\n     * you're using it on supports the precompiled contract for modular exponentiation at address 0x05 as specified in\n     * https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise, the underlying function will succeed given the lack\n     * of a revert, but the result may be incorrectly interpreted as 0.\n     */\n    function tryModExp(uint256 b, uint256 e, uint256 m) internal view returns (bool success, uint256 result) {\n        if (m == 0) return (false, 0);\n        assembly (\"memory-safe\") {\n            let ptr := mload(0x40)\n            // | Offset    | Content    | Content (Hex)                                                      |\n            // |-----------|------------|--------------------------------------------------------------------|\n            // | 0x00:0x1f | size of b  | 0x0000000000000000000000000000000000000000000000000000000000000020 |\n            // | 0x20:0x3f | size of e  | 0x0000000000000000000000000000000000000000000000000000000000000020 |\n            // | 0x40:0x5f | size of m  | 0x0000000000000000000000000000000000000000000000000000000000000020 |\n            // | 0x60:0x7f | value of b | 0x<.............................................................b> |\n            // | 0x80:0x9f | value of e | 0x<.............................................................e> |\n            // | 0xa0:0xbf | value of m | 0x<.............................................................m> |\n            mstore(ptr, 0x20)\n            mstore(add(ptr, 0x20), 0x20)\n            mstore(add(ptr, 0x40), 0x20)\n            mstore(add(ptr, 0x60), b)\n            mstore(add(ptr, 0x80), e)\n            mstore(add(ptr, 0xa0), m)\n\n            // Given the result < m, it's guaranteed to fit in 32 bytes,\n            // so we can use the memory scratch space located at offset 0.\n            success := staticcall(gas(), 0x05, ptr, 0xc0, 0x00, 0x20)\n            result := mload(0x00)\n        }\n    }\n\n    /**\n     * @dev Variant of {modExp} that supports inputs of arbitrary length.\n     */\n    function modExp(bytes memory b, bytes memory e, bytes memory m) internal view returns (bytes memory) {\n        (bool success, bytes memory result) = tryModExp(b, e, m);\n        if (!success) {\n            Panic.panic(Panic.DIVISION_BY_ZERO);\n        }\n        return result;\n    }\n\n    /**\n     * @dev Variant of {tryModExp} that supports inputs of arbitrary length.\n     */\n    function tryModExp(\n        bytes memory b,\n        bytes memory e,\n        bytes memory m\n    ) internal view returns (bool success, bytes memory result) {\n        if (_zeroBytes(m)) return (false, new bytes(0));\n\n        uint256 mLen = m.length;\n\n        // Encode call args in result and move the free memory pointer\n        result = abi.encodePacked(b.length, e.length, mLen, b, e, m);\n\n        assembly (\"memory-safe\") {\n            let dataPtr := add(result, 0x20)\n            // Write result on top of args to avoid allocating extra memory.\n            success := staticcall(gas(), 0x05, dataPtr, mload(result), dataPtr, mLen)\n            // Overwrite the length.\n            // result.length > returndatasize() is guaranteed because returndatasize() == m.length\n            mstore(result, mLen)\n            // Set the memory pointer after the returned data.\n            mstore(0x40, add(dataPtr, mLen))\n        }\n    }\n\n    /**\n     * @dev Returns whether the provided byte array is zero.\n     */\n    function _zeroBytes(bytes memory buffer) private pure returns (bool) {\n        uint256 chunk;\n        for (uint256 i = 0; i < buffer.length; i += 0x20) {\n            // See _unsafeReadBytesOffset from utils/Bytes.sol\n            assembly (\"memory-safe\") {\n                chunk := mload(add(add(buffer, 0x20), i))\n            }\n            if (chunk >> (8 * saturatingSub(i + 0x20, buffer.length)) != 0) {\n                return false;\n            }\n        }\n        return true;\n    }\n\n    /**\n     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded\n     * towards zero.\n     *\n     * This method is based on Newton's method for computing square roots; the algorithm is restricted to only\n     * using integer operations.\n     */\n    function sqrt(uint256 a) internal pure returns (uint256) {\n        unchecked {\n            // Take care of easy edge cases when a == 0 or a == 1\n            if (a <= 1) {\n                return a;\n            }\n\n            // In this function, we use Newton's method to get a root of `f(x) := x² - a`. It involves building a\n            // sequence x_n that converges toward sqrt(a). For each iteration x_n, we also define the error between\n            // the current value as `ε_n = | x_n - sqrt(a) |`.\n            //\n            // For our first estimation, we consider `e` the smallest power of 2 which is bigger than the square root\n            // of the target. (i.e. `2**(e-1) ≤ sqrt(a) < 2**e`). We know that `e ≤ 128` because `(2¹²⁸)² = 2²⁵⁶` is\n            // bigger than any uint256.\n            //\n            // By noticing that\n            // `2**(e-1) ≤ sqrt(a) < 2**e → (2**(e-1))² ≤ a < (2**e)² → 2**(2*e-2) ≤ a < 2**(2*e)`\n            // we can deduce that `e - 1` is `log2(a) / 2`. We can thus compute `x_n = 2**(e-1)` using a method similar\n            // to the msb function.\n            uint256 aa = a;\n            uint256 xn = 1;\n\n            if (aa >= (1 << 128)) {\n                aa >>= 128;\n                xn <<= 64;\n            }\n            if (aa >= (1 << 64)) {\n                aa >>= 64;\n                xn <<= 32;\n            }\n            if (aa >= (1 << 32)) {\n                aa >>= 32;\n                xn <<= 16;\n            }\n            if (aa >= (1 << 16)) {\n                aa >>= 16;\n                xn <<= 8;\n            }\n            if (aa >= (1 << 8)) {\n                aa >>= 8;\n                xn <<= 4;\n            }\n            if (aa >= (1 << 4)) {\n                aa >>= 4;\n                xn <<= 2;\n            }\n            if (aa >= (1 << 2)) {\n                xn <<= 1;\n            }\n\n            // We now have x_n such that `x_n = 2**(e-1) ≤ sqrt(a) < 2**e = 2 * x_n`. This implies ε_n ≤ 2**(e-1).\n            //\n            // We can refine our estimation by noticing that the middle of that interval minimizes the error.\n            // If we move x_n to equal 2**(e-1) + 2**(e-2), then we reduce the error to ε_n ≤ 2**(e-2).\n            // This is going to be our x_0 (and ε_0)\n            xn = (3 * xn) >> 1; // ε_0 := | x_0 - sqrt(a) | ≤ 2**(e-2)\n\n            // From here, Newton's method give us:\n            // x_{n+1} = (x_n + a / x_n) / 2\n            //\n            // One should note that:\n            // x_{n+1}² - a = ((x_n + a / x_n) / 2)² - a\n            //              = ((x_n² + a) / (2 * x_n))² - a\n            //              = (x_n⁴ + 2 * a * x_n² + a²) / (4 * x_n²) - a\n            //              = (x_n⁴ + 2 * a * x_n² + a² - 4 * a * x_n²) / (4 * x_n²)\n            //              = (x_n⁴ - 2 * a * x_n² + a²) / (4 * x_n²)\n            //              = (x_n² - a)² / (2 * x_n)²\n            //              = ((x_n² - a) / (2 * x_n))²\n            //              ≥ 0\n            // Which proves that for all n ≥ 1, sqrt(a) ≤ x_n\n            //\n            // This gives us the proof of quadratic convergence of the sequence:\n            // ε_{n+1} = | x_{n+1} - sqrt(a) |\n            //         = | (x_n + a / x_n) / 2 - sqrt(a) |\n            //         = | (x_n² + a - 2*x_n*sqrt(a)) / (2 * x_n) |\n            //         = | (x_n - sqrt(a))² / (2 * x_n) |\n            //         = | ε_n² / (2 * x_n) |\n            //         = ε_n² / | (2 * x_n) |\n            //\n            // For the first iteration, we have a special case where x_0 is known:\n            // ε_1 = ε_0² / | (2 * x_0) |\n            //     ≤ (2**(e-2))² / (2 * (2**(e-1) + 2**(e-2)))\n            //     ≤ 2**(2*e-4) / (3 * 2**(e-1))\n            //     ≤ 2**(e-3) / 3\n            //     ≤ 2**(e-3-log2(3))\n            //     ≤ 2**(e-4.5)\n            //\n            // For the following iterations, we use the fact that, 2**(e-1) ≤ sqrt(a) ≤ x_n:\n            // ε_{n+1} = ε_n² / | (2 * x_n) |\n            //         ≤ (2**(e-k))² / (2 * 2**(e-1))\n            //         ≤ 2**(2*e-2*k) / 2**e\n            //         ≤ 2**(e-2*k)\n            xn = (xn + a / xn) >> 1; // ε_1 := | x_1 - sqrt(a) | ≤ 2**(e-4.5)  -- special case, see above\n            xn = (xn + a / xn) >> 1; // ε_2 := | x_2 - sqrt(a) | ≤ 2**(e-9)    -- general case with k = 4.5\n            xn = (xn + a / xn) >> 1; // ε_3 := | x_3 - sqrt(a) | ≤ 2**(e-18)   -- general case with k = 9\n            xn = (xn + a / xn) >> 1; // ε_4 := | x_4 - sqrt(a) | ≤ 2**(e-36)   -- general case with k = 18\n            xn = (xn + a / xn) >> 1; // ε_5 := | x_5 - sqrt(a) | ≤ 2**(e-72)   -- general case with k = 36\n            xn = (xn + a / xn) >> 1; // ε_6 := | x_6 - sqrt(a) | ≤ 2**(e-144)  -- general case with k = 72\n\n            // Because e ≤ 128 (as discussed during the first estimation phase), we know have reached a precision\n            // ε_6 ≤ 2**(e-144) < 1. Given we're operating on integers, then we can ensure that xn is now either\n            // sqrt(a) or sqrt(a) + 1.\n            return xn - SafeCast.toUint(xn > a / xn);\n        }\n    }\n\n    /**\n     * @dev Calculates sqrt(a), following the selected rounding direction.\n     */\n    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = sqrt(a);\n            return result + SafeCast.toUint(unsignedRoundsUp(rounding) && result * result < a);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 2 of a positive value rounded towards zero.\n     * Returns 0 if given 0.\n     */\n    function log2(uint256 x) internal pure returns (uint256 r) {\n        // If value has upper 128 bits set, log2 result is at least 128\n        r = SafeCast.toUint(x > 0xffffffffffffffffffffffffffffffff) << 7;\n        // If upper 64 bits of 128-bit half set, add 64 to result\n        r |= SafeCast.toUint((x >> r) > 0xffffffffffffffff) << 6;\n        // If upper 32 bits of 64-bit half set, add 32 to result\n        r |= SafeCast.toUint((x >> r) > 0xffffffff) << 5;\n        // If upper 16 bits of 32-bit half set, add 16 to result\n        r |= SafeCast.toUint((x >> r) > 0xffff) << 4;\n        // If upper 8 bits of 16-bit half set, add 8 to result\n        r |= SafeCast.toUint((x >> r) > 0xff) << 3;\n        // If upper 4 bits of 8-bit half set, add 4 to result\n        r |= SafeCast.toUint((x >> r) > 0xf) << 2;\n\n        // Shifts value right by the current result and use it as an index into this lookup table:\n        //\n        // | x (4 bits) |  index  | table[index] = MSB position |\n        // |------------|---------|-----------------------------|\n        // |    0000    |    0    |        table[0] = 0         |\n        // |    0001    |    1    |        table[1] = 0         |\n        // |    0010    |    2    |        table[2] = 1         |\n        // |    0011    |    3    |        table[3] = 1         |\n        // |    0100    |    4    |        table[4] = 2         |\n        // |    0101    |    5    |        table[5] = 2         |\n        // |    0110    |    6    |        table[6] = 2         |\n        // |    0111    |    7    |        table[7] = 2         |\n        // |    1000    |    8    |        table[8] = 3         |\n        // |    1001    |    9    |        table[9] = 3         |\n        // |    1010    |   10    |        table[10] = 3        |\n        // |    1011    |   11    |        table[11] = 3        |\n        // |    1100    |   12    |        table[12] = 3        |\n        // |    1101    |   13    |        table[13] = 3        |\n        // |    1110    |   14    |        table[14] = 3        |\n        // |    1111    |   15    |        table[15] = 3        |\n        //\n        // The lookup table is represented as a 32-byte value with the MSB positions for 0-15 in the first 16 bytes (most significant half).\n        assembly (\"memory-safe\") {\n            r := or(r, byte(shr(r, x), 0x0000010102020202030303030303030300000000000000000000000000000000))\n        }\n    }\n\n    /**\n     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log2(value);\n            return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << result < value);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 10 of a positive value rounded towards zero.\n     * Returns 0 if given 0.\n     */\n    function log10(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >= 10 ** 64) {\n                value /= 10 ** 64;\n                result += 64;\n            }\n            if (value >= 10 ** 32) {\n                value /= 10 ** 32;\n                result += 32;\n            }\n            if (value >= 10 ** 16) {\n                value /= 10 ** 16;\n                result += 16;\n            }\n            if (value >= 10 ** 8) {\n                value /= 10 ** 8;\n                result += 8;\n            }\n            if (value >= 10 ** 4) {\n                value /= 10 ** 4;\n                result += 4;\n            }\n            if (value >= 10 ** 2) {\n                value /= 10 ** 2;\n                result += 2;\n            }\n            if (value >= 10 ** 1) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log10(value);\n            return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 10 ** result < value);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 256 of a positive value rounded towards zero.\n     * Returns 0 if given 0.\n     *\n     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n     */\n    function log256(uint256 x) internal pure returns (uint256 r) {\n        // If value has upper 128 bits set, log2 result is at least 128\n        r = SafeCast.toUint(x > 0xffffffffffffffffffffffffffffffff) << 7;\n        // If upper 64 bits of 128-bit half set, add 64 to result\n        r |= SafeCast.toUint((x >> r) > 0xffffffffffffffff) << 6;\n        // If upper 32 bits of 64-bit half set, add 32 to result\n        r |= SafeCast.toUint((x >> r) > 0xffffffff) << 5;\n        // If upper 16 bits of 32-bit half set, add 16 to result\n        r |= SafeCast.toUint((x >> r) > 0xffff) << 4;\n        // Add 1 if upper 8 bits of 16-bit half set, and divide accumulated result by 8\n        return (r >> 3) | SafeCast.toUint((x >> r) > 0xff);\n    }\n\n    /**\n     * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log256(value);\n            return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << (result << 3) < value);\n        }\n    }\n\n    /**\n     * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers.\n     */\n    function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) {\n        return uint8(rounding) % 2 == 1;\n    }\n\n    /**\n     * @dev Counts the number of leading zero bits in a uint256.\n     */\n    function clz(uint256 x) internal pure returns (uint256) {\n        return ternary(x == 0, 256, 255 - log2(x));\n    }\n}\n"},"V3/src/interfaces/pools/IPool.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\n/**\n * @title IPool\n * @notice Interface for the Pool contract, the abstract base shared by the Aerodrome V2 volatile and stable pools\n */\ninterface IPool {\n  /*////////////////////////////////////////////////////////////\n                            EVENTS\n  ////////////////////////////////////////////////////////////*/\n\n  /// @notice Emitted when fees are claimed by a liquidity provider\n  /// @param sender Address that triggered the fee claim\n  /// @param amount0 Amount of token0 fees collected\n  /// @param amount1 Amount of token1 fees collected\n  event Fees(address indexed sender, uint256 amount0, uint256 amount1);\n  /// @notice Emitted when liquidity is minted\n  /// @param sender Address that initiated the mint\n  /// @param to Address that received the LP tokens\n  /// @param amount0 Amount of token0 deposited\n  /// @param amount1 Amount of token1 deposited\n  event Mint(address indexed sender, address indexed to, uint256 amount0, uint256 amount1);\n  /// @notice Emitted when liquidity is burned\n  /// @param sender Address that initiated the burn\n  /// @param to Address that received the underlying tokens\n  /// @param amount0 Amount of token0 returned\n  /// @param amount1 Amount of token1 returned\n  event Burn(address indexed sender, address indexed to, uint256 amount0, uint256 amount1);\n  /// @notice Emitted on every swap executed through the pool\n  /// @param sender Address that initiated the swap\n  /// @param to Address that received the output tokens\n  /// @param amount0In Amount of token0 provided as input\n  /// @param amount1In Amount of token1 provided as input\n  /// @param amount0Out Amount of token0 sent as output\n  /// @param amount1Out Amount of token1 sent as output\n  event Swap(\n    address indexed sender,\n    address indexed to,\n    uint256 amount0In,\n    uint256 amount1In,\n    uint256 amount0Out,\n    uint256 amount1Out\n  );\n  /// @notice Emitted when reserves are synced to the current balances\n  /// @param reserve0 Updated reserve of token0\n  /// @param reserve1 Updated reserve of token1\n  event Sync(uint256 reserve0, uint256 reserve1);\n\n  /// @notice Emitted when accumulated fee tokens are claimed\n  /// @param caller Address that triggered the claim\n  /// @param account Address whose accumulated fees were claimed\n  /// @param recipient Address that received the fee tokens\n  /// @param amount0 Amount of token0 claimed\n  /// @param amount1 Amount of token1 claimed\n  event Claim(\n    address indexed caller, address indexed account, address indexed recipient, uint256 amount0, uint256 amount1\n  );\n  /// @notice Emitted when an account grants or revokes claim approval for an operator\n  /// @param account Account whose approval state changed\n  /// @param operator Operator being approved or revoked\n  /// @param approved New approval state\n  event ClaimApproval(address indexed account, address indexed operator, bool approved);\n  /// @notice Emitted whenever `observationCardinalityNext` is increased\n  /// @param caller Address that triggered the cardinality growth\n  /// @param observationCardinalityNextOld Previous value of `observationCardinalityNext`\n  /// @param observationCardinalityNextNew New value of `observationCardinalityNext`\n  event IncreaseObservationCardinalityNext(\n    address indexed caller, uint16 observationCardinalityNextOld, uint16 observationCardinalityNextNew\n  );\n\n  /*////////////////////////////////////////////////////////////\n                            ERRORS\n  ////////////////////////////////////////////////////////////*/\n\n  /// @notice Thrown when the factory address has already been set and cannot be changed\n  error FactoryAlreadySet();\n  /// @notice Thrown when the input amount provided to a swap is zero or insufficient\n  error InsufficientInputAmount();\n  /// @notice Thrown when the pool does not have enough liquidity to fulfil the operation\n  error InsufficientLiquidity();\n  /// @notice Thrown when burning LP tokens would return zero of at least one underlying token\n  error InsufficientLiquidityBurned();\n  /// @notice Thrown when minting would produce zero LP tokens\n  error InsufficientLiquidityMinted();\n  /// @notice Thrown when the output amount of a swap is zero or below the requested minimum\n  error InsufficientOutputAmount();\n  /// @notice Thrown when the `to` address supplied to swap or burn is one of the pool's tokens\n  error InvalidTo();\n  /// @notice Thrown when an operation is attempted while the pool is paused\n  error IsPaused();\n  /// @notice Thrown when the invariant K check fails after a swap\n  error K();\n  /// @notice Thrown when the caller is neither the account nor an approved claim operator\n  error NotAuthorized();\n  /// @notice Thrown when a zero address is supplied where a non-zero address is required\n  error ZeroAddress();\n  /*////////////////////////////////////////////////////////////\n                        EXTERNAL FUNCTIONS\n  ////////////////////////////////////////////////////////////*/\n  /// @notice Grants or revokes an operator's permission to claim the caller's accumulated fees\n  /// @param _operator Operator whose approval is updated\n  /// @param _approved Whether the operator is approved\n  function approveForClaim(address _operator, bool _approved) external;\n\n  /// @notice Claims the caller's accumulated fees\n  /// @param _recipient Address that receives the claimed fee tokens\n  /// @return _amount0 Amount of token0 claimed\n  /// @return _amount1 Amount of token1 claimed\n  function claimFees(address _recipient) external returns (uint256 _amount0, uint256 _amount1);\n\n  /// @notice Claims an account's accumulated fees\n  /// @dev The caller must be `_account` or an operator approved by `_account`\n  /// @param _account Account whose accumulated fees are claimed\n  /// @param _recipient Address that receives the claimed fee tokens\n  /// @return _amount0 Amount of token0 claimed\n  /// @return _amount1 Amount of token1 claimed\n  function claimFees(address _account, address _recipient) external returns (uint256 _amount0, uint256 _amount1);\n\n  /// @notice Returns the value of K in the Pool, based on its reserves.\n  function getK() external returns (uint256);\n\n  /// @notice Set pool name\n  ///         Only callable by IPoolFactory(factory).poolAdmin()\n  /// @param __name String of new name\n  function setName(string calldata __name) external;\n\n  /// @notice Set pool symbol\n  ///         Only callable by IPoolFactory(factory).poolAdmin()\n  /// @param __symbol String of new symbol\n  function setSymbol(string calldata __symbol) external;\n\n  /// @notice This low-level function should be called from a contract which performs important safety checks\n  /// @param amount0Out Amount of token0 to send to `to`\n  /// @param amount1Out Amount of token1 to send to `to`\n  /// @param to Address to recieve the swapped output\n  /// @param data Additional calldata for flashloans\n  function swap(uint256 amount0Out, uint256 amount1Out, address to, bytes calldata data) external;\n\n  /// @notice This low-level function should be called from a contract which performs important safety checks\n  ///         standard uniswap v2 implementation\n  /// @param to Address to receive token0 and token1 from burning the pool token\n  /// @return amount0 Amount of token0 returned\n  /// @return amount1 Amount of token1 returned\n  function burn(address to) external returns (uint256 amount0, uint256 amount1);\n\n  /// @notice This low-level function should be called by addLiquidity functions in Router.sol, which performs important safety checks\n  ///         standard uniswap v2 implementation\n  /// @param to Address to receive the minted LP token\n  /// @return liquidity Amount of LP token minted\n  function mint(address to) external returns (uint256 liquidity);\n\n  /// @notice Force balances to match reserves\n  /// @param to Address to receive any skimmed rewards\n  function skim(address to) external;\n\n  /// @notice Force reserves to match balances\n  function sync() external;\n\n  /// @notice Called on pool creation by the owning PoolFactory\n  /// @param _token0 Address of token0\n  /// @param _token1 Address of token1\n  function initialize(address _token0, address _token1) external;\n\n  /// @notice Pre-allocates buffer slots increasing the buffer capacity\n  /// @param _observationCardinalityNext New target capacity. At most 65,535.\n  function increaseObservationCardinalityNext(uint16 _observationCardinalityNext) external;\n\n  /*////////////////////////////////////////////////////////////\n                      PURE AND VIEW FUNCTIONS\n  ////////////////////////////////////////////////////////////*/\n  /// @notice Returns the decimal (dec), reserves (r), and tokens (t) of token0 and token1\n  function metadata() external view returns (uint256 dec0, uint256 dec1, uint256 r0, uint256 r1, address t0, address t1);\n\n  /// @notice Returns [token0, token1]\n  function tokens() external view returns (address, address);\n\n  /// @notice Returns accumulated but unclaimed fees for an account.\n  /// @param _account Address to query.\n  /// @return _amount0 Pending token0 fees.\n  /// @return _amount1 Pending token1 fees.\n  function pendingFees(address _account) external view returns (uint256 _amount0, uint256 _amount1);\n\n  /// @notice Address of token in the pool with the lower address value\n  function token0() external view returns (address);\n\n  /// @notice Address of token in the pool with the higher address value\n  function token1() external view returns (address);\n\n  /// @notice Address of linked PoolFees.sol\n  function poolFees() external view returns (address);\n\n  /// @notice Address of PoolFactory that created this contract\n  function factory() external view returns (address);\n\n  /// @notice Period gate for new observations, in seconds. A new observation is written when more\n  ///         than `PERIOD_SIZE` seconds have passed since the last one, so the smallest possible\n  ///         spacing between two stored observations is `PERIOD_SIZE + 1` (i.e. 61 seconds at the\n  ///         default value of 60).\n  function PERIOD_SIZE() external view returns (uint256);\n\n  /// @notice The pool type identifier\n  /// @return The pool type label to be able to identify the type of pool\n  function POOL_TYPE() external view returns (bytes32);\n\n  /// @notice Amount of token0 in pool\n  function reserve0() external view returns (uint256);\n\n  /// @notice Amount of token1 in pool\n  function reserve1() external view returns (uint256);\n\n  /// @notice Timestamp of last update to pool\n  function blockTimestampLast() external view returns (uint256);\n\n  /// @notice Cumulative of reserve0 factoring in time elapsed\n  function reserve0CumulativeLast() external view returns (uint256);\n\n  /// @notice Cumulative of reserve1 factoring in time elapsed\n  function reserve1CumulativeLast() external view returns (uint256);\n\n  /// @notice Accumulated fees of token0 (global)\n  function index0() external view returns (uint256);\n\n  /// @notice Accumulated fees of token1 (global)\n  function index1() external view returns (uint256);\n\n  /// @notice Get an LP's relative index0 to index0\n  function supplyIndex0(address) external view returns (uint256);\n\n  /// @notice Get an LP's relative index1 to index1\n  function supplyIndex1(address) external view returns (uint256);\n\n  /// @notice Amount of unclaimed, but claimable tokens from fees of token0 for an LP\n  function claimable0(address) external view returns (uint256);\n\n  /// @notice Amount of unclaimed, but claimable tokens from fees of token1 for an LP\n  function claimable1(address) external view returns (uint256);\n\n  /// @notice Whether an operator may claim an account's accumulated fees\n  /// @param _account Account that owns the accumulated fees\n  /// @param _operator Operator whose approval is queried\n  /// @return _approved Whether the operator is approved\n  function approvedForClaim(address _account, address _operator) external view returns (bool _approved);\n\n  /// @notice Produces the cumulative price using counterfactuals to save gas and avoid a call to sync.\n  function currentCumulativePrices()\n    external\n    view\n    returns (uint256 reserve0Cumulative, uint256 reserve1Cumulative, uint256 blockTimestamp);\n\n  /// @notice Update reserves and, on the first call per block, price accumulators\n  /// @return _reserve0 .\n  /// @return _reserve1 .\n  /// @return _blockTimestampLast .\n  function getReserves() external view returns (uint256 _reserve0, uint256 _reserve1, uint256 _blockTimestampLast);\n\n  /// @notice Get the amount of tokenOut given the amount of tokenIn, charging only the base fee\n  /// @dev Does not charge the MEV tax, so the result can be higher than what `swap` pays out.\n  ///      Use `getAmountOutWithTotalFee` to quote a swap.\n  /// @param amountIn Amount of token in\n  /// @param tokenIn Address of token\n  /// @return Amount out\n  function getAmountOut(uint256 amountIn, address tokenIn) external view returns (uint256);\n\n  /// @notice Get the amount of tokenOut given the amount of tokenIn, charging the total fees\n  /// @param amountIn Amount of token in\n  /// @param tokenIn Address of token in\n  /// @return Amount out\n  function getAmountOutWithTotalFee(uint256 amountIn, address tokenIn) external view returns (uint256);\n\n  /// @notice Get the amount of tokenIn required to receive the amount of tokenOut, charging the total fees\n  /// @dev Reverts if the exact output cannot be calculated\n  /// @param amountOut Amount of token out to receive\n  /// @param tokenOut Address of token out\n  /// @return Amount in, fee included\n  function getAmountInWithTotalFee(uint256 amountOut, address tokenOut) external view returns (uint256);\n\n  /// @notice Returns the cumulative reserves as of each requested `secondsAgo`. Reverts when any\n  ///         `secondsAgos[i]` predates the oldest stored observation.\n  /// @dev Offsets between two stored observations are linearly interpolated. Observations are\n  ///      period-gated, so reserve changes within an interval may go unrecorded, making the\n  ///      interpolation an approximation. Read from the pool directly when an exact value is required.\n  /// @dev A point newer than the newest stored observation is estimated from the current cumulative\n  ///      instead of two stored ones, so a trade after that point can change what it reads. It stops\n  ///      changing once an observation is stored at or after that point. Points that already fall\n  ///      between two stored observations read the same on every call.\n  /// @param secondsAgos Array of seconds offsets from `block.timestamp` to query\n  /// @return reserve0Cumulatives Cumulative reserve0 values at each requested point\n  /// @return reserve1Cumulatives Cumulative reserve1 values at each requested point\n  function observe(uint32[] calldata secondsAgos)\n    external\n    view\n    returns (uint256[] memory reserve0Cumulatives, uint256[] memory reserve1Cumulatives);\n\n  /// @notice Quote `amountIn` of `tokenIn` against a custom reserve snapshot\n  /// @dev Subtracts the base fee from `amountIn` before applying the curve. Does not charge the MEV\n  ///      tax, so use `getAmountOutWithTotalFee` to quote a swap.\n  /// @param amountIn Input amount in the smallest unit of `tokenIn`\n  /// @param tokenIn Address of the input token\n  /// @param _reserve0 Reserve of token0 to quote against\n  /// @param _reserve1 Reserve of token1 to quote against\n  /// @return Output amount the swap would produce against the supplied reserves\n  function getAmountOut(\n    uint256 amountIn,\n    address tokenIn,\n    uint256 _reserve0,\n    uint256 _reserve1\n  ) external view returns (uint256);\n\n  /// @notice TWAP circular buffer metadata\n  /// @return index Index of the most recent observation in the buffer\n  /// @return cardinality Number of populated slots in the buffer\n  /// @return cardinalityNext Number of slots that can be written\n  function observationBuffer() external view returns (uint16 index, uint16 cardinality, uint16 cardinalityNext);\n\n  /// @notice Returns the observation at the given index\n  /// @param index Index of the observation to return\n  /// @return timestamp Timestamp of the observation\n  /// @return reserve0Cumulative Cumulative reserve0 of the observation\n  /// @return reserve1Cumulative Cumulative reserve1 of the observation\n  function observations(uint256 index)\n    external\n    view\n    returns (uint32 timestamp, uint256 reserve0Cumulative, uint256 reserve1Cumulative);\n}\n"},"V3/src/interfaces/pools/IStablePool.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nimport {IPool} from 'V3/interfaces/pools/IPool.sol';\n\n/**\n * @title IStablePool\n * @notice Interface for the StablePool contract, an Aerodrome V2 stable-swap AMM pool\n */\ninterface IStablePool is IPool {\n  /*////////////////////////////////////////////////////////////\n                            ERRORS\n  ////////////////////////////////////////////////////////////*/\n  /// @notice Thrown on first mint when `_k(amount0, amount1)` is less than or equal to `MINIMUM_K`\n  error BelowMinimumK();\n\n  /// @notice Thrown when the Newton-Raphson search cannot solve for `y` within its iteration budget\n  error CannotCalculateY();\n\n  /// @notice Thrown when the deposited amounts are not equal\n  error DepositsNotEqual();\n\n  /// @notice Thrown after burn when remaining reserves cause `_k` to round to zero\n  error KIsZero();\n\n  /*////////////////////////////////////////////////////////////\n                      PURE AND VIEW FUNCTIONS\n  ////////////////////////////////////////////////////////////*/\n  /// @notice Minimum value of the stable-swap invariant\n  function MINIMUM_K() external view returns (uint256);\n}\n"},"V3/src/pools/Pool.sol":{"content":"// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity 0.8.36;\n\nimport {ERC20} from '@openzeppelin/contracts/token/ERC20/ERC20.sol';\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {ReentrancyGuard} from '@openzeppelin/contracts/utils/ReentrancyGuard.sol';\nimport {Math} from '@openzeppelin/contracts/utils/math/Math.sol';\n\nimport {PoolOracle} from 'V3/libraries/PoolOracle.sol';\n\nimport {IPoolFactory} from 'V3/interfaces/factories/IPoolFactory.sol';\nimport {IPool} from 'V3/interfaces/pools/IPool.sol';\nimport {IPoolCallee} from 'V3/interfaces/pools/IPoolCallee.sol';\nimport {IPoolTape} from 'V3/interfaces/pools/tape/IPoolTape.sol';\n\nimport {PoolFees} from 'V3/pools/PoolFees.sol';\n\n/// @title Pool\n/// @author velodrome.finance, Solidly, Uniswap Labs, @figs999, @pegahcarter\n/// @notice Abstract base for Aerodrome V2 token pools. Curve-specific math is supplied by child contracts.\nabstract contract Pool is IPool, ERC20, ReentrancyGuard {\n  using SafeERC20 for IERC20;\n  using PoolOracle for PoolOracle.ObservationBuffer;\n\n  /*////////////////////////////////////////////////////////////\n                              CONSTANTS\n  ////////////////////////////////////////////////////////////*/\n\n  /// @inheritdoc IPool\n  uint256 public constant PERIOD_SIZE = 1 minutes;\n  /// @notice The minimum liquidity for a pool\n  uint256 internal constant _MINIMUM_LIQUIDITY = 10 ** 3;\n  /// @notice Basis points scale used as the fee denominator (100%)\n  uint256 internal constant _MAX_BPS = 10_000;\n\n  /*////////////////////////////////////////////////////////////\n                              STORAGE\n  ////////////////////////////////////////////////////////////*/\n\n  /// @notice The name of the pool\n  // slither-disable-next-line shadowing-state\n  string private _name;\n  /// @notice The symbol of the pool\n  // slither-disable-next-line shadowing-state\n  string private _symbol;\n\n  /// @inheritdoc IPool\n  address public token0;\n  /// @inheritdoc IPool\n  address public token1;\n  /// @inheritdoc IPool\n  address public poolFees;\n  /// @inheritdoc IPool\n  address public factory;\n\n  /// @notice Circular buffer of TWAP observations with its write index and cardinality metadata.\n  PoolOracle.ObservationBuffer public observationBuffer;\n\n  /// @notice The number of decimals of token0\n  uint256 internal _decimals0;\n  /// @notice The number of decimals of token1\n  uint256 internal _decimals1;\n\n  /// @inheritdoc IPool\n  uint256 public reserve0;\n  /// @inheritdoc IPool\n  uint256 public reserve1;\n  /// @inheritdoc IPool\n  uint256 public blockTimestampLast;\n\n  /// @inheritdoc IPool\n  uint256 public reserve0CumulativeLast;\n  /// @inheritdoc IPool\n  uint256 public reserve1CumulativeLast;\n\n  /// @inheritdoc IPool\n  uint256 public index0;\n  /// @inheritdoc IPool\n  uint256 public index1;\n\n  /// @inheritdoc IPool\n  mapping(address => uint256) public supplyIndex0;\n  /// @inheritdoc IPool\n  mapping(address => uint256) public supplyIndex1;\n\n  /// @inheritdoc IPool\n  mapping(address => uint256) public claimable0;\n  /// @inheritdoc IPool\n  mapping(address => uint256) public claimable1;\n  /// @inheritdoc IPool\n  mapping(address _account => mapping(address _operator => bool _approved)) public approvedForClaim;\n\n  /*////////////////////////////////////////////////////////////\n                          CONSTRUCTOR\n  ////////////////////////////////////////////////////////////*/\n\n  constructor() ERC20('', '') {}\n\n  /*////////////////////////////////////////////////////////////\n                  EXTERNAL WRITE FUNCTIONS\n  ////////////////////////////////////////////////////////////*/\n\n  /// @inheritdoc IPool\n  function approveForClaim(address _operator, bool _approved) external {\n    if (_operator == address(0)) revert ZeroAddress();\n    approvedForClaim[msg.sender][_operator] = _approved;\n    emit ClaimApproval(msg.sender, _operator, _approved);\n  }\n\n  /// @inheritdoc IPool\n  function claimFees(address _recipient) external returns (uint256, uint256) {\n    if (_recipient == address(0)) revert ZeroAddress();\n    return _claimFees(msg.sender, _recipient);\n  }\n\n  /// @inheritdoc IPool\n  function claimFees(address _account, address _recipient) external returns (uint256, uint256) {\n    if (_recipient == address(0)) revert ZeroAddress();\n    if (msg.sender != _account && !approvedForClaim[_account][msg.sender]) revert NotAuthorized();\n    return _claimFees(_account, _recipient);\n  }\n\n  /// @inheritdoc IPool\n  function getK() external nonReentrant returns (uint256) {\n    return _k(reserve0, reserve1);\n  }\n\n  /// @inheritdoc IPool\n  function setName(string calldata __name) external {\n    if (msg.sender != IPoolFactory(factory).poolAdmin()) revert IPoolFactory.NotPoolAdmin();\n    _name = __name;\n  }\n\n  /// @inheritdoc IPool\n  function setSymbol(string calldata __symbol) external {\n    if (msg.sender != IPoolFactory(factory).poolAdmin()) revert IPoolFactory.NotPoolAdmin();\n    _symbol = __symbol;\n  }\n\n  // slither-disable-start reentrancy-no-eth\n  /// @inheritdoc IPool\n  function swap(uint256 amount0Out, uint256 amount1Out, address to, bytes calldata data) external nonReentrant {\n    if (IPoolFactory(factory).isPaused()) revert IsPaused();\n    if (amount0Out == 0 && amount1Out == 0) revert InsufficientOutputAmount();\n    (uint256 _reserve0, uint256 _reserve1) = (reserve0, reserve1);\n    if (amount0Out >= _reserve0 || amount1Out >= _reserve1) revert InsufficientLiquidity();\n\n    uint256 _balance0;\n    uint256 _balance1;\n    {\n      // scope for _token{0,1}, avoids stack too deep errors\n      (address _token0, address _token1) = (token0, token1);\n      if (to == _token0 || to == _token1) revert InvalidTo();\n      if (amount0Out > 0) IERC20(_token0).safeTransfer(to, amount0Out); // optimistically transfer tokens\n      if (amount1Out > 0) IERC20(_token1).safeTransfer(to, amount1Out); // optimistically transfer tokens\n      if (data.length > 0) IPoolCallee(to).hook(msg.sender, amount0Out, amount1Out, data); // callback, used for flash loans\n      _balance0 = IERC20(_token0).balanceOf(address(this));\n      _balance1 = IERC20(_token1).balanceOf(address(this));\n    }\n    uint256 amount0In = _balance0 > _reserve0 - amount0Out ? _balance0 - (_reserve0 - amount0Out) : 0;\n    uint256 amount1In = _balance1 > _reserve1 - amount1Out ? _balance1 - (_reserve1 - amount1Out) : 0;\n    if (amount0In == 0 && amount1In == 0) revert InsufficientInputAmount();\n    {\n      // scope for reserve{0,1}Adjusted, avoids stack too deep errors\n      // slither-disable-next-line uninitialized-local\n      IPoolTape.PoolTapeData memory _tapeData;\n      _tapeData.volume0 = uint128(amount0In + amount0Out);\n      _tapeData.volume1 = uint128(amount1In + amount1Out);\n      (address _token0, address _token1) = (token0, token1);\n      // Calls _getSwapFee to avoid stack too dep errors\n      (uint256 _fee, uint256 _mevFee, bool _toxic) = _getSwapFee(amount0In, amount1In, _reserve0, _reserve1);\n      if (amount0In > 0) {\n        uint256 _feeAmount0 = (amount0In * _fee) / _MAX_BPS;\n        _update0(_feeAmount0);\n        _tapeData.fee0 = uint128(_feeAmount0);\n        _tapeData.mevFee0 = uint128((amount0In * _mevFee) / _MAX_BPS);\n      }\n      if (amount1In > 0) {\n        uint256 _feeAmount1 = (amount1In * _fee) / _MAX_BPS;\n        _update1(_feeAmount1);\n        _tapeData.fee1 = uint128(_feeAmount1);\n        _tapeData.mevFee1 = uint128((amount1In * _mevFee) / _MAX_BPS);\n      }\n      if (_toxic) {\n        _tapeData.mevVolume0 = _tapeData.volume0;\n        _tapeData.mevVolume1 = _tapeData.volume1;\n      }\n      // since we removed tokens, we need to reconfirm balances\n      _balance0 = IERC20(_token0).balanceOf(address(this));\n      _balance1 = IERC20(_token1).balanceOf(address(this));\n      // The curve invariant, supplied by the child contract\n      if (_k(_balance0, _balance1) < _k(_reserve0, _reserve1)) revert K();\n      IPoolFactory(factory).recordPoolTape(_tapeData);\n    }\n\n    _update(_balance0, _balance1, _reserve0, _reserve1);\n    emit Swap(msg.sender, to, amount0In, amount1In, amount0Out, amount1Out);\n  }\n\n  // slither-disable-end reentrancy-no-eth\n  /// @inheritdoc IPool\n  function burn(address to) external nonReentrant returns (uint256 amount0, uint256 amount1) {\n    (uint256 _reserve0, uint256 _reserve1) = (reserve0, reserve1);\n    (address _token0, address _token1) = (token0, token1);\n    uint256 _balance0 = IERC20(_token0).balanceOf(address(this));\n    uint256 _balance1 = IERC20(_token1).balanceOf(address(this));\n    uint256 _liquidity = balanceOf(address(this));\n\n    uint256 _totalSupply = totalSupply(); // gas savings, must be defined here since totalSupply can update in _mintFee\n    amount0 = (_liquidity * _balance0) / _totalSupply; // using balances ensures pro-rata distribution\n    amount1 = (_liquidity * _balance1) / _totalSupply; // using balances ensures pro-rata distribution\n    if (amount0 == 0 || amount1 == 0) revert InsufficientLiquidityBurned();\n    _burn(address(this), _liquidity);\n    IERC20(_token0).safeTransfer(to, amount0);\n    IERC20(_token1).safeTransfer(to, amount1);\n    _balance0 = IERC20(_token0).balanceOf(address(this));\n    _balance1 = IERC20(_token1).balanceOf(address(this));\n\n    _kThresholdValidation(_balance0, _balance1);\n\n    _update(_balance0, _balance1, _reserve0, _reserve1);\n    emit Burn(msg.sender, to, amount0, amount1);\n  }\n\n  /// @inheritdoc IPool\n  function mint(address to) external nonReentrant returns (uint256 liquidity) {\n    (uint256 _reserve0, uint256 _reserve1) = (reserve0, reserve1);\n    uint256 _balance0 = IERC20(token0).balanceOf(address(this));\n    uint256 _balance1 = IERC20(token1).balanceOf(address(this));\n    uint256 _amount0 = _balance0 - _reserve0;\n    uint256 _amount1 = _balance1 - _reserve1;\n\n    uint256 _totalSupply = totalSupply(); // gas savings, must be defined here since totalSupply can update in _mintFee\n    if (_totalSupply == 0) {\n      liquidity = Math.sqrt(_amount0 * _amount1) - _MINIMUM_LIQUIDITY;\n      _mint(address(1), _MINIMUM_LIQUIDITY); // permanently lock the first _MINIMUM_LIQUIDITY tokens - cannot be address(0)\n      _mintValidation(_amount0, _amount1);\n      if (liquidity < _MINIMUM_LIQUIDITY) revert InsufficientLiquidityMinted();\n    } else {\n      liquidity = Math.min((_amount0 * _totalSupply) / _reserve0, (_amount1 * _totalSupply) / _reserve1);\n      if (liquidity == 0) revert InsufficientLiquidityMinted();\n    }\n    _mint(to, liquidity);\n\n    _update(_balance0, _balance1, _reserve0, _reserve1);\n    emit Mint(msg.sender, to, _amount0, _amount1);\n  }\n\n  /// @inheritdoc IPool\n  function skim(address to) external nonReentrant {\n    (address _token0, address _token1) = (token0, token1);\n    uint256 _excess0 = IERC20(_token0).balanceOf(address(this)) - reserve0;\n    if (_excess0 > 0) IERC20(_token0).safeTransfer(to, _excess0);\n    uint256 _excess1 = IERC20(_token1).balanceOf(address(this)) - reserve1;\n    if (_excess1 > 0) IERC20(_token1).safeTransfer(to, _excess1);\n  }\n\n  /// @inheritdoc IPool\n  function sync() external nonReentrant {\n    if (totalSupply() == 0) revert InsufficientLiquidity();\n    _update(IERC20(token0).balanceOf(address(this)), IERC20(token1).balanceOf(address(this)), reserve0, reserve1);\n  }\n\n  /// @inheritdoc IPool\n  function initialize(address _token0, address _token1) external {\n    if (factory != address(0)) revert FactoryAlreadySet();\n    factory = msg.sender;\n    (token0, token1) = (_token0, _token1);\n    poolFees = address(new PoolFees(_token0, _token1));\n    string memory symbol0 = ERC20(_token0).symbol();\n    string memory symbol1 = ERC20(_token1).symbol();\n    _name = _poolName(symbol0, symbol1);\n    _symbol = _poolSymbol(symbol0, symbol1);\n\n    _decimals0 = 10 ** ERC20(_token0).decimals();\n    _decimals1 = 10 ** ERC20(_token1).decimals();\n\n    observationBuffer.initialize();\n  }\n\n  /// @inheritdoc IPool\n  /// @dev Pre-initialises buffer slots so observation writes hit warm storage.\n  function increaseObservationCardinalityNext(uint16 _observationCardinalityNext) external {\n    uint16 _currentCardinalityNext = observationBuffer.cardinalityNext;\n    uint16 _updatedCardinalityNext = observationBuffer.grow(_observationCardinalityNext);\n    if (_updatedCardinalityNext != _currentCardinalityNext) {\n      emit IncreaseObservationCardinalityNext(msg.sender, _currentCardinalityNext, _updatedCardinalityNext);\n    }\n  }\n\n  /*////////////////////////////////////////////////////////////\n                        INTERNAL FUNCTIONS\n  ////////////////////////////////////////////////////////////*/\n\n  /// @dev Claims `_account`'s accumulated fees to `_recipient`.\n  function _claimFees(address _account, address _recipient) internal returns (uint256 _claimed0, uint256 _claimed1) {\n    _updateFor(_account);\n\n    _claimed0 = claimable0[_account];\n    _claimed1 = claimable1[_account];\n\n    if (_claimed0 > 0 || _claimed1 > 0) {\n      delete claimable0[_account];\n      delete claimable1[_account];\n\n      PoolFees(poolFees).claimFeesFor({_recipient: _recipient, _amount0: _claimed0, _amount1: _claimed1});\n\n      emit Claim({caller: msg.sender, account: _account, recipient: _recipient, amount0: _claimed0, amount1: _claimed1});\n    }\n  }\n\n  /// @dev Accrue fees on token0\n  function _update0(uint256 amount) internal {\n    // Only update on this pool if there is a fee\n    if (amount == 0) return;\n    IERC20(token0).safeTransfer(poolFees, amount); // transfer the fees out to PoolFees\n    uint256 _ratio = (amount * 1e18) / totalSupply(); // 1e18 adjustment is removed during claim\n    if (_ratio > 0) {\n      index0 += _ratio;\n    }\n    emit Fees(msg.sender, amount, 0);\n  }\n\n  /// @dev Accrue fees on token1\n  function _update1(uint256 amount) internal {\n    // Only update on this pool if there is a fee\n    if (amount == 0) return;\n    IERC20(token1).safeTransfer(poolFees, amount);\n    uint256 _ratio = (amount * 1e18) / totalSupply();\n    if (_ratio > 0) {\n      index1 += _ratio;\n    }\n    emit Fees(msg.sender, 0, amount);\n  }\n\n  /// @dev This function MUST be called on any balance changes, otherwise can be used to infinitely claim fees\n  ///      Fees are segregated from core funds, so fees can never put liquidity at risk.\n  function _updateFor(address recipient) internal {\n    uint256 _supplied = balanceOf(recipient); // get LP balance of `recipient`\n    if (_supplied > 0) {\n      uint256 _supplyIndex0 = supplyIndex0[recipient]; // get last adjusted index0 for recipient\n      uint256 _supplyIndex1 = supplyIndex1[recipient];\n      uint256 _index0 = index0; // get global index0 for accumulated fees\n      uint256 _index1 = index1;\n      supplyIndex0[recipient] = _index0; // update user current position to global position\n      supplyIndex1[recipient] = _index1;\n      uint256 _delta0 = _index0 - _supplyIndex0; // see if there is any difference that need to be accrued\n      uint256 _delta1 = _index1 - _supplyIndex1;\n      if (_delta0 > 0) {\n        uint256 _share = (_supplied * _delta0) / 1e18; // add accrued difference for each supplied token\n        claimable0[recipient] += _share;\n      }\n      if (_delta1 > 0) {\n        uint256 _share = (_supplied * _delta1) / 1e18;\n        claimable1[recipient] += _share;\n      }\n    } else {\n      supplyIndex0[recipient] = index0; // new users are set to the default global state\n      supplyIndex1[recipient] = index1;\n    }\n  }\n\n  /// @notice Commits new balances to reserves and writes a new observation when due.\n  /// @dev Cumulative accumulators advance by `_reserve* * timeElapsed` when previous reserves were\n  ///      nonzero. The observation write is delegated to `PoolOracle.write`, which advances the buffer\n  ///      only when more than `PERIOD_SIZE` has elapsed since the newest observation.\n  /// @param  balance0 New token0 balance.\n  /// @param  balance1 New token1 balance.\n  /// @param  _reserve0 Previous token0 reserve\n  /// @param  _reserve1 Previous token1 reserve\n  function _update(uint256 balance0, uint256 balance1, uint256 _reserve0, uint256 _reserve1) internal {\n    uint256 blockTimestamp = block.timestamp;\n    uint256 timeElapsed = blockTimestamp - blockTimestampLast;\n    if (timeElapsed > 0 && _reserve0 != 0 && _reserve1 != 0) {\n      reserve0CumulativeLast += _reserve0 * timeElapsed;\n      reserve1CumulativeLast += _reserve1 * timeElapsed;\n    }\n\n    observationBuffer.write(reserve0CumulativeLast, reserve1CumulativeLast, PERIOD_SIZE);\n\n    reserve0 = balance0;\n    reserve1 = balance1;\n    blockTimestampLast = blockTimestamp;\n    emit Sync(balance0, balance1);\n  }\n\n  /// @dev Resolves the swap fee via the factory.\n  function _getSwapFee(\n    uint256 _amount0In,\n    uint256 _amount1In,\n    uint256 _reserve0,\n    uint256 _reserve1\n  ) internal view returns (uint256 _fee, uint256 _mevFee, bool _toxic) {\n    // slither-disable-next-line unused-return\n    return IPoolFactory(factory).getFee(address(this), msg.sender, _amount0In, _amount1In, _reserve0, _reserve1);\n  }\n\n  /// @dev Curve invariant. The child contract supplies either the constant-product or\n  ///      stable-swap formula.\n  function _k(uint256 x, uint256 y) internal view virtual returns (uint256);\n\n  /// @dev Output amount given an input and reserve snapshot. The child contract supplies\n  ///      the curve-specific pricing.\n  function _getAmountOut(\n    uint256 amountIn,\n    address tokenIn,\n    uint256 _reserve0,\n    uint256 _reserve1\n  ) internal view virtual returns (uint256);\n\n  /// @dev Input amount required for a requested output, before the swap fee. The child contract\n  ///      supplies the curve-specific pricing.\n  /// @param  amountOut The output amount to receive\n  /// @param  tokenOut The output token\n  /// @param  _reserve0 The token0 reserve to quote against\n  /// @param  _reserve1 The token1 reserve to quote against\n  /// @return The input amount before the fee\n  function _getAmountIn(\n    uint256 amountOut,\n    address tokenOut,\n    uint256 _reserve0,\n    uint256 _reserve1\n  ) internal view virtual returns (uint256);\n\n  /// @dev Curve-specific validation invoked on the first mint.\n  function _mintValidation(uint256 _amount0, uint256 _amount1) internal view virtual {}\n\n  /// @dev Curve-specific post-burn check on remaining reserves\n  function _kThresholdValidation(uint256 _x, uint256 _y) internal view virtual {}\n\n  /// @dev Curve-specific full pool name used during initialization.\n  function _poolName(string memory _symbol0, string memory _symbol1) internal pure virtual returns (string memory);\n\n  /// @dev Curve-specific full pool symbol used during initialization.\n  function _poolSymbol(string memory _symbol0, string memory _symbol1) internal pure virtual returns (string memory);\n\n  function _update(address from, address to, uint256 amount) internal override {\n    if (from != address(0)) _updateFor(from);\n    if (to != address(0)) _updateFor(to);\n    super._update(from, to, amount);\n  }\n\n  /*////////////////////////////////////////////////////////////\n                      VIEW & PURE FUNCTIONS\n  ////////////////////////////////////////////////////////////*/\n\n  /// @inheritdoc IPool\n  function pendingFees(address _account) external view returns (uint256 _amount0, uint256 _amount1) {\n    _amount0 = claimable0[_account];\n    _amount1 = claimable1[_account];\n\n    uint256 _supplied = balanceOf(_account);\n    if (_supplied > 0) {\n      _amount0 += (_supplied * (index0 - supplyIndex0[_account])) / 1e18;\n      _amount1 += (_supplied * (index1 - supplyIndex1[_account])) / 1e18;\n    }\n  }\n\n  /// @inheritdoc IPool\n  function metadata()\n    external\n    view\n    returns (uint256 dec0, uint256 dec1, uint256 r0, uint256 r1, address t0, address t1)\n  {\n    return (_decimals0, _decimals1, reserve0, reserve1, token0, token1);\n  }\n\n  /// @inheritdoc IPool\n  function tokens() external view returns (address, address) {\n    return (token0, token1);\n  }\n\n  /// @inheritdoc IPool\n  function observe(uint32[] calldata _secondsAgos)\n    external\n    view\n    returns (uint256[] memory _reserve0Cumulatives, uint256[] memory _reserve1Cumulatives)\n  {\n    (uint256 _r0Now, uint256 _r1Now,) = currentCumulativePrices();\n    // slither-disable-next-line unused-return\n    return observationBuffer.observe(_secondsAgos, _r0Now, _r1Now);\n  }\n\n  /// @inheritdoc IPool\n  function observations(uint256 _index)\n    external\n    view\n    returns (uint32 timestamp, uint256 reserve0Cumulative, uint256 reserve1Cumulative)\n  {\n    PoolOracle.Observation memory _observation = observationBuffer.observations[_index];\n    return (_observation.timestamp, _observation.reserve0Cumulative, _observation.reserve1Cumulative);\n  }\n\n  /// @inheritdoc IPool\n  function getAmountOut(\n    uint256 amountIn,\n    address tokenIn,\n    uint256 _reserve0,\n    uint256 _reserve1\n  ) external view returns (uint256) {\n    (uint256 _amount0In, uint256 _amount1In) = tokenIn == token0 ? (amountIn, uint256(0)) : (uint256(0), amountIn);\n    amountIn -= (amountIn\n        * IPoolFactory(factory).getBaseFee(address(this), address(0), _amount0In, _amount1In, _reserve0, _reserve1))\n      / _MAX_BPS;\n    return _getAmountOut(amountIn, tokenIn, _reserve0, _reserve1);\n  }\n\n  /// @inheritdoc IPool\n  function currentCumulativePrices()\n    public\n    view\n    returns (uint256 reserve0Cumulative, uint256 reserve1Cumulative, uint256 blockTimestamp)\n  {\n    blockTimestamp = block.timestamp;\n    reserve0Cumulative = reserve0CumulativeLast;\n    reserve1Cumulative = reserve1CumulativeLast;\n\n    // if time has elapsed since the last update on the pool, mock the accumulated price values\n    (uint256 _reserve0, uint256 _reserve1, uint256 _blockTimestampLast) = getReserves();\n    if (_blockTimestampLast != blockTimestamp) {\n      // subtraction overflow is desired\n      uint256 timeElapsed = blockTimestamp - _blockTimestampLast;\n      reserve0Cumulative += _reserve0 * timeElapsed;\n      reserve1Cumulative += _reserve1 * timeElapsed;\n    }\n  }\n\n  /// @inheritdoc IPool\n  function getReserves() public view returns (uint256 _reserve0, uint256 _reserve1, uint256 _blockTimestampLast) {\n    _reserve0 = reserve0;\n    _reserve1 = reserve1;\n    _blockTimestampLast = blockTimestampLast;\n  }\n\n  /// @inheritdoc IPool\n  function getAmountOut(uint256 amountIn, address tokenIn) external view returns (uint256) {\n    (uint256 _reserve0, uint256 _reserve1) = (reserve0, reserve1);\n    (uint256 _amount0In, uint256 _amount1In) = tokenIn == token0 ? (amountIn, uint256(0)) : (uint256(0), amountIn);\n    // remove fee from amount received\n    amountIn -= (amountIn\n        * IPoolFactory(factory).getBaseFee(address(this), address(0), _amount0In, _amount1In, _reserve0, _reserve1))\n      / _MAX_BPS;\n    return _getAmountOut(amountIn, tokenIn, _reserve0, _reserve1);\n  }\n\n  /// @inheritdoc IPool\n  function getAmountOutWithTotalFee(uint256 amountIn, address tokenIn) external view returns (uint256) {\n    (uint256 _reserve0, uint256 _reserve1) = (reserve0, reserve1);\n    (uint256 _amount0In, uint256 _amount1In) = tokenIn == token0 ? (amountIn, uint256(0)) : (uint256(0), amountIn);\n    (uint256 _fee,,) = _getSwapFee(_amount0In, _amount1In, _reserve0, _reserve1);\n    // remove fee from amount received\n    amountIn -= (amountIn * _fee) / _MAX_BPS;\n    return _getAmountOut(amountIn, tokenIn, _reserve0, _reserve1);\n  }\n\n  /// @inheritdoc IPool\n  function getAmountInWithTotalFee(uint256 amountOut, address tokenOut) external view returns (uint256) {\n    if (amountOut == 0) return 0;\n    (uint256 _reserve0, uint256 _reserve1) = (reserve0, reserve1);\n    if (amountOut >= (tokenOut == token0 ? _reserve0 : _reserve1)) revert InsufficientLiquidity();\n\n    uint256 _amountInAfterFee = _getAmountIn(amountOut, tokenOut, _reserve0, _reserve1);\n\n    // this sanity check prevents underflow while calculating the grossed up input.\n    // a swap with amount zero will revert due to insufficient liquidity.\n    if (_amountInAfterFee == 0) return 0;\n\n    (uint256 _amount0In, uint256 _amount1In) =\n      tokenOut == token0 ? (uint256(0), _amountInAfterFee) : (_amountInAfterFee, uint256(0));\n    uint256 _fee =\n      IPoolFactory(factory).getFeeForAmountIn(address(this), msg.sender, _amount0In, _amount1In, _reserve0, _reserve1);\n    return _amountInAfterFee + Math.mulDiv(_fee, _amountInAfterFee - 1, _MAX_BPS - _fee);\n  }\n\n  function name() public view override returns (string memory) {\n    return _name;\n  }\n\n  function symbol() public view override returns (string memory) {\n    return _symbol;\n  }\n}\n"},"node_modules/@openzeppelin/contracts/utils/Panic.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/Panic.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Helper library for emitting standardized panic codes.\n *\n * ```solidity\n * contract Example {\n *      using Panic for uint256;\n *\n *      // Use any of the declared internal constants\n *      function foo() { Panic.GENERIC.panic(); }\n *\n *      // Alternatively\n *      function foo() { Panic.panic(Panic.GENERIC); }\n * }\n * ```\n *\n * Follows the list from https://github.com/ethereum/solidity/blob/v0.8.24/libsolutil/ErrorCodes.h[libsolutil].\n *\n * _Available since v5.1._\n */\n// slither-disable-next-line unused-state\nlibrary Panic {\n    /// @dev generic / unspecified error\n    uint256 internal constant GENERIC = 0x00;\n    /// @dev used by the assert() builtin\n    uint256 internal constant ASSERT = 0x01;\n    /// @dev arithmetic underflow or overflow\n    uint256 internal constant UNDER_OVERFLOW = 0x11;\n    /// @dev division or modulo by zero\n    uint256 internal constant DIVISION_BY_ZERO = 0x12;\n    /// @dev enum conversion error\n    uint256 internal constant ENUM_CONVERSION_ERROR = 0x21;\n    /// @dev invalid encoding in storage\n    uint256 internal constant STORAGE_ENCODING_ERROR = 0x22;\n    /// @dev empty array pop\n    uint256 internal constant EMPTY_ARRAY_POP = 0x31;\n    /// @dev array out of bounds access\n    uint256 internal constant ARRAY_OUT_OF_BOUNDS = 0x32;\n    /// @dev resource error (too large allocation or too large array)\n    uint256 internal constant RESOURCE_ERROR = 0x41;\n    /// @dev calling invalid internal function\n    uint256 internal constant INVALID_INTERNAL_FUNCTION = 0x51;\n\n    /// @dev Reverts with a panic code. Recommended to use with\n    /// the internal constants with predefined codes.\n    function panic(uint256 code) internal pure {\n        assembly (\"memory-safe\") {\n            mstore(0x00, 0x4e487b71)\n            mstore(0x20, code)\n            revert(0x1c, 0x24)\n        }\n    }\n}\n"},"node_modules/@openzeppelin/contracts/utils/math/SafeCast.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.6.0) (utils/math/SafeCast.sol)\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX/bool casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeCast {\n    /**\n     * @dev Value doesn't fit in a uint of `bits` size.\n     */\n    error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value);\n\n    /**\n     * @dev An int value doesn't fit in a uint of `bits` size.\n     */\n    error SafeCastOverflowedIntToUint(int256 value);\n\n    /**\n     * @dev Value doesn't fit in an int of `bits` size.\n     */\n    error SafeCastOverflowedIntDowncast(uint8 bits, int256 value);\n\n    /**\n     * @dev A uint value doesn't fit in an int of `bits` size.\n     */\n    error SafeCastOverflowedUintToInt(uint256 value);\n\n    /**\n     * @dev Returns the downcasted uint248 from uint256, reverting on\n     * overflow (when the input is greater than largest uint248).\n     *\n     * Counterpart to Solidity's `uint248` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 248 bits\n     */\n    function toUint248(uint256 value) internal pure returns (uint248) {\n        if (value > type(uint248).max) {\n            revert SafeCastOverflowedUintDowncast(248, value);\n        }\n        return uint248(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint240 from uint256, reverting on\n     * overflow (when the input is greater than largest uint240).\n     *\n     * Counterpart to Solidity's `uint240` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 240 bits\n     */\n    function toUint240(uint256 value) internal pure returns (uint240) {\n        if (value > type(uint240).max) {\n            revert SafeCastOverflowedUintDowncast(240, value);\n        }\n        return uint240(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint232 from uint256, reverting on\n     * overflow (when the input is greater than largest uint232).\n     *\n     * Counterpart to Solidity's `uint232` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 232 bits\n     */\n    function toUint232(uint256 value) internal pure returns (uint232) {\n        if (value > type(uint232).max) {\n            revert SafeCastOverflowedUintDowncast(232, value);\n        }\n        return uint232(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint224 from uint256, reverting on\n     * overflow (when the input is greater than largest uint224).\n     *\n     * Counterpart to Solidity's `uint224` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 224 bits\n     */\n    function toUint224(uint256 value) internal pure returns (uint224) {\n        if (value > type(uint224).max) {\n            revert SafeCastOverflowedUintDowncast(224, value);\n        }\n        return uint224(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint216 from uint256, reverting on\n     * overflow (when the input is greater than largest uint216).\n     *\n     * Counterpart to Solidity's `uint216` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 216 bits\n     */\n    function toUint216(uint256 value) internal pure returns (uint216) {\n        if (value > type(uint216).max) {\n            revert SafeCastOverflowedUintDowncast(216, value);\n        }\n        return uint216(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint208 from uint256, reverting on\n     * overflow (when the input is greater than largest uint208).\n     *\n     * Counterpart to Solidity's `uint208` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 208 bits\n     */\n    function toUint208(uint256 value) internal pure returns (uint208) {\n        if (value > type(uint208).max) {\n            revert SafeCastOverflowedUintDowncast(208, value);\n        }\n        return uint208(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint200 from uint256, reverting on\n     * overflow (when the input is greater than largest uint200).\n     *\n     * Counterpart to Solidity's `uint200` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 200 bits\n     */\n    function toUint200(uint256 value) internal pure returns (uint200) {\n        if (value > type(uint200).max) {\n            revert SafeCastOverflowedUintDowncast(200, value);\n        }\n        return uint200(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint192 from uint256, reverting on\n     * overflow (when the input is greater than largest uint192).\n     *\n     * Counterpart to Solidity's `uint192` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 192 bits\n     */\n    function toUint192(uint256 value) internal pure returns (uint192) {\n        if (value > type(uint192).max) {\n            revert SafeCastOverflowedUintDowncast(192, value);\n        }\n        return uint192(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint184 from uint256, reverting on\n     * overflow (when the input is greater than largest uint184).\n     *\n     * Counterpart to Solidity's `uint184` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 184 bits\n     */\n    function toUint184(uint256 value) internal pure returns (uint184) {\n        if (value > type(uint184).max) {\n            revert SafeCastOverflowedUintDowncast(184, value);\n        }\n        return uint184(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint176 from uint256, reverting on\n     * overflow (when the input is greater than largest uint176).\n     *\n     * Counterpart to Solidity's `uint176` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 176 bits\n     */\n    function toUint176(uint256 value) internal pure returns (uint176) {\n        if (value > type(uint176).max) {\n            revert SafeCastOverflowedUintDowncast(176, value);\n        }\n        return uint176(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint168 from uint256, reverting on\n     * overflow (when the input is greater than largest uint168).\n     *\n     * Counterpart to Solidity's `uint168` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 168 bits\n     */\n    function toUint168(uint256 value) internal pure returns (uint168) {\n        if (value > type(uint168).max) {\n            revert SafeCastOverflowedUintDowncast(168, value);\n        }\n        return uint168(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint160 from uint256, reverting on\n     * overflow (when the input is greater than largest uint160).\n     *\n     * Counterpart to Solidity's `uint160` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 160 bits\n     */\n    function toUint160(uint256 value) internal pure returns (uint160) {\n        if (value > type(uint160).max) {\n            revert SafeCastOverflowedUintDowncast(160, value);\n        }\n        return uint160(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint152 from uint256, reverting on\n     * overflow (when the input is greater than largest uint152).\n     *\n     * Counterpart to Solidity's `uint152` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 152 bits\n     */\n    function toUint152(uint256 value) internal pure returns (uint152) {\n        if (value > type(uint152).max) {\n            revert SafeCastOverflowedUintDowncast(152, value);\n        }\n        return uint152(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint144 from uint256, reverting on\n     * overflow (when the input is greater than largest uint144).\n     *\n     * Counterpart to Solidity's `uint144` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 144 bits\n     */\n    function toUint144(uint256 value) internal pure returns (uint144) {\n        if (value > type(uint144).max) {\n            revert SafeCastOverflowedUintDowncast(144, value);\n        }\n        return uint144(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint136 from uint256, reverting on\n     * overflow (when the input is greater than largest uint136).\n     *\n     * Counterpart to Solidity's `uint136` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 136 bits\n     */\n    function toUint136(uint256 value) internal pure returns (uint136) {\n        if (value > type(uint136).max) {\n            revert SafeCastOverflowedUintDowncast(136, value);\n        }\n        return uint136(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint128 from uint256, reverting on\n     * overflow (when the input is greater than largest uint128).\n     *\n     * Counterpart to Solidity's `uint128` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 128 bits\n     */\n    function toUint128(uint256 value) internal pure returns (uint128) {\n        if (value > type(uint128).max) {\n            revert SafeCastOverflowedUintDowncast(128, value);\n        }\n        return uint128(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint120 from uint256, reverting on\n     * overflow (when the input is greater than largest uint120).\n     *\n     * Counterpart to Solidity's `uint120` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 120 bits\n     */\n    function toUint120(uint256 value) internal pure returns (uint120) {\n        if (value > type(uint120).max) {\n            revert SafeCastOverflowedUintDowncast(120, value);\n        }\n        return uint120(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint112 from uint256, reverting on\n     * overflow (when the input is greater than largest uint112).\n     *\n     * Counterpart to Solidity's `uint112` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 112 bits\n     */\n    function toUint112(uint256 value) internal pure returns (uint112) {\n        if (value > type(uint112).max) {\n            revert SafeCastOverflowedUintDowncast(112, value);\n        }\n        return uint112(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint104 from uint256, reverting on\n     * overflow (when the input is greater than largest uint104).\n     *\n     * Counterpart to Solidity's `uint104` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 104 bits\n     */\n    function toUint104(uint256 value) internal pure returns (uint104) {\n        if (value > type(uint104).max) {\n            revert SafeCastOverflowedUintDowncast(104, value);\n        }\n        return uint104(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint96 from uint256, reverting on\n     * overflow (when the input is greater than largest uint96).\n     *\n     * Counterpart to Solidity's `uint96` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 96 bits\n     */\n    function toUint96(uint256 value) internal pure returns (uint96) {\n        if (value > type(uint96).max) {\n            revert SafeCastOverflowedUintDowncast(96, value);\n        }\n        return uint96(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint88 from uint256, reverting on\n     * overflow (when the input is greater than largest uint88).\n     *\n     * Counterpart to Solidity's `uint88` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 88 bits\n     */\n    function toUint88(uint256 value) internal pure returns (uint88) {\n        if (value > type(uint88).max) {\n            revert SafeCastOverflowedUintDowncast(88, value);\n        }\n        return uint88(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint80 from uint256, reverting on\n     * overflow (when the input is greater than largest uint80).\n     *\n     * Counterpart to Solidity's `uint80` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 80 bits\n     */\n    function toUint80(uint256 value) internal pure returns (uint80) {\n        if (value > type(uint80).max) {\n            revert SafeCastOverflowedUintDowncast(80, value);\n        }\n        return uint80(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint72 from uint256, reverting on\n     * overflow (when the input is greater than largest uint72).\n     *\n     * Counterpart to Solidity's `uint72` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 72 bits\n     */\n    function toUint72(uint256 value) internal pure returns (uint72) {\n        if (value > type(uint72).max) {\n            revert SafeCastOverflowedUintDowncast(72, value);\n        }\n        return uint72(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint64 from uint256, reverting on\n     * overflow (when the input is greater than largest uint64).\n     *\n     * Counterpart to Solidity's `uint64` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 64 bits\n     */\n    function toUint64(uint256 value) internal pure returns (uint64) {\n        if (value > type(uint64).max) {\n            revert SafeCastOverflowedUintDowncast(64, value);\n        }\n        return uint64(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint56 from uint256, reverting on\n     * overflow (when the input is greater than largest uint56).\n     *\n     * Counterpart to Solidity's `uint56` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 56 bits\n     */\n    function toUint56(uint256 value) internal pure returns (uint56) {\n        if (value > type(uint56).max) {\n            revert SafeCastOverflowedUintDowncast(56, value);\n        }\n        return uint56(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint48 from uint256, reverting on\n     * overflow (when the input is greater than largest uint48).\n     *\n     * Counterpart to Solidity's `uint48` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 48 bits\n     */\n    function toUint48(uint256 value) internal pure returns (uint48) {\n        if (value > type(uint48).max) {\n            revert SafeCastOverflowedUintDowncast(48, value);\n        }\n        return uint48(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint40 from uint256, reverting on\n     * overflow (when the input is greater than largest uint40).\n     *\n     * Counterpart to Solidity's `uint40` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 40 bits\n     */\n    function toUint40(uint256 value) internal pure returns (uint40) {\n        if (value > type(uint40).max) {\n            revert SafeCastOverflowedUintDowncast(40, value);\n        }\n        return uint40(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint32 from uint256, reverting on\n     * overflow (when the input is greater than largest uint32).\n     *\n     * Counterpart to Solidity's `uint32` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 32 bits\n     */\n    function toUint32(uint256 value) internal pure returns (uint32) {\n        if (value > type(uint32).max) {\n            revert SafeCastOverflowedUintDowncast(32, value);\n        }\n        return uint32(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint24 from uint256, reverting on\n     * overflow (when the input is greater than largest uint24).\n     *\n     * Counterpart to Solidity's `uint24` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 24 bits\n     */\n    function toUint24(uint256 value) internal pure returns (uint24) {\n        if (value > type(uint24).max) {\n            revert SafeCastOverflowedUintDowncast(24, value);\n        }\n        return uint24(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint16 from uint256, reverting on\n     * overflow (when the input is greater than largest uint16).\n     *\n     * Counterpart to Solidity's `uint16` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 16 bits\n     */\n    function toUint16(uint256 value) internal pure returns (uint16) {\n        if (value > type(uint16).max) {\n            revert SafeCastOverflowedUintDowncast(16, value);\n        }\n        return uint16(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint8 from uint256, reverting on\n     * overflow (when the input is greater than largest uint8).\n     *\n     * Counterpart to Solidity's `uint8` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 8 bits\n     */\n    function toUint8(uint256 value) internal pure returns (uint8) {\n        if (value > type(uint8).max) {\n            revert SafeCastOverflowedUintDowncast(8, value);\n        }\n        return uint8(value);\n    }\n\n    /**\n     * @dev Converts a signed int256 into an unsigned uint256.\n     *\n     * Requirements:\n     *\n     * - input must be greater than or equal to 0.\n     */\n    function toUint256(int256 value) internal pure returns (uint256) {\n        if (value < 0) {\n            revert SafeCastOverflowedIntToUint(value);\n        }\n        return uint256(value);\n    }\n\n    /**\n     * @dev Returns the downcasted int248 from int256, reverting on\n     * overflow (when the input is less than smallest int248 or\n     * greater than largest int248).\n     *\n     * Counterpart to Solidity's `int248` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 248 bits\n     */\n    function toInt248(int256 value) internal pure returns (int248 downcasted) {\n        downcasted = int248(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(248, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int240 from int256, reverting on\n     * overflow (when the input is less than smallest int240 or\n     * greater than largest int240).\n     *\n     * Counterpart to Solidity's `int240` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 240 bits\n     */\n    function toInt240(int256 value) internal pure returns (int240 downcasted) {\n        downcasted = int240(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(240, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int232 from int256, reverting on\n     * overflow (when the input is less than smallest int232 or\n     * greater than largest int232).\n     *\n     * Counterpart to Solidity's `int232` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 232 bits\n     */\n    function toInt232(int256 value) internal pure returns (int232 downcasted) {\n        downcasted = int232(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(232, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int224 from int256, reverting on\n     * overflow (when the input is less than smallest int224 or\n     * greater than largest int224).\n     *\n     * Counterpart to Solidity's `int224` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 224 bits\n     */\n    function toInt224(int256 value) internal pure returns (int224 downcasted) {\n        downcasted = int224(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(224, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int216 from int256, reverting on\n     * overflow (when the input is less than smallest int216 or\n     * greater than largest int216).\n     *\n     * Counterpart to Solidity's `int216` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 216 bits\n     */\n    function toInt216(int256 value) internal pure returns (int216 downcasted) {\n        downcasted = int216(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(216, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int208 from int256, reverting on\n     * overflow (when the input is less than smallest int208 or\n     * greater than largest int208).\n     *\n     * Counterpart to Solidity's `int208` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 208 bits\n     */\n    function toInt208(int256 value) internal pure returns (int208 downcasted) {\n        downcasted = int208(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(208, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int200 from int256, reverting on\n     * overflow (when the input is less than smallest int200 or\n     * greater than largest int200).\n     *\n     * Counterpart to Solidity's `int200` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 200 bits\n     */\n    function toInt200(int256 value) internal pure returns (int200 downcasted) {\n        downcasted = int200(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(200, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int192 from int256, reverting on\n     * overflow (when the input is less than smallest int192 or\n     * greater than largest int192).\n     *\n     * Counterpart to Solidity's `int192` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 192 bits\n     */\n    function toInt192(int256 value) internal pure returns (int192 downcasted) {\n        downcasted = int192(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(192, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int184 from int256, reverting on\n     * overflow (when the input is less than smallest int184 or\n     * greater than largest int184).\n     *\n     * Counterpart to Solidity's `int184` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 184 bits\n     */\n    function toInt184(int256 value) internal pure returns (int184 downcasted) {\n        downcasted = int184(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(184, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int176 from int256, reverting on\n     * overflow (when the input is less than smallest int176 or\n     * greater than largest int176).\n     *\n     * Counterpart to Solidity's `int176` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 176 bits\n     */\n    function toInt176(int256 value) internal pure returns (int176 downcasted) {\n        downcasted = int176(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(176, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int168 from int256, reverting on\n     * overflow (when the input is less than smallest int168 or\n     * greater than largest int168).\n     *\n     * Counterpart to Solidity's `int168` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 168 bits\n     */\n    function toInt168(int256 value) internal pure returns (int168 downcasted) {\n        downcasted = int168(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(168, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int160 from int256, reverting on\n     * overflow (when the input is less than smallest int160 or\n     * greater than largest int160).\n     *\n     * Counterpart to Solidity's `int160` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 160 bits\n     */\n    function toInt160(int256 value) internal pure returns (int160 downcasted) {\n        downcasted = int160(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(160, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int152 from int256, reverting on\n     * overflow (when the input is less than smallest int152 or\n     * greater than largest int152).\n     *\n     * Counterpart to Solidity's `int152` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 152 bits\n     */\n    function toInt152(int256 value) internal pure returns (int152 downcasted) {\n        downcasted = int152(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(152, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int144 from int256, reverting on\n     * overflow (when the input is less than smallest int144 or\n     * greater than largest int144).\n     *\n     * Counterpart to Solidity's `int144` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 144 bits\n     */\n    function toInt144(int256 value) internal pure returns (int144 downcasted) {\n        downcasted = int144(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(144, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int136 from int256, reverting on\n     * overflow (when the input is less than smallest int136 or\n     * greater than largest int136).\n     *\n     * Counterpart to Solidity's `int136` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 136 bits\n     */\n    function toInt136(int256 value) internal pure returns (int136 downcasted) {\n        downcasted = int136(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(136, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int128 from int256, reverting on\n     * overflow (when the input is less than smallest int128 or\n     * greater than largest int128).\n     *\n     * Counterpart to Solidity's `int128` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 128 bits\n     */\n    function toInt128(int256 value) internal pure returns (int128 downcasted) {\n        downcasted = int128(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(128, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int120 from int256, reverting on\n     * overflow (when the input is less than smallest int120 or\n     * greater than largest int120).\n     *\n     * Counterpart to Solidity's `int120` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 120 bits\n     */\n    function toInt120(int256 value) internal pure returns (int120 downcasted) {\n        downcasted = int120(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(120, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int112 from int256, reverting on\n     * overflow (when the input is less than smallest int112 or\n     * greater than largest int112).\n     *\n     * Counterpart to Solidity's `int112` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 112 bits\n     */\n    function toInt112(int256 value) internal pure returns (int112 downcasted) {\n        downcasted = int112(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(112, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int104 from int256, reverting on\n     * overflow (when the input is less than smallest int104 or\n     * greater than largest int104).\n     *\n     * Counterpart to Solidity's `int104` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 104 bits\n     */\n    function toInt104(int256 value) internal pure returns (int104 downcasted) {\n        downcasted = int104(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(104, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int96 from int256, reverting on\n     * overflow (when the input is less than smallest int96 or\n     * greater than largest int96).\n     *\n     * Counterpart to Solidity's `int96` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 96 bits\n     */\n    function toInt96(int256 value) internal pure returns (int96 downcasted) {\n        downcasted = int96(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(96, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int88 from int256, reverting on\n     * overflow (when the input is less than smallest int88 or\n     * greater than largest int88).\n     *\n     * Counterpart to Solidity's `int88` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 88 bits\n     */\n    function toInt88(int256 value) internal pure returns (int88 downcasted) {\n        downcasted = int88(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(88, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int80 from int256, reverting on\n     * overflow (when the input is less than smallest int80 or\n     * greater than largest int80).\n     *\n     * Counterpart to Solidity's `int80` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 80 bits\n     */\n    function toInt80(int256 value) internal pure returns (int80 downcasted) {\n        downcasted = int80(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(80, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int72 from int256, reverting on\n     * overflow (when the input is less than smallest int72 or\n     * greater than largest int72).\n     *\n     * Counterpart to Solidity's `int72` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 72 bits\n     */\n    function toInt72(int256 value) internal pure returns (int72 downcasted) {\n        downcasted = int72(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(72, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int64 from int256, reverting on\n     * overflow (when the input is less than smallest int64 or\n     * greater than largest int64).\n     *\n     * Counterpart to Solidity's `int64` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 64 bits\n     */\n    function toInt64(int256 value) internal pure returns (int64 downcasted) {\n        downcasted = int64(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(64, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int56 from int256, reverting on\n     * overflow (when the input is less than smallest int56 or\n     * greater than largest int56).\n     *\n     * Counterpart to Solidity's `int56` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 56 bits\n     */\n    function toInt56(int256 value) internal pure returns (int56 downcasted) {\n        downcasted = int56(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(56, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int48 from int256, reverting on\n     * overflow (when the input is less than smallest int48 or\n     * greater than largest int48).\n     *\n     * Counterpart to Solidity's `int48` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 48 bits\n     */\n    function toInt48(int256 value) internal pure returns (int48 downcasted) {\n        downcasted = int48(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(48, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int40 from int256, reverting on\n     * overflow (when the input is less than smallest int40 or\n     * greater than largest int40).\n     *\n     * Counterpart to Solidity's `int40` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 40 bits\n     */\n    function toInt40(int256 value) internal pure returns (int40 downcasted) {\n        downcasted = int40(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(40, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int32 from int256, reverting on\n     * overflow (when the input is less than smallest int32 or\n     * greater than largest int32).\n     *\n     * Counterpart to Solidity's `int32` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 32 bits\n     */\n    function toInt32(int256 value) internal pure returns (int32 downcasted) {\n        downcasted = int32(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(32, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int24 from int256, reverting on\n     * overflow (when the input is less than smallest int24 or\n     * greater than largest int24).\n     *\n     * Counterpart to Solidity's `int24` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 24 bits\n     */\n    function toInt24(int256 value) internal pure returns (int24 downcasted) {\n        downcasted = int24(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(24, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int16 from int256, reverting on\n     * overflow (when the input is less than smallest int16 or\n     * greater than largest int16).\n     *\n     * Counterpart to Solidity's `int16` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 16 bits\n     */\n    function toInt16(int256 value) internal pure returns (int16 downcasted) {\n        downcasted = int16(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(16, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int8 from int256, reverting on\n     * overflow (when the input is less than smallest int8 or\n     * greater than largest int8).\n     *\n     * Counterpart to Solidity's `int8` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 8 bits\n     */\n    function toInt8(int256 value) internal pure returns (int8 downcasted) {\n        downcasted = int8(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(8, value);\n        }\n    }\n\n    /**\n     * @dev Converts an unsigned uint256 into a signed int256.\n     *\n     * Requirements:\n     *\n     * - input must be less than or equal to maxInt256.\n     */\n    function toInt256(uint256 value) internal pure returns (int256) {\n        // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\n        if (value > uint256(type(int256).max)) {\n            revert SafeCastOverflowedUintToInt(value);\n        }\n        return int256(value);\n    }\n\n    /**\n     * @dev Cast a boolean (false or true) to a uint256 (0 or 1) with no jump.\n     */\n    function toUint(bool b) internal pure returns (uint256 u) {\n        assembly (\"memory-safe\") {\n            u := iszero(iszero(b))\n        }\n    }\n}\n"},"node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.5.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"./IERC20.sol\";\nimport {IERC20Metadata} from \"./extensions/IERC20Metadata.sol\";\nimport {Context} from \"../../utils/Context.sol\";\nimport {IERC20Errors} from \"../../interfaces/draft-IERC6093.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC-20\n * applications.\n */\nabstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors {\n    mapping(address account => uint256) private _balances;\n\n    mapping(address account => mapping(address spender => uint256)) private _allowances;\n\n    uint256 private _totalSupply;\n\n    string private _name;\n    string private _symbol;\n\n    /**\n     * @dev Sets the values for {name} and {symbol}.\n     *\n     * Both values are immutable: they can only be set once during construction.\n     */\n    constructor(string memory name_, string memory symbol_) {\n        _name = name_;\n        _symbol = symbol_;\n    }\n\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() public view virtual returns (string memory) {\n        return _name;\n    }\n\n    /**\n     * @dev Returns the symbol of the token, usually a shorter version of the\n     * name.\n     */\n    function symbol() public view virtual returns (string memory) {\n        return _symbol;\n    }\n\n    /**\n     * @dev Returns the number of decimals used to get its user representation.\n     * For example, if `decimals` equals `2`, a balance of `505` tokens should\n     * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n     *\n     * Tokens usually opt for a value of 18, imitating the relationship between\n     * Ether and Wei. This is the default value returned by this function, unless\n     * it's overridden.\n     *\n     * NOTE: This information is only used for _display_ purposes: it in\n     * no way affects any of the arithmetic of the contract, including\n     * {IERC20-balanceOf} and {IERC20-transfer}.\n     */\n    function decimals() public view virtual returns (uint8) {\n        return 18;\n    }\n\n    /// @inheritdoc IERC20\n    function totalSupply() public view virtual returns (uint256) {\n        return _totalSupply;\n    }\n\n    /// @inheritdoc IERC20\n    function balanceOf(address account) public view virtual returns (uint256) {\n        return _balances[account];\n    }\n\n    /**\n     * @dev See {IERC20-transfer}.\n     *\n     * Requirements:\n     *\n     * - `to` cannot be the zero address.\n     * - the caller must have a balance of at least `value`.\n     */\n    function transfer(address to, uint256 value) public virtual returns (bool) {\n        address owner = _msgSender();\n        _transfer(owner, to, value);\n        return true;\n    }\n\n    /// @inheritdoc IERC20\n    function allowance(address owner, address spender) public view virtual returns (uint256) {\n        return _allowances[owner][spender];\n    }\n\n    /**\n     * @dev See {IERC20-approve}.\n     *\n     * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on\n     * `transferFrom`. This is semantically equivalent to an infinite approval.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function approve(address spender, uint256 value) public virtual returns (bool) {\n        address owner = _msgSender();\n        _approve(owner, spender, value);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-transferFrom}.\n     *\n     * Skips emitting an {Approval} event indicating an allowance update. This is not\n     * required by the ERC. See {xref-ERC20-_approve-address-address-uint256-bool-}[_approve].\n     *\n     * NOTE: Does not update the allowance if the current allowance\n     * is the maximum `uint256`.\n     *\n     * Requirements:\n     *\n     * - `from` and `to` cannot be the zero address.\n     * - `from` must have a balance of at least `value`.\n     * - the caller must have allowance for ``from``'s tokens of at least\n     * `value`.\n     */\n    function transferFrom(address from, address to, uint256 value) public virtual returns (bool) {\n        address spender = _msgSender();\n        _spendAllowance(from, spender, value);\n        _transfer(from, to, value);\n        return true;\n    }\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to`.\n     *\n     * This internal function is equivalent to {transfer}, and can be used to\n     * e.g. implement automatic token fees, slashing mechanisms, etc.\n     *\n     * Emits a {Transfer} event.\n     *\n     * NOTE: This function is not virtual, {_update} should be overridden instead.\n     */\n    function _transfer(address from, address to, uint256 value) internal {\n        if (from == address(0)) {\n            revert ERC20InvalidSender(address(0));\n        }\n        if (to == address(0)) {\n            revert ERC20InvalidReceiver(address(0));\n        }\n        _update(from, to, value);\n    }\n\n    /**\n     * @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from`\n     * (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding\n     * this function.\n     *\n     * Emits a {Transfer} event.\n     */\n    function _update(address from, address to, uint256 value) internal virtual {\n        if (from == address(0)) {\n            // Overflow check required: The rest of the code assumes that totalSupply never overflows\n            _totalSupply += value;\n        } else {\n            uint256 fromBalance = _balances[from];\n            if (fromBalance < value) {\n                revert ERC20InsufficientBalance(from, fromBalance, value);\n            }\n            unchecked {\n                // Overflow not possible: value <= fromBalance <= totalSupply.\n                _balances[from] = fromBalance - value;\n            }\n        }\n\n        if (to == address(0)) {\n            unchecked {\n                // Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply.\n                _totalSupply -= value;\n            }\n        } else {\n            unchecked {\n                // Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256.\n                _balances[to] += value;\n            }\n        }\n\n        emit Transfer(from, to, value);\n    }\n\n    /**\n     * @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0).\n     * Relies on the `_update` mechanism\n     *\n     * Emits a {Transfer} event with `from` set to the zero address.\n     *\n     * NOTE: This function is not virtual, {_update} should be overridden instead.\n     */\n    function _mint(address account, uint256 value) internal {\n        if (account == address(0)) {\n            revert ERC20InvalidReceiver(address(0));\n        }\n        _update(address(0), account, value);\n    }\n\n    /**\n     * @dev Destroys a `value` amount of tokens from `account`, lowering the total supply.\n     * Relies on the `_update` mechanism.\n     *\n     * Emits a {Transfer} event with `to` set to the zero address.\n     *\n     * NOTE: This function is not virtual, {_update} should be overridden instead\n     */\n    function _burn(address account, uint256 value) internal {\n        if (account == address(0)) {\n            revert ERC20InvalidSender(address(0));\n        }\n        _update(account, address(0), value);\n    }\n\n    /**\n     * @dev Sets `value` as the allowance of `spender` over the `owner`'s tokens.\n     *\n     * This internal function is equivalent to `approve`, and can be used to\n     * e.g. set automatic allowances for certain subsystems, etc.\n     *\n     * Emits an {Approval} event.\n     *\n     * Requirements:\n     *\n     * - `owner` cannot be the zero address.\n     * - `spender` cannot be the zero address.\n     *\n     * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.\n     */\n    function _approve(address owner, address spender, uint256 value) internal {\n        _approve(owner, spender, value, true);\n    }\n\n    /**\n     * @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event.\n     *\n     * By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by\n     * `_spendAllowance` during the `transferFrom` operation sets the flag to false. This saves gas by not emitting any\n     * `Approval` event during `transferFrom` operations.\n     *\n     * Anyone who wishes to continue emitting `Approval` events on the `transferFrom` operation can force the flag to\n     * true using the following override:\n     *\n     * ```solidity\n     * function _approve(address owner, address spender, uint256 value, bool) internal virtual override {\n     *     super._approve(owner, spender, value, true);\n     * }\n     * ```\n     *\n     * Requirements are the same as {_approve}.\n     */\n    function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual {\n        if (owner == address(0)) {\n            revert ERC20InvalidApprover(address(0));\n        }\n        if (spender == address(0)) {\n            revert ERC20InvalidSpender(address(0));\n        }\n        _allowances[owner][spender] = value;\n        if (emitEvent) {\n            emit Approval(owner, spender, value);\n        }\n    }\n\n    /**\n     * @dev Updates `owner`'s allowance for `spender` based on spent `value`.\n     *\n     * Does not update the allowance value in case of infinite allowance.\n     * Revert if not enough allowance is available.\n     *\n     * Does not emit an {Approval} event.\n     */\n    function _spendAllowance(address owner, address spender, uint256 value) internal virtual {\n        uint256 currentAllowance = allowance(owner, spender);\n        if (currentAllowance < type(uint256).max) {\n            if (currentAllowance < value) {\n                revert ERC20InsufficientAllowance(spender, currentAllowance, value);\n            }\n            unchecked {\n                _approve(owner, spender, currentAllowance - value, false);\n            }\n        }\n    }\n}\n"},"node_modules/@openzeppelin/contracts/token/ERC20/IERC20.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/IERC20.sol)\n\npragma solidity >=0.4.16;\n\n/**\n * @dev Interface of the ERC-20 standard as defined in the ERC.\n */\ninterface IERC20 {\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n\n    /**\n     * @dev Returns the value of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the value of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves a `value` amount of tokens from the caller's account to `to`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address to, uint256 value) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n     * caller's tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender's allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 value) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to` using the\n     * allowance mechanism. `value` is then deducted from the caller's\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(address from, address to, uint256 value) external returns (bool);\n}\n"},"node_modules/@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.5.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"../IERC20.sol\";\nimport {IERC1363} from \"../../../interfaces/IERC1363.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC-20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n    /**\n     * @dev An operation with an ERC-20 token failed.\n     */\n    error SafeERC20FailedOperation(address token);\n\n    /**\n     * @dev Indicates a failed `decreaseAllowance` request.\n     */\n    error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);\n\n    /**\n     * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful.\n     */\n    function safeTransfer(IERC20 token, address to, uint256 value) internal {\n        if (!_safeTransfer(token, to, value, true)) {\n            revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\n     * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\n     */\n    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n        if (!_safeTransferFrom(token, from, to, value, true)) {\n            revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Variant of {safeTransfer} that returns a bool instead of reverting if the operation is not successful.\n     */\n    function trySafeTransfer(IERC20 token, address to, uint256 value) internal returns (bool) {\n        return _safeTransfer(token, to, value, false);\n    }\n\n    /**\n     * @dev Variant of {safeTransferFrom} that returns a bool instead of reverting if the operation is not successful.\n     */\n    function trySafeTransferFrom(IERC20 token, address from, address to, uint256 value) internal returns (bool) {\n        return _safeTransferFrom(token, from, to, value, false);\n    }\n\n    /**\n     * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful.\n     *\n     * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the \"client\"\n     * smart contract uses ERC-7674 to set temporary allowances, then the \"client\" smart contract should avoid using\n     * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract\n     * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.\n     */\n    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n        uint256 oldAllowance = token.allowance(address(this), spender);\n        forceApprove(token, spender, oldAllowance + value);\n    }\n\n    /**\n     * @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no\n     * value, non-reverting calls are assumed to be successful.\n     *\n     * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the \"client\"\n     * smart contract uses ERC-7674 to set temporary allowances, then the \"client\" smart contract should avoid using\n     * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract\n     * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.\n     */\n    function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal {\n        unchecked {\n            uint256 currentAllowance = token.allowance(address(this), spender);\n            if (currentAllowance < requestedDecrease) {\n                revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);\n            }\n            forceApprove(token, spender, currentAllowance - requestedDecrease);\n        }\n    }\n\n    /**\n     * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\n     * to be set to zero before setting it to a non-zero value, such as USDT.\n     *\n     * NOTE: If the token implements ERC-7674, this function will not modify any temporary allowance. This function\n     * only sets the \"standard\" allowance. Any temporary allowance will remain active, in addition to the value being\n     * set here.\n     */\n    function forceApprove(IERC20 token, address spender, uint256 value) internal {\n        if (!_safeApprove(token, spender, value, false)) {\n            if (!_safeApprove(token, spender, 0, true)) revert SafeERC20FailedOperation(address(token));\n            if (!_safeApprove(token, spender, value, true)) revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Performs an {ERC1363} transferAndCall, with a fallback to the simple {ERC20} transfer if the target has no\n     * code. This can be used to implement an {ERC721}-like safe transfer that relies on {ERC1363} checks when\n     * targeting contracts.\n     *\n     * Reverts if the returned value is other than `true`.\n     */\n    function transferAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {\n        if (to.code.length == 0) {\n            safeTransfer(token, to, value);\n        } else if (!token.transferAndCall(to, value, data)) {\n            revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Performs an {ERC1363} transferFromAndCall, with a fallback to the simple {ERC20} transferFrom if the target\n     * has no code. This can be used to implement an {ERC721}-like safe transfer that relies on {ERC1363} checks when\n     * targeting contracts.\n     *\n     * Reverts if the returned value is other than `true`.\n     */\n    function transferFromAndCallRelaxed(\n        IERC1363 token,\n        address from,\n        address to,\n        uint256 value,\n        bytes memory data\n    ) internal {\n        if (to.code.length == 0) {\n            safeTransferFrom(token, from, to, value);\n        } else if (!token.transferFromAndCall(from, to, value, data)) {\n            revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Performs an {ERC1363} approveAndCall, with a fallback to the simple {ERC20} approve if the target has no\n     * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when\n     * targeting contracts.\n     *\n     * NOTE: When the recipient address (`to`) has no code (i.e. is an EOA), this function behaves as {forceApprove}.\n     * Oppositely, when the recipient address (`to`) has code, this function only attempts to call {ERC1363-approveAndCall}\n     * once without retrying, and relies on the returned value to be true.\n     *\n     * Reverts if the returned value is other than `true`.\n     */\n    function approveAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {\n        if (to.code.length == 0) {\n            forceApprove(token, to, value);\n        } else if (!token.approveAndCall(to, value, data)) {\n            revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Imitates a Solidity `token.transfer(to, value)` call, relaxing the requirement on the return value: the\n     * return value is optional (but if data is returned, it must not be false).\n     *\n     * @param token The token targeted by the call.\n     * @param to The recipient of the tokens\n     * @param value The amount of token to transfer\n     * @param bubble Behavior switch if the transfer call reverts: bubble the revert reason or return a false boolean.\n     */\n    function _safeTransfer(IERC20 token, address to, uint256 value, bool bubble) private returns (bool success) {\n        bytes4 selector = IERC20.transfer.selector;\n\n        assembly (\"memory-safe\") {\n            let fmp := mload(0x40)\n            mstore(0x00, selector)\n            mstore(0x04, and(to, shr(96, not(0))))\n            mstore(0x24, value)\n            success := call(gas(), token, 0, 0x00, 0x44, 0x00, 0x20)\n            // if call success and return is true, all is good.\n            // otherwise (not success or return is not true), we need to perform further checks\n            if iszero(and(success, eq(mload(0x00), 1))) {\n                // if the call was a failure and bubble is enabled, bubble the error\n                if and(iszero(success), bubble) {\n                    returndatacopy(fmp, 0x00, returndatasize())\n                    revert(fmp, returndatasize())\n                }\n                // if the return value is not true, then the call is only successful if:\n                // - the token address has code\n                // - the returndata is empty\n                success := and(success, and(iszero(returndatasize()), gt(extcodesize(token), 0)))\n            }\n            mstore(0x40, fmp)\n        }\n    }\n\n    /**\n     * @dev Imitates a Solidity `token.transferFrom(from, to, value)` call, relaxing the requirement on the return\n     * value: the return value is optional (but if data is returned, it must not be false).\n     *\n     * @param token The token targeted by the call.\n     * @param from The sender of the tokens\n     * @param to The recipient of the tokens\n     * @param value The amount of token to transfer\n     * @param bubble Behavior switch if the transfer call reverts: bubble the revert reason or return a false boolean.\n     */\n    function _safeTransferFrom(\n        IERC20 token,\n        address from,\n        address to,\n        uint256 value,\n        bool bubble\n    ) private returns (bool success) {\n        bytes4 selector = IERC20.transferFrom.selector;\n\n        assembly (\"memory-safe\") {\n            let fmp := mload(0x40)\n            mstore(0x00, selector)\n            mstore(0x04, and(from, shr(96, not(0))))\n            mstore(0x24, and(to, shr(96, not(0))))\n            mstore(0x44, value)\n            success := call(gas(), token, 0, 0x00, 0x64, 0x00, 0x20)\n            // if call success and return is true, all is good.\n            // otherwise (not success or return is not true), we need to perform further checks\n            if iszero(and(success, eq(mload(0x00), 1))) {\n                // if the call was a failure and bubble is enabled, bubble the error\n                if and(iszero(success), bubble) {\n                    returndatacopy(fmp, 0x00, returndatasize())\n                    revert(fmp, returndatasize())\n                }\n                // if the return value is not true, then the call is only successful if:\n                // - the token address has code\n                // - the returndata is empty\n                success := and(success, and(iszero(returndatasize()), gt(extcodesize(token), 0)))\n            }\n            mstore(0x40, fmp)\n            mstore(0x60, 0)\n        }\n    }\n\n    /**\n     * @dev Imitates a Solidity `token.approve(spender, value)` call, relaxing the requirement on the return value:\n     * the return value is optional (but if data is returned, it must not be false).\n     *\n     * @param token The token targeted by the call.\n     * @param spender The spender of the tokens\n     * @param value The amount of token to transfer\n     * @param bubble Behavior switch if the transfer call reverts: bubble the revert reason or return a false boolean.\n     */\n    function _safeApprove(IERC20 token, address spender, uint256 value, bool bubble) private returns (bool success) {\n        bytes4 selector = IERC20.approve.selector;\n\n        assembly (\"memory-safe\") {\n            let fmp := mload(0x40)\n            mstore(0x00, selector)\n            mstore(0x04, and(spender, shr(96, not(0))))\n            mstore(0x24, value)\n            success := call(gas(), token, 0, 0x00, 0x44, 0x00, 0x20)\n            // if call success and return is true, all is good.\n            // otherwise (not success or return is not true), we need to perform further checks\n            if iszero(and(success, eq(mload(0x00), 1))) {\n                // if the call was a failure and bubble is enabled, bubble the error\n                if and(iszero(success), bubble) {\n                    returndatacopy(fmp, 0x00, returndatasize())\n                    revert(fmp, returndatasize())\n                }\n                // if the return value is not true, then the call is only successful if:\n                // - the token address has code\n                // - the returndata is empty\n                success := and(success, and(iszero(returndatasize()), gt(extcodesize(token), 0)))\n            }\n            mstore(0x40, fmp)\n        }\n    }\n}\n"},"node_modules/@openzeppelin/contracts/utils/ReentrancyGuard.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.5.0) (utils/ReentrancyGuard.sol)\n\npragma solidity ^0.8.20;\n\nimport {StorageSlot} from \"./StorageSlot.sol\";\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If EIP-1153 (transient storage) is available on the chain you're deploying at,\n * consider using {ReentrancyGuardTransient} instead.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n *\n * IMPORTANT: Deprecated. This storage-based reentrancy guard will be removed and replaced\n * by the {ReentrancyGuardTransient} variant in v6.0.\n *\n * @custom:stateless\n */\nabstract contract ReentrancyGuard {\n    using StorageSlot for bytes32;\n\n    // keccak256(abi.encode(uint256(keccak256(\"openzeppelin.storage.ReentrancyGuard\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant REENTRANCY_GUARD_STORAGE =\n        0x9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00;\n\n    // Booleans are more expensive than uint256 or any type that takes up a full\n    // word because each write operation emits an extra SLOAD to first read the\n    // slot's contents, replace the bits taken up by the boolean, and then write\n    // back. This is the compiler's defense against contract upgrades and\n    // pointer aliasing, and it cannot be disabled.\n\n    // The values being non-zero value makes deployment a bit more expensive,\n    // but in exchange the refund on every call to nonReentrant will be lower in\n    // amount. Since refunds are capped to a percentage of the total\n    // transaction's gas, it is best to keep them low in cases like this one, to\n    // increase the likelihood of the full refund coming into effect.\n    uint256 private constant NOT_ENTERED = 1;\n    uint256 private constant ENTERED = 2;\n\n    /**\n     * @dev Unauthorized reentrant call.\n     */\n    error ReentrancyGuardReentrantCall();\n\n    constructor() {\n        _reentrancyGuardStorageSlot().getUint256Slot().value = NOT_ENTERED;\n    }\n\n    /**\n     * @dev Prevents a contract from calling itself, directly or indirectly.\n     * Calling a `nonReentrant` function from another `nonReentrant`\n     * function is not supported. It is possible to prevent this from happening\n     * by making the `nonReentrant` function external, and making it call a\n     * `private` function that does the actual work.\n     */\n    modifier nonReentrant() {\n        _nonReentrantBefore();\n        _;\n        _nonReentrantAfter();\n    }\n\n    /**\n     * @dev A `view` only version of {nonReentrant}. Use to block view functions\n     * from being called, preventing reading from inconsistent contract state.\n     *\n     * CAUTION: This is a \"view\" modifier and does not change the reentrancy\n     * status. Use it only on view functions. For payable or non-payable functions,\n     * use the standard {nonReentrant} modifier instead.\n     */\n    modifier nonReentrantView() {\n        _nonReentrantBeforeView();\n        _;\n    }\n\n    function _nonReentrantBeforeView() private view {\n        if (_reentrancyGuardEntered()) {\n            revert ReentrancyGuardReentrantCall();\n        }\n    }\n\n    function _nonReentrantBefore() private {\n        // On the first call to nonReentrant, _status will be NOT_ENTERED\n        _nonReentrantBeforeView();\n\n        // Any calls to nonReentrant after this point will fail\n        _reentrancyGuardStorageSlot().getUint256Slot().value = ENTERED;\n    }\n\n    function _nonReentrantAfter() private {\n        // By storing the original value once again, a refund is triggered (see\n        // https://eips.ethereum.org/EIPS/eip-2200)\n        _reentrancyGuardStorageSlot().getUint256Slot().value = NOT_ENTERED;\n    }\n\n    /**\n     * @dev Returns true if the reentrancy guard is currently set to \"entered\", which indicates there is a\n     * `nonReentrant` function in the call stack.\n     */\n    function _reentrancyGuardEntered() internal view returns (bool) {\n        return _reentrancyGuardStorageSlot().getUint256Slot().value == ENTERED;\n    }\n\n    function _reentrancyGuardStorageSlot() internal pure virtual returns (bytes32) {\n        return REENTRANCY_GUARD_STORAGE;\n    }\n}\n"},"V3/src/libraries/PoolOracle.sol":{"content":"// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity 0.8.36;\n\nimport {Math} from '@openzeppelin/contracts/utils/math/Math.sol';\n\n/// @title PoolOracle\n/// @notice Circular-buffer TWAP mechanics for Aerodrome V2 pools.\nlibrary PoolOracle {\n  /*////////////////////////////////////////////////////////////\n                              STRUCTS\n  ////////////////////////////////////////////////////////////*/\n\n  /// @notice Captured TWAP observation circular buffer.\n  /// @param timestamp Observation timestamp (truncated to uint32).\n  /// @param reserve0Cumulative Reserve 0 cumulative.\n  /// @param reserve1Cumulative Reserve 1 cumulative.\n  struct Observation {\n    uint32 timestamp;\n    uint256 reserve0Cumulative;\n    uint256 reserve1Cumulative;\n  }\n\n  /// @notice Circular buffer of TWAP observations and its metadata.\n  /// @param observations Fixed-size buffer of reserve cumulative snapshots.\n  /// @param index Index of the most recently written observation.\n  /// @param cardinality Number of populated slots in the buffer.\n  /// @param cardinalityNext Number of observation slots that can be populated.\n  struct ObservationBuffer {\n    Observation[65_535] observations;\n    uint16 index;\n    uint16 cardinality;\n    uint16 cardinalityNext;\n  }\n\n  /*////////////////////////////////////////////////////////////\n                              ERRORS\n  ////////////////////////////////////////////////////////////*/\n\n  /// @notice Thrown when a requested timestamp predates the oldest stored observation.\n  error ObservationOld();\n\n  /*////////////////////////////////////////////////////////////\n                              FUNCTIONS\n  ////////////////////////////////////////////////////////////*/\n\n  /// @notice Seeds slot zero of the buffer and sets the starting cardinality.\n  /// @param self The observation buffer.\n  function initialize(ObservationBuffer storage self) internal {\n    self.observations[0].timestamp = uint32(block.timestamp);\n    self.cardinality = 1;\n    self.cardinalityNext = 1;\n  }\n\n  /// @notice Writes a new observation when more than `_periodSize` has elapsed since the newest one.\n  /// @dev `self.cardinality` increases by one when `self.index` reaches the last available slot and `self.cardinalityNext`\n  ///      is > `self.cardinality`.\n  /// @param self The observation buffer.\n  /// @param _reserve0CumulativeLast Running reserve0 cumulative to store.\n  /// @param _reserve1CumulativeLast Running reserve1 cumulative to store.\n  /// @param _periodSize Minimum seconds between observations.\n  function write(\n    ObservationBuffer storage self,\n    uint256 _reserve0CumulativeLast,\n    uint256 _reserve1CumulativeLast,\n    uint256 _periodSize\n  ) internal {\n    uint32 _blockTimestamp = uint32(block.timestamp);\n    uint16 _index = self.index;\n    uint256 _timeElapsed;\n    unchecked {\n      _timeElapsed = _blockTimestamp - self.observations[_index].timestamp;\n    }\n    if (_timeElapsed <= _periodSize) return;\n    uint16 _cardinality = self.cardinality;\n    uint16 _newCardinality = _cardinality;\n    /// @dev Grow by one slot per write since there is no `initialized` flag on `Observation`.\n    ///      This ensures that every read only hits initialized slots.\n    if (self.cardinalityNext > _cardinality && _index == _cardinality - 1) {\n      _newCardinality = _cardinality + 1;\n    }\n    uint16 _newIndex = (_index + 1) % _newCardinality;\n    self.observations[_newIndex] = Observation({\n      timestamp: _blockTimestamp,\n      reserve0Cumulative: _reserve0CumulativeLast,\n      reserve1Cumulative: _reserve1CumulativeLast\n    });\n    self.index = _newIndex;\n    if (_newCardinality != _cardinality) self.cardinality = _newCardinality;\n  }\n\n  /// @notice Pre-initialises the new buffer slots and updates `cardinalityNext` so observation writes hit warm storage.\n  /// @param self The observation buffer.\n  /// @param _next Requested target cardinality.\n  /// @return _grown The resulting target cardinality, unchanged when `_next` is not greater than the current.\n  function grow(ObservationBuffer storage self, uint16 _next) internal returns (uint16) {\n    uint16 _current = self.cardinalityNext;\n    if (_next <= _current) return _current;\n    for (uint16 _i = _current; _i < _next; _i++) {\n      self.observations[_i].timestamp = 1;\n      self.observations[_i].reserve0Cumulative = 1;\n      self.observations[_i].reserve1Cumulative = 1;\n    }\n    self.cardinalityNext = _next;\n    return _next;\n  }\n\n  /// @notice Returns the observations bracketing `_target`.\n  /// @dev When `_target` falls after the newest stored observation, `_atOrAfter` is interpolated from the\n  ///      current cumulatives. When `_target` equals the newest stored observation, that observation is\n  ///      returned as both bounds.\n  /// @param self The observation buffer.\n  /// @param _time The current timestamp.\n  /// @param _target Timestamp to locate inside or relative to the populated range.\n  /// @param _reserve0CumulativeNow Current reserve0 cumulative extrapolated to `_time`.\n  /// @param _reserve1CumulativeNow Current reserve1 cumulative extrapolated to `_time`.\n  /// @return _beforeOrAt Observation at or before `_target`.\n  /// @return _atOrAfter Observation at or after `_target`.\n  function _getSurroundingObservations(\n    ObservationBuffer storage self,\n    uint32 _time,\n    uint32 _target,\n    uint256 _reserve0CumulativeNow,\n    uint256 _reserve1CumulativeNow\n  ) internal view returns (Observation memory _beforeOrAt, Observation memory _atOrAfter) {\n    uint16 _index = self.index;\n    _beforeOrAt = self.observations[_index]; // newest written\n    if (_lte(_time, _beforeOrAt.timestamp, _target)) {\n      // target sits exactly on the newest observation, which brackets itself with no interpolation\n      if (_beforeOrAt.timestamp == _target) return (_beforeOrAt, _beforeOrAt);\n      (uint256 _r0Interpolated, uint256 _r1Interpolated) =\n        _interpolate(_beforeOrAt, _time, _reserve0CumulativeNow, _reserve1CumulativeNow, _target);\n      _atOrAfter =\n        Observation({timestamp: _target, reserve0Cumulative: _r0Interpolated, reserve1Cumulative: _r1Interpolated});\n      return (_beforeOrAt, _atOrAfter);\n    }\n    _beforeOrAt = self.observations[(_index + 1) % self.cardinality]; // oldest reachable\n    if (!_lte(_time, _beforeOrAt.timestamp, _target)) revert ObservationOld();\n    return _binarySearch(self, _time, _target);\n  }\n\n  /// @notice Resolves a single `_secondsAgo` offset into a pair of reserve cumulatives by interpolating between\n  ///         surrounding observations.\n  /// @dev A `_secondsAgo` that lands after the newest stored observation is estimated from the current\n  ///      cumulatives, so a later trade can change what it reads. It stops changing once an observation\n  ///      is stored at or after that point.\n  /// @param self The observation buffer.\n  /// @param _time The current timestamp.\n  /// @param _secondsAgo Offset from `_time` into the past. `0` requests the cumulatives at `_time`.\n  /// @param _reserve0CumulativeNow Current reserve0 cumulative extrapolated to `_time`.\n  /// @param _reserve1CumulativeNow Current reserve1 cumulative extrapolated to `_time`.\n  /// @return _reserve0Cumulative Cumulative reserve0 at `_time - _secondsAgo`.\n  /// @return _reserve1Cumulative Cumulative reserve1 at `_time - _secondsAgo`.\n  function observeSingle(\n    ObservationBuffer storage self,\n    uint32 _time,\n    uint32 _secondsAgo,\n    uint256 _reserve0CumulativeNow,\n    uint256 _reserve1CumulativeNow\n  ) internal view returns (uint256 _reserve0Cumulative, uint256 _reserve1Cumulative) {\n    if (_secondsAgo == 0) {\n      return (_reserve0CumulativeNow, _reserve1CumulativeNow);\n    }\n    uint32 _target;\n    unchecked {\n      _target = _time - _secondsAgo;\n    }\n    (Observation memory _beforeOrAt, Observation memory _atOrAfter) =\n      _getSurroundingObservations(self, _time, _target, _reserve0CumulativeNow, _reserve1CumulativeNow);\n    if (_atOrAfter.timestamp == _target) {\n      return (_atOrAfter.reserve0Cumulative, _atOrAfter.reserve1Cumulative);\n    }\n    (_reserve0Cumulative, _reserve1Cumulative) = _interpolate(\n      _beforeOrAt, _atOrAfter.timestamp, _atOrAfter.reserve0Cumulative, _atOrAfter.reserve1Cumulative, _target\n    );\n  }\n\n  /// @notice Resolves an array of `_secondsAgos` offsets into reserve cumulatives.\n  /// @param self The observation buffer.\n  /// @param _secondsAgos Offsets into the past from the current timestamp, `0` requesting the current cumulatives.\n  /// @param _reserve0CumulativeNow Current reserve0 cumulative extrapolated to the current timestamp.\n  /// @param _reserve1CumulativeNow Current reserve1 cumulative extrapolated to the current timestamp.\n  /// @return _reserve0Cumulatives Cumulative reserve0 at each requested offset.\n  /// @return _reserve1Cumulatives Cumulative reserve1 at each requested offset.\n  function observe(\n    ObservationBuffer storage self,\n    uint32[] calldata _secondsAgos,\n    uint256 _reserve0CumulativeNow,\n    uint256 _reserve1CumulativeNow\n  ) internal view returns (uint256[] memory _reserve0Cumulatives, uint256[] memory _reserve1Cumulatives) {\n    uint32 _time = uint32(block.timestamp);\n    uint256 _length = _secondsAgos.length;\n    _reserve0Cumulatives = new uint256[](_length);\n    _reserve1Cumulatives = new uint256[](_length);\n    for (uint256 _i; _i < _length; ++_i) {\n      (_reserve0Cumulatives[_i], _reserve1Cumulatives[_i]) =\n        observeSingle(self, _time, _secondsAgos[_i], _reserve0CumulativeNow, _reserve1CumulativeNow);\n    }\n  }\n\n  /// @notice Compares two uint32 timestamps chronologically, tolerating the uint32 rollover.\n  /// @param _time The current timestamp.\n  /// @param _a Timestamp to test.\n  /// @param _b Timestamp to compare against.\n  /// @return  Whether `_a` is chronologically less than or equal to `_b`.\n  function _lte(uint32 _time, uint32 _a, uint32 _b) internal pure returns (bool) {\n    if (_a <= _time && _b <= _time) return _a <= _b;\n\n    uint256 _aAdjusted = _a > _time ? _a : _a + 2 ** 32;\n    uint256 _bAdjusted = _b > _time ? _b : _b + 2 ** 32;\n\n    return _aAdjusted <= _bAdjusted;\n  }\n\n  /// @notice Interpolates the reserve cumulatives at `_target` between two observation points: `_beforeOrAt.timestamp` and `_afterTimestamp`.\n  /// @dev When `_target` equals `_afterTimestamp` the result equals the after cumulatives.\n  /// @dev When `_target` equals `_beforeOrAt.timestamp` the result equals the `_beforeOrAt` cumulatives.\n  /// @dev `_target` should fall between `_beforeOrAt.timestamp` and `_afterTimestamp` (inclusive).\n  /// @dev Timestamp subtractions are `unchecked` so the math holds across uint32 timestamp rollover.\n  /// @param _beforeOrAt Observation at or before `_target` chronologically.\n  /// @param _afterTimestamp Timestamp at the end of the interpolation window.\n  /// @param _afterReserve0Cumulative End-of-window reserve0 cumulative.\n  /// @param _afterReserve1Cumulative End-of-window reserve1 cumulative.\n  /// @param _target Timestamp at which to evaluate the interpolation.\n  /// @return _reserve0Cumulative Interpolated reserve0 cumulative at `_target`.\n  /// @return _reserve1Cumulative Interpolated reserve1 cumulative at `_target`.\n  function _interpolate(\n    Observation memory _beforeOrAt,\n    uint32 _afterTimestamp,\n    uint256 _afterReserve0Cumulative,\n    uint256 _afterReserve1Cumulative,\n    uint32 _target\n  ) internal pure returns (uint256 _reserve0Cumulative, uint256 _reserve1Cumulative) {\n    uint256 _beforeToAfterTimeDelta;\n    uint256 _beforeToTargetTimeDelta;\n    unchecked {\n      _beforeToAfterTimeDelta = uint256(_afterTimestamp - _beforeOrAt.timestamp);\n      _beforeToTargetTimeDelta = uint256(_target - _beforeOrAt.timestamp);\n    }\n    uint256 _reserve0Delta = _afterReserve0Cumulative - _beforeOrAt.reserve0Cumulative;\n    uint256 _reserve1Delta = _afterReserve1Cumulative - _beforeOrAt.reserve1Cumulative;\n    _reserve0Cumulative =\n      _beforeOrAt.reserve0Cumulative + Math.mulDiv(_reserve0Delta, _beforeToTargetTimeDelta, _beforeToAfterTimeDelta);\n    _reserve1Cumulative =\n      _beforeOrAt.reserve1Cumulative + Math.mulDiv(_reserve1Delta, _beforeToTargetTimeDelta, _beforeToAfterTimeDelta);\n  }\n\n  /// @notice Binary searches the active buffer for the observations bracketing `_target`.\n  /// @param self The observation buffer.\n  /// @param _time The current timestamp.\n  /// @param _target Timestamp to bracket.\n  /// @return _beforeOrAt Observation at or before `_target`.\n  /// @return _atOrAfter Observation at or after `_target`.\n  function _binarySearch(\n    ObservationBuffer storage self,\n    uint32 _time,\n    uint32 _target\n  ) private view returns (Observation memory _beforeOrAt, Observation memory _atOrAfter) {\n    uint16 _cardinality = self.cardinality;\n    Observation[65_535] storage observations = self.observations;\n    unchecked {\n      uint256 _l = (uint256(self.index) + 1) % _cardinality; // oldest reachable slot\n      uint256 _r = _l + _cardinality - 1; // newest written slot\n      while (true) {\n        uint256 _i = (_l + _r) / 2;\n        _beforeOrAt = observations[_i % _cardinality];\n        _atOrAfter = observations[(_i + 1) % _cardinality];\n        bool _targetAtOrAfterBefore = _lte(_time, _beforeOrAt.timestamp, _target);\n        bool _targetAtOrBeforeAfter = _lte(_time, _target, _atOrAfter.timestamp);\n        if (_targetAtOrAfterBefore && _targetAtOrBeforeAfter) break;\n        if (_targetAtOrAfterBefore) _l = _i + 1;\n        else _r = _i - 1;\n      }\n    }\n  }\n}\n"},"V3/src/interfaces/factories/IPoolFactory.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nimport {IPoolTape} from 'V3/interfaces/pools/tape/IPoolTape.sol';\n\n/**\n * @title IPoolFactory\n * @notice Interface for the PoolFactory contract, the abstract base shared by the Aerodrome V2 volatile and stable pool factories\n */\ninterface IPoolFactory {\n  /// @notice Initial governance roles and modules of a pool factory.\n  /// @dev Every launch installs a pool tape, fee module and exact output fee quoter. Lite launches omit\n  ///      the discount registry and MEV tax module.\n  ///      Factory-bound fee modules and quoters must already be deployed with this factory's address.\n  /// @param poolAdmin Pool administrator.\n  /// @param pauser Factory pauser.\n  /// @param feeManager Manager of fees, fee modules and exact output quoting.\n  /// @param discountRegistryManager Manager of the discount registry.\n  /// @param poolTapeManager Manager of the pool tape.\n  /// @param factoryRegistry Registry that records pools created by this factory.\n  /// @param discountRegistry Initial discount registry, or zero for a lite launch.\n  /// @param poolTape Initial pool tape.\n  /// @param poolTapeGasLimit Nonzero gas forwarded to the pool tape.\n  /// @param feeModule Initial fee module.\n  /// @param feeModuleGasLimit Nonzero gas forwarded to the fee module.\n  /// @param mevTaxModule Initial MEV tax module, or zero for a lite launch.\n  /// @param mevTaxModuleGasLimit Gas forwarded to the MEV tax module; nonzero when it is configured.\n  /// @param exactOutFeeQuoter Initial exact output fee quoter.\n  struct PoolFactoryConfig {\n    address poolAdmin;\n    address pauser;\n    address feeManager;\n    address discountRegistryManager;\n    address poolTapeManager;\n    address factoryRegistry;\n    address discountRegistry;\n    address poolTape;\n    uint32 poolTapeGasLimit;\n    address feeModule;\n    uint32 feeModuleGasLimit;\n    address mevTaxModule;\n    uint32 mevTaxModuleGasLimit;\n    address exactOutFeeQuoter;\n  }\n\n  /*////////////////////////////////////////////////////////////\n                            EVENTS\n  ////////////////////////////////////////////////////////////*/\n  event SetFeeManager(address indexed feeManager);\n  event SetPauser(address indexed pauser);\n  event SetPauseState(bool indexed state);\n  event SetPoolAdmin(address indexed poolAdmin);\n  event PoolCreated(address indexed token0, address indexed token1, address pool, uint256);\n  event SetDefaultFee(uint256 defaultFee);\n  /// @notice Emitted when the fee module and the gas limit forwarded to it are set.\n  /// @param feeModule The new fee module address.\n  /// @param gasLimit The gas limit forwarded to the module on each read.\n  event SetFeeModule(address indexed feeModule, uint32 gasLimit);\n  event SetDiscountRegistryManager(address indexed discountRegistryManager);\n  event SetDiscountRegistry(address indexed discountRegistry);\n\n  /// @notice Emitted when the pool tape module and the gas limit forwarded to it are set.\n  /// @param poolTape The new pool tape address. The zero address disables the pool tape.\n  /// @param gasLimit The gas limit forwarded to the tape on each record.\n  event SetPoolTape(address indexed poolTape, uint32 gasLimit);\n\n  /// @notice Emitted when the pool tape manager is set.\n  /// @param poolTapeManager The new pool tape manager.\n  event SetPoolTapeManager(address indexed poolTapeManager);\n\n  /// @notice Emitted when the MEV tax module and the gas limit forwarded to it are set.\n  /// @param mevTaxModule The new MEV tax module address. The zero address disables the MEV tax.\n  /// @param gasLimit The gas limit forwarded to the module on each read.\n  event SetMevTaxModule(address indexed mevTaxModule, uint32 gasLimit);\n\n  /// @notice Emitted when the exact output fee quoter is set.\n  /// @param exactOutFeeQuoter The new quoter address.\n  event SetExactOutFeeQuoter(address indexed exactOutFeeQuoter);\n\n  /*////////////////////////////////////////////////////////////\n                            ERRORS\n  ////////////////////////////////////////////////////////////*/\n  error FeeTooHigh();\n  /// @notice Reverts when the gas left in the frame is equal to or below the gas limit set for the external call.\n  /// @dev EIP-150 forwards `min(_gasLimit, gasleft() - gasleft() / 64)`, so a transaction that sets its own gas\n  ///      limit too low would leave the callee short. Stopping here keeps the outcome of the call independent of\n  ///      the gas the caller supplied.\n  error InsufficientGasForCall();\n  /// @notice Thrown when the exact output fee quoter being set belongs to another factory.\n  error InvalidExactOutFeeQuoter();\n  error InvalidFeeModule();\n  /// @notice Thrown when an exact output quote is requested while no exact output fee quoter is set.\n  error NoExactOutFeeQuoter();\n  error NotDiscountRegistryManager();\n  error NotFeeManager();\n  error NotPauser();\n  error NotPoolAdmin();\n  /// @notice Thrown when the caller is not the pool tape manager.\n  error NotPoolTapeManager();\n  error PoolAlreadyExists();\n  error SameAddress();\n  error ZeroFee();\n  error ZeroAddress();\n  /// @notice Thrown when a gas limit is set to zero.\n  error ZeroGasLimit();\n\n  /*////////////////////////////////////////////////////////////\n                        EXTERNAL FUNCTIONS\n  ////////////////////////////////////////////////////////////*/\n  /// @notice Set pool administrator\n  /// @dev Allowed to change the name and symbol of any pool created by this factory\n  /// @param _poolAdmin Address of the pool administrator\n  function setPoolAdmin(address _poolAdmin) external;\n\n  /// @notice Set the pauser for the factory contract\n  /// @dev The pauser can pause swaps on pools associated with the factory. Liquidity will always be withdrawable.\n  /// @dev Must be called by the pauser\n  /// @param _pauser Address of the pauser\n  function setPauser(address _pauser) external;\n\n  /// @notice Set discount registry manager\n  /// @dev The discount registry manager can update the `discountRegistry` variable\n  /// @param _discountRegistryManager Address of the discount registry manager\n  function setDiscountRegistryManager(address _discountRegistryManager) external;\n\n  /// @notice Set the discount registry for the factory contract\n  /// @param _discountRegistry Address of the discount registry\n  function setDiscountRegistry(address _discountRegistry) external;\n\n  /// @notice Pause or unpause swaps on pools associated with the factory\n  /// @param _state True to pause, false to unpause\n  function setPauseState(bool _state) external;\n\n  /// @notice Set the fee manager for the factory contract\n  /// @dev The fee manager can set fees on pools associated with the factory.\n  /// @dev Must be called by the fee manager\n  /// @param _feeManager Address of the fee manager\n  function setFeeManager(address _feeManager) external;\n\n  /// @notice Updates the feeModule of the factory and the gas limit forwarded to it\n  /// @dev Must be called by the current fee manager. Reverts if the gas limit set is zero.\n  /// @param _feeModule The new feeModule of the factory\n  /// @param _gasLimit The gas limit forwarded to the module on each read. Calculated as\n  ///        `(usage + buffer) * 64 / 63` where `usage` is the most gas the module can spend and `buffer` is what\n  ///        this factory spends checking the gas and dispatching the call. The `64 / 63` covers the share\n  ///        EIP-150 withholds from the callee.\n  function setFeeModule(address _feeModule, uint32 _gasLimit) external;\n\n  /// @notice Set the default fee for pools created by this factory.\n  /// @dev Throws if higher than maximum fee.\n  ///      Throws if fee is zero.\n  /// @param _defaultFee .\n  function setDefaultFee(uint256 _defaultFee) external;\n\n  /// @notice Create a pool for the given pair of tokens\n  /// @dev token order does not matter\n  /// @param tokenA .\n  /// @param tokenB .\n  function createPool(address tokenA, address tokenB) external returns (address pool);\n\n  /// @notice Sets the pool tape manager role that controls the pool tape configuration.\n  /// @dev Must be called by the current pool tape manager. The initial manager is set in the constructor.\n  /// @param _poolTapeManager Address of the new pool tape manager.\n  function setPoolTapeManager(address _poolTapeManager) external;\n\n  /// @notice Sets or clears the pool tape module that the pool records data into, and the gas limit sent to it.\n  /// @dev Must be called by the pool tape manager. The zero address disables the pool tape recording.\n  /// @dev Reverts if the gas limit set is zero.\n  /// @param _poolTape Address of the pool tape module.\n  /// @param _gasLimit The gas limit forwarded to the tape on each record. Calculated as\n  ///        `(usage + buffer) * 64 / 63` where `usage` is the most gas the tape can spend and `buffer` is what\n  ///        this factory spends checking the gas and dispatching the call. The `64 / 63` covers the share\n  ///        EIP-150 withholds from the callee.\n  function setPoolTape(address _poolTape, uint32 _gasLimit) external;\n\n  /// @notice Sets or clears the MEV tax module queried for the MEV tax on swaps, and the gas limit sent to it.\n  /// @dev Must be called by the fee manager. The zero address disables the MEV tax.\n  /// @dev Reverts if the gas limit set is zero.\n  /// @param _mevTaxModule Address of the MEV tax module.\n  /// @param _gasLimit The gas limit forwarded to the module on each read. Calculated as\n  ///        `(usage + buffer) * 64 / 63` where `usage` is the most gas the module can spend and `buffer` is what\n  ///        this factory spends checking the gas and dispatching the call. The `64 / 63` covers the share\n  ///        EIP-150 withholds from the callee.\n  function setMevTaxModule(address _mevTaxModule, uint32 _gasLimit) external;\n\n  /// @notice Sets the quoter that resolves the fee of exact output quotes.\n  /// @dev Must be called by the fee manager. Reverts on the zero address and when the quoter belongs to another\n  ///      factory. Exact output quotes revert until a quoter is set.\n  /// @param _exactOutFeeQuoter Address of the exact output fee quoter.\n  function setExactOutFeeQuoter(address _exactOutFeeQuoter) external;\n\n  /// @notice Forwards a pool's per-swap deltas to the pool tape, if one is set.\n  /// @param _data The per-swap deltas to record.\n  function recordPoolTape(IPoolTape.PoolTapeData calldata _data) external;\n\n  /*////////////////////////////////////////////////////////////\n                      PURE AND VIEW FUNCTIONS\n  ////////////////////////////////////////////////////////////*/\n  /// @notice Return a single pool created by this factory\n  /// @return Address of pool\n  function allPools(uint256 index) external view returns (address);\n\n  /// @notice Returns all pools created by this factory\n  /// @return Array of pool addresses\n  function allPools() external view returns (address[] memory);\n\n  /// @notice Returns the number of pools created from this factory\n  function allPoolsLength() external view returns (uint256);\n\n  /// @notice Is a valid pool created by this factory.\n  /// @param pool .\n  function isPool(address pool) external view returns (bool);\n\n  /// @notice Return address of pool created by this factory\n  /// @param tokenA .\n  /// @param tokenB .\n  function getPool(address tokenA, address tokenB) external view returns (address);\n\n  /// @notice Returns the base fee for a pool swap, accounting for custom fees set via the fee module.\n  /// @dev A fee module value above `MAX_BASE_FEE` is ignored, falling back to `defaultFee`.\n  /// @param _pool The pool to get the base fee for.\n  /// @param _caller The swap initiator.\n  /// @param _amount0In The token0 input amount of the swap, zero when token0 is not an input.\n  /// @param _amount1In The token1 input amount of the swap, zero when token1 is not an input.\n  /// @param _reserve0 The pre-swap token0 reserve of the pool.\n  /// @param _reserve1 The pre-swap token1 reserve of the pool.\n  /// @return The base fee in basis points.\n  function getBaseFee(\n    address _pool,\n    address _caller,\n    uint256 _amount0In,\n    uint256 _amount1In,\n    uint256 _reserve0,\n    uint256 _reserve1\n  ) external view returns (uint256);\n\n  /// @notice Returns the swap fee data for a pool swap, including the MEV tax.\n  /// @dev The MEV tax is clamped so the total stays at or below `MAX_FEE`.\n  /// @param _pool The pool to get the fee for.\n  /// @param _sender The swap caller, the pool's msg.sender.\n  /// @param _amount0In The token0 input amount of the swap, zero when token0 is not an input.\n  /// @param _amount1In The token1 input amount of the swap, zero when token1 is not an input.\n  /// @param _reserve0 The pre-swap token0 reserve of the pool.\n  /// @param _reserve1 The pre-swap token1 reserve of the pool.\n  /// @return _fee The combined swap fee in basis points.\n  /// @return _mevFee The MEV share of the fee in basis points, rounded up.\n  /// @return _toxic True when the swap is classified as toxic flow.\n  function getFee(\n    address _pool,\n    address _sender,\n    uint256 _amount0In,\n    uint256 _amount1In,\n    uint256 _reserve0,\n    uint256 _reserve1\n  ) external view returns (uint256 _fee, uint256 _mevFee, bool _toxic);\n\n  /// @notice Returns the total fee to gross up an exact output quote with, given the input the curve requires.\n  /// @dev Reverts with `NoExactOutFeeQuoter` while no quoter is set and with `FeeTooHigh` when the quoter\n  ///      answers above `MAX_FEE`.\n  /// @param _pool The pool to get the fee for.\n  /// @param _caller The swap initiator.\n  /// @param _amount0InAfterFee The token0 input the curve requires after the fee, zero when token0 is not an input.\n  /// @param _amount1InAfterFee The token1 input the curve requires after the fee, zero when token1 is not an input.\n  /// @param _reserve0 The pre-swap token0 reserve of the pool.\n  /// @param _reserve1 The pre-swap token1 reserve of the pool.\n  /// @return _fee The total fee in basis points.\n  function getFeeForAmountIn(\n    address _pool,\n    address _caller,\n    uint256 _amount0InAfterFee,\n    uint256 _amount1InAfterFee,\n    uint256 _reserve0,\n    uint256 _reserve1\n  ) external view returns (uint256 _fee);\n\n  /// @notice The pool implementation used to create pools\n  /// @return Address of pool implementation\n  function implementation() external view returns (address);\n\n  /// @notice The factory registry every created pool is recorded in as a target.\n  /// @dev Set at construction. createPool reverts until this factory is an approved\n  ///      target factory in the registry.\n  /// @return Address of the factory registry.\n  function factoryRegistry() external view returns (address);\n\n  /// @notice Whether the pools associated with the factory are paused or not.\n  /// @dev Pause only pauses swaps, liquidity will always be withdrawable.\n  function isPaused() external view returns (bool);\n\n  /// @notice The address of the pauser, can pause swaps on pools associated with factory.\n  /// @return Address of the pauser\n  function pauser() external view returns (address);\n\n  /// @notice The default fee for pools created by this factory.\n  /// @return Default fee\n  function defaultFee() external view returns (uint256);\n\n  /// @notice Hard-coded default fee value the factory variant is initialized with\n  /// @dev Constant per variant. The mutable current value lives in `defaultFee()`.\n  function DEFAULT_FEE() external view returns (uint256);\n\n  /// @notice Maximum default fee the fee manager can set\n  /// @return 3% in bips\n  function MAX_DEFAULT_FEE() external view returns (uint256);\n\n  /// @notice Maximum base fee the factory accepts from the fee module\n  /// @return 10% in bips\n  function MAX_BASE_FEE() external view returns (uint256);\n\n  /// @notice Maximum total fee a swap can be charged, base fee plus MEV tax\n  /// @return 20% in bips\n  function MAX_FEE() external view returns (uint256);\n\n  /// @notice Address of the fee manager, can set fees on pools associated with factory.\n  /// @notice This overrides the default fee for that pool.\n  /// @return Address of the fee manager\n  function feeManager() external view returns (address);\n\n  /// @notice Address of the fee module of the factory\n  /// @dev Can be changed by the current fee manager via setFeeModule\n  /// @return Address of the fee module\n  function feeModule() external view returns (address);\n\n  /// @notice The gas limit forwarded to the fee module on each read.\n  /// @return _gasLimit The gas limit.\n  function feeModuleGasLimit() external view returns (uint32 _gasLimit);\n\n  /// @notice Address of the pool administrator, can change the name and symbol of pools created by factory.\n  /// @return Address of the pool administrator\n  function poolAdmin() external view returns (address);\n\n  /// @notice Address of the discount registry manager, can update the `discountRegistry` variable\n  /// @return Address of the discount registry manager\n  function discountRegistryManager() external view returns (address);\n\n  /// @notice Address of the discount registry, that allows querying swap fee discounts\n  /// @return Address of the discount registry\n  function discountRegistry() external view returns (address);\n\n  /// @notice The pool tape module that pools record into. The zero address means recording is disabled.\n  /// @return Address of the pool tape module.\n  function poolTape() external view returns (address);\n\n  /// @notice The gas limit forwarded to the pool tape on each record.\n  /// @return _gasLimit The gas limit.\n  function poolTapeGasLimit() external view returns (uint32 _gasLimit);\n\n  /// @notice The pool tape manager, which controls the pool tape configuration.\n  /// @return Address of the pool tape manager.\n  function poolTapeManager() external view returns (address);\n\n  /// @notice The MEV tax module queried to get the mev tax for a swap. The zero address means the MEV tax is disabled.\n  /// @return Address of the MEV tax module.\n  function mevTaxModule() external view returns (address);\n\n  /// @notice The gas limit forwarded to the MEV tax module on each read.\n  /// @return _gasLimit The gas limit.\n  function mevTaxModuleGasLimit() external view returns (uint32 _gasLimit);\n\n  /// @notice The quoter that resolves the fee of exact output quotes. Exact output quotes revert while unset.\n  /// @return Address of the exact output fee quoter.\n  function exactOutFeeQuoter() external view returns (address);\n}\n"},"V3/src/interfaces/pools/IPoolCallee.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IPoolCallee {\n  function hook(address sender, uint256 amount0, uint256 amount1, bytes calldata data) external;\n}\n"},"V3/src/interfaces/pools/tape/IPoolTape.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/// @title IPoolTape\n/// @notice Records and exposes per-swap cumulative metrics for V2 pools.\ninterface IPoolTape {\n  /*////////////////////////////////////////////////////////////\n                            STRUCTS\n  ////////////////////////////////////////////////////////////*/\n\n  /// @notice Per-pool running cumulatives updated on every swap.\n  /// @param cumulativeFee0 Cumulative token0 fees.\n  /// @param cumulativeFee1 Cumulative token1 fees.\n  /// @param cumulativeVolume0 Cumulative token0 input volume.\n  /// @param cumulativeVolume1 Cumulative token1 input volume.\n  /// @param cumulativeMevVolume0 Cumulative token0 toxic volume.\n  /// @param cumulativeMevVolume1 Cumulative token1 toxic volume.\n  /// @param cumulativeMevFee0 Cumulative token0 MEV fees.\n  /// @param cumulativeMevFee1 Cumulative token1 MEV fees.\n  /// @param lastSwapTimestamp Timestamp of the most recent recorded swap.\n  /// @param swapCount Cumulative swap count.\n  struct Accumulator {\n    // Slot 1\n    uint128 cumulativeFee0;\n    uint128 cumulativeFee1;\n    // Slot 2\n    uint128 cumulativeVolume0;\n    uint128 cumulativeVolume1;\n    // Slot 3\n    uint128 cumulativeMevVolume0;\n    uint128 cumulativeMevVolume1;\n    // Slot 4\n    uint128 cumulativeMevFee0;\n    uint128 cumulativeMevFee1;\n    // Slot 5\n    uint48 lastSwapTimestamp;\n    uint48 swapCount;\n  }\n\n  /// @notice A committed snapshot of the accumulator at a cadence boundary.\n  /// @param cumulativeFee0 Cumulative token0 fees.\n  /// @param cumulativeFee1 Cumulative token1 fees.\n  /// @param cumulativeVolume0 Cumulative token0 input volume.\n  /// @param cumulativeVolume1 Cumulative token1 input volume.\n  /// @param cumulativeMevVolume0 Cumulative token0 toxic volume.\n  /// @param cumulativeMevVolume1 Cumulative token1 toxic volume.\n  /// @param cumulativeMevFee0 Cumulative token0 MEV fees.\n  /// @param cumulativeMevFee1 Cumulative token1 MEV fees.\n  /// @param blockTimestamp Timestamp the observation was committed.\n  /// @param swapCount Cumulative swap count at commit.\n  struct Observation {\n    // Slot 1\n    uint128 cumulativeFee0;\n    uint128 cumulativeFee1;\n    // Slot 2\n    uint128 cumulativeVolume0;\n    uint128 cumulativeVolume1;\n    // Slot 3\n    uint128 cumulativeMevVolume0;\n    uint128 cumulativeMevVolume1;\n    // Slot 4\n    uint128 cumulativeMevFee0;\n    uint128 cumulativeMevFee1;\n    // Slot 5\n    uint48 blockTimestamp;\n    uint48 swapCount;\n  }\n\n  /// @notice The per-pool circular buffer of observations and its metadata.\n  /// @param observations Fixed-size buffer of committed observations.\n  /// @param index Index of the most recently committed observation.\n  /// @param cardinality Number of populated slots in the buffer.\n  /// @param cardinalityNext Number of observation slots that can be populated.\n  struct ObservationBuffer {\n    Observation[65_535] observations;\n    uint16 index;\n    uint16 cardinality;\n    uint16 cardinalityNext;\n  }\n\n  /// @notice Per-swap deltas passed into `record`.\n  /// @param fee0 token0 fee for this swap.\n  /// @param fee1 token1 fee for this swap.\n  /// @param volume0 token0 volume for this swap.\n  /// @param volume1 token1 volume for this swap.\n  /// @param mevVolume0 token0 toxic volume for this swap.\n  /// @param mevVolume1 token1 toxic volume for this swap.\n  /// @param mevFee0 token0 MEV fee for this swap.\n  /// @param mevFee1 token1 MEV fee for this swap.\n  struct PoolTapeData {\n    uint128 fee0;\n    uint128 fee1;\n    uint128 volume0;\n    uint128 volume1;\n    uint128 mevVolume0;\n    uint128 mevVolume1;\n    uint128 mevFee0;\n    uint128 mevFee1;\n  }\n\n  /*////////////////////////////////////////////////////////////\n                    EXTERNAL WRITE FUNCTIONS\n  ////////////////////////////////////////////////////////////*/\n\n  /// @notice Records a swap's metrics, accumulating and committing at the cadence boundary.\n  /// @param _pool The pool the swap occurred in.\n  /// @param _data The per-swap deltas.\n  function record(address _pool, PoolTapeData calldata _data) external;\n\n  /*////////////////////////////////////////////////////////////\n                    EXTERNAL VIEW FUNCTIONS\n  ////////////////////////////////////////////////////////////*/\n\n  /// @notice Returns the stored observation at an index.\n  /// @dev Callers can get the valid index range from `observationBuffers`. The index must be in\n  ///      `[0, cardinality)` to read written observations.\n  /// @param _pool The pool to read.\n  /// @param _index The buffer index to read.\n  /// @return _observation The stored observation.\n  function getObservation(address _pool, uint16 _index) external view returns (Observation memory _observation);\n\n  /// @notice Returns an interpolated observation for each requested past timestamp (`block.timestamp - secondsAgo`).\n  /// @dev A timestamp at or after the latest swap returns the current accumulator with the requested timestamp,\n  ///      because the cumulatives have not moved since the last swap. A timestamp at or before the oldest stored\n  ///      observation returns the oldest available observation with its own timestamp. An unregistered pool returns zeroed observations.\n  /// @dev A timestamp newer than the newest committed observation is derived from live state, so its value moves\n  ///      as swaps land and a single transaction can shift it. Timestamps at or before the newest committed\n  ///      observation are settled and read the same on every call.\n  /// @param _pool The pool to read.\n  /// @param _secondsAgo The past timestamps to read. A zero timestamp returns the current accumulator.\n  /// @return _observations One observation per timestamp, in the same order as `_secondsAgo`.\n  function observe(\n    address _pool,\n    uint48[] calldata _secondsAgo\n  ) external view returns (Observation[] memory _observations);\n\n  /// @notice The per-pool current accumulator values getter.\n  /// @param _pool The pool to read.\n  /// @return cumulativeFee0 Cumulative token0 fees.\n  /// @return cumulativeFee1 Cumulative token1 fees.\n  /// @return cumulativeVolume0 Cumulative token0 input volume.\n  /// @return cumulativeVolume1 Cumulative token1 input volume.\n  /// @return cumulativeMevVolume0 Cumulative token0 toxic volume.\n  /// @return cumulativeMevVolume1 Cumulative token1 toxic volume.\n  /// @return cumulativeMevFee0 Cumulative token0 MEV fees.\n  /// @return cumulativeMevFee1 Cumulative token1 MEV fees.\n  /// @return lastSwapTimestamp Timestamp of the most recent recorded swap.\n  /// @return swapCount Cumulative swap count.\n  function accumulators(address _pool)\n    external\n    view\n    returns (\n      uint128 cumulativeFee0,\n      uint128 cumulativeFee1,\n      uint128 cumulativeVolume0,\n      uint128 cumulativeVolume1,\n      uint128 cumulativeMevVolume0,\n      uint128 cumulativeMevVolume1,\n      uint128 cumulativeMevFee0,\n      uint128 cumulativeMevFee1,\n      uint48 lastSwapTimestamp,\n      uint48 swapCount\n    );\n}\n"},"V3/src/pools/PoolFees.sol":{"content":"// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity 0.8.36;\n\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\n\n/// @title PoolFees\n/// @author velodrome.finance, Solidly\n/// @notice Ensures curve does not need to be modified for LP shares.\ncontract PoolFees {\n  using SafeERC20 for IERC20;\n\n  address internal immutable pool; // The pool it is bonded to\n  address internal immutable token0; // token0 of pool, saved localy and statically for gas optimization\n  address internal immutable token1; // Token1 of pool, saved localy and statically for gas optimization\n\n  error NotPool();\n\n  constructor(address _token0, address _token1) {\n    pool = msg.sender;\n    token0 = _token0;\n    token1 = _token1;\n  }\n\n  /// @notice Allow the pool to transfer fees to users\n  function claimFeesFor(address _recipient, uint256 _amount0, uint256 _amount1) external {\n    if (msg.sender != pool) revert NotPool();\n    if (_amount0 > 0) IERC20(token0).safeTransfer(_recipient, _amount0);\n    if (_amount1 > 0) IERC20(token1).safeTransfer(_recipient, _amount1);\n  }\n}\n"},"node_modules/@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity >=0.6.2;\n\nimport {IERC20} from \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC-20 standard.\n */\ninterface IERC20Metadata is IERC20 {\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() external view returns (string memory);\n\n    /**\n     * @dev Returns the symbol of the token.\n     */\n    function symbol() external view returns (string memory);\n\n    /**\n     * @dev Returns the decimals places of the token.\n     */\n    function decimals() external view returns (uint8);\n}\n"},"node_modules/@openzeppelin/contracts/utils/Context.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n\n    function _contextSuffixLength() internal view virtual returns (uint256) {\n        return 0;\n    }\n}\n"},"node_modules/@openzeppelin/contracts/interfaces/draft-IERC6093.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.5.0) (interfaces/draft-IERC6093.sol)\n\npragma solidity >=0.8.4;\n\n/**\n * @dev Standard ERC-20 Errors\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-20 tokens.\n */\ninterface IERC20Errors {\n    /**\n     * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     * @param balance Current balance for the interacting account.\n     * @param needed Minimum amount required to perform a transfer.\n     */\n    error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);\n\n    /**\n     * @dev Indicates a failure with the token `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     */\n    error ERC20InvalidSender(address sender);\n\n    /**\n     * @dev Indicates a failure with the token `receiver`. Used in transfers.\n     * @param receiver Address to which tokens are being transferred.\n     */\n    error ERC20InvalidReceiver(address receiver);\n\n    /**\n     * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers.\n     * @param spender Address that may be allowed to operate on tokens without being their owner.\n     * @param allowance Amount of tokens a `spender` is allowed to operate with.\n     * @param needed Minimum amount required to perform a transfer.\n     */\n    error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);\n\n    /**\n     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\n     * @param approver Address initiating an approval operation.\n     */\n    error ERC20InvalidApprover(address approver);\n\n    /**\n     * @dev Indicates a failure with the `spender` to be approved. Used in approvals.\n     * @param spender Address that may be allowed to operate on tokens without being their owner.\n     */\n    error ERC20InvalidSpender(address spender);\n}\n\n/**\n * @dev Standard ERC-721 Errors\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-721 tokens.\n */\ninterface IERC721Errors {\n    /**\n     * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in ERC-721.\n     * Used in balance queries.\n     * @param owner Address of the current owner of a token.\n     */\n    error ERC721InvalidOwner(address owner);\n\n    /**\n     * @dev Indicates a `tokenId` whose `owner` is the zero address.\n     * @param tokenId Identifier number of a token.\n     */\n    error ERC721NonexistentToken(uint256 tokenId);\n\n    /**\n     * @dev Indicates an error related to the ownership over a particular token. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     * @param tokenId Identifier number of a token.\n     * @param owner Address of the current owner of a token.\n     */\n    error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);\n\n    /**\n     * @dev Indicates a failure with the token `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     */\n    error ERC721InvalidSender(address sender);\n\n    /**\n     * @dev Indicates a failure with the token `receiver`. Used in transfers.\n     * @param receiver Address to which tokens are being transferred.\n     */\n    error ERC721InvalidReceiver(address receiver);\n\n    /**\n     * @dev Indicates a failure with the `operator`’s approval. Used in transfers.\n     * @param operator Address that may be allowed to operate on tokens without being their owner.\n     * @param tokenId Identifier number of a token.\n     */\n    error ERC721InsufficientApproval(address operator, uint256 tokenId);\n\n    /**\n     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\n     * @param approver Address initiating an approval operation.\n     */\n    error ERC721InvalidApprover(address approver);\n\n    /**\n     * @dev Indicates a failure with the `operator` to be approved. Used in approvals.\n     * @param operator Address that may be allowed to operate on tokens without being their owner.\n     */\n    error ERC721InvalidOperator(address operator);\n}\n\n/**\n * @dev Standard ERC-1155 Errors\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-1155 tokens.\n */\ninterface IERC1155Errors {\n    /**\n     * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     * @param balance Current balance for the interacting account.\n     * @param needed Minimum amount required to perform a transfer.\n     * @param tokenId Identifier number of a token.\n     */\n    error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);\n\n    /**\n     * @dev Indicates a failure with the token `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     */\n    error ERC1155InvalidSender(address sender);\n\n    /**\n     * @dev Indicates a failure with the token `receiver`. Used in transfers.\n     * @param receiver Address to which tokens are being transferred.\n     */\n    error ERC1155InvalidReceiver(address receiver);\n\n    /**\n     * @dev Indicates a failure with the `operator`’s approval. Used in transfers.\n     * @param operator Address that may be allowed to operate on tokens without being their owner.\n     * @param owner Address of the current owner of a token.\n     */\n    error ERC1155MissingApprovalForAll(address operator, address owner);\n\n    /**\n     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\n     * @param approver Address initiating an approval operation.\n     */\n    error ERC1155InvalidApprover(address approver);\n\n    /**\n     * @dev Indicates a failure with the `operator` to be approved. Used in approvals.\n     * @param operator Address that may be allowed to operate on tokens without being their owner.\n     */\n    error ERC1155InvalidOperator(address operator);\n\n    /**\n     * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation.\n     * Used in batch transfers.\n     * @param idsLength Length of the array of token identifiers\n     * @param valuesLength Length of the array of token amounts\n     */\n    error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);\n}\n"},"node_modules/@openzeppelin/contracts/interfaces/IERC1363.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC1363.sol)\n\npragma solidity >=0.6.2;\n\nimport {IERC20} from \"./IERC20.sol\";\nimport {IERC165} from \"./IERC165.sol\";\n\n/**\n * @title IERC1363\n * @dev Interface of the ERC-1363 standard as defined in the https://eips.ethereum.org/EIPS/eip-1363[ERC-1363].\n *\n * Defines an extension interface for ERC-20 tokens that supports executing code on a recipient contract\n * after `transfer` or `transferFrom`, or code on a spender contract after `approve`, in a single transaction.\n */\ninterface IERC1363 is IERC20, IERC165 {\n    /*\n     * Note: the ERC-165 identifier for this interface is 0xb0202a11.\n     * 0xb0202a11 ===\n     *   bytes4(keccak256('transferAndCall(address,uint256)')) ^\n     *   bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^\n     *   bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^\n     *   bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) ^\n     *   bytes4(keccak256('approveAndCall(address,uint256)')) ^\n     *   bytes4(keccak256('approveAndCall(address,uint256,bytes)'))\n     */\n\n    /**\n     * @dev Moves a `value` amount of tokens from the caller's account to `to`\n     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\n     * @param to The address which you want to transfer to.\n     * @param value The amount of tokens to be transferred.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function transferAndCall(address to, uint256 value) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from the caller's account to `to`\n     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\n     * @param to The address which you want to transfer to.\n     * @param value The amount of tokens to be transferred.\n     * @param data Additional data with no specified format, sent in call to `to`.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism\n     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\n     * @param from The address which you want to send tokens from.\n     * @param to The address which you want to transfer to.\n     * @param value The amount of tokens to be transferred.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function transferFromAndCall(address from, address to, uint256 value) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism\n     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\n     * @param from The address which you want to send tokens from.\n     * @param to The address which you want to transfer to.\n     * @param value The amount of tokens to be transferred.\n     * @param data Additional data with no specified format, sent in call to `to`.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function transferFromAndCall(address from, address to, uint256 value, bytes calldata data) external returns (bool);\n\n    /**\n     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n     * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.\n     * @param spender The address which will spend the funds.\n     * @param value The amount of tokens to be spent.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function approveAndCall(address spender, uint256 value) external returns (bool);\n\n    /**\n     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n     * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.\n     * @param spender The address which will spend the funds.\n     * @param value The amount of tokens to be spent.\n     * @param data Additional data with no specified format, sent in call to `spender`.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function approveAndCall(address spender, uint256 value, bytes calldata data) external returns (bool);\n}\n"},"node_modules/@openzeppelin/contracts/utils/StorageSlot.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/StorageSlot.sol)\n// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Library for reading and writing primitive types to specific storage slots.\n *\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\n * This library helps with reading and writing to such slots without the need for inline assembly.\n *\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\n *\n * Example usage to set ERC-1967 implementation slot:\n * ```solidity\n * contract ERC1967 {\n *     // Define the slot. Alternatively, use the SlotDerivation library to derive the slot.\n *     bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n *\n *     function _getImplementation() internal view returns (address) {\n *         return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n *     }\n *\n *     function _setImplementation(address newImplementation) internal {\n *         require(newImplementation.code.length > 0);\n *         StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n *     }\n * }\n * ```\n *\n * TIP: Consider using this library along with {SlotDerivation}.\n */\nlibrary StorageSlot {\n    struct AddressSlot {\n        address value;\n    }\n\n    struct BooleanSlot {\n        bool value;\n    }\n\n    struct Bytes32Slot {\n        bytes32 value;\n    }\n\n    struct Uint256Slot {\n        uint256 value;\n    }\n\n    struct Int256Slot {\n        int256 value;\n    }\n\n    struct StringSlot {\n        string value;\n    }\n\n    struct BytesSlot {\n        bytes value;\n    }\n\n    /**\n     * @dev Returns an `AddressSlot` with member `value` located at `slot`.\n     */\n    function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `BooleanSlot` with member `value` located at `slot`.\n     */\n    function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `Bytes32Slot` with member `value` located at `slot`.\n     */\n    function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `Uint256Slot` with member `value` located at `slot`.\n     */\n    function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `Int256Slot` with member `value` located at `slot`.\n     */\n    function getInt256Slot(bytes32 slot) internal pure returns (Int256Slot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `StringSlot` with member `value` located at `slot`.\n     */\n    function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `StringSlot` representation of the string storage pointer `store`.\n     */\n    function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := store.slot\n        }\n    }\n\n    /**\n     * @dev Returns a `BytesSlot` with member `value` located at `slot`.\n     */\n    function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.\n     */\n    function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := store.slot\n        }\n    }\n}\n"},"node_modules/@openzeppelin/contracts/interfaces/IERC20.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC20.sol)\n\npragma solidity >=0.4.16;\n\nimport {IERC20} from \"../token/ERC20/IERC20.sol\";\n"},"node_modules/@openzeppelin/contracts/interfaces/IERC165.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC165.sol)\n\npragma solidity >=0.4.16;\n\nimport {IERC165} from \"../utils/introspection/IERC165.sol\";\n"},"node_modules/@openzeppelin/contracts/utils/introspection/IERC165.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (utils/introspection/IERC165.sol)\n\npragma solidity >=0.4.16;\n\n/**\n * @dev Interface of the ERC-165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[ERC].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n    /**\n     * @dev Returns true if this contract implements the interface defined by\n     * `interfaceId`. See the corresponding\n     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section]\n     * to learn more about how these ids are created.\n     *\n     * This function call must use less than 30 000 gas.\n     */\n    function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"}},"compilation":{"language":"Solidity","compiler":"solc","compilerVersion":"0.8.36+commit.8a079791","compilerSettings":{"viaIR":false,"metadata":{"appendCBOR":true,"bytecodeHash":"ipfs","useLiteralContent":false},"libraries":{"V3/src/src/libraries/RewardsLogicLibrary.sol":{"RewardsLogicLibrary":"0x2b73DF2e7e957C77F1D8C01e0a71aD1fF38D6720"},"V3/src/src/libraries/LeafAllocationLibrary.sol":{"LeafAllocationLibrary":"0xC7E262e848fCa78C3C66Ee3c9835e4E65E3E0398"},"V3/src/src/libraries/VotingRewardsFactoryLibrary.sol":{"VotingRewardsFactoryLibrary":"0x1C3821772BFAAE08eE2D4ED8E2c29844CA49634e"}},"optimizer":{"runs":10000,"enabled":true},"viaSSACFG":false,"evmVersion":"prague","remappings":["forge-std/=node_modules/forge-std/src/","@hyperlane/contracts/=node_modules/@hyperlane-xyz/core/contracts/","node_modules/@hyperlane-xyz/:@openzeppelin/contracts/=node_modules/@openzeppelin/contracts-v4/","node_modules/@hyperlane-xyz/:@openzeppelin/contracts/=node_modules/@openzeppelin/contracts-v4/","node_modules/@hyperlane-xyz/:@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable-v4/","node_modules/@hyperlane-xyz/:@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable-v4/","@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/","@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/","@openzeppelin4/contracts/=node_modules/@openzeppelin/contracts-v4/","@solady/=node_modules/solady/src/","@nomad-xyz/src/=node_modules/@nomad-xyz/excessively-safe-call/src/","V3/=V3/src/","V3-script/=V3/script/","V3-test/=V3/test/"],"experimental":false},"name":"StablePool","fullyQualifiedName":"V3/src/pools/StablePool.sol:StablePool"},"abi":[{"name":"BelowMinimumK","type":"error","inputs":[]},{"name":"CannotCalculateY","type":"error","inputs":[]},{"name":"DepositsNotEqual","type":"error","inputs":[]},{"name":"ERC20InsufficientAllowance","type":"error","inputs":[{"name":"spender","type":"address","internalType":"address"},{"name":"allowance","type":"uint256","internalType":"uint256"},{"name":"needed","type":"uint256","internalType":"uint256"}]},{"name":"ERC20InsufficientBalance","type":"error","inputs":[{"name":"sender","type":"address","internalType":"address"},{"name":"balance","type":"uint256","internalType":"uint256"},{"name":"needed","type":"uint256","internalType":"uint256"}]},{"name":"ERC20InvalidApprover","type":"error","inputs":[{"name":"approver","type":"address","internalType":"address"}]},{"name":"ERC20InvalidReceiver","type":"error","inputs":[{"name":"receiver","type":"address","internalType":"address"}]},{"name":"ERC20InvalidSender","type":"error","inputs":[{"name":"sender","type":"address","internalType":"address"}]},{"name":"ERC20InvalidSpender","type":"error","inputs":[{"name":"spender","type":"address","internalType":"address"}]},{"name":"FactoryAlreadySet","type":"error","inputs":[]},{"name":"InsufficientInputAmount","type":"error","inputs":[]},{"name":"InsufficientLiquidity","type":"error","inputs":[]},{"name":"InsufficientLiquidityBurned","type":"error","inputs":[]},{"name":"InsufficientLiquidityMinted","type":"error","inputs":[]},{"name":"InsufficientOutputAmount","type":"error","inputs":[]},{"name":"InvalidTo","type":"error","inputs":[]},{"name":"IsPaused","type":"error","inputs":[]},{"name":"K","type":"error","inputs":[]},{"name":"KIsZero","type":"error","inputs":[]},{"name":"NotAuthorized","type":"error","inputs":[]},{"name":"NotPoolAdmin","type":"error","inputs":[]},{"name":"ObservationOld","type":"error","inputs":[]},{"name":"ReentrancyGuardReentrantCall","type":"error","inputs":[]},{"name":"SafeERC20FailedOperation","type":"error","inputs":[{"name":"token","type":"address","internalType":"address"}]},{"name":"ZeroAddress","type":"error","inputs":[]},{"name":"Approval","type":"event","inputs":[{"name":"owner","type":"address","indexed":true,"internalType":"address"},{"name":"spender","type":"address","indexed":true,"internalType":"address"},{"name":"value","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"Burn","type":"event","inputs":[{"name":"sender","type":"address","indexed":true,"internalType":"address"},{"name":"to","type":"address","indexed":true,"internalType":"address"},{"name":"amount0","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"amount1","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"Claim","type":"event","inputs":[{"name":"caller","type":"address","indexed":true,"internalType":"address"},{"name":"account","type":"address","indexed":true,"internalType":"address"},{"name":"recipient","type":"address","indexed":true,"internalType":"address"},{"name":"amount0","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"amount1","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"ClaimApproval","type":"event","inputs":[{"name":"account","type":"address","indexed":true,"internalType":"address"},{"name":"operator","type":"address","indexed":true,"internalType":"address"},{"name":"approved","type":"bool","indexed":false,"internalType":"bool"}],"anonymous":false},{"name":"Fees","type":"event","inputs":[{"name":"sender","type":"address","indexed":true,"internalType":"address"},{"name":"amount0","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"amount1","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"IncreaseObservationCardinalityNext","type":"event","inputs":[{"name":"caller","type":"address","indexed":true,"internalType":"address"},{"name":"observationCardinalityNextOld","type":"uint16","indexed":false,"internalType":"uint16"},{"name":"observationCardinalityNextNew","type":"uint16","indexed":false,"internalType":"uint16"}],"anonymous":false},{"name":"Mint","type":"event","inputs":[{"name":"sender","type":"address","indexed":true,"internalType":"address"},{"name":"to","type":"address","indexed":true,"internalType":"address"},{"name":"amount0","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"amount1","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"Swap","type":"event","inputs":[{"name":"sender","type":"address","indexed":true,"internalType":"address"},{"name":"to","type":"address","indexed":true,"internalType":"address"},{"name":"amount0In","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"amount1In","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"amount0Out","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"amount1Out","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"Sync","type":"event","inputs":[{"name":"reserve0","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"reserve1","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"Transfer","type":"event","inputs":[{"name":"from","type":"address","indexed":true,"internalType":"address"},{"name":"to","type":"address","indexed":true,"internalType":"address"},{"name":"value","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"MINIMUM_K","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"PERIOD_SIZE","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"POOL_TYPE","type":"function","inputs":[],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"name":"allowance","type":"function","inputs":[{"name":"owner","type":"address","internalType":"address"},{"name":"spender","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"approve","type":"function","inputs":[{"name":"spender","type":"address","internalType":"address"},{"name":"value","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"nonpayable"},{"name":"approveForClaim","type":"function","inputs":[{"name":"_operator","type":"address","internalType":"address"},{"name":"_approved","type":"bool","internalType":"bool"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"approvedForClaim","type":"function","inputs":[{"name":"_account","type":"address","internalType":"address"},{"name":"_operator","type":"address","internalType":"address"}],"outputs":[{"name":"_approved","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"balanceOf","type":"function","inputs":[{"name":"account","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"blockTimestampLast","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"burn","type":"function","inputs":[{"name":"to","type":"address","internalType":"address"}],"outputs":[{"name":"amount0","type":"uint256","internalType":"uint256"},{"name":"amount1","type":"uint256","internalType":"uint256"}],"stateMutability":"nonpayable"},{"name":"claimFees","type":"function","inputs":[{"name":"_recipient","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"},{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"nonpayable"},{"name":"claimFees","type":"function","inputs":[{"name":"_account","type":"address","internalType":"address"},{"name":"_recipient","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"},{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"nonpayable"},{"name":"claimable0","type":"function","inputs":[{"name":"","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"claimable1","type":"function","inputs":[{"name":"","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"currentCumulativePrices","type":"function","inputs":[],"outputs":[{"name":"reserve0Cumulative","type":"uint256","internalType":"uint256"},{"name":"reserve1Cumulative","type":"uint256","internalType":"uint256"},{"name":"blockTimestamp","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"decimals","type":"function","inputs":[],"outputs":[{"name":"","type":"uint8","internalType":"uint8"}],"stateMutability":"view"},{"name":"factory","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"getAmountInWithTotalFee","type":"function","inputs":[{"name":"amountOut","type":"uint256","internalType":"uint256"},{"name":"tokenOut","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"getAmountOut","type":"function","inputs":[{"name":"amountIn","type":"uint256","internalType":"uint256"},{"name":"tokenIn","type":"address","internalType":"address"},{"name":"_reserve0","type":"uint256","internalType":"uint256"},{"name":"_reserve1","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"getAmountOut","type":"function","inputs":[{"name":"amountIn","type":"uint256","internalType":"uint256"},{"name":"tokenIn","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"getAmountOutWithTotalFee","type":"function","inputs":[{"name":"amountIn","type":"uint256","internalType":"uint256"},{"name":"tokenIn","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"getK","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"nonpayable"},{"name":"getReserves","type":"function","inputs":[],"outputs":[{"name":"_reserve0","type":"uint256","internalType":"uint256"},{"name":"_reserve1","type":"uint256","internalType":"uint256"},{"name":"_blockTimestampLast","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"increaseObservationCardinalityNext","type":"function","inputs":[{"name":"_observationCardinalityNext","type":"uint16","internalType":"uint16"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"index0","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"index1","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"initialize","type":"function","inputs":[{"name":"_token0","type":"address","internalType":"address"},{"name":"_token1","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"metadata","type":"function","inputs":[],"outputs":[{"name":"dec0","type":"uint256","internalType":"uint256"},{"name":"dec1","type":"uint256","internalType":"uint256"},{"name":"r0","type":"uint256","internalType":"uint256"},{"name":"r1","type":"uint256","internalType":"uint256"},{"name":"t0","type":"address","internalType":"address"},{"name":"t1","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"mint","type":"function","inputs":[{"name":"to","type":"address","internalType":"address"}],"outputs":[{"name":"liquidity","type":"uint256","internalType":"uint256"}],"stateMutability":"nonpayable"},{"name":"name","type":"function","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"name":"observationBuffer","type":"function","inputs":[],"outputs":[{"name":"index","type":"uint16","internalType":"uint16"},{"name":"cardinality","type":"uint16","internalType":"uint16"},{"name":"cardinalityNext","type":"uint16","internalType":"uint16"}],"stateMutability":"view"},{"name":"observations","type":"function","inputs":[{"name":"_index","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"timestamp","type":"uint32","internalType":"uint32"},{"name":"reserve0Cumulative","type":"uint256","internalType":"uint256"},{"name":"reserve1Cumulative","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"observe","type":"function","inputs":[{"name":"_secondsAgos","type":"uint32[]","internalType":"uint32[]"}],"outputs":[{"name":"_reserve0Cumulatives","type":"uint256[]","internalType":"uint256[]"},{"name":"_reserve1Cumulatives","type":"uint256[]","internalType":"uint256[]"}],"stateMutability":"view"},{"name":"pendingFees","type":"function","inputs":[{"name":"_account","type":"address","internalType":"address"}],"outputs":[{"name":"_amount0","type":"uint256","internalType":"uint256"},{"name":"_amount1","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"poolFees","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"reserve0","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"reserve0CumulativeLast","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"reserve1","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"reserve1CumulativeLast","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"setName","type":"function","inputs":[{"name":"__name","type":"string","internalType":"string"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"setSymbol","type":"function","inputs":[{"name":"__symbol","type":"string","internalType":"string"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"skim","type":"function","inputs":[{"name":"to","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"supplyIndex0","type":"function","inputs":[{"name":"","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"supplyIndex1","type":"function","inputs":[{"name":"","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"swap","type":"function","inputs":[{"name":"amount0Out","type":"uint256","internalType":"uint256"},{"name":"amount1Out","type":"uint256","internalType":"uint256"},{"name":"to","type":"address","internalType":"address"},{"name":"data","type":"bytes","internalType":"bytes"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"symbol","type":"function","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"name":"sync","type":"function","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"name":"token0","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"token1","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"tokens","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"},{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"totalSupply","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"transfer","type":"function","inputs":[{"name":"to","type":"address","internalType":"address"},{"name":"value","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"nonpayable"},{"name":"transferFrom","type":"function","inputs":[{"name":"from","type":"address","internalType":"address"},{"name":"to","type":"address","internalType":"address"},{"name":"value","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"nonpayable"}],"metadata":{"compiler":{"version":"0.8.36+commit.8a079791"},"language":"Solidity","output":{"abi":[{"inputs":[],"name":"BelowMinimumK","type":"error"},{"inputs":[],"name":"CannotCalculateY","type":"error"},{"inputs":[],"name":"DepositsNotEqual","type":"error"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"allowance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientAllowance","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientBalance","type":"error"},{"inputs":[{"internalType":"address","name":"approver","type":"address"}],"name":"ERC20InvalidApprover","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC20InvalidReceiver","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"ERC20InvalidSender","type":"error"},{"inputs":[{"internalType":"address","name":"spender","type":"address"}],"name":"ERC20InvalidSpender","type":"error"},{"inputs":[],"name":"FactoryAlreadySet","type":"error"},{"inputs":[],"name":"InsufficientInputAmount","type":"error"},{"inputs":[],"name":"InsufficientLiquidity","type":"error"},{"inputs":[],"name":"InsufficientLiquidityBurned","type":"error"},{"inputs":[],"name":"InsufficientLiquidityMinted","type":"error"},{"inputs":[],"name":"InsufficientOutputAmount","type":"error"},{"inputs":[],"name":"InvalidTo","type":"error"},{"inputs":[],"name":"IsPaused","type":"error"},{"inputs":[],"name":"K","type":"error"},{"inputs":[],"name":"KIsZero","type":"error"},{"inputs":[],"name":"NotAuthorized","type":"error"},{"inputs":[],"name":"NotPoolAdmin","type":"error"},{"inputs":[],"name":"ObservationOld","type":"error"},{"inputs":[],"name":"ReentrancyGuardReentrantCall","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"inputs":[],"name":"ZeroAddress","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount0","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount1","type":"uint256"}],"name":"Burn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount0","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount1","type":"uint256"}],"name":"Claim","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ClaimApproval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount0","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount1","type":"uint256"}],"name":"Fees","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"uint16","name":"observationCardinalityNextOld","type":"uint16"},{"indexed":false,"internalType":"uint16","name":"observationCardinalityNextNew","type":"uint16"}],"name":"IncreaseObservationCardinalityNext","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount0","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount1","type":"uint256"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount0In","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount1In","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount0Out","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount1Out","type":"uint256"}],"name":"Swap","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"reserve0","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"reserve1","type":"uint256"}],"name":"Sync","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"MINIMUM_K","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PERIOD_SIZE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"POOL_TYPE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_operator","type":"address"},{"internalType":"bool","name":"_approved","type":"bool"}],"name":"approveForClaim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"address","name":"_operator","type":"address"}],"name":"approvedForClaim","outputs":[{"internalType":"bool","name":"_approved","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"blockTimestampLast","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"burn","outputs":[{"internalType":"uint256","name":"amount0","type":"uint256"},{"internalType":"uint256","name":"amount1","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_recipient","type":"address"}],"name":"claimFees","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"address","name":"_recipient","type":"address"}],"name":"claimFees","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"claimable0","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"claimable1","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentCumulativePrices","outputs":[{"internalType":"uint256","name":"reserve0Cumulative","type":"uint256"},{"internalType":"uint256","name":"reserve1Cumulative","type":"uint256"},{"internalType":"uint256","name":"blockTimestamp","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"factory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"address","name":"tokenOut","type":"address"}],"name":"getAmountInWithTotalFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"uint256","name":"_reserve0","type":"uint256"},{"internalType":"uint256","name":"_reserve1","type":"uint256"}],"name":"getAmountOut","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"address","name":"tokenIn","type":"address"}],"name":"getAmountOut","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"address","name":"tokenIn","type":"address"}],"name":"getAmountOutWithTotalFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getK","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getReserves","outputs":[{"internalType":"uint256","name":"_reserve0","type":"uint256"},{"internalType":"uint256","name":"_reserve1","type":"uint256"},{"internalType":"uint256","name":"_blockTimestampLast","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_observationCardinalityNext","type":"uint16"}],"name":"increaseObservationCardinalityNext","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"index0","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"index1","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token0","type":"address"},{"internalType":"address","name":"_token1","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"metadata","outputs":[{"internalType":"uint256","name":"dec0","type":"uint256"},{"internalType":"uint256","name":"dec1","type":"uint256"},{"internalType":"uint256","name":"r0","type":"uint256"},{"internalType":"uint256","name":"r1","type":"uint256"},{"internalType":"address","name":"t0","type":"address"},{"internalType":"address","name":"t1","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"mint","outputs":[{"internalType":"uint256","name":"liquidity","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"observationBuffer","outputs":[{"internalType":"uint16","name":"index","type":"uint16"},{"internalType":"uint16","name":"cardinality","type":"uint16"},{"internalType":"uint16","name":"cardinalityNext","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"observations","outputs":[{"internalType":"uint32","name":"timestamp","type":"uint32"},{"internalType":"uint256","name":"reserve0Cumulative","type":"uint256"},{"internalType":"uint256","name":"reserve1Cumulative","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32[]","name":"_secondsAgos","type":"uint32[]"}],"name":"observe","outputs":[{"internalType":"uint256[]","name":"_reserve0Cumulatives","type":"uint256[]"},{"internalType":"uint256[]","name":"_reserve1Cumulatives","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"pendingFees","outputs":[{"internalType":"uint256","name":"_amount0","type":"uint256"},{"internalType":"uint256","name":"_amount1","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolFees","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"reserve0","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"reserve0CumulativeLast","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"reserve1","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"reserve1CumulativeLast","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"__name","type":"string"}],"name":"setName","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"__symbol","type":"string"}],"name":"setSymbol","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"skim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"supplyIndex0","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"supplyIndex1","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount0Out","type":"uint256"},{"internalType":"uint256","name":"amount1Out","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"swap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sync","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"token0","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token1","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokens","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}],"devdoc":{"errors":{"ERC20InsufficientAllowance(address,uint256,uint256)":[{"details":"Indicates a failure with the `spender`’s `allowance`. Used in transfers.","params":{"allowance":"Amount of tokens a `spender` is allowed to operate with.","needed":"Minimum amount required to perform a transfer.","spender":"Address that may be allowed to operate on tokens without being their owner."}}],"ERC20InsufficientBalance(address,uint256,uint256)":[{"details":"Indicates an error related to the current `balance` of a `sender`. Used in transfers.","params":{"balance":"Current balance for the interacting account.","needed":"Minimum amount required to perform a transfer.","sender":"Address whose tokens are being transferred."}}],"ERC20InvalidApprover(address)":[{"details":"Indicates a failure with the `approver` of a token to be approved. Used in approvals.","params":{"approver":"Address initiating an approval operation."}}],"ERC20InvalidReceiver(address)":[{"details":"Indicates a failure with the token `receiver`. Used in transfers.","params":{"receiver":"Address to which tokens are being transferred."}}],"ERC20InvalidSender(address)":[{"details":"Indicates a failure with the token `sender`. Used in transfers.","params":{"sender":"Address whose tokens are being transferred."}}],"ERC20InvalidSpender(address)":[{"details":"Indicates a failure with the `spender` to be approved. Used in approvals.","params":{"spender":"Address that may be allowed to operate on tokens without being their owner."}}],"ReentrancyGuardReentrantCall()":[{"details":"Unauthorized reentrant call."}],"SafeERC20FailedOperation(address)":[{"details":"An operation with an ERC-20 token failed."}]},"events":{"Approval(address,address,uint256)":{"details":"Emitted when the allowance of a `spender` for an `owner` is set by a call to {approve}. `value` is the new allowance."},"Burn(address,address,uint256,uint256)":{"params":{"amount0":"Amount of token0 returned","amount1":"Amount of token1 returned","sender":"Address that initiated the burn","to":"Address that received the underlying tokens"}},"Claim(address,address,address,uint256,uint256)":{"params":{"account":"Address whose accumulated fees were claimed","amount0":"Amount of token0 claimed","amount1":"Amount of token1 claimed","caller":"Address that triggered the claim","recipient":"Address that received the fee tokens"}},"ClaimApproval(address,address,bool)":{"params":{"account":"Account whose approval state changed","approved":"New approval state","operator":"Operator being approved or revoked"}},"Fees(address,uint256,uint256)":{"params":{"amount0":"Amount of token0 fees collected","amount1":"Amount of token1 fees collected","sender":"Address that triggered the fee claim"}},"IncreaseObservationCardinalityNext(address,uint16,uint16)":{"params":{"caller":"Address that triggered the cardinality growth","observationCardinalityNextNew":"New value of `observationCardinalityNext`","observationCardinalityNextOld":"Previous value of `observationCardinalityNext`"}},"Mint(address,address,uint256,uint256)":{"params":{"amount0":"Amount of token0 deposited","amount1":"Amount of token1 deposited","sender":"Address that initiated the mint","to":"Address that received the LP tokens"}},"Swap(address,address,uint256,uint256,uint256,uint256)":{"params":{"amount0In":"Amount of token0 provided as input","amount0Out":"Amount of token0 sent as output","amount1In":"Amount of token1 provided as input","amount1Out":"Amount of token1 sent as output","sender":"Address that initiated the swap","to":"Address that received the output tokens"}},"Sync(uint256,uint256)":{"params":{"reserve0":"Updated reserve of token0","reserve1":"Updated reserve of token1"}},"Transfer(address,address,uint256)":{"details":"Emitted when `value` tokens are moved from one account (`from`) to another (`to`). Note that `value` may be zero."}},"kind":"dev","methods":{"allowance(address,address)":{"details":"Returns the remaining number of tokens that `spender` will be allowed to spend on behalf of `owner` through {transferFrom}. This is zero by default. This value changes when {approve} or {transferFrom} are called."},"approve(address,uint256)":{"details":"See {IERC20-approve}. NOTE: If `value` is the maximum `uint256`, the allowance is not updated on `transferFrom`. This is semantically equivalent to an infinite approval. Requirements: - `spender` cannot be the zero address."},"approveForClaim(address,bool)":{"params":{"_approved":"Whether the operator is approved","_operator":"Operator whose approval is updated"}},"balanceOf(address)":{"details":"Returns the value of tokens owned by `account`."},"burn(address)":{"params":{"to":"Address to receive token0 and token1 from burning the pool token"},"returns":{"amount0":"Amount of token0 returned","amount1":"Amount of token1 returned"}},"claimFees(address)":{"params":{"_recipient":"Address that receives the claimed fee tokens"},"returns":{"_0":"Amount of token0 claimed","_1":"Amount of token1 claimed"}},"claimFees(address,address)":{"details":"The caller must be `_account` or an operator approved by `_account`","params":{"_account":"Account whose accumulated fees are claimed","_recipient":"Address that receives the claimed fee tokens"},"returns":{"_0":"Amount of token0 claimed","_1":"Amount of token1 claimed"}},"decimals()":{"details":"Returns the number of decimals used to get its user representation. For example, if `decimals` equals `2`, a balance of `505` tokens should be displayed to a user as `5.05` (`505 / 10 ** 2`). Tokens usually opt for a value of 18, imitating the relationship between Ether and Wei. This is the default value returned by this function, unless it's overridden. NOTE: This information is only used for _display_ purposes: it in no way affects any of the arithmetic of the contract, including {IERC20-balanceOf} and {IERC20-transfer}."},"getAmountInWithTotalFee(uint256,address)":{"details":"Reverts if the exact output cannot be calculated","params":{"amountOut":"Amount of token out to receive","tokenOut":"Address of token out"},"returns":{"_0":"Amount in, fee included"}},"getAmountOut(uint256,address)":{"details":"Does not charge the MEV tax, so the result can be higher than what `swap` pays out.      Use `getAmountOutWithTotalFee` to quote a swap.","params":{"amountIn":"Amount of token in","tokenIn":"Address of token"},"returns":{"_0":"Amount out"}},"getAmountOut(uint256,address,uint256,uint256)":{"details":"Subtracts the base fee from `amountIn` before applying the curve. Does not charge the MEV      tax, so use `getAmountOutWithTotalFee` to quote a swap.","params":{"_reserve0":"Reserve of token0 to quote against","_reserve1":"Reserve of token1 to quote against","amountIn":"Input amount in the smallest unit of `tokenIn`","tokenIn":"Address of the input token"},"returns":{"_0":"Output amount the swap would produce against the supplied reserves"}},"getAmountOutWithTotalFee(uint256,address)":{"params":{"amountIn":"Amount of token in","tokenIn":"Address of token in"},"returns":{"_0":"Amount out"}},"getReserves()":{"returns":{"_blockTimestampLast":".","_reserve0":".","_reserve1":"."}},"increaseObservationCardinalityNext(uint16)":{"details":"Pre-initialises buffer slots so observation writes hit warm storage.","params":{"_observationCardinalityNext":"New target capacity. At most 65,535."}},"initialize(address,address)":{"params":{"_token0":"Address of token0","_token1":"Address of token1"}},"mint(address)":{"params":{"to":"Address to receive the minted LP token"},"returns":{"liquidity":"Amount of LP token minted"}},"name()":{"details":"Returns the name of the token."},"observations(uint256)":{"params":{"index":"Index of the observation to return"},"returns":{"reserve0Cumulative":"Cumulative reserve0 of the observation","reserve1Cumulative":"Cumulative reserve1 of the observation","timestamp":"Timestamp of the observation"}},"observe(uint32[])":{"details":"Offsets between two stored observations are linearly interpolated. Observations are      period-gated, so reserve changes within an interval may go unrecorded, making the      interpolation an approximation. Read from the pool directly when an exact value is required.A point newer than the newest stored observation is estimated from the current cumulative      instead of two stored ones, so a trade after that point can change what it reads. It stops      changing once an observation is stored at or after that point. Points that already fall      between two stored observations read the same on every call.","params":{"secondsAgos":"Array of seconds offsets from `block.timestamp` to query"},"returns":{"_reserve0Cumulatives":"Cumulative reserve0 values at each requested point","_reserve1Cumulatives":"Cumulative reserve1 values at each requested point"}},"pendingFees(address)":{"params":{"_account":"Address to query."},"returns":{"_amount0":"Pending token0 fees.","_amount1":"Pending token1 fees."}},"setName(string)":{"params":{"__name":"String of new name"}},"setSymbol(string)":{"params":{"__symbol":"String of new symbol"}},"skim(address)":{"params":{"to":"Address to receive any skimmed rewards"}},"swap(uint256,uint256,address,bytes)":{"params":{"amount0Out":"Amount of token0 to send to `to`","amount1Out":"Amount of token1 to send to `to`","data":"Additional calldata for flashloans","to":"Address to recieve the swapped output"}},"symbol()":{"details":"Returns the symbol of the token, usually a shorter version of the name."},"totalSupply()":{"details":"Returns the value of tokens in existence."},"transfer(address,uint256)":{"details":"See {IERC20-transfer}. Requirements: - `to` cannot be the zero address. - the caller must have a balance of at least `value`."},"transferFrom(address,address,uint256)":{"details":"See {IERC20-transferFrom}. Skips emitting an {Approval} event indicating an allowance update. This is not required by the ERC. See {xref-ERC20-_approve-address-address-uint256-bool-}[_approve]. NOTE: Does not update the allowance if the current allowance is the maximum `uint256`. Requirements: - `from` and `to` cannot be the zero address. - `from` must have a balance of at least `value`. - the caller must have allowance for ``from``'s tokens of at least `value`."}},"stateVariables":{"POOL_TYPE":{"return":"The pool type label to be able to identify the type of pool","returns":{"_0":"The pool type label to be able to identify the type of pool"}}},"title":"StablePool","version":1},"userdoc":{"errors":{"BelowMinimumK()":[{"notice":"Thrown on first mint when `_k(amount0, amount1)` is less than or equal to `MINIMUM_K`"}],"CannotCalculateY()":[{"notice":"Thrown when the Newton-Raphson search cannot solve for `y` within its iteration budget"}],"DepositsNotEqual()":[{"notice":"Thrown when the deposited amounts are not equal"}],"FactoryAlreadySet()":[{"notice":"Thrown when the factory address has already been set and cannot be changed"}],"InsufficientInputAmount()":[{"notice":"Thrown when the input amount provided to a swap is zero or insufficient"}],"InsufficientLiquidity()":[{"notice":"Thrown when the pool does not have enough liquidity to fulfil the operation"}],"InsufficientLiquidityBurned()":[{"notice":"Thrown when burning LP tokens would return zero of at least one underlying token"}],"InsufficientLiquidityMinted()":[{"notice":"Thrown when minting would produce zero LP tokens"}],"InsufficientOutputAmount()":[{"notice":"Thrown when the output amount of a swap is zero or below the requested minimum"}],"InvalidTo()":[{"notice":"Thrown when the `to` address supplied to swap or burn is one of the pool's tokens"}],"IsPaused()":[{"notice":"Thrown when an operation is attempted while the pool is paused"}],"K()":[{"notice":"Thrown when the invariant K check fails after a swap"}],"KIsZero()":[{"notice":"Thrown after burn when remaining reserves cause `_k` to round to zero"}],"NotAuthorized()":[{"notice":"Thrown when the caller is neither the account nor an approved claim operator"}],"ObservationOld()":[{"notice":"Thrown when a requested timestamp predates the oldest stored observation."}],"ZeroAddress()":[{"notice":"Thrown when a zero address is supplied where a non-zero address is required"}]},"events":{"Burn(address,address,uint256,uint256)":{"notice":"Emitted when liquidity is burned"},"Claim(address,address,address,uint256,uint256)":{"notice":"Emitted when accumulated fee tokens are claimed"},"ClaimApproval(address,address,bool)":{"notice":"Emitted when an account grants or revokes claim approval for an operator"},"Fees(address,uint256,uint256)":{"notice":"Emitted when fees are claimed by a liquidity provider"},"IncreaseObservationCardinalityNext(address,uint16,uint16)":{"notice":"Emitted whenever `observationCardinalityNext` is increased"},"Mint(address,address,uint256,uint256)":{"notice":"Emitted when liquidity is minted"},"Swap(address,address,uint256,uint256,uint256,uint256)":{"notice":"Emitted on every swap executed through the pool"},"Sync(uint256,uint256)":{"notice":"Emitted when reserves are synced to the current balances"}},"kind":"user","methods":{"MINIMUM_K()":{"notice":"Minimum value of the stable-swap invariant"},"PERIOD_SIZE()":{"notice":"Period gate for new observations, in seconds. A new observation is written when more         than `PERIOD_SIZE` seconds have passed since the last one, so the smallest possible         spacing between two stored observations is `PERIOD_SIZE + 1` (i.e. 61 seconds at the         default value of 60)."},"POOL_TYPE()":{"notice":"The pool type identifier"},"approveForClaim(address,bool)":{"notice":"Grants or revokes an operator's permission to claim the caller's accumulated fees"},"approvedForClaim(address,address)":{"notice":"Whether an operator may claim an account's accumulated fees"},"blockTimestampLast()":{"notice":"Timestamp of last update to pool"},"burn(address)":{"notice":"This low-level function should be called from a contract which performs important safety checks         standard uniswap v2 implementation"},"claimFees(address)":{"notice":"Claims the caller's accumulated fees"},"claimFees(address,address)":{"notice":"Claims an account's accumulated fees"},"claimable0(address)":{"notice":"Amount of unclaimed, but claimable tokens from fees of token0 for an LP"},"claimable1(address)":{"notice":"Amount of unclaimed, but claimable tokens from fees of token1 for an LP"},"currentCumulativePrices()":{"notice":"Produces the cumulative price using counterfactuals to save gas and avoid a call to sync."},"factory()":{"notice":"Address of PoolFactory that created this contract"},"getAmountInWithTotalFee(uint256,address)":{"notice":"Get the amount of tokenIn required to receive the amount of tokenOut, charging the total fees"},"getAmountOut(uint256,address)":{"notice":"Get the amount of tokenOut given the amount of tokenIn, charging only the base fee"},"getAmountOut(uint256,address,uint256,uint256)":{"notice":"Quote `amountIn` of `tokenIn` against a custom reserve snapshot"},"getAmountOutWithTotalFee(uint256,address)":{"notice":"Get the amount of tokenOut given the amount of tokenIn, charging the total fees"},"getK()":{"notice":"Returns the value of K in the Pool, based on its reserves."},"getReserves()":{"notice":"Update reserves and, on the first call per block, price accumulators"},"increaseObservationCardinalityNext(uint16)":{"notice":"Pre-allocates buffer slots increasing the buffer capacity"},"index0()":{"notice":"Accumulated fees of token0 (global)"},"index1()":{"notice":"Accumulated fees of token1 (global)"},"initialize(address,address)":{"notice":"Called on pool creation by the owning PoolFactory"},"metadata()":{"notice":"Returns the decimal (dec), reserves (r), and tokens (t) of token0 and token1"},"mint(address)":{"notice":"This low-level function should be called by addLiquidity functions in Router.sol, which performs important safety checks         standard uniswap v2 implementation"},"observationBuffer()":{"notice":"Circular buffer of TWAP observations with its write index and cardinality metadata."},"observations(uint256)":{"notice":"Returns the observation at the given index"},"observe(uint32[])":{"notice":"Returns the cumulative reserves as of each requested `secondsAgo`. Reverts when any         `secondsAgos[i]` predates the oldest stored observation."},"pendingFees(address)":{"notice":"Returns accumulated but unclaimed fees for an account."},"poolFees()":{"notice":"Address of linked PoolFees.sol"},"reserve0()":{"notice":"Amount of token0 in pool"},"reserve0CumulativeLast()":{"notice":"Cumulative of reserve0 factoring in time elapsed"},"reserve1()":{"notice":"Amount of token1 in pool"},"reserve1CumulativeLast()":{"notice":"Cumulative of reserve1 factoring in time elapsed"},"setName(string)":{"notice":"Set pool name         Only callable by IPoolFactory(factory).poolAdmin()"},"setSymbol(string)":{"notice":"Set pool symbol         Only callable by IPoolFactory(factory).poolAdmin()"},"skim(address)":{"notice":"Force balances to match reserves"},"supplyIndex0(address)":{"notice":"Get an LP's relative index0 to index0"},"supplyIndex1(address)":{"notice":"Get an LP's relative index1 to index1"},"swap(uint256,uint256,address,bytes)":{"notice":"This low-level function should be called from a contract which performs important safety checks"},"sync()":{"notice":"Force reserves to match balances"},"token0()":{"notice":"Address of token in the pool with the lower address value"},"token1()":{"notice":"Address of token in the pool with the higher address value"},"tokens()":{"notice":"Returns [token0, token1]"}},"notice":"Aerodrome V2 stable-swap pool.","version":1}},"settings":{"compilationTarget":{"V3/src/pools/StablePool.sol":"StablePool"},"evmVersion":"prague","libraries":{"V3/src/src/libraries/LeafAllocationLibrary.sol:LeafAllocationLibrary":"0xc7e262e848fca78c3c66ee3c9835e4e65e3e0398","V3/src/src/libraries/RewardsLogicLibrary.sol:RewardsLogicLibrary":"0x2b73df2e7e957c77f1d8c01e0a71ad1ff38d6720","V3/src/src/libraries/VotingRewardsFactoryLibrary.sol:VotingRewardsFactoryLibrary":"0x1c3821772bfaae08ee2d4ed8e2c29844ca49634e"},"metadata":{"bytecodeHash":"ipfs"},"optimizer":{"enabled":true,"runs":10000},"remappings":[":@hyperlane/contracts/=node_modules/@hyperlane-xyz/core/contracts/",":@nomad-xyz/src/=node_modules/@nomad-xyz/excessively-safe-call/src/",":@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/",":@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/",":@openzeppelin4/contracts/=node_modules/@openzeppelin/contracts-v4/",":@solady/=node_modules/solady/src/",":V3-script/=V3/script/",":V3-test/=V3/test/",":V3/=V3/src/",":forge-std/=node_modules/forge-std/src/","node_modules/@hyperlane-xyz/:@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable-v4/","node_modules/@hyperlane-xyz/:@openzeppelin/contracts/=node_modules/@openzeppelin/contracts-v4/"]},"sources":{"V3/src/interfaces/factories/IPoolFactory.sol":{"keccak256":"0x1f8dc8eab9ed8c2af9fdc70a79ad87fa32c0b944ad264dbfa0ff73840b1eb5cd","license":"MIT","urls":["bzz-raw://210e03abf15c2b019338710a28df9b19da6f34a50e3274a7a3f21d0004d803d5","dweb:/ipfs/QmYcX93yesan7C2BneWPCdqLJV5nqroCrmPRosCgAsmPSZ"]},"V3/src/interfaces/pools/IPool.sol":{"keccak256":"0x4ac3d8b3381f9f0b24516a34f28a25c36a3f11448b72e11155a8fb47e33cf65c","license":"MIT","urls":["bzz-raw://5e5fd853c52b861cb4884edfdef7519cdac15a852a59f0047ec8582280fb8a68","dweb:/ipfs/QmbxZcm4BH4Nu4V2rm767AtxHnroZofENMSNQJjg4dknc7"]},"V3/src/interfaces/pools/IPoolCallee.sol":{"keccak256":"0xc1e83c75cb704ca137543fd48127b5f3904d2644d13093d678c4edf6a618cfa9","license":"MIT","urls":["bzz-raw://3a03eb17ea6a74081180b3ef1386ccaaa8214c5efdd59bff833385b6c595603d","dweb:/ipfs/QmRr8YmMC3n1mtjFU1Ukh3JphT267KFeBeFSChCik5hfhz"]},"V3/src/interfaces/pools/IStablePool.sol":{"keccak256":"0x2ef11f9e8c2845a0d0e6854db6fad6ad85d5c4dc26e1e61fade770c41691d6bd","license":"MIT","urls":["bzz-raw://493275d0ee5e7226644cc127587a8fffa57aa29157289f6fe31648670fc1175c","dweb:/ipfs/QmQr1UKZ22AZYyKvB8XqPVEWrZAaCzXYS65x3QroAD9TB6"]},"V3/src/interfaces/pools/tape/IPoolTape.sol":{"keccak256":"0xbafec7377a6f67eafa045e7395c59cdbab75e2a517207868cb216c69289d1b36","license":"MIT","urls":["bzz-raw://9bbb4ad7a82504240c578972aa0cb4c5dbcf64a3cd34d455df2878c37061f0a4","dweb:/ipfs/QmPnZJ1JQXdWBo7mStv4Rcw1C51mmBHZp8eSosFyKfa2WU"]},"V3/src/libraries/PoolOracle.sol":{"keccak256":"0x149aeb7e33e8a25357632ce0dede4c614e377eb3158755954869152f4cbdeffe","license":"GPL-3.0-or-later","urls":["bzz-raw://6cb60ad438b8415995b69614859d5a4a6fc1cfe09fc1429a0d67d3dbaa03d394","dweb:/ipfs/QmPmeR5efBLbsUjiAPxFiLi1iKoZa3Qoww5h5X5JVoY28n"]},"V3/src/pools/Pool.sol":{"keccak256":"0xe9f9e84d0714dccf6e244c4deda76b2b1b7520b8758204655c2b3f57c0a33874","license":"GPL-3.0-or-later","urls":["bzz-raw://feeea4a1a04ff36ef97cd13bec25105ccb4dc213631ced965545b61a8df44226","dweb:/ipfs/QmVPMEZjQr9kFtcH4ssrgXsjmHyNg2uEPAKXGsW3aUjSpo"]},"V3/src/pools/PoolFees.sol":{"keccak256":"0xcacae30b57729c48c074d85d95be72137b15beb64e52cc85a8f9947b9ca49882","license":"GPL-3.0-or-later","urls":["bzz-raw://794663e81644b94ac2b62ece1ea5abbb9ee0415392f8cbcf591e425e32ea7679","dweb:/ipfs/QmYyVAiZeniGrmMyu9SLP94mHFFGR9UsD3ktPePxstLdDG"]},"V3/src/pools/StablePool.sol":{"keccak256":"0xab686a4bdcc2c218119e259a9330ca5d3f7a4d664a5d8d287dedab1bfb2d17f9","license":"GPL-3.0-or-later","urls":["bzz-raw://9d73c976a388c68e3450f5ca9c83c3ddab1d0cfdbaac37970b0d0f2773e42a25","dweb:/ipfs/QmfD2FFZDD7BssFoy4db7tVQEvdLB9toN63t76Qw9MRyfv"]},"node_modules/@openzeppelin/contracts/interfaces/IERC1363.sol":{"keccak256":"0xd5ea07362ab630a6a3dee4285a74cf2377044ca2e4be472755ad64d7c5d4b69d","license":"MIT","urls":["bzz-raw://da5e832b40fc5c3145d3781e2e5fa60ac2052c9d08af7e300dc8ab80c4343100","dweb:/ipfs/QmTzf7N5ZUdh5raqtzbM11yexiUoLC9z3Ws632MCuycq1d"]},"node_modules/@openzeppelin/contracts/interfaces/IERC165.sol":{"keccak256":"0x0afcb7e740d1537b252cb2676f600465ce6938398569f09ba1b9ca240dde2dfc","license":"MIT","urls":["bzz-raw://1c299900ac4ec268d4570ecef0d697a3013cd11a6eb74e295ee3fbc945056037","dweb:/ipfs/Qmab9owJoxcA7vJT5XNayCMaUR1qxqj1NDzzisduwaJMcZ"]},"node_modules/@openzeppelin/contracts/interfaces/IERC20.sol":{"keccak256":"0x1a6221315ce0307746c2c4827c125d821ee796c74a676787762f4778671d4f44","license":"MIT","urls":["bzz-raw://1bb2332a7ee26dd0b0de9b7fe266749f54820c99ab6a3bcb6f7e6b751d47ee2d","dweb:/ipfs/QmcRWpaBeCYkhy68PR3B4AgD7asuQk7PwkWxrvJbZcikLF"]},"node_modules/@openzeppelin/contracts/interfaces/draft-IERC6093.sol":{"keccak256":"0x1b88b3fb3d85ba5496d7d5f396f83ee1fddcdd6762059ff65992655b67920998","license":"MIT","urls":["bzz-raw://89393bb3212da1c0889601b9706a07b39419ddc4d2faab9eaf6e7f9152cf6a1c","dweb:/ipfs/QmcCfzzxv1Bkdz1c1yF4gQCeYb6Us5BJANnzTFqawfd1HL"]},"node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol":{"keccak256":"0x669464167428061ee0f8618b73b3ee90aff8405683e7ddde8cd77dadaa1afe29","license":"MIT","urls":["bzz-raw://0dda78587a7358b4fdf6b9fca0fde5a5e34930f36d5268a16028627fc0170195","dweb:/ipfs/QmQ1b6cCceDRWNxti9HifsTCzmVP25Haxs1bWugm52vTqH"]},"node_modules/@openzeppelin/contracts/token/ERC20/IERC20.sol":{"keccak256":"0x74ed01eb66b923d0d0cfe3be84604ac04b76482a55f9dd655e1ef4d367f95bc2","license":"MIT","urls":["bzz-raw://5282825a626cfe924e504274b864a652b0023591fa66f06a067b25b51ba9b303","dweb:/ipfs/QmeCfPykghhMc81VJTrHTC7sF6CRvaA1FXVq2pJhwYp1dV"]},"node_modules/@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol":{"keccak256":"0xd6fa4088198f04eef10c5bce8a2f4d60554b7ec4b987f684393c01bf79b94d9f","license":"MIT","urls":["bzz-raw://f95ee0bbd4dd3ac730d066ba3e785ded4565e890dbec2fa7d3b9fe3bad9d0d6e","dweb:/ipfs/QmSLr6bHkPFWT7ntj34jmwfyskpwo97T9jZUrk5sz3sdtR"]},"node_modules/@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol":{"keccak256":"0x304d732678032a9781ae85c8f204c8fba3d3a5e31c02616964e75cfdc5049098","license":"MIT","urls":["bzz-raw://299ced486011781dc98f638059678323c03079fefae1482abaa2135b22fa92d0","dweb:/ipfs/QmbZNbcPTBxNvwChavN2kkZZs7xHhYL7mv51KrxMhsMs3j"]},"node_modules/@openzeppelin/contracts/utils/Context.sol":{"keccak256":"0x493033a8d1b176a037b2cc6a04dad01a5c157722049bbecf632ca876224dd4b2","license":"MIT","urls":["bzz-raw://6a708e8a5bdb1011c2c381c9a5cfd8a9a956d7d0a9dc1bd8bcdaf52f76ef2f12","dweb:/ipfs/Qmax9WHBnVsZP46ZxEMNRQpLQnrdE4dK8LehML1Py8FowF"]},"node_modules/@openzeppelin/contracts/utils/Panic.sol":{"keccak256":"0xf7fe324703a64fc51702311dc51562d5cb1497734f074e4f483bfb6717572d7a","license":"MIT","urls":["bzz-raw://c6a5ff4f9fd8649b7ee20800b7fa387d3465bd77cf20c2d1068cd5c98e1ed57a","dweb:/ipfs/QmVSaVJf9FXFhdYEYeCEfjMVHrxDh5qL4CGkxdMWpQCrqG"]},"node_modules/@openzeppelin/contracts/utils/ReentrancyGuard.sol":{"keccak256":"0xa516cbf1c7d15d3517c2d668601ce016c54395bf5171918a14e2686977465f53","license":"MIT","urls":["bzz-raw://1e1d079e8edfb58efd23a311e315a4807b01b5d1cf153f8fa2d0608b9dec3e99","dweb:/ipfs/QmTBExeX2SDTkn5xbk5ssbYSx7VqRp9H4Ux1CY4uQM4b9N"]},"node_modules/@openzeppelin/contracts/utils/StorageSlot.sol":{"keccak256":"0xcf74f855663ce2ae00ed8352666b7935f6cddea2932fdf2c3ecd30a9b1cd0e97","license":"MIT","urls":["bzz-raw://9f660b1f351b757dfe01438e59888f31f33ded3afcf5cb5b0d9bf9aa6f320a8b","dweb:/ipfs/QmarDJ5hZEgBtCmmrVzEZWjub9769eD686jmzb2XpSU1cM"]},"node_modules/@openzeppelin/contracts/utils/introspection/IERC165.sol":{"keccak256":"0x8891738ffe910f0cf2da09566928589bf5d63f4524dd734fd9cedbac3274dd5c","license":"MIT","urls":["bzz-raw://971f954442df5c2ef5b5ebf1eb245d7105d9fbacc7386ee5c796df1d45b21617","dweb:/ipfs/QmadRjHbkicwqwwh61raUEapaVEtaLMcYbQZWs9gUkgj3u"]},"node_modules/@openzeppelin/contracts/utils/math/Math.sol":{"keccak256":"0x59973a93b1f983f94e10529f46ca46544a9fec2b5f56fb1390bbe9e0dc79f857","license":"MIT","urls":["bzz-raw://c55ef8f0b9719790c2ae6f81d80a59ffb89f2f0abe6bc065585bd79edce058c5","dweb:/ipfs/QmNNmCbX9NjPXKqHJN8R1WC2rNeZSQrPZLd6FF6AKLyH5Y"]},"node_modules/@openzeppelin/contracts/utils/math/SafeCast.sol":{"keccak256":"0xc8cae21c9ae4a46e5162ff9bf5b351d6fa6a6eba72d515f3bc1bdfeda7fdf083","license":"MIT","urls":["bzz-raw://ce830ebcf28e31643caba318996db3763c36d52cd0f23798ba83c135355d45e9","dweb:/ipfs/QmdGPcvptHN7UBCbUYBbRX3hiRVRFLRwno8b4uga6uFNif"]}},"version":1},"storageLayout":{"types":{"t_bool":{"label":"bool","encoding":"inplace","numberOfBytes":"1"},"t_uint16":{"label":"uint16","encoding":"inplace","numberOfBytes":"2"},"t_uint32":{"label":"uint32","encoding":"inplace","numberOfBytes":"4"},"t_address":{"label":"address","encoding":"inplace","numberOfBytes":"20"},"t_uint256":{"label":"uint256","encoding":"inplace","numberOfBytes":"32"},"t_string_storage":{"label":"string","encoding":"bytes","numberOfBytes":"32"},"t_mapping(t_address,t_bool)":{"key":"t_address","label":"mapping(address => bool)","value":"t_bool","encoding":"mapping","numberOfBytes":"32"},"t_mapping(t_address,t_uint256)":{"key":"t_address","label":"mapping(address => uint256)","value":"t_uint256","encoding":"mapping","numberOfBytes":"32"},"t_struct(Observation)1124_storage":{"label":"struct PoolOracle.Observation","members":[{"slot":"0","type":"t_uint32","astId":1119,"label":"timestamp","offset":0,"contract":"V3/src/pools/StablePool.sol:StablePool"},{"slot":"1","type":"t_uint256","astId":1121,"label":"reserve0Cumulative","offset":0,"contract":"V3/src/pools/StablePool.sol:StablePool"},{"slot":"2","type":"t_uint256","astId":1123,"label":"reserve1Cumulative","offset":0,"contract":"V3/src/pools/StablePool.sol:StablePool"}],"encoding":"inplace","numberOfBytes":"96"},"t_struct(ObservationBuffer)1137_storage":{"label":"struct PoolOracle.ObservationBuffer","members":[{"slot":"0","type":"t_array(t_struct(Observation)1124_storage)65535_storage","astId":1130,"label":"observations","offset":0,"contract":"V3/src/pools/StablePool.sol:StablePool"},{"slot":"196605","type":"t_uint16","astId":1132,"label":"index","offset":0,"contract":"V3/src/pools/StablePool.sol:StablePool"},{"slot":"196605","type":"t_uint16","astId":1134,"label":"cardinality","offset":2,"contract":"V3/src/pools/StablePool.sol:StablePool"},{"slot":"196605","type":"t_uint16","astId":1136,"label":"cardinalityNext","offset":4,"contract":"V3/src/pools/StablePool.sol:StablePool"}],"encoding":"inplace","numberOfBytes":"6291392"},"t_mapping(t_address,t_mapping(t_address,t_bool))":{"key":"t_address","label":"mapping(address => mapping(address => bool))","value":"t_mapping(t_address,t_bool)","encoding":"mapping","numberOfBytes":"32"},"t_mapping(t_address,t_mapping(t_address,t_uint256))":{"key":"t_address","label":"mapping(address => mapping(address => uint256))","value":"t_mapping(t_address,t_uint256)","encoding":"mapping","numberOfBytes":"32"},"t_array(t_struct(Observation)1124_storage)65535_storage":{"base":"t_struct(Observation)1124_storage","label":"struct PoolOracle.Observation[65535]","encoding":"inplace","numberOfBytes":"6291360"}},"storage":[{"slot":"0","type":"t_mapping(t_address,t_uint256)","astId":5142,"label":"_balances","offset":0,"contract":"V3/src/pools/StablePool.sol:StablePool"},{"slot":"1","type":"t_mapping(t_address,t_mapping(t_address,t_uint256))","astId":5148,"label":"_allowances","offset":0,"contract":"V3/src/pools/StablePool.sol:StablePool"},{"slot":"2","type":"t_uint256","astId":5150,"label":"_totalSupply","offset":0,"contract":"V3/src/pools/StablePool.sol:StablePool"},{"slot":"3","type":"t_string_storage","astId":5152,"label":"_name","offset":0,"contract":"V3/src/pools/StablePool.sol:StablePool"},{"slot":"4","type":"t_string_storage","astId":5154,"label":"_symbol","offset":0,"contract":"V3/src/pools/StablePool.sol:StablePool"},{"slot":"5","type":"t_string_storage","astId":1936,"label":"_name","offset":0,"contract":"V3/src/pools/StablePool.sol:StablePool"},{"slot":"6","type":"t_string_storage","astId":1939,"label":"_symbol","offset":0,"contract":"V3/src/pools/StablePool.sol:StablePool"},{"slot":"7","type":"t_address","astId":1942,"label":"token0","offset":0,"contract":"V3/src/pools/StablePool.sol:StablePool"},{"slot":"8","type":"t_address","astId":1945,"label":"token1","offset":0,"contract":"V3/src/pools/StablePool.sol:StablePool"},{"slot":"9","type":"t_address","astId":1948,"label":"poolFees","offset":0,"contract":"V3/src/pools/StablePool.sol:StablePool"},{"slot":"10","type":"t_address","astId":1951,"label":"factory","offset":0,"contract":"V3/src/pools/StablePool.sol:StablePool"},{"slot":"11","type":"t_struct(ObservationBuffer)1137_storage","astId":1955,"label":"observationBuffer","offset":0,"contract":"V3/src/pools/StablePool.sol:StablePool"},{"slot":"196617","type":"t_uint256","astId":1958,"label":"_decimals0","offset":0,"contract":"V3/src/pools/StablePool.sol:StablePool"},{"slot":"196618","type":"t_uint256","astId":1961,"label":"_decimals1","offset":0,"contract":"V3/src/pools/StablePool.sol:StablePool"},{"slot":"196619","type":"t_uint256","astId":1964,"label":"reserve0","offset":0,"contract":"V3/src/pools/StablePool.sol:StablePool"},{"slot":"196620","type":"t_uint256","astId":1967,"label":"reserve1","offset":0,"contract":"V3/src/pools/StablePool.sol:StablePool"},{"slot":"196621","type":"t_uint256","astId":1970,"label":"blockTimestampLast","offset":0,"contract":"V3/src/pools/StablePool.sol:StablePool"},{"slot":"196622","type":"t_uint256","astId":1973,"label":"reserve0CumulativeLast","offset":0,"contract":"V3/src/pools/StablePool.sol:StablePool"},{"slot":"196623","type":"t_uint256","astId":1976,"label":"reserve1CumulativeLast","offset":0,"contract":"V3/src/pools/StablePool.sol:StablePool"},{"slot":"196624","type":"t_uint256","astId":1979,"label":"index0","offset":0,"contract":"V3/src/pools/StablePool.sol:StablePool"},{"slot":"196625","type":"t_uint256","astId":1982,"label":"index1","offset":0,"contract":"V3/src/pools/StablePool.sol:StablePool"},{"slot":"196626","type":"t_mapping(t_address,t_uint256)","astId":1987,"label":"supplyIndex0","offset":0,"contract":"V3/src/pools/StablePool.sol:StablePool"},{"slot":"196627","type":"t_mapping(t_address,t_uint256)","astId":1992,"label":"supplyIndex1","offset":0,"contract":"V3/src/pools/StablePool.sol:StablePool"},{"slot":"196628","type":"t_mapping(t_address,t_uint256)","astId":1997,"label":"claimable0","offset":0,"contract":"V3/src/pools/StablePool.sol:StablePool"},{"slot":"196629","type":"t_mapping(t_address,t_uint256)","astId":2002,"label":"claimable1","offset":0,"contract":"V3/src/pools/StablePool.sol:StablePool"},{"slot":"196630","type":"t_mapping(t_address,t_mapping(t_address,t_bool))","astId":2009,"label":"approvedForClaim","offset":0,"contract":"V3/src/pools/StablePool.sol:StablePool"}]},"transientStorageLayout":{"types":null,"storage":[]},"userdoc":{"kind":"user","errors":{"K()":[{"notice":"Thrown when the invariant K check fails after a swap"}],"KIsZero()":[{"notice":"Thrown after burn when remaining reserves cause `_k` to round to zero"}],"IsPaused()":[{"notice":"Thrown when an operation is attempted while the pool is paused"}],"InvalidTo()":[{"notice":"Thrown when the `to` address supplied to swap or burn is one of the pool's tokens"}],"ZeroAddress()":[{"notice":"Thrown when a zero address is supplied where a non-zero address is required"}],"BelowMinimumK()":[{"notice":"Thrown on first mint when `_k(amount0, amount1)` is less than or equal to `MINIMUM_K`"}],"NotAuthorized()":[{"notice":"Thrown when the caller is neither the account nor an approved claim operator"}],"ObservationOld()":[{"notice":"Thrown when a requested timestamp predates the oldest stored observation."}],"CannotCalculateY()":[{"notice":"Thrown when the Newton-Raphson search cannot solve for `y` within its iteration budget"}],"DepositsNotEqual()":[{"notice":"Thrown when the deposited amounts are not equal"}],"FactoryAlreadySet()":[{"notice":"Thrown when the factory address has already been set and cannot be changed"}],"InsufficientLiquidity()":[{"notice":"Thrown when the pool does not have enough liquidity to fulfil the operation"}],"InsufficientInputAmount()":[{"notice":"Thrown when the input amount provided to a swap is zero or insufficient"}],"InsufficientOutputAmount()":[{"notice":"Thrown when the output amount of a swap is zero or below the requested minimum"}],"InsufficientLiquidityBurned()":[{"notice":"Thrown when burning LP tokens would return zero of at least one underlying token"}],"InsufficientLiquidityMinted()":[{"notice":"Thrown when minting would produce zero LP tokens"}]},"events":{"Sync(uint256,uint256)":{"notice":"Emitted when reserves are synced to the current balances"},"Fees(address,uint256,uint256)":{"notice":"Emitted when fees are claimed by a liquidity provider"},"ClaimApproval(address,address,bool)":{"notice":"Emitted when an account grants or revokes claim approval for an operator"},"Burn(address,address,uint256,uint256)":{"notice":"Emitted when liquidity is burned"},"Mint(address,address,uint256,uint256)":{"notice":"Emitted when liquidity is minted"},"Claim(address,address,address,uint256,uint256)":{"notice":"Emitted when accumulated fee tokens are claimed"},"Swap(address,address,uint256,uint256,uint256,uint256)":{"notice":"Emitted on every swap executed through the pool"},"IncreaseObservationCardinalityNext(address,uint16,uint16)":{"notice":"Emitted whenever `observationCardinalityNext` is increased"}},"notice":"Aerodrome V2 stable-swap pool.","methods":{"getK()":{"notice":"Returns the value of K in the Pool, based on its reserves."},"sync()":{"notice":"Force reserves to match balances"},"index0()":{"notice":"Accumulated fees of token0 (global)"},"index1()":{"notice":"Accumulated fees of token1 (global)"},"token0()":{"notice":"Address of token in the pool with the lower address value"},"token1()":{"notice":"Address of token in the pool with the higher address value"},"tokens()":{"notice":"Returns [token0, token1]"},"factory()":{"notice":"Address of PoolFactory that created this contract"},"metadata()":{"notice":"Returns the decimal (dec), reserves (r), and tokens (t) of token0 and token1"},"poolFees()":{"notice":"Address of linked PoolFees.sol"},"reserve0()":{"notice":"Amount of token0 in pool"},"reserve1()":{"notice":"Amount of token1 in pool"},"MINIMUM_K()":{"notice":"Minimum value of the stable-swap invariant"},"POOL_TYPE()":{"notice":"The pool type identifier"},"PERIOD_SIZE()":{"notice":"Period gate for new observations, in seconds. A new observation is written when more         than `PERIOD_SIZE` seconds have passed since the last one, so the smallest possible         spacing between two stored observations is `PERIOD_SIZE + 1` (i.e. 61 seconds at the         default value of 60)."},"burn(address)":{"notice":"This low-level function should be called from a contract which performs important safety checks         standard uniswap v2 implementation"},"getReserves()":{"notice":"Update reserves and, on the first call per block, price accumulators"},"mint(address)":{"notice":"This low-level function should be called by addLiquidity functions in Router.sol, which performs important safety checks         standard uniswap v2 implementation"},"skim(address)":{"notice":"Force balances to match reserves"},"setName(string)":{"notice":"Set pool name         Only callable by IPoolFactory(factory).poolAdmin()"},"observe(uint32[])":{"notice":"Returns the cumulative reserves as of each requested `secondsAgo`. Reverts when any         `secondsAgos[i]` predates the oldest stored observation."},"setSymbol(string)":{"notice":"Set pool symbol         Only callable by IPoolFactory(factory).poolAdmin()"},"claimFees(address)":{"notice":"Claims the caller's accumulated fees"},"claimable0(address)":{"notice":"Amount of unclaimed, but claimable tokens from fees of token0 for an LP"},"claimable1(address)":{"notice":"Amount of unclaimed, but claimable tokens from fees of token1 for an LP"},"observationBuffer()":{"notice":"Circular buffer of TWAP observations with its write index and cardinality metadata."},"blockTimestampLast()":{"notice":"Timestamp of last update to pool"},"pendingFees(address)":{"notice":"Returns accumulated but unclaimed fees for an account."},"observations(uint256)":{"notice":"Returns the observation at the given index"},"supplyIndex0(address)":{"notice":"Get an LP's relative index0 to index0"},"supplyIndex1(address)":{"notice":"Get an LP's relative index1 to index1"},"reserve0CumulativeLast()":{"notice":"Cumulative of reserve0 factoring in time elapsed"},"reserve1CumulativeLast()":{"notice":"Cumulative of reserve1 factoring in time elapsed"},"currentCumulativePrices()":{"notice":"Produces the cumulative price using counterfactuals to save gas and avoid a call to sync."},"claimFees(address,address)":{"notice":"Claims an account's accumulated fees"},"initialize(address,address)":{"notice":"Called on pool creation by the owning PoolFactory"},"approveForClaim(address,bool)":{"notice":"Grants or revokes an operator's permission to claim the caller's accumulated fees"},"getAmountOut(uint256,address)":{"notice":"Get the amount of tokenOut given the amount of tokenIn, charging only the base fee"},"approvedForClaim(address,address)":{"notice":"Whether an operator may claim an account's accumulated fees"},"swap(uint256,uint256,address,bytes)":{"notice":"This low-level function should be called from a contract which performs important safety checks"},"getAmountInWithTotalFee(uint256,address)":{"notice":"Get the amount of tokenIn required to receive the amount of tokenOut, charging the total fees"},"getAmountOutWithTotalFee(uint256,address)":{"notice":"Get the amount of tokenOut given the amount of tokenIn, charging the total fees"},"increaseObservationCardinalityNext(uint16)":{"notice":"Pre-allocates buffer slots increasing the buffer capacity"},"getAmountOut(uint256,address,uint256,uint256)":{"notice":"Quote `amountIn` of `tokenIn` against a custom reserve snapshot"}},"version":1},"devdoc":{"kind":"dev","title":"StablePool","errors":{"ERC20InvalidSender(address)":[{"params":{"sender":"Address whose tokens are being transferred."},"details":"Indicates a failure with the token `sender`. Used in transfers."}],"ERC20InvalidSpender(address)":[{"params":{"spender":"Address that may be allowed to operate on tokens without being their owner."},"details":"Indicates a failure with the `spender` to be approved. Used in approvals."}],"ERC20InvalidApprover(address)":[{"params":{"approver":"Address initiating an approval operation."},"details":"Indicates a failure with the `approver` of a token to be approved. Used in approvals."}],"ERC20InvalidReceiver(address)":[{"params":{"receiver":"Address to which tokens are being transferred."},"details":"Indicates a failure with the token `receiver`. Used in transfers."}],"ReentrancyGuardReentrantCall()":[{"details":"Unauthorized reentrant call."}],"SafeERC20FailedOperation(address)":[{"details":"An operation with an ERC-20 token failed."}],"ERC20InsufficientBalance(address,uint256,uint256)":[{"params":{"needed":"Minimum amount required to perform a transfer.","sender":"Address whose tokens are being transferred.","balance":"Current balance for the interacting account."},"details":"Indicates an error related to the current `balance` of a `sender`. Used in transfers."}],"ERC20InsufficientAllowance(address,uint256,uint256)":[{"params":{"needed":"Minimum amount required to perform a transfer.","spender":"Address that may be allowed to operate on tokens without being their owner.","allowance":"Amount of tokens a `spender` is allowed to operate with."},"details":"Indicates a failure with the `spender`’s `allowance`. Used in transfers."}]},"events":{"Sync(uint256,uint256)":{"params":{"reserve0":"Updated reserve of token0","reserve1":"Updated reserve of token1"}},"Fees(address,uint256,uint256)":{"params":{"sender":"Address that triggered the fee claim","amount0":"Amount of token0 fees collected","amount1":"Amount of token1 fees collected"}},"Approval(address,address,uint256)":{"details":"Emitted when the allowance of a `spender` for an `owner` is set by a call to {approve}. `value` is the new allowance."},"Transfer(address,address,uint256)":{"details":"Emitted when `value` tokens are moved from one account (`from`) to another (`to`). Note that `value` may be zero."},"ClaimApproval(address,address,bool)":{"params":{"account":"Account whose approval state changed","approved":"New approval state","operator":"Operator being approved or revoked"}},"Burn(address,address,uint256,uint256)":{"params":{"to":"Address that received the underlying tokens","sender":"Address that initiated the burn","amount0":"Amount of token0 returned","amount1":"Amount of token1 returned"}},"Mint(address,address,uint256,uint256)":{"params":{"to":"Address that received the LP tokens","sender":"Address that initiated the mint","amount0":"Amount of token0 deposited","amount1":"Amount of token1 deposited"}},"Claim(address,address,address,uint256,uint256)":{"params":{"caller":"Address that triggered the claim","account":"Address whose accumulated fees were claimed","amount0":"Amount of token0 claimed","amount1":"Amount of token1 claimed","recipient":"Address that received the fee tokens"}},"Swap(address,address,uint256,uint256,uint256,uint256)":{"params":{"to":"Address that received the output tokens","sender":"Address that initiated the swap","amount0In":"Amount of token0 provided as input","amount1In":"Amount of token1 provided as input","amount0Out":"Amount of token0 sent as output","amount1Out":"Amount of token1 sent as output"}},"IncreaseObservationCardinalityNext(address,uint16,uint16)":{"params":{"caller":"Address that triggered the cardinality growth","observationCardinalityNextNew":"New value of `observationCardinalityNext`","observationCardinalityNextOld":"Previous value of `observationCardinalityNext`"}}},"methods":{"name()":{"details":"Returns the name of the token."},"symbol()":{"details":"Returns the symbol of the token, usually a shorter version of the name."},"decimals()":{"details":"Returns the number of decimals used to get its user representation. For example, if `decimals` equals `2`, a balance of `505` tokens should be displayed to a user as `5.05` (`505 / 10 ** 2`). Tokens usually opt for a value of 18, imitating the relationship between Ether and Wei. This is the default value returned by this function, unless it's overridden. NOTE: This information is only used for _display_ purposes: it in no way affects any of the arithmetic of the contract, including {IERC20-balanceOf} and {IERC20-transfer}."},"burn(address)":{"params":{"to":"Address to receive token0 and token1 from burning the pool token"},"returns":{"amount0":"Amount of token0 returned","amount1":"Amount of token1 returned"}},"getReserves()":{"returns":{"_reserve0":".","_reserve1":".","_blockTimestampLast":"."}},"mint(address)":{"params":{"to":"Address to receive the minted LP token"},"returns":{"liquidity":"Amount of LP token minted"}},"skim(address)":{"params":{"to":"Address to receive any skimmed rewards"}},"totalSupply()":{"details":"Returns the value of tokens in existence."},"setName(string)":{"params":{"__name":"String of new name"}},"observe(uint32[])":{"params":{"secondsAgos":"Array of seconds offsets from `block.timestamp` to query"},"details":"Offsets between two stored observations are linearly interpolated. Observations are      period-gated, so reserve changes within an interval may go unrecorded, making the      interpolation an approximation. Read from the pool directly when an exact value is required.A point newer than the newest stored observation is estimated from the current cumulative      instead of two stored ones, so a trade after that point can change what it reads. It stops      changing once an observation is stored at or after that point. Points that already fall      between two stored observations read the same on every call.","returns":{"_reserve0Cumulatives":"Cumulative reserve0 values at each requested point","_reserve1Cumulatives":"Cumulative reserve1 values at each requested point"}},"setSymbol(string)":{"params":{"__symbol":"String of new symbol"}},"balanceOf(address)":{"details":"Returns the value of tokens owned by `account`."},"claimFees(address)":{"params":{"_recipient":"Address that receives the claimed fee tokens"},"returns":{"_0":"Amount of token0 claimed","_1":"Amount of token1 claimed"}},"pendingFees(address)":{"params":{"_account":"Address to query."},"returns":{"_amount0":"Pending token0 fees.","_amount1":"Pending token1 fees."}},"observations(uint256)":{"params":{"index":"Index of the observation to return"},"returns":{"timestamp":"Timestamp of the observation","reserve0Cumulative":"Cumulative reserve0 of the observation","reserve1Cumulative":"Cumulative reserve1 of the observation"}},"approve(address,uint256)":{"details":"See {IERC20-approve}. NOTE: If `value` is the maximum `uint256`, the allowance is not updated on `transferFrom`. This is semantically equivalent to an infinite approval. Requirements: - `spender` cannot be the zero address."},"transfer(address,uint256)":{"details":"See {IERC20-transfer}. Requirements: - `to` cannot be the zero address. - the caller must have a balance of at least `value`."},"allowance(address,address)":{"details":"Returns the remaining number of tokens that `spender` will be allowed to spend on behalf of `owner` through {transferFrom}. This is zero by default. This value changes when {approve} or {transferFrom} are called."},"claimFees(address,address)":{"params":{"_account":"Account whose accumulated fees are claimed","_recipient":"Address that receives the claimed fee tokens"},"details":"The caller must be `_account` or an operator approved by `_account`","returns":{"_0":"Amount of token0 claimed","_1":"Amount of token1 claimed"}},"initialize(address,address)":{"params":{"_token0":"Address of token0","_token1":"Address of token1"}},"approveForClaim(address,bool)":{"params":{"_approved":"Whether the operator is approved","_operator":"Operator whose approval is updated"}},"getAmountOut(uint256,address)":{"params":{"tokenIn":"Address of token","amountIn":"Amount of token in"},"details":"Does not charge the MEV tax, so the result can be higher than what `swap` pays out.      Use `getAmountOutWithTotalFee` to quote a swap.","returns":{"_0":"Amount out"}},"swap(uint256,uint256,address,bytes)":{"params":{"to":"Address to recieve the swapped output","data":"Additional calldata for flashloans","amount0Out":"Amount of token0 to send to `to`","amount1Out":"Amount of token1 to send to `to`"}},"transferFrom(address,address,uint256)":{"details":"See {IERC20-transferFrom}. Skips emitting an {Approval} event indicating an allowance update. This is not required by the ERC. See {xref-ERC20-_approve-address-address-uint256-bool-}[_approve]. NOTE: Does not update the allowance if the current allowance is the maximum `uint256`. Requirements: - `from` and `to` cannot be the zero address. - `from` must have a balance of at least `value`. - the caller must have allowance for ``from``'s tokens of at least `value`."},"getAmountInWithTotalFee(uint256,address)":{"params":{"tokenOut":"Address of token out","amountOut":"Amount of token out to receive"},"details":"Reverts if the exact output cannot be calculated","returns":{"_0":"Amount in, fee included"}},"getAmountOutWithTotalFee(uint256,address)":{"params":{"tokenIn":"Address of token in","amountIn":"Amount of token in"},"returns":{"_0":"Amount out"}},"increaseObservationCardinalityNext(uint16)":{"params":{"_observationCardinalityNext":"New target capacity. At most 65,535."},"details":"Pre-initialises buffer slots so observation writes hit warm storage."},"getAmountOut(uint256,address,uint256,uint256)":{"params":{"tokenIn":"Address of the input token","amountIn":"Input amount in the smallest unit of `tokenIn`","_reserve0":"Reserve of token0 to quote against","_reserve1":"Reserve of token1 to quote against"},"details":"Subtracts the base fee from `amountIn` before applying the curve. Does not charge the MEV      tax, so use `getAmountOutWithTotalFee` to quote a swap.","returns":{"_0":"Output amount the swap would produce against the supplied reserves"}}},"version":1,"stateVariables":{"POOL_TYPE":{"return":"The pool type label to be able to identify the type of pool","returns":{"_0":"The pool type label to be able to identify the type of pool"}}}},"sourceIds":{"V3/src/pools/Pool.sol":{"id":6},"V3/src/pools/PoolFees.sol":{"id":7},"V3/src/pools/StablePool.sol":{"id":8},"V3/src/libraries/PoolOracle.sol":{"id":5},"V3/src/interfaces/pools/IPool.sol":{"id":1},"V3/src/interfaces/pools/IPoolCallee.sol":{"id":2},"V3/src/interfaces/pools/IStablePool.sol":{"id":3},"V3/src/interfaces/pools/tape/IPoolTape.sol":{"id":4},"V3/src/interfaces/factories/IPoolFactory.sol":{"id":0},"node_modules/@openzeppelin/contracts/utils/Panic.sol":{"id":18},"node_modules/@openzeppelin/contracts/utils/Context.sol":{"id":17},"node_modules/@openzeppelin/contracts/utils/math/Math.sol":{"id":22},"node_modules/@openzeppelin/contracts/interfaces/IERC20.sol":{"id":11},"node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol":{"id":13},"node_modules/@openzeppelin/contracts/utils/StorageSlot.sol":{"id":20},"node_modules/@openzeppelin/contracts/interfaces/IERC165.sol":{"id":10},"node_modules/@openzeppelin/contracts/token/ERC20/IERC20.sol":{"id":14},"node_modules/@openzeppelin/contracts/interfaces/IERC1363.sol":{"id":9},"node_modules/@openzeppelin/contracts/utils/math/SafeCast.sol":{"id":23},"node_modules/@openzeppelin/contracts/utils/ReentrancyGuard.sol":{"id":19},"node_modules/@openzeppelin/contracts/interfaces/draft-IERC6093.sol":{"id":12},"node_modules/@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol":{"id":16},"node_modules/@openzeppelin/contracts/utils/introspection/IERC165.sol":{"id":21},"node_modules/@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol":{"id":15}},"additionalInput":null,"stdJsonInput":{"sources":{"V3/src/pools/Pool.sol":{"content":"// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity 0.8.36;\n\nimport {ERC20} from '@openzeppelin/contracts/token/ERC20/ERC20.sol';\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {ReentrancyGuard} from '@openzeppelin/contracts/utils/ReentrancyGuard.sol';\nimport {Math} from '@openzeppelin/contracts/utils/math/Math.sol';\n\nimport {PoolOracle} from 'V3/libraries/PoolOracle.sol';\n\nimport {IPoolFactory} from 'V3/interfaces/factories/IPoolFactory.sol';\nimport {IPool} from 'V3/interfaces/pools/IPool.sol';\nimport {IPoolCallee} from 'V3/interfaces/pools/IPoolCallee.sol';\nimport {IPoolTape} from 'V3/interfaces/pools/tape/IPoolTape.sol';\n\nimport {PoolFees} from 'V3/pools/PoolFees.sol';\n\n/// @title Pool\n/// @author velodrome.finance, Solidly, Uniswap Labs, @figs999, @pegahcarter\n/// @notice Abstract base for Aerodrome V2 token pools. Curve-specific math is supplied by child contracts.\nabstract contract Pool is IPool, ERC20, ReentrancyGuard {\n  using SafeERC20 for IERC20;\n  using PoolOracle for PoolOracle.ObservationBuffer;\n\n  /*////////////////////////////////////////////////////////////\n                              CONSTANTS\n  ////////////////////////////////////////////////////////////*/\n\n  /// @inheritdoc IPool\n  uint256 public constant PERIOD_SIZE = 1 minutes;\n  /// @notice The minimum liquidity for a pool\n  uint256 internal constant _MINIMUM_LIQUIDITY = 10 ** 3;\n  /// @notice Basis points scale used as the fee denominator (100%)\n  uint256 internal constant _MAX_BPS = 10_000;\n\n  /*////////////////////////////////////////////////////////////\n                              STORAGE\n  ////////////////////////////////////////////////////////////*/\n\n  /// @notice The name of the pool\n  // slither-disable-next-line shadowing-state\n  string private _name;\n  /// @notice The symbol of the pool\n  // slither-disable-next-line shadowing-state\n  string private _symbol;\n\n  /// @inheritdoc IPool\n  address public token0;\n  /// @inheritdoc IPool\n  address public token1;\n  /// @inheritdoc IPool\n  address public poolFees;\n  /// @inheritdoc IPool\n  address public factory;\n\n  /// @notice Circular buffer of TWAP observations with its write index and cardinality metadata.\n  PoolOracle.ObservationBuffer public observationBuffer;\n\n  /// @notice The number of decimals of token0\n  uint256 internal _decimals0;\n  /// @notice The number of decimals of token1\n  uint256 internal _decimals1;\n\n  /// @inheritdoc IPool\n  uint256 public reserve0;\n  /// @inheritdoc IPool\n  uint256 public reserve1;\n  /// @inheritdoc IPool\n  uint256 public blockTimestampLast;\n\n  /// @inheritdoc IPool\n  uint256 public reserve0CumulativeLast;\n  /// @inheritdoc IPool\n  uint256 public reserve1CumulativeLast;\n\n  /// @inheritdoc IPool\n  uint256 public index0;\n  /// @inheritdoc IPool\n  uint256 public index1;\n\n  /// @inheritdoc IPool\n  mapping(address => uint256) public supplyIndex0;\n  /// @inheritdoc IPool\n  mapping(address => uint256) public supplyIndex1;\n\n  /// @inheritdoc IPool\n  mapping(address => uint256) public claimable0;\n  /// @inheritdoc IPool\n  mapping(address => uint256) public claimable1;\n  /// @inheritdoc IPool\n  mapping(address _account => mapping(address _operator => bool _approved)) public approvedForClaim;\n\n  /*////////////////////////////////////////////////////////////\n                          CONSTRUCTOR\n  ////////////////////////////////////////////////////////////*/\n\n  constructor() ERC20('', '') {}\n\n  /*////////////////////////////////////////////////////////////\n                  EXTERNAL WRITE FUNCTIONS\n  ////////////////////////////////////////////////////////////*/\n\n  /// @inheritdoc IPool\n  function approveForClaim(address _operator, bool _approved) external {\n    if (_operator == address(0)) revert ZeroAddress();\n    approvedForClaim[msg.sender][_operator] = _approved;\n    emit ClaimApproval(msg.sender, _operator, _approved);\n  }\n\n  /// @inheritdoc IPool\n  function claimFees(address _recipient) external returns (uint256, uint256) {\n    if (_recipient == address(0)) revert ZeroAddress();\n    return _claimFees(msg.sender, _recipient);\n  }\n\n  /// @inheritdoc IPool\n  function claimFees(address _account, address _recipient) external returns (uint256, uint256) {\n    if (_recipient == address(0)) revert ZeroAddress();\n    if (msg.sender != _account && !approvedForClaim[_account][msg.sender]) revert NotAuthorized();\n    return _claimFees(_account, _recipient);\n  }\n\n  /// @inheritdoc IPool\n  function getK() external nonReentrant returns (uint256) {\n    return _k(reserve0, reserve1);\n  }\n\n  /// @inheritdoc IPool\n  function setName(string calldata __name) external {\n    if (msg.sender != IPoolFactory(factory).poolAdmin()) revert IPoolFactory.NotPoolAdmin();\n    _name = __name;\n  }\n\n  /// @inheritdoc IPool\n  function setSymbol(string calldata __symbol) external {\n    if (msg.sender != IPoolFactory(factory).poolAdmin()) revert IPoolFactory.NotPoolAdmin();\n    _symbol = __symbol;\n  }\n\n  // slither-disable-start reentrancy-no-eth\n  /// @inheritdoc IPool\n  function swap(uint256 amount0Out, uint256 amount1Out, address to, bytes calldata data) external nonReentrant {\n    if (IPoolFactory(factory).isPaused()) revert IsPaused();\n    if (amount0Out == 0 && amount1Out == 0) revert InsufficientOutputAmount();\n    (uint256 _reserve0, uint256 _reserve1) = (reserve0, reserve1);\n    if (amount0Out >= _reserve0 || amount1Out >= _reserve1) revert InsufficientLiquidity();\n\n    uint256 _balance0;\n    uint256 _balance1;\n    {\n      // scope for _token{0,1}, avoids stack too deep errors\n      (address _token0, address _token1) = (token0, token1);\n      if (to == _token0 || to == _token1) revert InvalidTo();\n      if (amount0Out > 0) IERC20(_token0).safeTransfer(to, amount0Out); // optimistically transfer tokens\n      if (amount1Out > 0) IERC20(_token1).safeTransfer(to, amount1Out); // optimistically transfer tokens\n      if (data.length > 0) IPoolCallee(to).hook(msg.sender, amount0Out, amount1Out, data); // callback, used for flash loans\n      _balance0 = IERC20(_token0).balanceOf(address(this));\n      _balance1 = IERC20(_token1).balanceOf(address(this));\n    }\n    uint256 amount0In = _balance0 > _reserve0 - amount0Out ? _balance0 - (_reserve0 - amount0Out) : 0;\n    uint256 amount1In = _balance1 > _reserve1 - amount1Out ? _balance1 - (_reserve1 - amount1Out) : 0;\n    if (amount0In == 0 && amount1In == 0) revert InsufficientInputAmount();\n    {\n      // scope for reserve{0,1}Adjusted, avoids stack too deep errors\n      // slither-disable-next-line uninitialized-local\n      IPoolTape.PoolTapeData memory _tapeData;\n      _tapeData.volume0 = uint128(amount0In + amount0Out);\n      _tapeData.volume1 = uint128(amount1In + amount1Out);\n      (address _token0, address _token1) = (token0, token1);\n      // Calls _getSwapFee to avoid stack too dep errors\n      (uint256 _fee, uint256 _mevFee, bool _toxic) = _getSwapFee(amount0In, amount1In, _reserve0, _reserve1);\n      if (amount0In > 0) {\n        uint256 _feeAmount0 = (amount0In * _fee) / _MAX_BPS;\n        _update0(_feeAmount0);\n        _tapeData.fee0 = uint128(_feeAmount0);\n        _tapeData.mevFee0 = uint128((amount0In * _mevFee) / _MAX_BPS);\n      }\n      if (amount1In > 0) {\n        uint256 _feeAmount1 = (amount1In * _fee) / _MAX_BPS;\n        _update1(_feeAmount1);\n        _tapeData.fee1 = uint128(_feeAmount1);\n        _tapeData.mevFee1 = uint128((amount1In * _mevFee) / _MAX_BPS);\n      }\n      if (_toxic) {\n        _tapeData.mevVolume0 = _tapeData.volume0;\n        _tapeData.mevVolume1 = _tapeData.volume1;\n      }\n      // since we removed tokens, we need to reconfirm balances\n      _balance0 = IERC20(_token0).balanceOf(address(this));\n      _balance1 = IERC20(_token1).balanceOf(address(this));\n      // The curve invariant, supplied by the child contract\n      if (_k(_balance0, _balance1) < _k(_reserve0, _reserve1)) revert K();\n      IPoolFactory(factory).recordPoolTape(_tapeData);\n    }\n\n    _update(_balance0, _balance1, _reserve0, _reserve1);\n    emit Swap(msg.sender, to, amount0In, amount1In, amount0Out, amount1Out);\n  }\n\n  // slither-disable-end reentrancy-no-eth\n  /// @inheritdoc IPool\n  function burn(address to) external nonReentrant returns (uint256 amount0, uint256 amount1) {\n    (uint256 _reserve0, uint256 _reserve1) = (reserve0, reserve1);\n    (address _token0, address _token1) = (token0, token1);\n    uint256 _balance0 = IERC20(_token0).balanceOf(address(this));\n    uint256 _balance1 = IERC20(_token1).balanceOf(address(this));\n    uint256 _liquidity = balanceOf(address(this));\n\n    uint256 _totalSupply = totalSupply(); // gas savings, must be defined here since totalSupply can update in _mintFee\n    amount0 = (_liquidity * _balance0) / _totalSupply; // using balances ensures pro-rata distribution\n    amount1 = (_liquidity * _balance1) / _totalSupply; // using balances ensures pro-rata distribution\n    if (amount0 == 0 || amount1 == 0) revert InsufficientLiquidityBurned();\n    _burn(address(this), _liquidity);\n    IERC20(_token0).safeTransfer(to, amount0);\n    IERC20(_token1).safeTransfer(to, amount1);\n    _balance0 = IERC20(_token0).balanceOf(address(this));\n    _balance1 = IERC20(_token1).balanceOf(address(this));\n\n    _kThresholdValidation(_balance0, _balance1);\n\n    _update(_balance0, _balance1, _reserve0, _reserve1);\n    emit Burn(msg.sender, to, amount0, amount1);\n  }\n\n  /// @inheritdoc IPool\n  function mint(address to) external nonReentrant returns (uint256 liquidity) {\n    (uint256 _reserve0, uint256 _reserve1) = (reserve0, reserve1);\n    uint256 _balance0 = IERC20(token0).balanceOf(address(this));\n    uint256 _balance1 = IERC20(token1).balanceOf(address(this));\n    uint256 _amount0 = _balance0 - _reserve0;\n    uint256 _amount1 = _balance1 - _reserve1;\n\n    uint256 _totalSupply = totalSupply(); // gas savings, must be defined here since totalSupply can update in _mintFee\n    if (_totalSupply == 0) {\n      liquidity = Math.sqrt(_amount0 * _amount1) - _MINIMUM_LIQUIDITY;\n      _mint(address(1), _MINIMUM_LIQUIDITY); // permanently lock the first _MINIMUM_LIQUIDITY tokens - cannot be address(0)\n      _mintValidation(_amount0, _amount1);\n      if (liquidity < _MINIMUM_LIQUIDITY) revert InsufficientLiquidityMinted();\n    } else {\n      liquidity = Math.min((_amount0 * _totalSupply) / _reserve0, (_amount1 * _totalSupply) / _reserve1);\n      if (liquidity == 0) revert InsufficientLiquidityMinted();\n    }\n    _mint(to, liquidity);\n\n    _update(_balance0, _balance1, _reserve0, _reserve1);\n    emit Mint(msg.sender, to, _amount0, _amount1);\n  }\n\n  /// @inheritdoc IPool\n  function skim(address to) external nonReentrant {\n    (address _token0, address _token1) = (token0, token1);\n    uint256 _excess0 = IERC20(_token0).balanceOf(address(this)) - reserve0;\n    if (_excess0 > 0) IERC20(_token0).safeTransfer(to, _excess0);\n    uint256 _excess1 = IERC20(_token1).balanceOf(address(this)) - reserve1;\n    if (_excess1 > 0) IERC20(_token1).safeTransfer(to, _excess1);\n  }\n\n  /// @inheritdoc IPool\n  function sync() external nonReentrant {\n    if (totalSupply() == 0) revert InsufficientLiquidity();\n    _update(IERC20(token0).balanceOf(address(this)), IERC20(token1).balanceOf(address(this)), reserve0, reserve1);\n  }\n\n  /// @inheritdoc IPool\n  function initialize(address _token0, address _token1) external {\n    if (factory != address(0)) revert FactoryAlreadySet();\n    factory = msg.sender;\n    (token0, token1) = (_token0, _token1);\n    poolFees = address(new PoolFees(_token0, _token1));\n    string memory symbol0 = ERC20(_token0).symbol();\n    string memory symbol1 = ERC20(_token1).symbol();\n    _name = _poolName(symbol0, symbol1);\n    _symbol = _poolSymbol(symbol0, symbol1);\n\n    _decimals0 = 10 ** ERC20(_token0).decimals();\n    _decimals1 = 10 ** ERC20(_token1).decimals();\n\n    observationBuffer.initialize();\n  }\n\n  /// @inheritdoc IPool\n  /// @dev Pre-initialises buffer slots so observation writes hit warm storage.\n  function increaseObservationCardinalityNext(uint16 _observationCardinalityNext) external {\n    uint16 _currentCardinalityNext = observationBuffer.cardinalityNext;\n    uint16 _updatedCardinalityNext = observationBuffer.grow(_observationCardinalityNext);\n    if (_updatedCardinalityNext != _currentCardinalityNext) {\n      emit IncreaseObservationCardinalityNext(msg.sender, _currentCardinalityNext, _updatedCardinalityNext);\n    }\n  }\n\n  /*////////////////////////////////////////////////////////////\n                        INTERNAL FUNCTIONS\n  ////////////////////////////////////////////////////////////*/\n\n  /// @dev Claims `_account`'s accumulated fees to `_recipient`.\n  function _claimFees(address _account, address _recipient) internal returns (uint256 _claimed0, uint256 _claimed1) {\n    _updateFor(_account);\n\n    _claimed0 = claimable0[_account];\n    _claimed1 = claimable1[_account];\n\n    if (_claimed0 > 0 || _claimed1 > 0) {\n      delete claimable0[_account];\n      delete claimable1[_account];\n\n      PoolFees(poolFees).claimFeesFor({_recipient: _recipient, _amount0: _claimed0, _amount1: _claimed1});\n\n      emit Claim({caller: msg.sender, account: _account, recipient: _recipient, amount0: _claimed0, amount1: _claimed1});\n    }\n  }\n\n  /// @dev Accrue fees on token0\n  function _update0(uint256 amount) internal {\n    // Only update on this pool if there is a fee\n    if (amount == 0) return;\n    IERC20(token0).safeTransfer(poolFees, amount); // transfer the fees out to PoolFees\n    uint256 _ratio = (amount * 1e18) / totalSupply(); // 1e18 adjustment is removed during claim\n    if (_ratio > 0) {\n      index0 += _ratio;\n    }\n    emit Fees(msg.sender, amount, 0);\n  }\n\n  /// @dev Accrue fees on token1\n  function _update1(uint256 amount) internal {\n    // Only update on this pool if there is a fee\n    if (amount == 0) return;\n    IERC20(token1).safeTransfer(poolFees, amount);\n    uint256 _ratio = (amount * 1e18) / totalSupply();\n    if (_ratio > 0) {\n      index1 += _ratio;\n    }\n    emit Fees(msg.sender, 0, amount);\n  }\n\n  /// @dev This function MUST be called on any balance changes, otherwise can be used to infinitely claim fees\n  ///      Fees are segregated from core funds, so fees can never put liquidity at risk.\n  function _updateFor(address recipient) internal {\n    uint256 _supplied = balanceOf(recipient); // get LP balance of `recipient`\n    if (_supplied > 0) {\n      uint256 _supplyIndex0 = supplyIndex0[recipient]; // get last adjusted index0 for recipient\n      uint256 _supplyIndex1 = supplyIndex1[recipient];\n      uint256 _index0 = index0; // get global index0 for accumulated fees\n      uint256 _index1 = index1;\n      supplyIndex0[recipient] = _index0; // update user current position to global position\n      supplyIndex1[recipient] = _index1;\n      uint256 _delta0 = _index0 - _supplyIndex0; // see if there is any difference that need to be accrued\n      uint256 _delta1 = _index1 - _supplyIndex1;\n      if (_delta0 > 0) {\n        uint256 _share = (_supplied * _delta0) / 1e18; // add accrued difference for each supplied token\n        claimable0[recipient] += _share;\n      }\n      if (_delta1 > 0) {\n        uint256 _share = (_supplied * _delta1) / 1e18;\n        claimable1[recipient] += _share;\n      }\n    } else {\n      supplyIndex0[recipient] = index0; // new users are set to the default global state\n      supplyIndex1[recipient] = index1;\n    }\n  }\n\n  /// @notice Commits new balances to reserves and writes a new observation when due.\n  /// @dev Cumulative accumulators advance by `_reserve* * timeElapsed` when previous reserves were\n  ///      nonzero. The observation write is delegated to `PoolOracle.write`, which advances the buffer\n  ///      only when more than `PERIOD_SIZE` has elapsed since the newest observation.\n  /// @param  balance0 New token0 balance.\n  /// @param  balance1 New token1 balance.\n  /// @param  _reserve0 Previous token0 reserve\n  /// @param  _reserve1 Previous token1 reserve\n  function _update(uint256 balance0, uint256 balance1, uint256 _reserve0, uint256 _reserve1) internal {\n    uint256 blockTimestamp = block.timestamp;\n    uint256 timeElapsed = blockTimestamp - blockTimestampLast;\n    if (timeElapsed > 0 && _reserve0 != 0 && _reserve1 != 0) {\n      reserve0CumulativeLast += _reserve0 * timeElapsed;\n      reserve1CumulativeLast += _reserve1 * timeElapsed;\n    }\n\n    observationBuffer.write(reserve0CumulativeLast, reserve1CumulativeLast, PERIOD_SIZE);\n\n    reserve0 = balance0;\n    reserve1 = balance1;\n    blockTimestampLast = blockTimestamp;\n    emit Sync(balance0, balance1);\n  }\n\n  /// @dev Resolves the swap fee via the factory.\n  function _getSwapFee(\n    uint256 _amount0In,\n    uint256 _amount1In,\n    uint256 _reserve0,\n    uint256 _reserve1\n  ) internal view returns (uint256 _fee, uint256 _mevFee, bool _toxic) {\n    // slither-disable-next-line unused-return\n    return IPoolFactory(factory).getFee(address(this), msg.sender, _amount0In, _amount1In, _reserve0, _reserve1);\n  }\n\n  /// @dev Curve invariant. The child contract supplies either the constant-product or\n  ///      stable-swap formula.\n  function _k(uint256 x, uint256 y) internal view virtual returns (uint256);\n\n  /// @dev Output amount given an input and reserve snapshot. The child contract supplies\n  ///      the curve-specific pricing.\n  function _getAmountOut(\n    uint256 amountIn,\n    address tokenIn,\n    uint256 _reserve0,\n    uint256 _reserve1\n  ) internal view virtual returns (uint256);\n\n  /// @dev Input amount required for a requested output, before the swap fee. The child contract\n  ///      supplies the curve-specific pricing.\n  /// @param  amountOut The output amount to receive\n  /// @param  tokenOut The output token\n  /// @param  _reserve0 The token0 reserve to quote against\n  /// @param  _reserve1 The token1 reserve to quote against\n  /// @return The input amount before the fee\n  function _getAmountIn(\n    uint256 amountOut,\n    address tokenOut,\n    uint256 _reserve0,\n    uint256 _reserve1\n  ) internal view virtual returns (uint256);\n\n  /// @dev Curve-specific validation invoked on the first mint.\n  function _mintValidation(uint256 _amount0, uint256 _amount1) internal view virtual {}\n\n  /// @dev Curve-specific post-burn check on remaining reserves\n  function _kThresholdValidation(uint256 _x, uint256 _y) internal view virtual {}\n\n  /// @dev Curve-specific full pool name used during initialization.\n  function _poolName(string memory _symbol0, string memory _symbol1) internal pure virtual returns (string memory);\n\n  /// @dev Curve-specific full pool symbol used during initialization.\n  function _poolSymbol(string memory _symbol0, string memory _symbol1) internal pure virtual returns (string memory);\n\n  function _update(address from, address to, uint256 amount) internal override {\n    if (from != address(0)) _updateFor(from);\n    if (to != address(0)) _updateFor(to);\n    super._update(from, to, amount);\n  }\n\n  /*////////////////////////////////////////////////////////////\n                      VIEW & PURE FUNCTIONS\n  ////////////////////////////////////////////////////////////*/\n\n  /// @inheritdoc IPool\n  function pendingFees(address _account) external view returns (uint256 _amount0, uint256 _amount1) {\n    _amount0 = claimable0[_account];\n    _amount1 = claimable1[_account];\n\n    uint256 _supplied = balanceOf(_account);\n    if (_supplied > 0) {\n      _amount0 += (_supplied * (index0 - supplyIndex0[_account])) / 1e18;\n      _amount1 += (_supplied * (index1 - supplyIndex1[_account])) / 1e18;\n    }\n  }\n\n  /// @inheritdoc IPool\n  function metadata()\n    external\n    view\n    returns (uint256 dec0, uint256 dec1, uint256 r0, uint256 r1, address t0, address t1)\n  {\n    return (_decimals0, _decimals1, reserve0, reserve1, token0, token1);\n  }\n\n  /// @inheritdoc IPool\n  function tokens() external view returns (address, address) {\n    return (token0, token1);\n  }\n\n  /// @inheritdoc IPool\n  function observe(uint32[] calldata _secondsAgos)\n    external\n    view\n    returns (uint256[] memory _reserve0Cumulatives, uint256[] memory _reserve1Cumulatives)\n  {\n    (uint256 _r0Now, uint256 _r1Now,) = currentCumulativePrices();\n    // slither-disable-next-line unused-return\n    return observationBuffer.observe(_secondsAgos, _r0Now, _r1Now);\n  }\n\n  /// @inheritdoc IPool\n  function observations(uint256 _index)\n    external\n    view\n    returns (uint32 timestamp, uint256 reserve0Cumulative, uint256 reserve1Cumulative)\n  {\n    PoolOracle.Observation memory _observation = observationBuffer.observations[_index];\n    return (_observation.timestamp, _observation.reserve0Cumulative, _observation.reserve1Cumulative);\n  }\n\n  /// @inheritdoc IPool\n  function getAmountOut(\n    uint256 amountIn,\n    address tokenIn,\n    uint256 _reserve0,\n    uint256 _reserve1\n  ) external view returns (uint256) {\n    (uint256 _amount0In, uint256 _amount1In) = tokenIn == token0 ? (amountIn, uint256(0)) : (uint256(0), amountIn);\n    amountIn -= (amountIn\n        * IPoolFactory(factory).getBaseFee(address(this), address(0), _amount0In, _amount1In, _reserve0, _reserve1))\n      / _MAX_BPS;\n    return _getAmountOut(amountIn, tokenIn, _reserve0, _reserve1);\n  }\n\n  /// @inheritdoc IPool\n  function currentCumulativePrices()\n    public\n    view\n    returns (uint256 reserve0Cumulative, uint256 reserve1Cumulative, uint256 blockTimestamp)\n  {\n    blockTimestamp = block.timestamp;\n    reserve0Cumulative = reserve0CumulativeLast;\n    reserve1Cumulative = reserve1CumulativeLast;\n\n    // if time has elapsed since the last update on the pool, mock the accumulated price values\n    (uint256 _reserve0, uint256 _reserve1, uint256 _blockTimestampLast) = getReserves();\n    if (_blockTimestampLast != blockTimestamp) {\n      // subtraction overflow is desired\n      uint256 timeElapsed = blockTimestamp - _blockTimestampLast;\n      reserve0Cumulative += _reserve0 * timeElapsed;\n      reserve1Cumulative += _reserve1 * timeElapsed;\n    }\n  }\n\n  /// @inheritdoc IPool\n  function getReserves() public view returns (uint256 _reserve0, uint256 _reserve1, uint256 _blockTimestampLast) {\n    _reserve0 = reserve0;\n    _reserve1 = reserve1;\n    _blockTimestampLast = blockTimestampLast;\n  }\n\n  /// @inheritdoc IPool\n  function getAmountOut(uint256 amountIn, address tokenIn) external view returns (uint256) {\n    (uint256 _reserve0, uint256 _reserve1) = (reserve0, reserve1);\n    (uint256 _amount0In, uint256 _amount1In) = tokenIn == token0 ? (amountIn, uint256(0)) : (uint256(0), amountIn);\n    // remove fee from amount received\n    amountIn -= (amountIn\n        * IPoolFactory(factory).getBaseFee(address(this), address(0), _amount0In, _amount1In, _reserve0, _reserve1))\n      / _MAX_BPS;\n    return _getAmountOut(amountIn, tokenIn, _reserve0, _reserve1);\n  }\n\n  /// @inheritdoc IPool\n  function getAmountOutWithTotalFee(uint256 amountIn, address tokenIn) external view returns (uint256) {\n    (uint256 _reserve0, uint256 _reserve1) = (reserve0, reserve1);\n    (uint256 _amount0In, uint256 _amount1In) = tokenIn == token0 ? (amountIn, uint256(0)) : (uint256(0), amountIn);\n    (uint256 _fee,,) = _getSwapFee(_amount0In, _amount1In, _reserve0, _reserve1);\n    // remove fee from amount received\n    amountIn -= (amountIn * _fee) / _MAX_BPS;\n    return _getAmountOut(amountIn, tokenIn, _reserve0, _reserve1);\n  }\n\n  /// @inheritdoc IPool\n  function getAmountInWithTotalFee(uint256 amountOut, address tokenOut) external view returns (uint256) {\n    if (amountOut == 0) return 0;\n    (uint256 _reserve0, uint256 _reserve1) = (reserve0, reserve1);\n    if (amountOut >= (tokenOut == token0 ? _reserve0 : _reserve1)) revert InsufficientLiquidity();\n\n    uint256 _amountInAfterFee = _getAmountIn(amountOut, tokenOut, _reserve0, _reserve1);\n\n    // this sanity check prevents underflow while calculating the grossed up input.\n    // a swap with amount zero will revert due to insufficient liquidity.\n    if (_amountInAfterFee == 0) return 0;\n\n    (uint256 _amount0In, uint256 _amount1In) =\n      tokenOut == token0 ? (uint256(0), _amountInAfterFee) : (_amountInAfterFee, uint256(0));\n    uint256 _fee =\n      IPoolFactory(factory).getFeeForAmountIn(address(this), msg.sender, _amount0In, _amount1In, _reserve0, _reserve1);\n    return _amountInAfterFee + Math.mulDiv(_fee, _amountInAfterFee - 1, _MAX_BPS - _fee);\n  }\n\n  function name() public view override returns (string memory) {\n    return _name;\n  }\n\n  function symbol() public view override returns (string memory) {\n    return _symbol;\n  }\n}\n"},"V3/src/pools/PoolFees.sol":{"content":"// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity 0.8.36;\n\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\n\n/// @title PoolFees\n/// @author velodrome.finance, Solidly\n/// @notice Ensures curve does not need to be modified for LP shares.\ncontract PoolFees {\n  using SafeERC20 for IERC20;\n\n  address internal immutable pool; // The pool it is bonded to\n  address internal immutable token0; // token0 of pool, saved localy and statically for gas optimization\n  address internal immutable token1; // Token1 of pool, saved localy and statically for gas optimization\n\n  error NotPool();\n\n  constructor(address _token0, address _token1) {\n    pool = msg.sender;\n    token0 = _token0;\n    token1 = _token1;\n  }\n\n  /// @notice Allow the pool to transfer fees to users\n  function claimFeesFor(address _recipient, uint256 _amount0, uint256 _amount1) external {\n    if (msg.sender != pool) revert NotPool();\n    if (_amount0 > 0) IERC20(token0).safeTransfer(_recipient, _amount0);\n    if (_amount1 > 0) IERC20(token1).safeTransfer(_recipient, _amount1);\n  }\n}\n"},"V3/src/pools/StablePool.sol":{"content":"// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity 0.8.36;\n\nimport {Math} from '@openzeppelin/contracts/utils/math/Math.sol';\n\nimport {IPool} from 'V3/interfaces/pools/IPool.sol';\nimport {IStablePool} from 'V3/interfaces/pools/IStablePool.sol';\n\nimport {Pool} from 'V3/pools/Pool.sol';\n\n/// @title StablePool\n/// @notice Aerodrome V2 stable-swap pool.\ncontract StablePool is Pool, IStablePool {\n  /// @inheritdoc IStablePool\n  uint256 public constant MINIMUM_K = 10 ** 10;\n\n  /// @inheritdoc IPool\n  bytes32 public constant POOL_TYPE = 'V2_STABLE';\n\n  /// @inheritdoc Pool\n  function _getAmountOut(\n    uint256 _amountIn,\n    address _tokenIn,\n    uint256 _reserve0,\n    uint256 _reserve1\n  ) internal view override returns (uint256) {\n    uint256 _targetK = _k(_reserve0, _reserve1);\n    _reserve0 = (_reserve0 * 1e18) / _decimals0;\n    _reserve1 = (_reserve1 * 1e18) / _decimals1;\n    (uint256 _reserveA, uint256 _reserveB) = _tokenIn == token0 ? (_reserve0, _reserve1) : (_reserve1, _reserve0);\n    _amountIn = _tokenIn == token0 ? (_amountIn * 1e18) / _decimals0 : (_amountIn * 1e18) / _decimals1;\n    uint256 _amountOut = _reserveB - _getY(_amountIn + _reserveA, _targetK, _reserveB);\n    return (_amountOut * (_tokenIn == token0 ? _decimals1 : _decimals0)) / 1e18;\n  }\n\n  /// @inheritdoc Pool\n  function _getAmountIn(\n    uint256 _amountOut,\n    address _tokenOut,\n    uint256 _reserve0,\n    uint256 _reserve1\n  ) internal view override returns (uint256) {\n    uint256 _targetK = _k(_reserve0, _reserve1);\n    _reserve0 = (_reserve0 * 1e18) / _decimals0;\n    _reserve1 = (_reserve1 * 1e18) / _decimals1;\n    (uint256 _reserveOut, uint256 _reserveIn) = _tokenOut == token0 ? (_reserve0, _reserve1) : (_reserve1, _reserve0);\n    (uint256 _decimalsOut, uint256 _decimalsIn) =\n      _tokenOut == token0 ? (_decimals0, _decimals1) : (_decimals1, _decimals0);\n    _amountOut = Math.ceilDiv(_amountOut * 1e18, _decimalsOut);\n    if (_amountOut >= _reserveOut) revert InsufficientLiquidity();\n    uint256 _newReserveIn = _getY(_reserveOut - _amountOut, _targetK, _reserveIn);\n    return Math.ceilDiv((_newReserveIn - _reserveIn) * _decimalsIn, 1e18);\n  }\n\n  /// @inheritdoc Pool\n  function _k(uint256 _x, uint256 _y) internal view override returns (uint256) {\n    uint256 _scaledX = (_x * 1e18) / _decimals0;\n    uint256 _scaledY = (_y * 1e18) / _decimals1;\n    uint256 _a = Math.mulDiv(_scaledX, _scaledY, 1e18);\n    uint256 _b = Math.mulDiv(_scaledX, _scaledX, 1e18) + Math.mulDiv(_scaledY, _scaledY, 1e18);\n    return Math.mulDiv(_a, _b, 1e18); // x^3*y + y^3*x\n  }\n\n  /// @inheritdoc Pool\n  function _mintValidation(uint256 _amount0, uint256 _amount1) internal view override {\n    if ((_amount0 * 1e18) / _decimals0 != (_amount1 * 1e18) / _decimals1) revert DepositsNotEqual();\n    if (_k(_amount0, _amount1) <= MINIMUM_K) revert BelowMinimumK();\n  }\n\n  /// @inheritdoc Pool\n  function _kThresholdValidation(uint256 _x, uint256 _y) internal view override {\n    if (_k(_x, _y) == 0) revert KIsZero();\n  }\n\n  /// @inheritdoc Pool\n  function _poolName(string memory _symbol0, string memory _symbol1) internal pure override returns (string memory) {\n    return string(abi.encodePacked('StableV2 AMM - ', _symbol0, '/', _symbol1));\n  }\n\n  /// @inheritdoc Pool\n  function _poolSymbol(string memory _symbol0, string memory _symbol1) internal pure override returns (string memory) {\n    return string(abi.encodePacked('sAMMV2-', _symbol0, '/', _symbol1));\n  }\n\n  function _f(uint256 _x0, uint256 _y) private pure returns (uint256) {\n    uint256 _a = Math.mulDiv(_x0, _y, 1e18);\n    uint256 _b = Math.mulDiv(_x0, _x0, 1e18) + Math.mulDiv(_y, _y, 1e18);\n    return Math.mulDiv(_a, _b, 1e18);\n  }\n\n  function _d(uint256 _x0, uint256 _y) private pure returns (uint256) {\n    uint256 _ySquared = Math.mulDiv(_y, _y, 1e18);\n    uint256 _x0Squared = Math.mulDiv(_x0, _x0, 1e18);\n    return Math.mulDiv(3 * _x0, _ySquared, 1e18) + Math.mulDiv(_x0Squared, _x0, 1e18); // 3*x0*y^2 + x0^3\n  }\n\n  /// @dev Use Newton-Raphson to approximate the solution to `x^3*y + y^3*x >= k`.\n  function _getY(uint256 _x0, uint256 _targetK, uint256 _y) private pure returns (uint256) {\n    for (uint256 _i = 0; _i < 255; _i++) {\n      uint256 _currentK = _f(_x0, _y);\n      if (_currentK < _targetK) {\n        // dy == 0 means _d(_x0, _y) is too large compare to (_targetK - _currentK) and the rounding error\n        // screwed us. In this case, we need to increase y by 1\n        uint256 _dy = Math.mulDiv(_targetK - _currentK, 1e18, _d(_x0, _y));\n        if (_dy == 0) {\n          if (_f(_x0, _y + 1) > _targetK) {\n            // If _f(_x0, _y + 1) > _targetK, then we are close to the correct answer.\n            // There's no closer answer than y + 1\n            return _y + 1;\n          }\n          _dy = 1;\n        }\n        _y = _y + _dy;\n      } else {\n        uint256 _dy = Math.mulDiv(_currentK - _targetK, 1e18, _d(_x0, _y));\n        if (_dy == 0) {\n          if (_currentK == _targetK || _f(_x0, _y - 1) < _targetK) {\n            // Likewise, if _currentK == _targetK, we found the correct answer.\n            // If _f(_x0, _y - 1) < _targetK, then we are close to the correct answer.\n            // There's no closer answer than \"y\"\n            // It's worth mentioning that we need to find y where f(x0, y) >= _targetK\n            // As a result, we can't return y - 1 even it's closer to the correct answer\n            return _y;\n          }\n          _dy = 1;\n        }\n        _y = _y - _dy;\n      }\n    }\n    revert CannotCalculateY();\n  }\n}\n"},"V3/src/libraries/PoolOracle.sol":{"content":"// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity 0.8.36;\n\nimport {Math} from '@openzeppelin/contracts/utils/math/Math.sol';\n\n/// @title PoolOracle\n/// @notice Circular-buffer TWAP mechanics for Aerodrome V2 pools.\nlibrary PoolOracle {\n  /*////////////////////////////////////////////////////////////\n                              STRUCTS\n  ////////////////////////////////////////////////////////////*/\n\n  /// @notice Captured TWAP observation circular buffer.\n  /// @param timestamp Observation timestamp (truncated to uint32).\n  /// @param reserve0Cumulative Reserve 0 cumulative.\n  /// @param reserve1Cumulative Reserve 1 cumulative.\n  struct Observation {\n    uint32 timestamp;\n    uint256 reserve0Cumulative;\n    uint256 reserve1Cumulative;\n  }\n\n  /// @notice Circular buffer of TWAP observations and its metadata.\n  /// @param observations Fixed-size buffer of reserve cumulative snapshots.\n  /// @param index Index of the most recently written observation.\n  /// @param cardinality Number of populated slots in the buffer.\n  /// @param cardinalityNext Number of observation slots that can be populated.\n  struct ObservationBuffer {\n    Observation[65_535] observations;\n    uint16 index;\n    uint16 cardinality;\n    uint16 cardinalityNext;\n  }\n\n  /*////////////////////////////////////////////////////////////\n                              ERRORS\n  ////////////////////////////////////////////////////////////*/\n\n  /// @notice Thrown when a requested timestamp predates the oldest stored observation.\n  error ObservationOld();\n\n  /*////////////////////////////////////////////////////////////\n                              FUNCTIONS\n  ////////////////////////////////////////////////////////////*/\n\n  /// @notice Seeds slot zero of the buffer and sets the starting cardinality.\n  /// @param self The observation buffer.\n  function initialize(ObservationBuffer storage self) internal {\n    self.observations[0].timestamp = uint32(block.timestamp);\n    self.cardinality = 1;\n    self.cardinalityNext = 1;\n  }\n\n  /// @notice Writes a new observation when more than `_periodSize` has elapsed since the newest one.\n  /// @dev `self.cardinality` increases by one when `self.index` reaches the last available slot and `self.cardinalityNext`\n  ///      is > `self.cardinality`.\n  /// @param self The observation buffer.\n  /// @param _reserve0CumulativeLast Running reserve0 cumulative to store.\n  /// @param _reserve1CumulativeLast Running reserve1 cumulative to store.\n  /// @param _periodSize Minimum seconds between observations.\n  function write(\n    ObservationBuffer storage self,\n    uint256 _reserve0CumulativeLast,\n    uint256 _reserve1CumulativeLast,\n    uint256 _periodSize\n  ) internal {\n    uint32 _blockTimestamp = uint32(block.timestamp);\n    uint16 _index = self.index;\n    uint256 _timeElapsed;\n    unchecked {\n      _timeElapsed = _blockTimestamp - self.observations[_index].timestamp;\n    }\n    if (_timeElapsed <= _periodSize) return;\n    uint16 _cardinality = self.cardinality;\n    uint16 _newCardinality = _cardinality;\n    /// @dev Grow by one slot per write since there is no `initialized` flag on `Observation`.\n    ///      This ensures that every read only hits initialized slots.\n    if (self.cardinalityNext > _cardinality && _index == _cardinality - 1) {\n      _newCardinality = _cardinality + 1;\n    }\n    uint16 _newIndex = (_index + 1) % _newCardinality;\n    self.observations[_newIndex] = Observation({\n      timestamp: _blockTimestamp,\n      reserve0Cumulative: _reserve0CumulativeLast,\n      reserve1Cumulative: _reserve1CumulativeLast\n    });\n    self.index = _newIndex;\n    if (_newCardinality != _cardinality) self.cardinality = _newCardinality;\n  }\n\n  /// @notice Pre-initialises the new buffer slots and updates `cardinalityNext` so observation writes hit warm storage.\n  /// @param self The observation buffer.\n  /// @param _next Requested target cardinality.\n  /// @return _grown The resulting target cardinality, unchanged when `_next` is not greater than the current.\n  function grow(ObservationBuffer storage self, uint16 _next) internal returns (uint16) {\n    uint16 _current = self.cardinalityNext;\n    if (_next <= _current) return _current;\n    for (uint16 _i = _current; _i < _next; _i++) {\n      self.observations[_i].timestamp = 1;\n      self.observations[_i].reserve0Cumulative = 1;\n      self.observations[_i].reserve1Cumulative = 1;\n    }\n    self.cardinalityNext = _next;\n    return _next;\n  }\n\n  /// @notice Returns the observations bracketing `_target`.\n  /// @dev When `_target` falls after the newest stored observation, `_atOrAfter` is interpolated from the\n  ///      current cumulatives. When `_target` equals the newest stored observation, that observation is\n  ///      returned as both bounds.\n  /// @param self The observation buffer.\n  /// @param _time The current timestamp.\n  /// @param _target Timestamp to locate inside or relative to the populated range.\n  /// @param _reserve0CumulativeNow Current reserve0 cumulative extrapolated to `_time`.\n  /// @param _reserve1CumulativeNow Current reserve1 cumulative extrapolated to `_time`.\n  /// @return _beforeOrAt Observation at or before `_target`.\n  /// @return _atOrAfter Observation at or after `_target`.\n  function _getSurroundingObservations(\n    ObservationBuffer storage self,\n    uint32 _time,\n    uint32 _target,\n    uint256 _reserve0CumulativeNow,\n    uint256 _reserve1CumulativeNow\n  ) internal view returns (Observation memory _beforeOrAt, Observation memory _atOrAfter) {\n    uint16 _index = self.index;\n    _beforeOrAt = self.observations[_index]; // newest written\n    if (_lte(_time, _beforeOrAt.timestamp, _target)) {\n      // target sits exactly on the newest observation, which brackets itself with no interpolation\n      if (_beforeOrAt.timestamp == _target) return (_beforeOrAt, _beforeOrAt);\n      (uint256 _r0Interpolated, uint256 _r1Interpolated) =\n        _interpolate(_beforeOrAt, _time, _reserve0CumulativeNow, _reserve1CumulativeNow, _target);\n      _atOrAfter =\n        Observation({timestamp: _target, reserve0Cumulative: _r0Interpolated, reserve1Cumulative: _r1Interpolated});\n      return (_beforeOrAt, _atOrAfter);\n    }\n    _beforeOrAt = self.observations[(_index + 1) % self.cardinality]; // oldest reachable\n    if (!_lte(_time, _beforeOrAt.timestamp, _target)) revert ObservationOld();\n    return _binarySearch(self, _time, _target);\n  }\n\n  /// @notice Resolves a single `_secondsAgo` offset into a pair of reserve cumulatives by interpolating between\n  ///         surrounding observations.\n  /// @dev A `_secondsAgo` that lands after the newest stored observation is estimated from the current\n  ///      cumulatives, so a later trade can change what it reads. It stops changing once an observation\n  ///      is stored at or after that point.\n  /// @param self The observation buffer.\n  /// @param _time The current timestamp.\n  /// @param _secondsAgo Offset from `_time` into the past. `0` requests the cumulatives at `_time`.\n  /// @param _reserve0CumulativeNow Current reserve0 cumulative extrapolated to `_time`.\n  /// @param _reserve1CumulativeNow Current reserve1 cumulative extrapolated to `_time`.\n  /// @return _reserve0Cumulative Cumulative reserve0 at `_time - _secondsAgo`.\n  /// @return _reserve1Cumulative Cumulative reserve1 at `_time - _secondsAgo`.\n  function observeSingle(\n    ObservationBuffer storage self,\n    uint32 _time,\n    uint32 _secondsAgo,\n    uint256 _reserve0CumulativeNow,\n    uint256 _reserve1CumulativeNow\n  ) internal view returns (uint256 _reserve0Cumulative, uint256 _reserve1Cumulative) {\n    if (_secondsAgo == 0) {\n      return (_reserve0CumulativeNow, _reserve1CumulativeNow);\n    }\n    uint32 _target;\n    unchecked {\n      _target = _time - _secondsAgo;\n    }\n    (Observation memory _beforeOrAt, Observation memory _atOrAfter) =\n      _getSurroundingObservations(self, _time, _target, _reserve0CumulativeNow, _reserve1CumulativeNow);\n    if (_atOrAfter.timestamp == _target) {\n      return (_atOrAfter.reserve0Cumulative, _atOrAfter.reserve1Cumulative);\n    }\n    (_reserve0Cumulative, _reserve1Cumulative) = _interpolate(\n      _beforeOrAt, _atOrAfter.timestamp, _atOrAfter.reserve0Cumulative, _atOrAfter.reserve1Cumulative, _target\n    );\n  }\n\n  /// @notice Resolves an array of `_secondsAgos` offsets into reserve cumulatives.\n  /// @param self The observation buffer.\n  /// @param _secondsAgos Offsets into the past from the current timestamp, `0` requesting the current cumulatives.\n  /// @param _reserve0CumulativeNow Current reserve0 cumulative extrapolated to the current timestamp.\n  /// @param _reserve1CumulativeNow Current reserve1 cumulative extrapolated to the current timestamp.\n  /// @return _reserve0Cumulatives Cumulative reserve0 at each requested offset.\n  /// @return _reserve1Cumulatives Cumulative reserve1 at each requested offset.\n  function observe(\n    ObservationBuffer storage self,\n    uint32[] calldata _secondsAgos,\n    uint256 _reserve0CumulativeNow,\n    uint256 _reserve1CumulativeNow\n  ) internal view returns (uint256[] memory _reserve0Cumulatives, uint256[] memory _reserve1Cumulatives) {\n    uint32 _time = uint32(block.timestamp);\n    uint256 _length = _secondsAgos.length;\n    _reserve0Cumulatives = new uint256[](_length);\n    _reserve1Cumulatives = new uint256[](_length);\n    for (uint256 _i; _i < _length; ++_i) {\n      (_reserve0Cumulatives[_i], _reserve1Cumulatives[_i]) =\n        observeSingle(self, _time, _secondsAgos[_i], _reserve0CumulativeNow, _reserve1CumulativeNow);\n    }\n  }\n\n  /// @notice Compares two uint32 timestamps chronologically, tolerating the uint32 rollover.\n  /// @param _time The current timestamp.\n  /// @param _a Timestamp to test.\n  /// @param _b Timestamp to compare against.\n  /// @return  Whether `_a` is chronologically less than or equal to `_b`.\n  function _lte(uint32 _time, uint32 _a, uint32 _b) internal pure returns (bool) {\n    if (_a <= _time && _b <= _time) return _a <= _b;\n\n    uint256 _aAdjusted = _a > _time ? _a : _a + 2 ** 32;\n    uint256 _bAdjusted = _b > _time ? _b : _b + 2 ** 32;\n\n    return _aAdjusted <= _bAdjusted;\n  }\n\n  /// @notice Interpolates the reserve cumulatives at `_target` between two observation points: `_beforeOrAt.timestamp` and `_afterTimestamp`.\n  /// @dev When `_target` equals `_afterTimestamp` the result equals the after cumulatives.\n  /// @dev When `_target` equals `_beforeOrAt.timestamp` the result equals the `_beforeOrAt` cumulatives.\n  /// @dev `_target` should fall between `_beforeOrAt.timestamp` and `_afterTimestamp` (inclusive).\n  /// @dev Timestamp subtractions are `unchecked` so the math holds across uint32 timestamp rollover.\n  /// @param _beforeOrAt Observation at or before `_target` chronologically.\n  /// @param _afterTimestamp Timestamp at the end of the interpolation window.\n  /// @param _afterReserve0Cumulative End-of-window reserve0 cumulative.\n  /// @param _afterReserve1Cumulative End-of-window reserve1 cumulative.\n  /// @param _target Timestamp at which to evaluate the interpolation.\n  /// @return _reserve0Cumulative Interpolated reserve0 cumulative at `_target`.\n  /// @return _reserve1Cumulative Interpolated reserve1 cumulative at `_target`.\n  function _interpolate(\n    Observation memory _beforeOrAt,\n    uint32 _afterTimestamp,\n    uint256 _afterReserve0Cumulative,\n    uint256 _afterReserve1Cumulative,\n    uint32 _target\n  ) internal pure returns (uint256 _reserve0Cumulative, uint256 _reserve1Cumulative) {\n    uint256 _beforeToAfterTimeDelta;\n    uint256 _beforeToTargetTimeDelta;\n    unchecked {\n      _beforeToAfterTimeDelta = uint256(_afterTimestamp - _beforeOrAt.timestamp);\n      _beforeToTargetTimeDelta = uint256(_target - _beforeOrAt.timestamp);\n    }\n    uint256 _reserve0Delta = _afterReserve0Cumulative - _beforeOrAt.reserve0Cumulative;\n    uint256 _reserve1Delta = _afterReserve1Cumulative - _beforeOrAt.reserve1Cumulative;\n    _reserve0Cumulative =\n      _beforeOrAt.reserve0Cumulative + Math.mulDiv(_reserve0Delta, _beforeToTargetTimeDelta, _beforeToAfterTimeDelta);\n    _reserve1Cumulative =\n      _beforeOrAt.reserve1Cumulative + Math.mulDiv(_reserve1Delta, _beforeToTargetTimeDelta, _beforeToAfterTimeDelta);\n  }\n\n  /// @notice Binary searches the active buffer for the observations bracketing `_target`.\n  /// @param self The observation buffer.\n  /// @param _time The current timestamp.\n  /// @param _target Timestamp to bracket.\n  /// @return _beforeOrAt Observation at or before `_target`.\n  /// @return _atOrAfter Observation at or after `_target`.\n  function _binarySearch(\n    ObservationBuffer storage self,\n    uint32 _time,\n    uint32 _target\n  ) private view returns (Observation memory _beforeOrAt, Observation memory _atOrAfter) {\n    uint16 _cardinality = self.cardinality;\n    Observation[65_535] storage observations = self.observations;\n    unchecked {\n      uint256 _l = (uint256(self.index) + 1) % _cardinality; // oldest reachable slot\n      uint256 _r = _l + _cardinality - 1; // newest written slot\n      while (true) {\n        uint256 _i = (_l + _r) / 2;\n        _beforeOrAt = observations[_i % _cardinality];\n        _atOrAfter = observations[(_i + 1) % _cardinality];\n        bool _targetAtOrAfterBefore = _lte(_time, _beforeOrAt.timestamp, _target);\n        bool _targetAtOrBeforeAfter = _lte(_time, _target, _atOrAfter.timestamp);\n        if (_targetAtOrAfterBefore && _targetAtOrBeforeAfter) break;\n        if (_targetAtOrAfterBefore) _l = _i + 1;\n        else _r = _i - 1;\n      }\n    }\n  }\n}\n"},"V3/src/interfaces/pools/IPool.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\n/**\n * @title IPool\n * @notice Interface for the Pool contract, the abstract base shared by the Aerodrome V2 volatile and stable pools\n */\ninterface IPool {\n  /*////////////////////////////////////////////////////////////\n                            EVENTS\n  ////////////////////////////////////////////////////////////*/\n\n  /// @notice Emitted when fees are claimed by a liquidity provider\n  /// @param sender Address that triggered the fee claim\n  /// @param amount0 Amount of token0 fees collected\n  /// @param amount1 Amount of token1 fees collected\n  event Fees(address indexed sender, uint256 amount0, uint256 amount1);\n  /// @notice Emitted when liquidity is minted\n  /// @param sender Address that initiated the mint\n  /// @param to Address that received the LP tokens\n  /// @param amount0 Amount of token0 deposited\n  /// @param amount1 Amount of token1 deposited\n  event Mint(address indexed sender, address indexed to, uint256 amount0, uint256 amount1);\n  /// @notice Emitted when liquidity is burned\n  /// @param sender Address that initiated the burn\n  /// @param to Address that received the underlying tokens\n  /// @param amount0 Amount of token0 returned\n  /// @param amount1 Amount of token1 returned\n  event Burn(address indexed sender, address indexed to, uint256 amount0, uint256 amount1);\n  /// @notice Emitted on every swap executed through the pool\n  /// @param sender Address that initiated the swap\n  /// @param to Address that received the output tokens\n  /// @param amount0In Amount of token0 provided as input\n  /// @param amount1In Amount of token1 provided as input\n  /// @param amount0Out Amount of token0 sent as output\n  /// @param amount1Out Amount of token1 sent as output\n  event Swap(\n    address indexed sender,\n    address indexed to,\n    uint256 amount0In,\n    uint256 amount1In,\n    uint256 amount0Out,\n    uint256 amount1Out\n  );\n  /// @notice Emitted when reserves are synced to the current balances\n  /// @param reserve0 Updated reserve of token0\n  /// @param reserve1 Updated reserve of token1\n  event Sync(uint256 reserve0, uint256 reserve1);\n\n  /// @notice Emitted when accumulated fee tokens are claimed\n  /// @param caller Address that triggered the claim\n  /// @param account Address whose accumulated fees were claimed\n  /// @param recipient Address that received the fee tokens\n  /// @param amount0 Amount of token0 claimed\n  /// @param amount1 Amount of token1 claimed\n  event Claim(\n    address indexed caller, address indexed account, address indexed recipient, uint256 amount0, uint256 amount1\n  );\n  /// @notice Emitted when an account grants or revokes claim approval for an operator\n  /// @param account Account whose approval state changed\n  /// @param operator Operator being approved or revoked\n  /// @param approved New approval state\n  event ClaimApproval(address indexed account, address indexed operator, bool approved);\n  /// @notice Emitted whenever `observationCardinalityNext` is increased\n  /// @param caller Address that triggered the cardinality growth\n  /// @param observationCardinalityNextOld Previous value of `observationCardinalityNext`\n  /// @param observationCardinalityNextNew New value of `observationCardinalityNext`\n  event IncreaseObservationCardinalityNext(\n    address indexed caller, uint16 observationCardinalityNextOld, uint16 observationCardinalityNextNew\n  );\n\n  /*////////////////////////////////////////////////////////////\n                            ERRORS\n  ////////////////////////////////////////////////////////////*/\n\n  /// @notice Thrown when the factory address has already been set and cannot be changed\n  error FactoryAlreadySet();\n  /// @notice Thrown when the input amount provided to a swap is zero or insufficient\n  error InsufficientInputAmount();\n  /// @notice Thrown when the pool does not have enough liquidity to fulfil the operation\n  error InsufficientLiquidity();\n  /// @notice Thrown when burning LP tokens would return zero of at least one underlying token\n  error InsufficientLiquidityBurned();\n  /// @notice Thrown when minting would produce zero LP tokens\n  error InsufficientLiquidityMinted();\n  /// @notice Thrown when the output amount of a swap is zero or below the requested minimum\n  error InsufficientOutputAmount();\n  /// @notice Thrown when the `to` address supplied to swap or burn is one of the pool's tokens\n  error InvalidTo();\n  /// @notice Thrown when an operation is attempted while the pool is paused\n  error IsPaused();\n  /// @notice Thrown when the invariant K check fails after a swap\n  error K();\n  /// @notice Thrown when the caller is neither the account nor an approved claim operator\n  error NotAuthorized();\n  /// @notice Thrown when a zero address is supplied where a non-zero address is required\n  error ZeroAddress();\n  /*////////////////////////////////////////////////////////////\n                        EXTERNAL FUNCTIONS\n  ////////////////////////////////////////////////////////////*/\n  /// @notice Grants or revokes an operator's permission to claim the caller's accumulated fees\n  /// @param _operator Operator whose approval is updated\n  /// @param _approved Whether the operator is approved\n  function approveForClaim(address _operator, bool _approved) external;\n\n  /// @notice Claims the caller's accumulated fees\n  /// @param _recipient Address that receives the claimed fee tokens\n  /// @return _amount0 Amount of token0 claimed\n  /// @return _amount1 Amount of token1 claimed\n  function claimFees(address _recipient) external returns (uint256 _amount0, uint256 _amount1);\n\n  /// @notice Claims an account's accumulated fees\n  /// @dev The caller must be `_account` or an operator approved by `_account`\n  /// @param _account Account whose accumulated fees are claimed\n  /// @param _recipient Address that receives the claimed fee tokens\n  /// @return _amount0 Amount of token0 claimed\n  /// @return _amount1 Amount of token1 claimed\n  function claimFees(address _account, address _recipient) external returns (uint256 _amount0, uint256 _amount1);\n\n  /// @notice Returns the value of K in the Pool, based on its reserves.\n  function getK() external returns (uint256);\n\n  /// @notice Set pool name\n  ///         Only callable by IPoolFactory(factory).poolAdmin()\n  /// @param __name String of new name\n  function setName(string calldata __name) external;\n\n  /// @notice Set pool symbol\n  ///         Only callable by IPoolFactory(factory).poolAdmin()\n  /// @param __symbol String of new symbol\n  function setSymbol(string calldata __symbol) external;\n\n  /// @notice This low-level function should be called from a contract which performs important safety checks\n  /// @param amount0Out Amount of token0 to send to `to`\n  /// @param amount1Out Amount of token1 to send to `to`\n  /// @param to Address to recieve the swapped output\n  /// @param data Additional calldata for flashloans\n  function swap(uint256 amount0Out, uint256 amount1Out, address to, bytes calldata data) external;\n\n  /// @notice This low-level function should be called from a contract which performs important safety checks\n  ///         standard uniswap v2 implementation\n  /// @param to Address to receive token0 and token1 from burning the pool token\n  /// @return amount0 Amount of token0 returned\n  /// @return amount1 Amount of token1 returned\n  function burn(address to) external returns (uint256 amount0, uint256 amount1);\n\n  /// @notice This low-level function should be called by addLiquidity functions in Router.sol, which performs important safety checks\n  ///         standard uniswap v2 implementation\n  /// @param to Address to receive the minted LP token\n  /// @return liquidity Amount of LP token minted\n  function mint(address to) external returns (uint256 liquidity);\n\n  /// @notice Force balances to match reserves\n  /// @param to Address to receive any skimmed rewards\n  function skim(address to) external;\n\n  /// @notice Force reserves to match balances\n  function sync() external;\n\n  /// @notice Called on pool creation by the owning PoolFactory\n  /// @param _token0 Address of token0\n  /// @param _token1 Address of token1\n  function initialize(address _token0, address _token1) external;\n\n  /// @notice Pre-allocates buffer slots increasing the buffer capacity\n  /// @param _observationCardinalityNext New target capacity. At most 65,535.\n  function increaseObservationCardinalityNext(uint16 _observationCardinalityNext) external;\n\n  /*////////////////////////////////////////////////////////////\n                      PURE AND VIEW FUNCTIONS\n  ////////////////////////////////////////////////////////////*/\n  /// @notice Returns the decimal (dec), reserves (r), and tokens (t) of token0 and token1\n  function metadata() external view returns (uint256 dec0, uint256 dec1, uint256 r0, uint256 r1, address t0, address t1);\n\n  /// @notice Returns [token0, token1]\n  function tokens() external view returns (address, address);\n\n  /// @notice Returns accumulated but unclaimed fees for an account.\n  /// @param _account Address to query.\n  /// @return _amount0 Pending token0 fees.\n  /// @return _amount1 Pending token1 fees.\n  function pendingFees(address _account) external view returns (uint256 _amount0, uint256 _amount1);\n\n  /// @notice Address of token in the pool with the lower address value\n  function token0() external view returns (address);\n\n  /// @notice Address of token in the pool with the higher address value\n  function token1() external view returns (address);\n\n  /// @notice Address of linked PoolFees.sol\n  function poolFees() external view returns (address);\n\n  /// @notice Address of PoolFactory that created this contract\n  function factory() external view returns (address);\n\n  /// @notice Period gate for new observations, in seconds. A new observation is written when more\n  ///         than `PERIOD_SIZE` seconds have passed since the last one, so the smallest possible\n  ///         spacing between two stored observations is `PERIOD_SIZE + 1` (i.e. 61 seconds at the\n  ///         default value of 60).\n  function PERIOD_SIZE() external view returns (uint256);\n\n  /// @notice The pool type identifier\n  /// @return The pool type label to be able to identify the type of pool\n  function POOL_TYPE() external view returns (bytes32);\n\n  /// @notice Amount of token0 in pool\n  function reserve0() external view returns (uint256);\n\n  /// @notice Amount of token1 in pool\n  function reserve1() external view returns (uint256);\n\n  /// @notice Timestamp of last update to pool\n  function blockTimestampLast() external view returns (uint256);\n\n  /// @notice Cumulative of reserve0 factoring in time elapsed\n  function reserve0CumulativeLast() external view returns (uint256);\n\n  /// @notice Cumulative of reserve1 factoring in time elapsed\n  function reserve1CumulativeLast() external view returns (uint256);\n\n  /// @notice Accumulated fees of token0 (global)\n  function index0() external view returns (uint256);\n\n  /// @notice Accumulated fees of token1 (global)\n  function index1() external view returns (uint256);\n\n  /// @notice Get an LP's relative index0 to index0\n  function supplyIndex0(address) external view returns (uint256);\n\n  /// @notice Get an LP's relative index1 to index1\n  function supplyIndex1(address) external view returns (uint256);\n\n  /// @notice Amount of unclaimed, but claimable tokens from fees of token0 for an LP\n  function claimable0(address) external view returns (uint256);\n\n  /// @notice Amount of unclaimed, but claimable tokens from fees of token1 for an LP\n  function claimable1(address) external view returns (uint256);\n\n  /// @notice Whether an operator may claim an account's accumulated fees\n  /// @param _account Account that owns the accumulated fees\n  /// @param _operator Operator whose approval is queried\n  /// @return _approved Whether the operator is approved\n  function approvedForClaim(address _account, address _operator) external view returns (bool _approved);\n\n  /// @notice Produces the cumulative price using counterfactuals to save gas and avoid a call to sync.\n  function currentCumulativePrices()\n    external\n    view\n    returns (uint256 reserve0Cumulative, uint256 reserve1Cumulative, uint256 blockTimestamp);\n\n  /// @notice Update reserves and, on the first call per block, price accumulators\n  /// @return _reserve0 .\n  /// @return _reserve1 .\n  /// @return _blockTimestampLast .\n  function getReserves() external view returns (uint256 _reserve0, uint256 _reserve1, uint256 _blockTimestampLast);\n\n  /// @notice Get the amount of tokenOut given the amount of tokenIn, charging only the base fee\n  /// @dev Does not charge the MEV tax, so the result can be higher than what `swap` pays out.\n  ///      Use `getAmountOutWithTotalFee` to quote a swap.\n  /// @param amountIn Amount of token in\n  /// @param tokenIn Address of token\n  /// @return Amount out\n  function getAmountOut(uint256 amountIn, address tokenIn) external view returns (uint256);\n\n  /// @notice Get the amount of tokenOut given the amount of tokenIn, charging the total fees\n  /// @param amountIn Amount of token in\n  /// @param tokenIn Address of token in\n  /// @return Amount out\n  function getAmountOutWithTotalFee(uint256 amountIn, address tokenIn) external view returns (uint256);\n\n  /// @notice Get the amount of tokenIn required to receive the amount of tokenOut, charging the total fees\n  /// @dev Reverts if the exact output cannot be calculated\n  /// @param amountOut Amount of token out to receive\n  /// @param tokenOut Address of token out\n  /// @return Amount in, fee included\n  function getAmountInWithTotalFee(uint256 amountOut, address tokenOut) external view returns (uint256);\n\n  /// @notice Returns the cumulative reserves as of each requested `secondsAgo`. Reverts when any\n  ///         `secondsAgos[i]` predates the oldest stored observation.\n  /// @dev Offsets between two stored observations are linearly interpolated. Observations are\n  ///      period-gated, so reserve changes within an interval may go unrecorded, making the\n  ///      interpolation an approximation. Read from the pool directly when an exact value is required.\n  /// @dev A point newer than the newest stored observation is estimated from the current cumulative\n  ///      instead of two stored ones, so a trade after that point can change what it reads. It stops\n  ///      changing once an observation is stored at or after that point. Points that already fall\n  ///      between two stored observations read the same on every call.\n  /// @param secondsAgos Array of seconds offsets from `block.timestamp` to query\n  /// @return reserve0Cumulatives Cumulative reserve0 values at each requested point\n  /// @return reserve1Cumulatives Cumulative reserve1 values at each requested point\n  function observe(uint32[] calldata secondsAgos)\n    external\n    view\n    returns (uint256[] memory reserve0Cumulatives, uint256[] memory reserve1Cumulatives);\n\n  /// @notice Quote `amountIn` of `tokenIn` against a custom reserve snapshot\n  /// @dev Subtracts the base fee from `amountIn` before applying the curve. Does not charge the MEV\n  ///      tax, so use `getAmountOutWithTotalFee` to quote a swap.\n  /// @param amountIn Input amount in the smallest unit of `tokenIn`\n  /// @param tokenIn Address of the input token\n  /// @param _reserve0 Reserve of token0 to quote against\n  /// @param _reserve1 Reserve of token1 to quote against\n  /// @return Output amount the swap would produce against the supplied reserves\n  function getAmountOut(\n    uint256 amountIn,\n    address tokenIn,\n    uint256 _reserve0,\n    uint256 _reserve1\n  ) external view returns (uint256);\n\n  /// @notice TWAP circular buffer metadata\n  /// @return index Index of the most recent observation in the buffer\n  /// @return cardinality Number of populated slots in the buffer\n  /// @return cardinalityNext Number of slots that can be written\n  function observationBuffer() external view returns (uint16 index, uint16 cardinality, uint16 cardinalityNext);\n\n  /// @notice Returns the observation at the given index\n  /// @param index Index of the observation to return\n  /// @return timestamp Timestamp of the observation\n  /// @return reserve0Cumulative Cumulative reserve0 of the observation\n  /// @return reserve1Cumulative Cumulative reserve1 of the observation\n  function observations(uint256 index)\n    external\n    view\n    returns (uint32 timestamp, uint256 reserve0Cumulative, uint256 reserve1Cumulative);\n}\n"},"V3/src/interfaces/pools/IPoolCallee.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IPoolCallee {\n  function hook(address sender, uint256 amount0, uint256 amount1, bytes calldata data) external;\n}\n"},"V3/src/interfaces/pools/IStablePool.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nimport {IPool} from 'V3/interfaces/pools/IPool.sol';\n\n/**\n * @title IStablePool\n * @notice Interface for the StablePool contract, an Aerodrome V2 stable-swap AMM pool\n */\ninterface IStablePool is IPool {\n  /*////////////////////////////////////////////////////////////\n                            ERRORS\n  ////////////////////////////////////////////////////////////*/\n  /// @notice Thrown on first mint when `_k(amount0, amount1)` is less than or equal to `MINIMUM_K`\n  error BelowMinimumK();\n\n  /// @notice Thrown when the Newton-Raphson search cannot solve for `y` within its iteration budget\n  error CannotCalculateY();\n\n  /// @notice Thrown when the deposited amounts are not equal\n  error DepositsNotEqual();\n\n  /// @notice Thrown after burn when remaining reserves cause `_k` to round to zero\n  error KIsZero();\n\n  /*////////////////////////////////////////////////////////////\n                      PURE AND VIEW FUNCTIONS\n  ////////////////////////////////////////////////////////////*/\n  /// @notice Minimum value of the stable-swap invariant\n  function MINIMUM_K() external view returns (uint256);\n}\n"},"V3/src/interfaces/pools/tape/IPoolTape.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/// @title IPoolTape\n/// @notice Records and exposes per-swap cumulative metrics for V2 pools.\ninterface IPoolTape {\n  /*////////////////////////////////////////////////////////////\n                            STRUCTS\n  ////////////////////////////////////////////////////////////*/\n\n  /// @notice Per-pool running cumulatives updated on every swap.\n  /// @param cumulativeFee0 Cumulative token0 fees.\n  /// @param cumulativeFee1 Cumulative token1 fees.\n  /// @param cumulativeVolume0 Cumulative token0 input volume.\n  /// @param cumulativeVolume1 Cumulative token1 input volume.\n  /// @param cumulativeMevVolume0 Cumulative token0 toxic volume.\n  /// @param cumulativeMevVolume1 Cumulative token1 toxic volume.\n  /// @param cumulativeMevFee0 Cumulative token0 MEV fees.\n  /// @param cumulativeMevFee1 Cumulative token1 MEV fees.\n  /// @param lastSwapTimestamp Timestamp of the most recent recorded swap.\n  /// @param swapCount Cumulative swap count.\n  struct Accumulator {\n    // Slot 1\n    uint128 cumulativeFee0;\n    uint128 cumulativeFee1;\n    // Slot 2\n    uint128 cumulativeVolume0;\n    uint128 cumulativeVolume1;\n    // Slot 3\n    uint128 cumulativeMevVolume0;\n    uint128 cumulativeMevVolume1;\n    // Slot 4\n    uint128 cumulativeMevFee0;\n    uint128 cumulativeMevFee1;\n    // Slot 5\n    uint48 lastSwapTimestamp;\n    uint48 swapCount;\n  }\n\n  /// @notice A committed snapshot of the accumulator at a cadence boundary.\n  /// @param cumulativeFee0 Cumulative token0 fees.\n  /// @param cumulativeFee1 Cumulative token1 fees.\n  /// @param cumulativeVolume0 Cumulative token0 input volume.\n  /// @param cumulativeVolume1 Cumulative token1 input volume.\n  /// @param cumulativeMevVolume0 Cumulative token0 toxic volume.\n  /// @param cumulativeMevVolume1 Cumulative token1 toxic volume.\n  /// @param cumulativeMevFee0 Cumulative token0 MEV fees.\n  /// @param cumulativeMevFee1 Cumulative token1 MEV fees.\n  /// @param blockTimestamp Timestamp the observation was committed.\n  /// @param swapCount Cumulative swap count at commit.\n  struct Observation {\n    // Slot 1\n    uint128 cumulativeFee0;\n    uint128 cumulativeFee1;\n    // Slot 2\n    uint128 cumulativeVolume0;\n    uint128 cumulativeVolume1;\n    // Slot 3\n    uint128 cumulativeMevVolume0;\n    uint128 cumulativeMevVolume1;\n    // Slot 4\n    uint128 cumulativeMevFee0;\n    uint128 cumulativeMevFee1;\n    // Slot 5\n    uint48 blockTimestamp;\n    uint48 swapCount;\n  }\n\n  /// @notice The per-pool circular buffer of observations and its metadata.\n  /// @param observations Fixed-size buffer of committed observations.\n  /// @param index Index of the most recently committed observation.\n  /// @param cardinality Number of populated slots in the buffer.\n  /// @param cardinalityNext Number of observation slots that can be populated.\n  struct ObservationBuffer {\n    Observation[65_535] observations;\n    uint16 index;\n    uint16 cardinality;\n    uint16 cardinalityNext;\n  }\n\n  /// @notice Per-swap deltas passed into `record`.\n  /// @param fee0 token0 fee for this swap.\n  /// @param fee1 token1 fee for this swap.\n  /// @param volume0 token0 volume for this swap.\n  /// @param volume1 token1 volume for this swap.\n  /// @param mevVolume0 token0 toxic volume for this swap.\n  /// @param mevVolume1 token1 toxic volume for this swap.\n  /// @param mevFee0 token0 MEV fee for this swap.\n  /// @param mevFee1 token1 MEV fee for this swap.\n  struct PoolTapeData {\n    uint128 fee0;\n    uint128 fee1;\n    uint128 volume0;\n    uint128 volume1;\n    uint128 mevVolume0;\n    uint128 mevVolume1;\n    uint128 mevFee0;\n    uint128 mevFee1;\n  }\n\n  /*////////////////////////////////////////////////////////////\n                    EXTERNAL WRITE FUNCTIONS\n  ////////////////////////////////////////////////////////////*/\n\n  /// @notice Records a swap's metrics, accumulating and committing at the cadence boundary.\n  /// @param _pool The pool the swap occurred in.\n  /// @param _data The per-swap deltas.\n  function record(address _pool, PoolTapeData calldata _data) external;\n\n  /*////////////////////////////////////////////////////////////\n                    EXTERNAL VIEW FUNCTIONS\n  ////////////////////////////////////////////////////////////*/\n\n  /// @notice Returns the stored observation at an index.\n  /// @dev Callers can get the valid index range from `observationBuffers`. The index must be in\n  ///      `[0, cardinality)` to read written observations.\n  /// @param _pool The pool to read.\n  /// @param _index The buffer index to read.\n  /// @return _observation The stored observation.\n  function getObservation(address _pool, uint16 _index) external view returns (Observation memory _observation);\n\n  /// @notice Returns an interpolated observation for each requested past timestamp (`block.timestamp - secondsAgo`).\n  /// @dev A timestamp at or after the latest swap returns the current accumulator with the requested timestamp,\n  ///      because the cumulatives have not moved since the last swap. A timestamp at or before the oldest stored\n  ///      observation returns the oldest available observation with its own timestamp. An unregistered pool returns zeroed observations.\n  /// @dev A timestamp newer than the newest committed observation is derived from live state, so its value moves\n  ///      as swaps land and a single transaction can shift it. Timestamps at or before the newest committed\n  ///      observation are settled and read the same on every call.\n  /// @param _pool The pool to read.\n  /// @param _secondsAgo The past timestamps to read. A zero timestamp returns the current accumulator.\n  /// @return _observations One observation per timestamp, in the same order as `_secondsAgo`.\n  function observe(\n    address _pool,\n    uint48[] calldata _secondsAgo\n  ) external view returns (Observation[] memory _observations);\n\n  /// @notice The per-pool current accumulator values getter.\n  /// @param _pool The pool to read.\n  /// @return cumulativeFee0 Cumulative token0 fees.\n  /// @return cumulativeFee1 Cumulative token1 fees.\n  /// @return cumulativeVolume0 Cumulative token0 input volume.\n  /// @return cumulativeVolume1 Cumulative token1 input volume.\n  /// @return cumulativeMevVolume0 Cumulative token0 toxic volume.\n  /// @return cumulativeMevVolume1 Cumulative token1 toxic volume.\n  /// @return cumulativeMevFee0 Cumulative token0 MEV fees.\n  /// @return cumulativeMevFee1 Cumulative token1 MEV fees.\n  /// @return lastSwapTimestamp Timestamp of the most recent recorded swap.\n  /// @return swapCount Cumulative swap count.\n  function accumulators(address _pool)\n    external\n    view\n    returns (\n      uint128 cumulativeFee0,\n      uint128 cumulativeFee1,\n      uint128 cumulativeVolume0,\n      uint128 cumulativeVolume1,\n      uint128 cumulativeMevVolume0,\n      uint128 cumulativeMevVolume1,\n      uint128 cumulativeMevFee0,\n      uint128 cumulativeMevFee1,\n      uint48 lastSwapTimestamp,\n      uint48 swapCount\n    );\n}\n"},"V3/src/interfaces/factories/IPoolFactory.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nimport {IPoolTape} from 'V3/interfaces/pools/tape/IPoolTape.sol';\n\n/**\n * @title IPoolFactory\n * @notice Interface for the PoolFactory contract, the abstract base shared by the Aerodrome V2 volatile and stable pool factories\n */\ninterface IPoolFactory {\n  /// @notice Initial governance roles and modules of a pool factory.\n  /// @dev Every launch installs a pool tape, fee module and exact output fee quoter. Lite launches omit\n  ///      the discount registry and MEV tax module.\n  ///      Factory-bound fee modules and quoters must already be deployed with this factory's address.\n  /// @param poolAdmin Pool administrator.\n  /// @param pauser Factory pauser.\n  /// @param feeManager Manager of fees, fee modules and exact output quoting.\n  /// @param discountRegistryManager Manager of the discount registry.\n  /// @param poolTapeManager Manager of the pool tape.\n  /// @param factoryRegistry Registry that records pools created by this factory.\n  /// @param discountRegistry Initial discount registry, or zero for a lite launch.\n  /// @param poolTape Initial pool tape.\n  /// @param poolTapeGasLimit Nonzero gas forwarded to the pool tape.\n  /// @param feeModule Initial fee module.\n  /// @param feeModuleGasLimit Nonzero gas forwarded to the fee module.\n  /// @param mevTaxModule Initial MEV tax module, or zero for a lite launch.\n  /// @param mevTaxModuleGasLimit Gas forwarded to the MEV tax module; nonzero when it is configured.\n  /// @param exactOutFeeQuoter Initial exact output fee quoter.\n  struct PoolFactoryConfig {\n    address poolAdmin;\n    address pauser;\n    address feeManager;\n    address discountRegistryManager;\n    address poolTapeManager;\n    address factoryRegistry;\n    address discountRegistry;\n    address poolTape;\n    uint32 poolTapeGasLimit;\n    address feeModule;\n    uint32 feeModuleGasLimit;\n    address mevTaxModule;\n    uint32 mevTaxModuleGasLimit;\n    address exactOutFeeQuoter;\n  }\n\n  /*////////////////////////////////////////////////////////////\n                            EVENTS\n  ////////////////////////////////////////////////////////////*/\n  event SetFeeManager(address indexed feeManager);\n  event SetPauser(address indexed pauser);\n  event SetPauseState(bool indexed state);\n  event SetPoolAdmin(address indexed poolAdmin);\n  event PoolCreated(address indexed token0, address indexed token1, address pool, uint256);\n  event SetDefaultFee(uint256 defaultFee);\n  /// @notice Emitted when the fee module and the gas limit forwarded to it are set.\n  /// @param feeModule The new fee module address.\n  /// @param gasLimit The gas limit forwarded to the module on each read.\n  event SetFeeModule(address indexed feeModule, uint32 gasLimit);\n  event SetDiscountRegistryManager(address indexed discountRegistryManager);\n  event SetDiscountRegistry(address indexed discountRegistry);\n\n  /// @notice Emitted when the pool tape module and the gas limit forwarded to it are set.\n  /// @param poolTape The new pool tape address. The zero address disables the pool tape.\n  /// @param gasLimit The gas limit forwarded to the tape on each record.\n  event SetPoolTape(address indexed poolTape, uint32 gasLimit);\n\n  /// @notice Emitted when the pool tape manager is set.\n  /// @param poolTapeManager The new pool tape manager.\n  event SetPoolTapeManager(address indexed poolTapeManager);\n\n  /// @notice Emitted when the MEV tax module and the gas limit forwarded to it are set.\n  /// @param mevTaxModule The new MEV tax module address. The zero address disables the MEV tax.\n  /// @param gasLimit The gas limit forwarded to the module on each read.\n  event SetMevTaxModule(address indexed mevTaxModule, uint32 gasLimit);\n\n  /// @notice Emitted when the exact output fee quoter is set.\n  /// @param exactOutFeeQuoter The new quoter address.\n  event SetExactOutFeeQuoter(address indexed exactOutFeeQuoter);\n\n  /*////////////////////////////////////////////////////////////\n                            ERRORS\n  ////////////////////////////////////////////////////////////*/\n  error FeeTooHigh();\n  /// @notice Reverts when the gas left in the frame is equal to or below the gas limit set for the external call.\n  /// @dev EIP-150 forwards `min(_gasLimit, gasleft() - gasleft() / 64)`, so a transaction that sets its own gas\n  ///      limit too low would leave the callee short. Stopping here keeps the outcome of the call independent of\n  ///      the gas the caller supplied.\n  error InsufficientGasForCall();\n  /// @notice Thrown when the exact output fee quoter being set belongs to another factory.\n  error InvalidExactOutFeeQuoter();\n  error InvalidFeeModule();\n  /// @notice Thrown when an exact output quote is requested while no exact output fee quoter is set.\n  error NoExactOutFeeQuoter();\n  error NotDiscountRegistryManager();\n  error NotFeeManager();\n  error NotPauser();\n  error NotPoolAdmin();\n  /// @notice Thrown when the caller is not the pool tape manager.\n  error NotPoolTapeManager();\n  error PoolAlreadyExists();\n  error SameAddress();\n  error ZeroFee();\n  error ZeroAddress();\n  /// @notice Thrown when a gas limit is set to zero.\n  error ZeroGasLimit();\n\n  /*////////////////////////////////////////////////////////////\n                        EXTERNAL FUNCTIONS\n  ////////////////////////////////////////////////////////////*/\n  /// @notice Set pool administrator\n  /// @dev Allowed to change the name and symbol of any pool created by this factory\n  /// @param _poolAdmin Address of the pool administrator\n  function setPoolAdmin(address _poolAdmin) external;\n\n  /// @notice Set the pauser for the factory contract\n  /// @dev The pauser can pause swaps on pools associated with the factory. Liquidity will always be withdrawable.\n  /// @dev Must be called by the pauser\n  /// @param _pauser Address of the pauser\n  function setPauser(address _pauser) external;\n\n  /// @notice Set discount registry manager\n  /// @dev The discount registry manager can update the `discountRegistry` variable\n  /// @param _discountRegistryManager Address of the discount registry manager\n  function setDiscountRegistryManager(address _discountRegistryManager) external;\n\n  /// @notice Set the discount registry for the factory contract\n  /// @param _discountRegistry Address of the discount registry\n  function setDiscountRegistry(address _discountRegistry) external;\n\n  /// @notice Pause or unpause swaps on pools associated with the factory\n  /// @param _state True to pause, false to unpause\n  function setPauseState(bool _state) external;\n\n  /// @notice Set the fee manager for the factory contract\n  /// @dev The fee manager can set fees on pools associated with the factory.\n  /// @dev Must be called by the fee manager\n  /// @param _feeManager Address of the fee manager\n  function setFeeManager(address _feeManager) external;\n\n  /// @notice Updates the feeModule of the factory and the gas limit forwarded to it\n  /// @dev Must be called by the current fee manager. Reverts if the gas limit set is zero.\n  /// @param _feeModule The new feeModule of the factory\n  /// @param _gasLimit The gas limit forwarded to the module on each read. Calculated as\n  ///        `(usage + buffer) * 64 / 63` where `usage` is the most gas the module can spend and `buffer` is what\n  ///        this factory spends checking the gas and dispatching the call. The `64 / 63` covers the share\n  ///        EIP-150 withholds from the callee.\n  function setFeeModule(address _feeModule, uint32 _gasLimit) external;\n\n  /// @notice Set the default fee for pools created by this factory.\n  /// @dev Throws if higher than maximum fee.\n  ///      Throws if fee is zero.\n  /// @param _defaultFee .\n  function setDefaultFee(uint256 _defaultFee) external;\n\n  /// @notice Create a pool for the given pair of tokens\n  /// @dev token order does not matter\n  /// @param tokenA .\n  /// @param tokenB .\n  function createPool(address tokenA, address tokenB) external returns (address pool);\n\n  /// @notice Sets the pool tape manager role that controls the pool tape configuration.\n  /// @dev Must be called by the current pool tape manager. The initial manager is set in the constructor.\n  /// @param _poolTapeManager Address of the new pool tape manager.\n  function setPoolTapeManager(address _poolTapeManager) external;\n\n  /// @notice Sets or clears the pool tape module that the pool records data into, and the gas limit sent to it.\n  /// @dev Must be called by the pool tape manager. The zero address disables the pool tape recording.\n  /// @dev Reverts if the gas limit set is zero.\n  /// @param _poolTape Address of the pool tape module.\n  /// @param _gasLimit The gas limit forwarded to the tape on each record. Calculated as\n  ///        `(usage + buffer) * 64 / 63` where `usage` is the most gas the tape can spend and `buffer` is what\n  ///        this factory spends checking the gas and dispatching the call. The `64 / 63` covers the share\n  ///        EIP-150 withholds from the callee.\n  function setPoolTape(address _poolTape, uint32 _gasLimit) external;\n\n  /// @notice Sets or clears the MEV tax module queried for the MEV tax on swaps, and the gas limit sent to it.\n  /// @dev Must be called by the fee manager. The zero address disables the MEV tax.\n  /// @dev Reverts if the gas limit set is zero.\n  /// @param _mevTaxModule Address of the MEV tax module.\n  /// @param _gasLimit The gas limit forwarded to the module on each read. Calculated as\n  ///        `(usage + buffer) * 64 / 63` where `usage` is the most gas the module can spend and `buffer` is what\n  ///        this factory spends checking the gas and dispatching the call. The `64 / 63` covers the share\n  ///        EIP-150 withholds from the callee.\n  function setMevTaxModule(address _mevTaxModule, uint32 _gasLimit) external;\n\n  /// @notice Sets the quoter that resolves the fee of exact output quotes.\n  /// @dev Must be called by the fee manager. Reverts on the zero address and when the quoter belongs to another\n  ///      factory. Exact output quotes revert until a quoter is set.\n  /// @param _exactOutFeeQuoter Address of the exact output fee quoter.\n  function setExactOutFeeQuoter(address _exactOutFeeQuoter) external;\n\n  /// @notice Forwards a pool's per-swap deltas to the pool tape, if one is set.\n  /// @param _data The per-swap deltas to record.\n  function recordPoolTape(IPoolTape.PoolTapeData calldata _data) external;\n\n  /*////////////////////////////////////////////////////////////\n                      PURE AND VIEW FUNCTIONS\n  ////////////////////////////////////////////////////////////*/\n  /// @notice Return a single pool created by this factory\n  /// @return Address of pool\n  function allPools(uint256 index) external view returns (address);\n\n  /// @notice Returns all pools created by this factory\n  /// @return Array of pool addresses\n  function allPools() external view returns (address[] memory);\n\n  /// @notice Returns the number of pools created from this factory\n  function allPoolsLength() external view returns (uint256);\n\n  /// @notice Is a valid pool created by this factory.\n  /// @param pool .\n  function isPool(address pool) external view returns (bool);\n\n  /// @notice Return address of pool created by this factory\n  /// @param tokenA .\n  /// @param tokenB .\n  function getPool(address tokenA, address tokenB) external view returns (address);\n\n  /// @notice Returns the base fee for a pool swap, accounting for custom fees set via the fee module.\n  /// @dev A fee module value above `MAX_BASE_FEE` is ignored, falling back to `defaultFee`.\n  /// @param _pool The pool to get the base fee for.\n  /// @param _caller The swap initiator.\n  /// @param _amount0In The token0 input amount of the swap, zero when token0 is not an input.\n  /// @param _amount1In The token1 input amount of the swap, zero when token1 is not an input.\n  /// @param _reserve0 The pre-swap token0 reserve of the pool.\n  /// @param _reserve1 The pre-swap token1 reserve of the pool.\n  /// @return The base fee in basis points.\n  function getBaseFee(\n    address _pool,\n    address _caller,\n    uint256 _amount0In,\n    uint256 _amount1In,\n    uint256 _reserve0,\n    uint256 _reserve1\n  ) external view returns (uint256);\n\n  /// @notice Returns the swap fee data for a pool swap, including the MEV tax.\n  /// @dev The MEV tax is clamped so the total stays at or below `MAX_FEE`.\n  /// @param _pool The pool to get the fee for.\n  /// @param _sender The swap caller, the pool's msg.sender.\n  /// @param _amount0In The token0 input amount of the swap, zero when token0 is not an input.\n  /// @param _amount1In The token1 input amount of the swap, zero when token1 is not an input.\n  /// @param _reserve0 The pre-swap token0 reserve of the pool.\n  /// @param _reserve1 The pre-swap token1 reserve of the pool.\n  /// @return _fee The combined swap fee in basis points.\n  /// @return _mevFee The MEV share of the fee in basis points, rounded up.\n  /// @return _toxic True when the swap is classified as toxic flow.\n  function getFee(\n    address _pool,\n    address _sender,\n    uint256 _amount0In,\n    uint256 _amount1In,\n    uint256 _reserve0,\n    uint256 _reserve1\n  ) external view returns (uint256 _fee, uint256 _mevFee, bool _toxic);\n\n  /// @notice Returns the total fee to gross up an exact output quote with, given the input the curve requires.\n  /// @dev Reverts with `NoExactOutFeeQuoter` while no quoter is set and with `FeeTooHigh` when the quoter\n  ///      answers above `MAX_FEE`.\n  /// @param _pool The pool to get the fee for.\n  /// @param _caller The swap initiator.\n  /// @param _amount0InAfterFee The token0 input the curve requires after the fee, zero when token0 is not an input.\n  /// @param _amount1InAfterFee The token1 input the curve requires after the fee, zero when token1 is not an input.\n  /// @param _reserve0 The pre-swap token0 reserve of the pool.\n  /// @param _reserve1 The pre-swap token1 reserve of the pool.\n  /// @return _fee The total fee in basis points.\n  function getFeeForAmountIn(\n    address _pool,\n    address _caller,\n    uint256 _amount0InAfterFee,\n    uint256 _amount1InAfterFee,\n    uint256 _reserve0,\n    uint256 _reserve1\n  ) external view returns (uint256 _fee);\n\n  /// @notice The pool implementation used to create pools\n  /// @return Address of pool implementation\n  function implementation() external view returns (address);\n\n  /// @notice The factory registry every created pool is recorded in as a target.\n  /// @dev Set at construction. createPool reverts until this factory is an approved\n  ///      target factory in the registry.\n  /// @return Address of the factory registry.\n  function factoryRegistry() external view returns (address);\n\n  /// @notice Whether the pools associated with the factory are paused or not.\n  /// @dev Pause only pauses swaps, liquidity will always be withdrawable.\n  function isPaused() external view returns (bool);\n\n  /// @notice The address of the pauser, can pause swaps on pools associated with factory.\n  /// @return Address of the pauser\n  function pauser() external view returns (address);\n\n  /// @notice The default fee for pools created by this factory.\n  /// @return Default fee\n  function defaultFee() external view returns (uint256);\n\n  /// @notice Hard-coded default fee value the factory variant is initialized with\n  /// @dev Constant per variant. The mutable current value lives in `defaultFee()`.\n  function DEFAULT_FEE() external view returns (uint256);\n\n  /// @notice Maximum default fee the fee manager can set\n  /// @return 3% in bips\n  function MAX_DEFAULT_FEE() external view returns (uint256);\n\n  /// @notice Maximum base fee the factory accepts from the fee module\n  /// @return 10% in bips\n  function MAX_BASE_FEE() external view returns (uint256);\n\n  /// @notice Maximum total fee a swap can be charged, base fee plus MEV tax\n  /// @return 20% in bips\n  function MAX_FEE() external view returns (uint256);\n\n  /// @notice Address of the fee manager, can set fees on pools associated with factory.\n  /// @notice This overrides the default fee for that pool.\n  /// @return Address of the fee manager\n  function feeManager() external view returns (address);\n\n  /// @notice Address of the fee module of the factory\n  /// @dev Can be changed by the current fee manager via setFeeModule\n  /// @return Address of the fee module\n  function feeModule() external view returns (address);\n\n  /// @notice The gas limit forwarded to the fee module on each read.\n  /// @return _gasLimit The gas limit.\n  function feeModuleGasLimit() external view returns (uint32 _gasLimit);\n\n  /// @notice Address of the pool administrator, can change the name and symbol of pools created by factory.\n  /// @return Address of the pool administrator\n  function poolAdmin() external view returns (address);\n\n  /// @notice Address of the discount registry manager, can update the `discountRegistry` variable\n  /// @return Address of the discount registry manager\n  function discountRegistryManager() external view returns (address);\n\n  /// @notice Address of the discount registry, that allows querying swap fee discounts\n  /// @return Address of the discount registry\n  function discountRegistry() external view returns (address);\n\n  /// @notice The pool tape module that pools record into. The zero address means recording is disabled.\n  /// @return Address of the pool tape module.\n  function poolTape() external view returns (address);\n\n  /// @notice The gas limit forwarded to the pool tape on each record.\n  /// @return _gasLimit The gas limit.\n  function poolTapeGasLimit() external view returns (uint32 _gasLimit);\n\n  /// @notice The pool tape manager, which controls the pool tape configuration.\n  /// @return Address of the pool tape manager.\n  function poolTapeManager() external view returns (address);\n\n  /// @notice The MEV tax module queried to get the mev tax for a swap. The zero address means the MEV tax is disabled.\n  /// @return Address of the MEV tax module.\n  function mevTaxModule() external view returns (address);\n\n  /// @notice The gas limit forwarded to the MEV tax module on each read.\n  /// @return _gasLimit The gas limit.\n  function mevTaxModuleGasLimit() external view returns (uint32 _gasLimit);\n\n  /// @notice The quoter that resolves the fee of exact output quotes. Exact output quotes revert while unset.\n  /// @return Address of the exact output fee quoter.\n  function exactOutFeeQuoter() external view returns (address);\n}\n"},"node_modules/@openzeppelin/contracts/utils/Panic.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/Panic.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Helper library for emitting standardized panic codes.\n *\n * ```solidity\n * contract Example {\n *      using Panic for uint256;\n *\n *      // Use any of the declared internal constants\n *      function foo() { Panic.GENERIC.panic(); }\n *\n *      // Alternatively\n *      function foo() { Panic.panic(Panic.GENERIC); }\n * }\n * ```\n *\n * Follows the list from https://github.com/ethereum/solidity/blob/v0.8.24/libsolutil/ErrorCodes.h[libsolutil].\n *\n * _Available since v5.1._\n */\n// slither-disable-next-line unused-state\nlibrary Panic {\n    /// @dev generic / unspecified error\n    uint256 internal constant GENERIC = 0x00;\n    /// @dev used by the assert() builtin\n    uint256 internal constant ASSERT = 0x01;\n    /// @dev arithmetic underflow or overflow\n    uint256 internal constant UNDER_OVERFLOW = 0x11;\n    /// @dev division or modulo by zero\n    uint256 internal constant DIVISION_BY_ZERO = 0x12;\n    /// @dev enum conversion error\n    uint256 internal constant ENUM_CONVERSION_ERROR = 0x21;\n    /// @dev invalid encoding in storage\n    uint256 internal constant STORAGE_ENCODING_ERROR = 0x22;\n    /// @dev empty array pop\n    uint256 internal constant EMPTY_ARRAY_POP = 0x31;\n    /// @dev array out of bounds access\n    uint256 internal constant ARRAY_OUT_OF_BOUNDS = 0x32;\n    /// @dev resource error (too large allocation or too large array)\n    uint256 internal constant RESOURCE_ERROR = 0x41;\n    /// @dev calling invalid internal function\n    uint256 internal constant INVALID_INTERNAL_FUNCTION = 0x51;\n\n    /// @dev Reverts with a panic code. Recommended to use with\n    /// the internal constants with predefined codes.\n    function panic(uint256 code) internal pure {\n        assembly (\"memory-safe\") {\n            mstore(0x00, 0x4e487b71)\n            mstore(0x20, code)\n            revert(0x1c, 0x24)\n        }\n    }\n}\n"},"node_modules/@openzeppelin/contracts/utils/Context.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n\n    function _contextSuffixLength() internal view virtual returns (uint256) {\n        return 0;\n    }\n}\n"},"node_modules/@openzeppelin/contracts/utils/math/Math.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.6.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.20;\n\nimport {Panic} from \"../Panic.sol\";\nimport {SafeCast} from \"./SafeCast.sol\";\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n    enum Rounding {\n        Floor, // Toward negative infinity\n        Ceil, // Toward positive infinity\n        Trunc, // Toward zero\n        Expand // Away from zero\n    }\n\n    /**\n     * @dev Return the 512-bit addition of two uint256.\n     *\n     * The result is stored in two 256 variables such that sum = high * 2²⁵⁶ + low.\n     */\n    function add512(uint256 a, uint256 b) internal pure returns (uint256 high, uint256 low) {\n        assembly (\"memory-safe\") {\n            low := add(a, b)\n            high := lt(low, a)\n        }\n    }\n\n    /**\n     * @dev Return the 512-bit multiplication of two uint256.\n     *\n     * The result is stored in two 256 variables such that product = high * 2²⁵⁶ + low.\n     */\n    function mul512(uint256 a, uint256 b) internal pure returns (uint256 high, uint256 low) {\n        // 512-bit multiply [high low] = x * y. Compute the product mod 2²⁵⁶ and mod 2²⁵⁶ - 1, then use\n        // the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n        // variables such that product = high * 2²⁵⁶ + low.\n        assembly (\"memory-safe\") {\n            let mm := mulmod(a, b, not(0))\n            low := mul(a, b)\n            high := sub(sub(mm, low), lt(mm, low))\n        }\n    }\n\n    /**\n     * @dev Returns the addition of two unsigned integers, with a success flag (no overflow).\n     */\n    function tryAdd(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n        unchecked {\n            uint256 c = a + b;\n            success = c >= a;\n            result = c * SafeCast.toUint(success);\n        }\n    }\n\n    /**\n     * @dev Returns the subtraction of two unsigned integers, with a success flag (no overflow).\n     */\n    function trySub(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n        unchecked {\n            uint256 c = a - b;\n            success = c <= a;\n            result = c * SafeCast.toUint(success);\n        }\n    }\n\n    /**\n     * @dev Returns the multiplication of two unsigned integers, with a success flag (no overflow).\n     */\n    function tryMul(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n        unchecked {\n            uint256 c = a * b;\n            assembly (\"memory-safe\") {\n                // Only true when the multiplication doesn't overflow\n                // (c / a == b) || (a == 0)\n                success := or(eq(div(c, a), b), iszero(a))\n            }\n            // equivalent to: success ? c : 0\n            result = c * SafeCast.toUint(success);\n        }\n    }\n\n    /**\n     * @dev Returns the division of two unsigned integers, with a success flag (no division by zero).\n     */\n    function tryDiv(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n        unchecked {\n            success = b > 0;\n            assembly (\"memory-safe\") {\n                // The `DIV` opcode returns zero when the denominator is 0.\n                result := div(a, b)\n            }\n        }\n    }\n\n    /**\n     * @dev Returns the remainder of dividing two unsigned integers, with a success flag (no division by zero).\n     */\n    function tryMod(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n        unchecked {\n            success = b > 0;\n            assembly (\"memory-safe\") {\n                // The `MOD` opcode returns zero when the denominator is 0.\n                result := mod(a, b)\n            }\n        }\n    }\n\n    /**\n     * @dev Unsigned saturating addition, bounds to `2²⁵⁶ - 1` instead of overflowing.\n     */\n    function saturatingAdd(uint256 a, uint256 b) internal pure returns (uint256) {\n        (bool success, uint256 result) = tryAdd(a, b);\n        return ternary(success, result, type(uint256).max);\n    }\n\n    /**\n     * @dev Unsigned saturating subtraction, bounds to zero instead of overflowing.\n     */\n    function saturatingSub(uint256 a, uint256 b) internal pure returns (uint256) {\n        (, uint256 result) = trySub(a, b);\n        return result;\n    }\n\n    /**\n     * @dev Unsigned saturating multiplication, bounds to `2²⁵⁶ - 1` instead of overflowing.\n     */\n    function saturatingMul(uint256 a, uint256 b) internal pure returns (uint256) {\n        (bool success, uint256 result) = tryMul(a, b);\n        return ternary(success, result, type(uint256).max);\n    }\n\n    /**\n     * @dev Branchless ternary evaluation for `condition ? a : b`. Gas costs are constant.\n     *\n     * IMPORTANT: This function may reduce bytecode size and consume less gas when used standalone.\n     * However, the compiler may optimize Solidity ternary operations (i.e. `condition ? a : b`) to only compute\n     * one branch when needed, making this function more expensive.\n     */\n    function ternary(bool condition, uint256 a, uint256 b) internal pure returns (uint256) {\n        unchecked {\n            // branchless ternary works because:\n            // b ^ (a ^ b) == a\n            // b ^ 0 == b\n            return b ^ ((a ^ b) * SafeCast.toUint(condition));\n        }\n    }\n\n    /**\n     * @dev Returns the largest of two numbers.\n     */\n    function max(uint256 a, uint256 b) internal pure returns (uint256) {\n        return ternary(a > b, a, b);\n    }\n\n    /**\n     * @dev Returns the smallest of two numbers.\n     */\n    function min(uint256 a, uint256 b) internal pure returns (uint256) {\n        return ternary(a < b, a, b);\n    }\n\n    /**\n     * @dev Returns the average of two numbers. The result is rounded towards\n     * zero.\n     */\n    function average(uint256 a, uint256 b) internal pure returns (uint256) {\n        unchecked {\n            // (a + b) / 2 can overflow.\n            return (a & b) + (a ^ b) / 2;\n        }\n    }\n\n    /**\n     * @dev Returns the ceiling of the division of two numbers.\n     *\n     * This differs from standard division with `/` in that it rounds towards infinity instead\n     * of rounding towards zero.\n     */\n    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n        if (b == 0) {\n            // Guarantee the same behavior as in a regular Solidity division.\n            Panic.panic(Panic.DIVISION_BY_ZERO);\n        }\n\n        // The following calculation ensures accurate ceiling division without overflow.\n        // Since a is non-zero, (a - 1) / b will not overflow.\n        // The largest possible result occurs when (a - 1) / b is type(uint256).max,\n        // but the largest value we can obtain is type(uint256).max - 1, which happens\n        // when a = type(uint256).max and b = 1.\n        unchecked {\n            return SafeCast.toUint(a > 0) * ((a - 1) / b + 1);\n        }\n    }\n\n    /**\n     * @dev Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or\n     * denominator == 0.\n     *\n     * Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) with further edits by\n     * Uniswap Labs also under MIT license.\n     */\n    function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n        unchecked {\n            (uint256 high, uint256 low) = mul512(x, y);\n\n            // Handle non-overflow cases, 256 by 256 division.\n            if (high == 0) {\n                // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n                // The surrounding unchecked block does not change this fact.\n                // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n                return low / denominator;\n            }\n\n            // Make sure the result is less than 2²⁵⁶. Also prevents denominator == 0.\n            if (denominator <= high) {\n                Panic.panic(ternary(denominator == 0, Panic.DIVISION_BY_ZERO, Panic.UNDER_OVERFLOW));\n            }\n\n            ///////////////////////////////////////////////\n            // 512 by 256 division.\n            ///////////////////////////////////////////////\n\n            // Make division exact by subtracting the remainder from [high low].\n            uint256 remainder;\n            assembly (\"memory-safe\") {\n                // Compute remainder using mulmod.\n                remainder := mulmod(x, y, denominator)\n\n                // Subtract 256 bit number from 512 bit number.\n                high := sub(high, gt(remainder, low))\n                low := sub(low, remainder)\n            }\n\n            // Factor powers of two out of denominator and compute largest power of two divisor of denominator.\n            // Always >= 1. See https://cs.stackexchange.com/q/138556/92363.\n\n            uint256 twos = denominator & (0 - denominator);\n            assembly (\"memory-safe\") {\n                // Divide denominator by twos.\n                denominator := div(denominator, twos)\n\n                // Divide [high low] by twos.\n                low := div(low, twos)\n\n                // Flip twos such that it is 2²⁵⁶ / twos. If twos is zero, then it becomes one.\n                twos := add(div(sub(0, twos), twos), 1)\n            }\n\n            // Shift in bits from high into low.\n            low |= high * twos;\n\n            // Invert denominator mod 2²⁵⁶. Now that denominator is an odd number, it has an inverse modulo 2²⁵⁶ such\n            // that denominator * inv ≡ 1 mod 2²⁵⁶. Compute the inverse by starting with a seed that is correct for\n            // four bits. That is, denominator * inv ≡ 1 mod 2⁴.\n            uint256 inverse = (3 * denominator) ^ 2;\n\n            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also\n            // works in modular arithmetic, doubling the correct bits in each step.\n            inverse *= 2 - denominator * inverse; // inverse mod 2⁸\n            inverse *= 2 - denominator * inverse; // inverse mod 2¹⁶\n            inverse *= 2 - denominator * inverse; // inverse mod 2³²\n            inverse *= 2 - denominator * inverse; // inverse mod 2⁶⁴\n            inverse *= 2 - denominator * inverse; // inverse mod 2¹²⁸\n            inverse *= 2 - denominator * inverse; // inverse mod 2²⁵⁶\n\n            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n            // This will give us the correct result modulo 2²⁵⁶. Since the preconditions guarantee that the outcome is\n            // less than 2²⁵⁶, this is the final result. We don't need to compute the high bits of the result and high\n            // is no longer required.\n            result = low * inverse;\n            return result;\n        }\n    }\n\n    /**\n     * @dev Calculates x * y / denominator with full precision, following the selected rounding direction.\n     */\n    function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n        return mulDiv(x, y, denominator) + SafeCast.toUint(unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0);\n    }\n\n    /**\n     * @dev Calculates floor(x * y >> n) with full precision. Throws if result overflows a uint256.\n     */\n    function mulShr(uint256 x, uint256 y, uint8 n) internal pure returns (uint256 result) {\n        unchecked {\n            (uint256 high, uint256 low) = mul512(x, y);\n            if (high >= 1 << n) {\n                Panic.panic(Panic.UNDER_OVERFLOW);\n            }\n            return (high << (256 - n)) | (low >> n);\n        }\n    }\n\n    /**\n     * @dev Calculates x * y >> n with full precision, following the selected rounding direction.\n     */\n    function mulShr(uint256 x, uint256 y, uint8 n, Rounding rounding) internal pure returns (uint256) {\n        return mulShr(x, y, n) + SafeCast.toUint(unsignedRoundsUp(rounding) && mulmod(x, y, 1 << n) > 0);\n    }\n\n    /**\n     * @dev Calculate the modular multiplicative inverse of a number in Z/nZ.\n     *\n     * If n is a prime, then Z/nZ is a field. In that case all elements are inversible, except 0.\n     * If n is not a prime, then Z/nZ is not a field, and some elements might not be inversible.\n     *\n     * If the input value is not inversible, 0 is returned.\n     *\n     * NOTE: If you know for sure that n is (big) a prime, it may be cheaper to use Fermat's little theorem and get the\n     * inverse using `Math.modExp(a, n - 2, n)`. See {invModPrime}.\n     */\n    function invMod(uint256 a, uint256 n) internal pure returns (uint256) {\n        unchecked {\n            if (n == 0) return 0;\n\n            // The inverse modulo is calculated using the Extended Euclidean Algorithm (iterative version)\n            // Used to compute integers x and y such that: ax + ny = gcd(a, n).\n            // When the gcd is 1, then the inverse of a modulo n exists and it's x.\n            // ax + ny = 1\n            // ax = 1 + (-y)n\n            // ax ≡ 1 (mod n) # x is the inverse of a modulo n\n\n            // If the remainder is 0 the gcd is n right away.\n            uint256 remainder = a % n;\n            uint256 gcd = n;\n\n            // Therefore the initial coefficients are:\n            // ax + ny = gcd(a, n) = n\n            // 0a + 1n = n\n            int256 x = 0;\n            int256 y = 1;\n\n            while (remainder != 0) {\n                uint256 quotient = gcd / remainder;\n\n                (gcd, remainder) = (\n                    // The old remainder is the next gcd to try.\n                    remainder,\n                    // Compute the next remainder.\n                    // Can't overflow given that (a % gcd) * (gcd // (a % gcd)) <= gcd\n                    // where gcd is at most n (capped to type(uint256).max)\n                    gcd - remainder * quotient\n                );\n\n                (x, y) = (\n                    // Increment the coefficient of a.\n                    y,\n                    // Decrement the coefficient of n.\n                    // Can overflow, but the result is casted to uint256 so that the\n                    // next value of y is \"wrapped around\" to a value between 0 and n - 1.\n                    x - y * int256(quotient)\n                );\n            }\n\n            if (gcd != 1) return 0; // No inverse exists.\n            return ternary(x < 0, n - uint256(-x), uint256(x)); // Wrap the result if it's negative.\n        }\n    }\n\n    /**\n     * @dev Variant of {invMod}. More efficient, but only works if `p` is known to be a prime greater than `2`.\n     *\n     * From https://en.wikipedia.org/wiki/Fermat%27s_little_theorem[Fermat's little theorem], we know that if p is\n     * prime, then `a**(p-1) ≡ 1 mod p`. As a consequence, we have `a * a**(p-2) ≡ 1 mod p`, which means that\n     * `a**(p-2)` is the modular multiplicative inverse of a in Fp.\n     *\n     * NOTE: this function does NOT check that `p` is a prime greater than `2`.\n     */\n    function invModPrime(uint256 a, uint256 p) internal view returns (uint256) {\n        unchecked {\n            return Math.modExp(a, p - 2, p);\n        }\n    }\n\n    /**\n     * @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m)\n     *\n     * Requirements:\n     * - modulus can't be zero\n     * - underlying staticcall to precompile must succeed\n     *\n     * IMPORTANT: The result is only valid if the underlying call succeeds. When using this function, make\n     * sure the chain you're using it on supports the precompiled contract for modular exponentiation\n     * at address 0x05 as specified in https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise,\n     * the underlying function will succeed given the lack of a revert, but the result may be incorrectly\n     * interpreted as 0.\n     */\n    function modExp(uint256 b, uint256 e, uint256 m) internal view returns (uint256) {\n        (bool success, uint256 result) = tryModExp(b, e, m);\n        if (!success) {\n            Panic.panic(Panic.DIVISION_BY_ZERO);\n        }\n        return result;\n    }\n\n    /**\n     * @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m).\n     * It includes a success flag indicating if the operation succeeded. Operation will be marked as failed if trying\n     * to operate modulo 0 or if the underlying precompile reverted.\n     *\n     * IMPORTANT: The result is only valid if the success flag is true. When using this function, make sure the chain\n     * you're using it on supports the precompiled contract for modular exponentiation at address 0x05 as specified in\n     * https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise, the underlying function will succeed given the lack\n     * of a revert, but the result may be incorrectly interpreted as 0.\n     */\n    function tryModExp(uint256 b, uint256 e, uint256 m) internal view returns (bool success, uint256 result) {\n        if (m == 0) return (false, 0);\n        assembly (\"memory-safe\") {\n            let ptr := mload(0x40)\n            // | Offset    | Content    | Content (Hex)                                                      |\n            // |-----------|------------|--------------------------------------------------------------------|\n            // | 0x00:0x1f | size of b  | 0x0000000000000000000000000000000000000000000000000000000000000020 |\n            // | 0x20:0x3f | size of e  | 0x0000000000000000000000000000000000000000000000000000000000000020 |\n            // | 0x40:0x5f | size of m  | 0x0000000000000000000000000000000000000000000000000000000000000020 |\n            // | 0x60:0x7f | value of b | 0x<.............................................................b> |\n            // | 0x80:0x9f | value of e | 0x<.............................................................e> |\n            // | 0xa0:0xbf | value of m | 0x<.............................................................m> |\n            mstore(ptr, 0x20)\n            mstore(add(ptr, 0x20), 0x20)\n            mstore(add(ptr, 0x40), 0x20)\n            mstore(add(ptr, 0x60), b)\n            mstore(add(ptr, 0x80), e)\n            mstore(add(ptr, 0xa0), m)\n\n            // Given the result < m, it's guaranteed to fit in 32 bytes,\n            // so we can use the memory scratch space located at offset 0.\n            success := staticcall(gas(), 0x05, ptr, 0xc0, 0x00, 0x20)\n            result := mload(0x00)\n        }\n    }\n\n    /**\n     * @dev Variant of {modExp} that supports inputs of arbitrary length.\n     */\n    function modExp(bytes memory b, bytes memory e, bytes memory m) internal view returns (bytes memory) {\n        (bool success, bytes memory result) = tryModExp(b, e, m);\n        if (!success) {\n            Panic.panic(Panic.DIVISION_BY_ZERO);\n        }\n        return result;\n    }\n\n    /**\n     * @dev Variant of {tryModExp} that supports inputs of arbitrary length.\n     */\n    function tryModExp(\n        bytes memory b,\n        bytes memory e,\n        bytes memory m\n    ) internal view returns (bool success, bytes memory result) {\n        if (_zeroBytes(m)) return (false, new bytes(0));\n\n        uint256 mLen = m.length;\n\n        // Encode call args in result and move the free memory pointer\n        result = abi.encodePacked(b.length, e.length, mLen, b, e, m);\n\n        assembly (\"memory-safe\") {\n            let dataPtr := add(result, 0x20)\n            // Write result on top of args to avoid allocating extra memory.\n            success := staticcall(gas(), 0x05, dataPtr, mload(result), dataPtr, mLen)\n            // Overwrite the length.\n            // result.length > returndatasize() is guaranteed because returndatasize() == m.length\n            mstore(result, mLen)\n            // Set the memory pointer after the returned data.\n            mstore(0x40, add(dataPtr, mLen))\n        }\n    }\n\n    /**\n     * @dev Returns whether the provided byte array is zero.\n     */\n    function _zeroBytes(bytes memory buffer) private pure returns (bool) {\n        uint256 chunk;\n        for (uint256 i = 0; i < buffer.length; i += 0x20) {\n            // See _unsafeReadBytesOffset from utils/Bytes.sol\n            assembly (\"memory-safe\") {\n                chunk := mload(add(add(buffer, 0x20), i))\n            }\n            if (chunk >> (8 * saturatingSub(i + 0x20, buffer.length)) != 0) {\n                return false;\n            }\n        }\n        return true;\n    }\n\n    /**\n     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded\n     * towards zero.\n     *\n     * This method is based on Newton's method for computing square roots; the algorithm is restricted to only\n     * using integer operations.\n     */\n    function sqrt(uint256 a) internal pure returns (uint256) {\n        unchecked {\n            // Take care of easy edge cases when a == 0 or a == 1\n            if (a <= 1) {\n                return a;\n            }\n\n            // In this function, we use Newton's method to get a root of `f(x) := x² - a`. It involves building a\n            // sequence x_n that converges toward sqrt(a). For each iteration x_n, we also define the error between\n            // the current value as `ε_n = | x_n - sqrt(a) |`.\n            //\n            // For our first estimation, we consider `e` the smallest power of 2 which is bigger than the square root\n            // of the target. (i.e. `2**(e-1) ≤ sqrt(a) < 2**e`). We know that `e ≤ 128` because `(2¹²⁸)² = 2²⁵⁶` is\n            // bigger than any uint256.\n            //\n            // By noticing that\n            // `2**(e-1) ≤ sqrt(a) < 2**e → (2**(e-1))² ≤ a < (2**e)² → 2**(2*e-2) ≤ a < 2**(2*e)`\n            // we can deduce that `e - 1` is `log2(a) / 2`. We can thus compute `x_n = 2**(e-1)` using a method similar\n            // to the msb function.\n            uint256 aa = a;\n            uint256 xn = 1;\n\n            if (aa >= (1 << 128)) {\n                aa >>= 128;\n                xn <<= 64;\n            }\n            if (aa >= (1 << 64)) {\n                aa >>= 64;\n                xn <<= 32;\n            }\n            if (aa >= (1 << 32)) {\n                aa >>= 32;\n                xn <<= 16;\n            }\n            if (aa >= (1 << 16)) {\n                aa >>= 16;\n                xn <<= 8;\n            }\n            if (aa >= (1 << 8)) {\n                aa >>= 8;\n                xn <<= 4;\n            }\n            if (aa >= (1 << 4)) {\n                aa >>= 4;\n                xn <<= 2;\n            }\n            if (aa >= (1 << 2)) {\n                xn <<= 1;\n            }\n\n            // We now have x_n such that `x_n = 2**(e-1) ≤ sqrt(a) < 2**e = 2 * x_n`. This implies ε_n ≤ 2**(e-1).\n            //\n            // We can refine our estimation by noticing that the middle of that interval minimizes the error.\n            // If we move x_n to equal 2**(e-1) + 2**(e-2), then we reduce the error to ε_n ≤ 2**(e-2).\n            // This is going to be our x_0 (and ε_0)\n            xn = (3 * xn) >> 1; // ε_0 := | x_0 - sqrt(a) | ≤ 2**(e-2)\n\n            // From here, Newton's method give us:\n            // x_{n+1} = (x_n + a / x_n) / 2\n            //\n            // One should note that:\n            // x_{n+1}² - a = ((x_n + a / x_n) / 2)² - a\n            //              = ((x_n² + a) / (2 * x_n))² - a\n            //              = (x_n⁴ + 2 * a * x_n² + a²) / (4 * x_n²) - a\n            //              = (x_n⁴ + 2 * a * x_n² + a² - 4 * a * x_n²) / (4 * x_n²)\n            //              = (x_n⁴ - 2 * a * x_n² + a²) / (4 * x_n²)\n            //              = (x_n² - a)² / (2 * x_n)²\n            //              = ((x_n² - a) / (2 * x_n))²\n            //              ≥ 0\n            // Which proves that for all n ≥ 1, sqrt(a) ≤ x_n\n            //\n            // This gives us the proof of quadratic convergence of the sequence:\n            // ε_{n+1} = | x_{n+1} - sqrt(a) |\n            //         = | (x_n + a / x_n) / 2 - sqrt(a) |\n            //         = | (x_n² + a - 2*x_n*sqrt(a)) / (2 * x_n) |\n            //         = | (x_n - sqrt(a))² / (2 * x_n) |\n            //         = | ε_n² / (2 * x_n) |\n            //         = ε_n² / | (2 * x_n) |\n            //\n            // For the first iteration, we have a special case where x_0 is known:\n            // ε_1 = ε_0² / | (2 * x_0) |\n            //     ≤ (2**(e-2))² / (2 * (2**(e-1) + 2**(e-2)))\n            //     ≤ 2**(2*e-4) / (3 * 2**(e-1))\n            //     ≤ 2**(e-3) / 3\n            //     ≤ 2**(e-3-log2(3))\n            //     ≤ 2**(e-4.5)\n            //\n            // For the following iterations, we use the fact that, 2**(e-1) ≤ sqrt(a) ≤ x_n:\n            // ε_{n+1} = ε_n² / | (2 * x_n) |\n            //         ≤ (2**(e-k))² / (2 * 2**(e-1))\n            //         ≤ 2**(2*e-2*k) / 2**e\n            //         ≤ 2**(e-2*k)\n            xn = (xn + a / xn) >> 1; // ε_1 := | x_1 - sqrt(a) | ≤ 2**(e-4.5)  -- special case, see above\n            xn = (xn + a / xn) >> 1; // ε_2 := | x_2 - sqrt(a) | ≤ 2**(e-9)    -- general case with k = 4.5\n            xn = (xn + a / xn) >> 1; // ε_3 := | x_3 - sqrt(a) | ≤ 2**(e-18)   -- general case with k = 9\n            xn = (xn + a / xn) >> 1; // ε_4 := | x_4 - sqrt(a) | ≤ 2**(e-36)   -- general case with k = 18\n            xn = (xn + a / xn) >> 1; // ε_5 := | x_5 - sqrt(a) | ≤ 2**(e-72)   -- general case with k = 36\n            xn = (xn + a / xn) >> 1; // ε_6 := | x_6 - sqrt(a) | ≤ 2**(e-144)  -- general case with k = 72\n\n            // Because e ≤ 128 (as discussed during the first estimation phase), we know have reached a precision\n            // ε_6 ≤ 2**(e-144) < 1. Given we're operating on integers, then we can ensure that xn is now either\n            // sqrt(a) or sqrt(a) + 1.\n            return xn - SafeCast.toUint(xn > a / xn);\n        }\n    }\n\n    /**\n     * @dev Calculates sqrt(a), following the selected rounding direction.\n     */\n    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = sqrt(a);\n            return result + SafeCast.toUint(unsignedRoundsUp(rounding) && result * result < a);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 2 of a positive value rounded towards zero.\n     * Returns 0 if given 0.\n     */\n    function log2(uint256 x) internal pure returns (uint256 r) {\n        // If value has upper 128 bits set, log2 result is at least 128\n        r = SafeCast.toUint(x > 0xffffffffffffffffffffffffffffffff) << 7;\n        // If upper 64 bits of 128-bit half set, add 64 to result\n        r |= SafeCast.toUint((x >> r) > 0xffffffffffffffff) << 6;\n        // If upper 32 bits of 64-bit half set, add 32 to result\n        r |= SafeCast.toUint((x >> r) > 0xffffffff) << 5;\n        // If upper 16 bits of 32-bit half set, add 16 to result\n        r |= SafeCast.toUint((x >> r) > 0xffff) << 4;\n        // If upper 8 bits of 16-bit half set, add 8 to result\n        r |= SafeCast.toUint((x >> r) > 0xff) << 3;\n        // If upper 4 bits of 8-bit half set, add 4 to result\n        r |= SafeCast.toUint((x >> r) > 0xf) << 2;\n\n        // Shifts value right by the current result and use it as an index into this lookup table:\n        //\n        // | x (4 bits) |  index  | table[index] = MSB position |\n        // |------------|---------|-----------------------------|\n        // |    0000    |    0    |        table[0] = 0         |\n        // |    0001    |    1    |        table[1] = 0         |\n        // |    0010    |    2    |        table[2] = 1         |\n        // |    0011    |    3    |        table[3] = 1         |\n        // |    0100    |    4    |        table[4] = 2         |\n        // |    0101    |    5    |        table[5] = 2         |\n        // |    0110    |    6    |        table[6] = 2         |\n        // |    0111    |    7    |        table[7] = 2         |\n        // |    1000    |    8    |        table[8] = 3         |\n        // |    1001    |    9    |        table[9] = 3         |\n        // |    1010    |   10    |        table[10] = 3        |\n        // |    1011    |   11    |        table[11] = 3        |\n        // |    1100    |   12    |        table[12] = 3        |\n        // |    1101    |   13    |        table[13] = 3        |\n        // |    1110    |   14    |        table[14] = 3        |\n        // |    1111    |   15    |        table[15] = 3        |\n        //\n        // The lookup table is represented as a 32-byte value with the MSB positions for 0-15 in the first 16 bytes (most significant half).\n        assembly (\"memory-safe\") {\n            r := or(r, byte(shr(r, x), 0x0000010102020202030303030303030300000000000000000000000000000000))\n        }\n    }\n\n    /**\n     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log2(value);\n            return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << result < value);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 10 of a positive value rounded towards zero.\n     * Returns 0 if given 0.\n     */\n    function log10(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >= 10 ** 64) {\n                value /= 10 ** 64;\n                result += 64;\n            }\n            if (value >= 10 ** 32) {\n                value /= 10 ** 32;\n                result += 32;\n            }\n            if (value >= 10 ** 16) {\n                value /= 10 ** 16;\n                result += 16;\n            }\n            if (value >= 10 ** 8) {\n                value /= 10 ** 8;\n                result += 8;\n            }\n            if (value >= 10 ** 4) {\n                value /= 10 ** 4;\n                result += 4;\n            }\n            if (value >= 10 ** 2) {\n                value /= 10 ** 2;\n                result += 2;\n            }\n            if (value >= 10 ** 1) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log10(value);\n            return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 10 ** result < value);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 256 of a positive value rounded towards zero.\n     * Returns 0 if given 0.\n     *\n     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n     */\n    function log256(uint256 x) internal pure returns (uint256 r) {\n        // If value has upper 128 bits set, log2 result is at least 128\n        r = SafeCast.toUint(x > 0xffffffffffffffffffffffffffffffff) << 7;\n        // If upper 64 bits of 128-bit half set, add 64 to result\n        r |= SafeCast.toUint((x >> r) > 0xffffffffffffffff) << 6;\n        // If upper 32 bits of 64-bit half set, add 32 to result\n        r |= SafeCast.toUint((x >> r) > 0xffffffff) << 5;\n        // If upper 16 bits of 32-bit half set, add 16 to result\n        r |= SafeCast.toUint((x >> r) > 0xffff) << 4;\n        // Add 1 if upper 8 bits of 16-bit half set, and divide accumulated result by 8\n        return (r >> 3) | SafeCast.toUint((x >> r) > 0xff);\n    }\n\n    /**\n     * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log256(value);\n            return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << (result << 3) < value);\n        }\n    }\n\n    /**\n     * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers.\n     */\n    function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) {\n        return uint8(rounding) % 2 == 1;\n    }\n\n    /**\n     * @dev Counts the number of leading zero bits in a uint256.\n     */\n    function clz(uint256 x) internal pure returns (uint256) {\n        return ternary(x == 0, 256, 255 - log2(x));\n    }\n}\n"},"node_modules/@openzeppelin/contracts/interfaces/IERC20.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC20.sol)\n\npragma solidity >=0.4.16;\n\nimport {IERC20} from \"../token/ERC20/IERC20.sol\";\n"},"node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.5.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"./IERC20.sol\";\nimport {IERC20Metadata} from \"./extensions/IERC20Metadata.sol\";\nimport {Context} from \"../../utils/Context.sol\";\nimport {IERC20Errors} from \"../../interfaces/draft-IERC6093.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC-20\n * applications.\n */\nabstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors {\n    mapping(address account => uint256) private _balances;\n\n    mapping(address account => mapping(address spender => uint256)) private _allowances;\n\n    uint256 private _totalSupply;\n\n    string private _name;\n    string private _symbol;\n\n    /**\n     * @dev Sets the values for {name} and {symbol}.\n     *\n     * Both values are immutable: they can only be set once during construction.\n     */\n    constructor(string memory name_, string memory symbol_) {\n        _name = name_;\n        _symbol = symbol_;\n    }\n\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() public view virtual returns (string memory) {\n        return _name;\n    }\n\n    /**\n     * @dev Returns the symbol of the token, usually a shorter version of the\n     * name.\n     */\n    function symbol() public view virtual returns (string memory) {\n        return _symbol;\n    }\n\n    /**\n     * @dev Returns the number of decimals used to get its user representation.\n     * For example, if `decimals` equals `2`, a balance of `505` tokens should\n     * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n     *\n     * Tokens usually opt for a value of 18, imitating the relationship between\n     * Ether and Wei. This is the default value returned by this function, unless\n     * it's overridden.\n     *\n     * NOTE: This information is only used for _display_ purposes: it in\n     * no way affects any of the arithmetic of the contract, including\n     * {IERC20-balanceOf} and {IERC20-transfer}.\n     */\n    function decimals() public view virtual returns (uint8) {\n        return 18;\n    }\n\n    /// @inheritdoc IERC20\n    function totalSupply() public view virtual returns (uint256) {\n        return _totalSupply;\n    }\n\n    /// @inheritdoc IERC20\n    function balanceOf(address account) public view virtual returns (uint256) {\n        return _balances[account];\n    }\n\n    /**\n     * @dev See {IERC20-transfer}.\n     *\n     * Requirements:\n     *\n     * - `to` cannot be the zero address.\n     * - the caller must have a balance of at least `value`.\n     */\n    function transfer(address to, uint256 value) public virtual returns (bool) {\n        address owner = _msgSender();\n        _transfer(owner, to, value);\n        return true;\n    }\n\n    /// @inheritdoc IERC20\n    function allowance(address owner, address spender) public view virtual returns (uint256) {\n        return _allowances[owner][spender];\n    }\n\n    /**\n     * @dev See {IERC20-approve}.\n     *\n     * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on\n     * `transferFrom`. This is semantically equivalent to an infinite approval.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function approve(address spender, uint256 value) public virtual returns (bool) {\n        address owner = _msgSender();\n        _approve(owner, spender, value);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-transferFrom}.\n     *\n     * Skips emitting an {Approval} event indicating an allowance update. This is not\n     * required by the ERC. See {xref-ERC20-_approve-address-address-uint256-bool-}[_approve].\n     *\n     * NOTE: Does not update the allowance if the current allowance\n     * is the maximum `uint256`.\n     *\n     * Requirements:\n     *\n     * - `from` and `to` cannot be the zero address.\n     * - `from` must have a balance of at least `value`.\n     * - the caller must have allowance for ``from``'s tokens of at least\n     * `value`.\n     */\n    function transferFrom(address from, address to, uint256 value) public virtual returns (bool) {\n        address spender = _msgSender();\n        _spendAllowance(from, spender, value);\n        _transfer(from, to, value);\n        return true;\n    }\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to`.\n     *\n     * This internal function is equivalent to {transfer}, and can be used to\n     * e.g. implement automatic token fees, slashing mechanisms, etc.\n     *\n     * Emits a {Transfer} event.\n     *\n     * NOTE: This function is not virtual, {_update} should be overridden instead.\n     */\n    function _transfer(address from, address to, uint256 value) internal {\n        if (from == address(0)) {\n            revert ERC20InvalidSender(address(0));\n        }\n        if (to == address(0)) {\n            revert ERC20InvalidReceiver(address(0));\n        }\n        _update(from, to, value);\n    }\n\n    /**\n     * @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from`\n     * (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding\n     * this function.\n     *\n     * Emits a {Transfer} event.\n     */\n    function _update(address from, address to, uint256 value) internal virtual {\n        if (from == address(0)) {\n            // Overflow check required: The rest of the code assumes that totalSupply never overflows\n            _totalSupply += value;\n        } else {\n            uint256 fromBalance = _balances[from];\n            if (fromBalance < value) {\n                revert ERC20InsufficientBalance(from, fromBalance, value);\n            }\n            unchecked {\n                // Overflow not possible: value <= fromBalance <= totalSupply.\n                _balances[from] = fromBalance - value;\n            }\n        }\n\n        if (to == address(0)) {\n            unchecked {\n                // Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply.\n                _totalSupply -= value;\n            }\n        } else {\n            unchecked {\n                // Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256.\n                _balances[to] += value;\n            }\n        }\n\n        emit Transfer(from, to, value);\n    }\n\n    /**\n     * @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0).\n     * Relies on the `_update` mechanism\n     *\n     * Emits a {Transfer} event with `from` set to the zero address.\n     *\n     * NOTE: This function is not virtual, {_update} should be overridden instead.\n     */\n    function _mint(address account, uint256 value) internal {\n        if (account == address(0)) {\n            revert ERC20InvalidReceiver(address(0));\n        }\n        _update(address(0), account, value);\n    }\n\n    /**\n     * @dev Destroys a `value` amount of tokens from `account`, lowering the total supply.\n     * Relies on the `_update` mechanism.\n     *\n     * Emits a {Transfer} event with `to` set to the zero address.\n     *\n     * NOTE: This function is not virtual, {_update} should be overridden instead\n     */\n    function _burn(address account, uint256 value) internal {\n        if (account == address(0)) {\n            revert ERC20InvalidSender(address(0));\n        }\n        _update(account, address(0), value);\n    }\n\n    /**\n     * @dev Sets `value` as the allowance of `spender` over the `owner`'s tokens.\n     *\n     * This internal function is equivalent to `approve`, and can be used to\n     * e.g. set automatic allowances for certain subsystems, etc.\n     *\n     * Emits an {Approval} event.\n     *\n     * Requirements:\n     *\n     * - `owner` cannot be the zero address.\n     * - `spender` cannot be the zero address.\n     *\n     * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.\n     */\n    function _approve(address owner, address spender, uint256 value) internal {\n        _approve(owner, spender, value, true);\n    }\n\n    /**\n     * @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event.\n     *\n     * By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by\n     * `_spendAllowance` during the `transferFrom` operation sets the flag to false. This saves gas by not emitting any\n     * `Approval` event during `transferFrom` operations.\n     *\n     * Anyone who wishes to continue emitting `Approval` events on the `transferFrom` operation can force the flag to\n     * true using the following override:\n     *\n     * ```solidity\n     * function _approve(address owner, address spender, uint256 value, bool) internal virtual override {\n     *     super._approve(owner, spender, value, true);\n     * }\n     * ```\n     *\n     * Requirements are the same as {_approve}.\n     */\n    function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual {\n        if (owner == address(0)) {\n            revert ERC20InvalidApprover(address(0));\n        }\n        if (spender == address(0)) {\n            revert ERC20InvalidSpender(address(0));\n        }\n        _allowances[owner][spender] = value;\n        if (emitEvent) {\n            emit Approval(owner, spender, value);\n        }\n    }\n\n    /**\n     * @dev Updates `owner`'s allowance for `spender` based on spent `value`.\n     *\n     * Does not update the allowance value in case of infinite allowance.\n     * Revert if not enough allowance is available.\n     *\n     * Does not emit an {Approval} event.\n     */\n    function _spendAllowance(address owner, address spender, uint256 value) internal virtual {\n        uint256 currentAllowance = allowance(owner, spender);\n        if (currentAllowance < type(uint256).max) {\n            if (currentAllowance < value) {\n                revert ERC20InsufficientAllowance(spender, currentAllowance, value);\n            }\n            unchecked {\n                _approve(owner, spender, currentAllowance - value, false);\n            }\n        }\n    }\n}\n"},"node_modules/@openzeppelin/contracts/utils/StorageSlot.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/StorageSlot.sol)\n// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Library for reading and writing primitive types to specific storage slots.\n *\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\n * This library helps with reading and writing to such slots without the need for inline assembly.\n *\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\n *\n * Example usage to set ERC-1967 implementation slot:\n * ```solidity\n * contract ERC1967 {\n *     // Define the slot. Alternatively, use the SlotDerivation library to derive the slot.\n *     bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n *\n *     function _getImplementation() internal view returns (address) {\n *         return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n *     }\n *\n *     function _setImplementation(address newImplementation) internal {\n *         require(newImplementation.code.length > 0);\n *         StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n *     }\n * }\n * ```\n *\n * TIP: Consider using this library along with {SlotDerivation}.\n */\nlibrary StorageSlot {\n    struct AddressSlot {\n        address value;\n    }\n\n    struct BooleanSlot {\n        bool value;\n    }\n\n    struct Bytes32Slot {\n        bytes32 value;\n    }\n\n    struct Uint256Slot {\n        uint256 value;\n    }\n\n    struct Int256Slot {\n        int256 value;\n    }\n\n    struct StringSlot {\n        string value;\n    }\n\n    struct BytesSlot {\n        bytes value;\n    }\n\n    /**\n     * @dev Returns an `AddressSlot` with member `value` located at `slot`.\n     */\n    function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `BooleanSlot` with member `value` located at `slot`.\n     */\n    function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `Bytes32Slot` with member `value` located at `slot`.\n     */\n    function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `Uint256Slot` with member `value` located at `slot`.\n     */\n    function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `Int256Slot` with member `value` located at `slot`.\n     */\n    function getInt256Slot(bytes32 slot) internal pure returns (Int256Slot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `StringSlot` with member `value` located at `slot`.\n     */\n    function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `StringSlot` representation of the string storage pointer `store`.\n     */\n    function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := store.slot\n        }\n    }\n\n    /**\n     * @dev Returns a `BytesSlot` with member `value` located at `slot`.\n     */\n    function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.\n     */\n    function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := store.slot\n        }\n    }\n}\n"},"node_modules/@openzeppelin/contracts/interfaces/IERC165.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC165.sol)\n\npragma solidity >=0.4.16;\n\nimport {IERC165} from \"../utils/introspection/IERC165.sol\";\n"},"node_modules/@openzeppelin/contracts/token/ERC20/IERC20.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/IERC20.sol)\n\npragma solidity >=0.4.16;\n\n/**\n * @dev Interface of the ERC-20 standard as defined in the ERC.\n */\ninterface IERC20 {\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n\n    /**\n     * @dev Returns the value of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the value of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves a `value` amount of tokens from the caller's account to `to`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address to, uint256 value) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n     * caller's tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender's allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 value) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to` using the\n     * allowance mechanism. `value` is then deducted from the caller's\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(address from, address to, uint256 value) external returns (bool);\n}\n"},"node_modules/@openzeppelin/contracts/interfaces/IERC1363.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC1363.sol)\n\npragma solidity >=0.6.2;\n\nimport {IERC20} from \"./IERC20.sol\";\nimport {IERC165} from \"./IERC165.sol\";\n\n/**\n * @title IERC1363\n * @dev Interface of the ERC-1363 standard as defined in the https://eips.ethereum.org/EIPS/eip-1363[ERC-1363].\n *\n * Defines an extension interface for ERC-20 tokens that supports executing code on a recipient contract\n * after `transfer` or `transferFrom`, or code on a spender contract after `approve`, in a single transaction.\n */\ninterface IERC1363 is IERC20, IERC165 {\n    /*\n     * Note: the ERC-165 identifier for this interface is 0xb0202a11.\n     * 0xb0202a11 ===\n     *   bytes4(keccak256('transferAndCall(address,uint256)')) ^\n     *   bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^\n     *   bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^\n     *   bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) ^\n     *   bytes4(keccak256('approveAndCall(address,uint256)')) ^\n     *   bytes4(keccak256('approveAndCall(address,uint256,bytes)'))\n     */\n\n    /**\n     * @dev Moves a `value` amount of tokens from the caller's account to `to`\n     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\n     * @param to The address which you want to transfer to.\n     * @param value The amount of tokens to be transferred.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function transferAndCall(address to, uint256 value) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from the caller's account to `to`\n     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\n     * @param to The address which you want to transfer to.\n     * @param value The amount of tokens to be transferred.\n     * @param data Additional data with no specified format, sent in call to `to`.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism\n     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\n     * @param from The address which you want to send tokens from.\n     * @param to The address which you want to transfer to.\n     * @param value The amount of tokens to be transferred.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function transferFromAndCall(address from, address to, uint256 value) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism\n     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\n     * @param from The address which you want to send tokens from.\n     * @param to The address which you want to transfer to.\n     * @param value The amount of tokens to be transferred.\n     * @param data Additional data with no specified format, sent in call to `to`.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function transferFromAndCall(address from, address to, uint256 value, bytes calldata data) external returns (bool);\n\n    /**\n     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n     * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.\n     * @param spender The address which will spend the funds.\n     * @param value The amount of tokens to be spent.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function approveAndCall(address spender, uint256 value) external returns (bool);\n\n    /**\n     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n     * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.\n     * @param spender The address which will spend the funds.\n     * @param value The amount of tokens to be spent.\n     * @param data Additional data with no specified format, sent in call to `spender`.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function approveAndCall(address spender, uint256 value, bytes calldata data) external returns (bool);\n}\n"},"node_modules/@openzeppelin/contracts/utils/math/SafeCast.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.6.0) (utils/math/SafeCast.sol)\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX/bool casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeCast {\n    /**\n     * @dev Value doesn't fit in a uint of `bits` size.\n     */\n    error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value);\n\n    /**\n     * @dev An int value doesn't fit in a uint of `bits` size.\n     */\n    error SafeCastOverflowedIntToUint(int256 value);\n\n    /**\n     * @dev Value doesn't fit in an int of `bits` size.\n     */\n    error SafeCastOverflowedIntDowncast(uint8 bits, int256 value);\n\n    /**\n     * @dev A uint value doesn't fit in an int of `bits` size.\n     */\n    error SafeCastOverflowedUintToInt(uint256 value);\n\n    /**\n     * @dev Returns the downcasted uint248 from uint256, reverting on\n     * overflow (when the input is greater than largest uint248).\n     *\n     * Counterpart to Solidity's `uint248` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 248 bits\n     */\n    function toUint248(uint256 value) internal pure returns (uint248) {\n        if (value > type(uint248).max) {\n            revert SafeCastOverflowedUintDowncast(248, value);\n        }\n        return uint248(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint240 from uint256, reverting on\n     * overflow (when the input is greater than largest uint240).\n     *\n     * Counterpart to Solidity's `uint240` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 240 bits\n     */\n    function toUint240(uint256 value) internal pure returns (uint240) {\n        if (value > type(uint240).max) {\n            revert SafeCastOverflowedUintDowncast(240, value);\n        }\n        return uint240(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint232 from uint256, reverting on\n     * overflow (when the input is greater than largest uint232).\n     *\n     * Counterpart to Solidity's `uint232` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 232 bits\n     */\n    function toUint232(uint256 value) internal pure returns (uint232) {\n        if (value > type(uint232).max) {\n            revert SafeCastOverflowedUintDowncast(232, value);\n        }\n        return uint232(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint224 from uint256, reverting on\n     * overflow (when the input is greater than largest uint224).\n     *\n     * Counterpart to Solidity's `uint224` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 224 bits\n     */\n    function toUint224(uint256 value) internal pure returns (uint224) {\n        if (value > type(uint224).max) {\n            revert SafeCastOverflowedUintDowncast(224, value);\n        }\n        return uint224(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint216 from uint256, reverting on\n     * overflow (when the input is greater than largest uint216).\n     *\n     * Counterpart to Solidity's `uint216` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 216 bits\n     */\n    function toUint216(uint256 value) internal pure returns (uint216) {\n        if (value > type(uint216).max) {\n            revert SafeCastOverflowedUintDowncast(216, value);\n        }\n        return uint216(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint208 from uint256, reverting on\n     * overflow (when the input is greater than largest uint208).\n     *\n     * Counterpart to Solidity's `uint208` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 208 bits\n     */\n    function toUint208(uint256 value) internal pure returns (uint208) {\n        if (value > type(uint208).max) {\n            revert SafeCastOverflowedUintDowncast(208, value);\n        }\n        return uint208(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint200 from uint256, reverting on\n     * overflow (when the input is greater than largest uint200).\n     *\n     * Counterpart to Solidity's `uint200` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 200 bits\n     */\n    function toUint200(uint256 value) internal pure returns (uint200) {\n        if (value > type(uint200).max) {\n            revert SafeCastOverflowedUintDowncast(200, value);\n        }\n        return uint200(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint192 from uint256, reverting on\n     * overflow (when the input is greater than largest uint192).\n     *\n     * Counterpart to Solidity's `uint192` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 192 bits\n     */\n    function toUint192(uint256 value) internal pure returns (uint192) {\n        if (value > type(uint192).max) {\n            revert SafeCastOverflowedUintDowncast(192, value);\n        }\n        return uint192(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint184 from uint256, reverting on\n     * overflow (when the input is greater than largest uint184).\n     *\n     * Counterpart to Solidity's `uint184` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 184 bits\n     */\n    function toUint184(uint256 value) internal pure returns (uint184) {\n        if (value > type(uint184).max) {\n            revert SafeCastOverflowedUintDowncast(184, value);\n        }\n        return uint184(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint176 from uint256, reverting on\n     * overflow (when the input is greater than largest uint176).\n     *\n     * Counterpart to Solidity's `uint176` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 176 bits\n     */\n    function toUint176(uint256 value) internal pure returns (uint176) {\n        if (value > type(uint176).max) {\n            revert SafeCastOverflowedUintDowncast(176, value);\n        }\n        return uint176(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint168 from uint256, reverting on\n     * overflow (when the input is greater than largest uint168).\n     *\n     * Counterpart to Solidity's `uint168` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 168 bits\n     */\n    function toUint168(uint256 value) internal pure returns (uint168) {\n        if (value > type(uint168).max) {\n            revert SafeCastOverflowedUintDowncast(168, value);\n        }\n        return uint168(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint160 from uint256, reverting on\n     * overflow (when the input is greater than largest uint160).\n     *\n     * Counterpart to Solidity's `uint160` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 160 bits\n     */\n    function toUint160(uint256 value) internal pure returns (uint160) {\n        if (value > type(uint160).max) {\n            revert SafeCastOverflowedUintDowncast(160, value);\n        }\n        return uint160(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint152 from uint256, reverting on\n     * overflow (when the input is greater than largest uint152).\n     *\n     * Counterpart to Solidity's `uint152` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 152 bits\n     */\n    function toUint152(uint256 value) internal pure returns (uint152) {\n        if (value > type(uint152).max) {\n            revert SafeCastOverflowedUintDowncast(152, value);\n        }\n        return uint152(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint144 from uint256, reverting on\n     * overflow (when the input is greater than largest uint144).\n     *\n     * Counterpart to Solidity's `uint144` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 144 bits\n     */\n    function toUint144(uint256 value) internal pure returns (uint144) {\n        if (value > type(uint144).max) {\n            revert SafeCastOverflowedUintDowncast(144, value);\n        }\n        return uint144(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint136 from uint256, reverting on\n     * overflow (when the input is greater than largest uint136).\n     *\n     * Counterpart to Solidity's `uint136` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 136 bits\n     */\n    function toUint136(uint256 value) internal pure returns (uint136) {\n        if (value > type(uint136).max) {\n            revert SafeCastOverflowedUintDowncast(136, value);\n        }\n        return uint136(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint128 from uint256, reverting on\n     * overflow (when the input is greater than largest uint128).\n     *\n     * Counterpart to Solidity's `uint128` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 128 bits\n     */\n    function toUint128(uint256 value) internal pure returns (uint128) {\n        if (value > type(uint128).max) {\n            revert SafeCastOverflowedUintDowncast(128, value);\n        }\n        return uint128(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint120 from uint256, reverting on\n     * overflow (when the input is greater than largest uint120).\n     *\n     * Counterpart to Solidity's `uint120` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 120 bits\n     */\n    function toUint120(uint256 value) internal pure returns (uint120) {\n        if (value > type(uint120).max) {\n            revert SafeCastOverflowedUintDowncast(120, value);\n        }\n        return uint120(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint112 from uint256, reverting on\n     * overflow (when the input is greater than largest uint112).\n     *\n     * Counterpart to Solidity's `uint112` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 112 bits\n     */\n    function toUint112(uint256 value) internal pure returns (uint112) {\n        if (value > type(uint112).max) {\n            revert SafeCastOverflowedUintDowncast(112, value);\n        }\n        return uint112(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint104 from uint256, reverting on\n     * overflow (when the input is greater than largest uint104).\n     *\n     * Counterpart to Solidity's `uint104` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 104 bits\n     */\n    function toUint104(uint256 value) internal pure returns (uint104) {\n        if (value > type(uint104).max) {\n            revert SafeCastOverflowedUintDowncast(104, value);\n        }\n        return uint104(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint96 from uint256, reverting on\n     * overflow (when the input is greater than largest uint96).\n     *\n     * Counterpart to Solidity's `uint96` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 96 bits\n     */\n    function toUint96(uint256 value) internal pure returns (uint96) {\n        if (value > type(uint96).max) {\n            revert SafeCastOverflowedUintDowncast(96, value);\n        }\n        return uint96(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint88 from uint256, reverting on\n     * overflow (when the input is greater than largest uint88).\n     *\n     * Counterpart to Solidity's `uint88` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 88 bits\n     */\n    function toUint88(uint256 value) internal pure returns (uint88) {\n        if (value > type(uint88).max) {\n            revert SafeCastOverflowedUintDowncast(88, value);\n        }\n        return uint88(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint80 from uint256, reverting on\n     * overflow (when the input is greater than largest uint80).\n     *\n     * Counterpart to Solidity's `uint80` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 80 bits\n     */\n    function toUint80(uint256 value) internal pure returns (uint80) {\n        if (value > type(uint80).max) {\n            revert SafeCastOverflowedUintDowncast(80, value);\n        }\n        return uint80(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint72 from uint256, reverting on\n     * overflow (when the input is greater than largest uint72).\n     *\n     * Counterpart to Solidity's `uint72` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 72 bits\n     */\n    function toUint72(uint256 value) internal pure returns (uint72) {\n        if (value > type(uint72).max) {\n            revert SafeCastOverflowedUintDowncast(72, value);\n        }\n        return uint72(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint64 from uint256, reverting on\n     * overflow (when the input is greater than largest uint64).\n     *\n     * Counterpart to Solidity's `uint64` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 64 bits\n     */\n    function toUint64(uint256 value) internal pure returns (uint64) {\n        if (value > type(uint64).max) {\n            revert SafeCastOverflowedUintDowncast(64, value);\n        }\n        return uint64(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint56 from uint256, reverting on\n     * overflow (when the input is greater than largest uint56).\n     *\n     * Counterpart to Solidity's `uint56` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 56 bits\n     */\n    function toUint56(uint256 value) internal pure returns (uint56) {\n        if (value > type(uint56).max) {\n            revert SafeCastOverflowedUintDowncast(56, value);\n        }\n        return uint56(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint48 from uint256, reverting on\n     * overflow (when the input is greater than largest uint48).\n     *\n     * Counterpart to Solidity's `uint48` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 48 bits\n     */\n    function toUint48(uint256 value) internal pure returns (uint48) {\n        if (value > type(uint48).max) {\n            revert SafeCastOverflowedUintDowncast(48, value);\n        }\n        return uint48(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint40 from uint256, reverting on\n     * overflow (when the input is greater than largest uint40).\n     *\n     * Counterpart to Solidity's `uint40` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 40 bits\n     */\n    function toUint40(uint256 value) internal pure returns (uint40) {\n        if (value > type(uint40).max) {\n            revert SafeCastOverflowedUintDowncast(40, value);\n        }\n        return uint40(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint32 from uint256, reverting on\n     * overflow (when the input is greater than largest uint32).\n     *\n     * Counterpart to Solidity's `uint32` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 32 bits\n     */\n    function toUint32(uint256 value) internal pure returns (uint32) {\n        if (value > type(uint32).max) {\n            revert SafeCastOverflowedUintDowncast(32, value);\n        }\n        return uint32(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint24 from uint256, reverting on\n     * overflow (when the input is greater than largest uint24).\n     *\n     * Counterpart to Solidity's `uint24` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 24 bits\n     */\n    function toUint24(uint256 value) internal pure returns (uint24) {\n        if (value > type(uint24).max) {\n            revert SafeCastOverflowedUintDowncast(24, value);\n        }\n        return uint24(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint16 from uint256, reverting on\n     * overflow (when the input is greater than largest uint16).\n     *\n     * Counterpart to Solidity's `uint16` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 16 bits\n     */\n    function toUint16(uint256 value) internal pure returns (uint16) {\n        if (value > type(uint16).max) {\n            revert SafeCastOverflowedUintDowncast(16, value);\n        }\n        return uint16(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint8 from uint256, reverting on\n     * overflow (when the input is greater than largest uint8).\n     *\n     * Counterpart to Solidity's `uint8` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 8 bits\n     */\n    function toUint8(uint256 value) internal pure returns (uint8) {\n        if (value > type(uint8).max) {\n            revert SafeCastOverflowedUintDowncast(8, value);\n        }\n        return uint8(value);\n    }\n\n    /**\n     * @dev Converts a signed int256 into an unsigned uint256.\n     *\n     * Requirements:\n     *\n     * - input must be greater than or equal to 0.\n     */\n    function toUint256(int256 value) internal pure returns (uint256) {\n        if (value < 0) {\n            revert SafeCastOverflowedIntToUint(value);\n        }\n        return uint256(value);\n    }\n\n    /**\n     * @dev Returns the downcasted int248 from int256, reverting on\n     * overflow (when the input is less than smallest int248 or\n     * greater than largest int248).\n     *\n     * Counterpart to Solidity's `int248` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 248 bits\n     */\n    function toInt248(int256 value) internal pure returns (int248 downcasted) {\n        downcasted = int248(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(248, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int240 from int256, reverting on\n     * overflow (when the input is less than smallest int240 or\n     * greater than largest int240).\n     *\n     * Counterpart to Solidity's `int240` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 240 bits\n     */\n    function toInt240(int256 value) internal pure returns (int240 downcasted) {\n        downcasted = int240(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(240, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int232 from int256, reverting on\n     * overflow (when the input is less than smallest int232 or\n     * greater than largest int232).\n     *\n     * Counterpart to Solidity's `int232` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 232 bits\n     */\n    function toInt232(int256 value) internal pure returns (int232 downcasted) {\n        downcasted = int232(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(232, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int224 from int256, reverting on\n     * overflow (when the input is less than smallest int224 or\n     * greater than largest int224).\n     *\n     * Counterpart to Solidity's `int224` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 224 bits\n     */\n    function toInt224(int256 value) internal pure returns (int224 downcasted) {\n        downcasted = int224(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(224, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int216 from int256, reverting on\n     * overflow (when the input is less than smallest int216 or\n     * greater than largest int216).\n     *\n     * Counterpart to Solidity's `int216` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 216 bits\n     */\n    function toInt216(int256 value) internal pure returns (int216 downcasted) {\n        downcasted = int216(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(216, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int208 from int256, reverting on\n     * overflow (when the input is less than smallest int208 or\n     * greater than largest int208).\n     *\n     * Counterpart to Solidity's `int208` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 208 bits\n     */\n    function toInt208(int256 value) internal pure returns (int208 downcasted) {\n        downcasted = int208(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(208, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int200 from int256, reverting on\n     * overflow (when the input is less than smallest int200 or\n     * greater than largest int200).\n     *\n     * Counterpart to Solidity's `int200` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 200 bits\n     */\n    function toInt200(int256 value) internal pure returns (int200 downcasted) {\n        downcasted = int200(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(200, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int192 from int256, reverting on\n     * overflow (when the input is less than smallest int192 or\n     * greater than largest int192).\n     *\n     * Counterpart to Solidity's `int192` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 192 bits\n     */\n    function toInt192(int256 value) internal pure returns (int192 downcasted) {\n        downcasted = int192(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(192, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int184 from int256, reverting on\n     * overflow (when the input is less than smallest int184 or\n     * greater than largest int184).\n     *\n     * Counterpart to Solidity's `int184` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 184 bits\n     */\n    function toInt184(int256 value) internal pure returns (int184 downcasted) {\n        downcasted = int184(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(184, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int176 from int256, reverting on\n     * overflow (when the input is less than smallest int176 or\n     * greater than largest int176).\n     *\n     * Counterpart to Solidity's `int176` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 176 bits\n     */\n    function toInt176(int256 value) internal pure returns (int176 downcasted) {\n        downcasted = int176(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(176, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int168 from int256, reverting on\n     * overflow (when the input is less than smallest int168 or\n     * greater than largest int168).\n     *\n     * Counterpart to Solidity's `int168` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 168 bits\n     */\n    function toInt168(int256 value) internal pure returns (int168 downcasted) {\n        downcasted = int168(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(168, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int160 from int256, reverting on\n     * overflow (when the input is less than smallest int160 or\n     * greater than largest int160).\n     *\n     * Counterpart to Solidity's `int160` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 160 bits\n     */\n    function toInt160(int256 value) internal pure returns (int160 downcasted) {\n        downcasted = int160(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(160, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int152 from int256, reverting on\n     * overflow (when the input is less than smallest int152 or\n     * greater than largest int152).\n     *\n     * Counterpart to Solidity's `int152` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 152 bits\n     */\n    function toInt152(int256 value) internal pure returns (int152 downcasted) {\n        downcasted = int152(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(152, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int144 from int256, reverting on\n     * overflow (when the input is less than smallest int144 or\n     * greater than largest int144).\n     *\n     * Counterpart to Solidity's `int144` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 144 bits\n     */\n    function toInt144(int256 value) internal pure returns (int144 downcasted) {\n        downcasted = int144(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(144, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int136 from int256, reverting on\n     * overflow (when the input is less than smallest int136 or\n     * greater than largest int136).\n     *\n     * Counterpart to Solidity's `int136` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 136 bits\n     */\n    function toInt136(int256 value) internal pure returns (int136 downcasted) {\n        downcasted = int136(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(136, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int128 from int256, reverting on\n     * overflow (when the input is less than smallest int128 or\n     * greater than largest int128).\n     *\n     * Counterpart to Solidity's `int128` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 128 bits\n     */\n    function toInt128(int256 value) internal pure returns (int128 downcasted) {\n        downcasted = int128(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(128, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int120 from int256, reverting on\n     * overflow (when the input is less than smallest int120 or\n     * greater than largest int120).\n     *\n     * Counterpart to Solidity's `int120` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 120 bits\n     */\n    function toInt120(int256 value) internal pure returns (int120 downcasted) {\n        downcasted = int120(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(120, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int112 from int256, reverting on\n     * overflow (when the input is less than smallest int112 or\n     * greater than largest int112).\n     *\n     * Counterpart to Solidity's `int112` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 112 bits\n     */\n    function toInt112(int256 value) internal pure returns (int112 downcasted) {\n        downcasted = int112(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(112, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int104 from int256, reverting on\n     * overflow (when the input is less than smallest int104 or\n     * greater than largest int104).\n     *\n     * Counterpart to Solidity's `int104` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 104 bits\n     */\n    function toInt104(int256 value) internal pure returns (int104 downcasted) {\n        downcasted = int104(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(104, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int96 from int256, reverting on\n     * overflow (when the input is less than smallest int96 or\n     * greater than largest int96).\n     *\n     * Counterpart to Solidity's `int96` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 96 bits\n     */\n    function toInt96(int256 value) internal pure returns (int96 downcasted) {\n        downcasted = int96(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(96, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int88 from int256, reverting on\n     * overflow (when the input is less than smallest int88 or\n     * greater than largest int88).\n     *\n     * Counterpart to Solidity's `int88` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 88 bits\n     */\n    function toInt88(int256 value) internal pure returns (int88 downcasted) {\n        downcasted = int88(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(88, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int80 from int256, reverting on\n     * overflow (when the input is less than smallest int80 or\n     * greater than largest int80).\n     *\n     * Counterpart to Solidity's `int80` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 80 bits\n     */\n    function toInt80(int256 value) internal pure returns (int80 downcasted) {\n        downcasted = int80(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(80, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int72 from int256, reverting on\n     * overflow (when the input is less than smallest int72 or\n     * greater than largest int72).\n     *\n     * Counterpart to Solidity's `int72` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 72 bits\n     */\n    function toInt72(int256 value) internal pure returns (int72 downcasted) {\n        downcasted = int72(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(72, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int64 from int256, reverting on\n     * overflow (when the input is less than smallest int64 or\n     * greater than largest int64).\n     *\n     * Counterpart to Solidity's `int64` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 64 bits\n     */\n    function toInt64(int256 value) internal pure returns (int64 downcasted) {\n        downcasted = int64(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(64, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int56 from int256, reverting on\n     * overflow (when the input is less than smallest int56 or\n     * greater than largest int56).\n     *\n     * Counterpart to Solidity's `int56` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 56 bits\n     */\n    function toInt56(int256 value) internal pure returns (int56 downcasted) {\n        downcasted = int56(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(56, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int48 from int256, reverting on\n     * overflow (when the input is less than smallest int48 or\n     * greater than largest int48).\n     *\n     * Counterpart to Solidity's `int48` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 48 bits\n     */\n    function toInt48(int256 value) internal pure returns (int48 downcasted) {\n        downcasted = int48(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(48, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int40 from int256, reverting on\n     * overflow (when the input is less than smallest int40 or\n     * greater than largest int40).\n     *\n     * Counterpart to Solidity's `int40` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 40 bits\n     */\n    function toInt40(int256 value) internal pure returns (int40 downcasted) {\n        downcasted = int40(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(40, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int32 from int256, reverting on\n     * overflow (when the input is less than smallest int32 or\n     * greater than largest int32).\n     *\n     * Counterpart to Solidity's `int32` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 32 bits\n     */\n    function toInt32(int256 value) internal pure returns (int32 downcasted) {\n        downcasted = int32(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(32, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int24 from int256, reverting on\n     * overflow (when the input is less than smallest int24 or\n     * greater than largest int24).\n     *\n     * Counterpart to Solidity's `int24` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 24 bits\n     */\n    function toInt24(int256 value) internal pure returns (int24 downcasted) {\n        downcasted = int24(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(24, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int16 from int256, reverting on\n     * overflow (when the input is less than smallest int16 or\n     * greater than largest int16).\n     *\n     * Counterpart to Solidity's `int16` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 16 bits\n     */\n    function toInt16(int256 value) internal pure returns (int16 downcasted) {\n        downcasted = int16(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(16, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int8 from int256, reverting on\n     * overflow (when the input is less than smallest int8 or\n     * greater than largest int8).\n     *\n     * Counterpart to Solidity's `int8` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 8 bits\n     */\n    function toInt8(int256 value) internal pure returns (int8 downcasted) {\n        downcasted = int8(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(8, value);\n        }\n    }\n\n    /**\n     * @dev Converts an unsigned uint256 into a signed int256.\n     *\n     * Requirements:\n     *\n     * - input must be less than or equal to maxInt256.\n     */\n    function toInt256(uint256 value) internal pure returns (int256) {\n        // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\n        if (value > uint256(type(int256).max)) {\n            revert SafeCastOverflowedUintToInt(value);\n        }\n        return int256(value);\n    }\n\n    /**\n     * @dev Cast a boolean (false or true) to a uint256 (0 or 1) with no jump.\n     */\n    function toUint(bool b) internal pure returns (uint256 u) {\n        assembly (\"memory-safe\") {\n            u := iszero(iszero(b))\n        }\n    }\n}\n"},"node_modules/@openzeppelin/contracts/utils/ReentrancyGuard.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.5.0) (utils/ReentrancyGuard.sol)\n\npragma solidity ^0.8.20;\n\nimport {StorageSlot} from \"./StorageSlot.sol\";\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If EIP-1153 (transient storage) is available on the chain you're deploying at,\n * consider using {ReentrancyGuardTransient} instead.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n *\n * IMPORTANT: Deprecated. This storage-based reentrancy guard will be removed and replaced\n * by the {ReentrancyGuardTransient} variant in v6.0.\n *\n * @custom:stateless\n */\nabstract contract ReentrancyGuard {\n    using StorageSlot for bytes32;\n\n    // keccak256(abi.encode(uint256(keccak256(\"openzeppelin.storage.ReentrancyGuard\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant REENTRANCY_GUARD_STORAGE =\n        0x9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00;\n\n    // Booleans are more expensive than uint256 or any type that takes up a full\n    // word because each write operation emits an extra SLOAD to first read the\n    // slot's contents, replace the bits taken up by the boolean, and then write\n    // back. This is the compiler's defense against contract upgrades and\n    // pointer aliasing, and it cannot be disabled.\n\n    // The values being non-zero value makes deployment a bit more expensive,\n    // but in exchange the refund on every call to nonReentrant will be lower in\n    // amount. Since refunds are capped to a percentage of the total\n    // transaction's gas, it is best to keep them low in cases like this one, to\n    // increase the likelihood of the full refund coming into effect.\n    uint256 private constant NOT_ENTERED = 1;\n    uint256 private constant ENTERED = 2;\n\n    /**\n     * @dev Unauthorized reentrant call.\n     */\n    error ReentrancyGuardReentrantCall();\n\n    constructor() {\n        _reentrancyGuardStorageSlot().getUint256Slot().value = NOT_ENTERED;\n    }\n\n    /**\n     * @dev Prevents a contract from calling itself, directly or indirectly.\n     * Calling a `nonReentrant` function from another `nonReentrant`\n     * function is not supported. It is possible to prevent this from happening\n     * by making the `nonReentrant` function external, and making it call a\n     * `private` function that does the actual work.\n     */\n    modifier nonReentrant() {\n        _nonReentrantBefore();\n        _;\n        _nonReentrantAfter();\n    }\n\n    /**\n     * @dev A `view` only version of {nonReentrant}. Use to block view functions\n     * from being called, preventing reading from inconsistent contract state.\n     *\n     * CAUTION: This is a \"view\" modifier and does not change the reentrancy\n     * status. Use it only on view functions. For payable or non-payable functions,\n     * use the standard {nonReentrant} modifier instead.\n     */\n    modifier nonReentrantView() {\n        _nonReentrantBeforeView();\n        _;\n    }\n\n    function _nonReentrantBeforeView() private view {\n        if (_reentrancyGuardEntered()) {\n            revert ReentrancyGuardReentrantCall();\n        }\n    }\n\n    function _nonReentrantBefore() private {\n        // On the first call to nonReentrant, _status will be NOT_ENTERED\n        _nonReentrantBeforeView();\n\n        // Any calls to nonReentrant after this point will fail\n        _reentrancyGuardStorageSlot().getUint256Slot().value = ENTERED;\n    }\n\n    function _nonReentrantAfter() private {\n        // By storing the original value once again, a refund is triggered (see\n        // https://eips.ethereum.org/EIPS/eip-2200)\n        _reentrancyGuardStorageSlot().getUint256Slot().value = NOT_ENTERED;\n    }\n\n    /**\n     * @dev Returns true if the reentrancy guard is currently set to \"entered\", which indicates there is a\n     * `nonReentrant` function in the call stack.\n     */\n    function _reentrancyGuardEntered() internal view returns (bool) {\n        return _reentrancyGuardStorageSlot().getUint256Slot().value == ENTERED;\n    }\n\n    function _reentrancyGuardStorageSlot() internal pure virtual returns (bytes32) {\n        return REENTRANCY_GUARD_STORAGE;\n    }\n}\n"},"node_modules/@openzeppelin/contracts/interfaces/draft-IERC6093.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.5.0) (interfaces/draft-IERC6093.sol)\n\npragma solidity >=0.8.4;\n\n/**\n * @dev Standard ERC-20 Errors\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-20 tokens.\n */\ninterface IERC20Errors {\n    /**\n     * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     * @param balance Current balance for the interacting account.\n     * @param needed Minimum amount required to perform a transfer.\n     */\n    error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);\n\n    /**\n     * @dev Indicates a failure with the token `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     */\n    error ERC20InvalidSender(address sender);\n\n    /**\n     * @dev Indicates a failure with the token `receiver`. Used in transfers.\n     * @param receiver Address to which tokens are being transferred.\n     */\n    error ERC20InvalidReceiver(address receiver);\n\n    /**\n     * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers.\n     * @param spender Address that may be allowed to operate on tokens without being their owner.\n     * @param allowance Amount of tokens a `spender` is allowed to operate with.\n     * @param needed Minimum amount required to perform a transfer.\n     */\n    error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);\n\n    /**\n     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\n     * @param approver Address initiating an approval operation.\n     */\n    error ERC20InvalidApprover(address approver);\n\n    /**\n     * @dev Indicates a failure with the `spender` to be approved. Used in approvals.\n     * @param spender Address that may be allowed to operate on tokens without being their owner.\n     */\n    error ERC20InvalidSpender(address spender);\n}\n\n/**\n * @dev Standard ERC-721 Errors\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-721 tokens.\n */\ninterface IERC721Errors {\n    /**\n     * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in ERC-721.\n     * Used in balance queries.\n     * @param owner Address of the current owner of a token.\n     */\n    error ERC721InvalidOwner(address owner);\n\n    /**\n     * @dev Indicates a `tokenId` whose `owner` is the zero address.\n     * @param tokenId Identifier number of a token.\n     */\n    error ERC721NonexistentToken(uint256 tokenId);\n\n    /**\n     * @dev Indicates an error related to the ownership over a particular token. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     * @param tokenId Identifier number of a token.\n     * @param owner Address of the current owner of a token.\n     */\n    error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);\n\n    /**\n     * @dev Indicates a failure with the token `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     */\n    error ERC721InvalidSender(address sender);\n\n    /**\n     * @dev Indicates a failure with the token `receiver`. Used in transfers.\n     * @param receiver Address to which tokens are being transferred.\n     */\n    error ERC721InvalidReceiver(address receiver);\n\n    /**\n     * @dev Indicates a failure with the `operator`’s approval. Used in transfers.\n     * @param operator Address that may be allowed to operate on tokens without being their owner.\n     * @param tokenId Identifier number of a token.\n     */\n    error ERC721InsufficientApproval(address operator, uint256 tokenId);\n\n    /**\n     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\n     * @param approver Address initiating an approval operation.\n     */\n    error ERC721InvalidApprover(address approver);\n\n    /**\n     * @dev Indicates a failure with the `operator` to be approved. Used in approvals.\n     * @param operator Address that may be allowed to operate on tokens without being their owner.\n     */\n    error ERC721InvalidOperator(address operator);\n}\n\n/**\n * @dev Standard ERC-1155 Errors\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-1155 tokens.\n */\ninterface IERC1155Errors {\n    /**\n     * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     * @param balance Current balance for the interacting account.\n     * @param needed Minimum amount required to perform a transfer.\n     * @param tokenId Identifier number of a token.\n     */\n    error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);\n\n    /**\n     * @dev Indicates a failure with the token `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     */\n    error ERC1155InvalidSender(address sender);\n\n    /**\n     * @dev Indicates a failure with the token `receiver`. Used in transfers.\n     * @param receiver Address to which tokens are being transferred.\n     */\n    error ERC1155InvalidReceiver(address receiver);\n\n    /**\n     * @dev Indicates a failure with the `operator`’s approval. Used in transfers.\n     * @param operator Address that may be allowed to operate on tokens without being their owner.\n     * @param owner Address of the current owner of a token.\n     */\n    error ERC1155MissingApprovalForAll(address operator, address owner);\n\n    /**\n     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\n     * @param approver Address initiating an approval operation.\n     */\n    error ERC1155InvalidApprover(address approver);\n\n    /**\n     * @dev Indicates a failure with the `operator` to be approved. Used in approvals.\n     * @param operator Address that may be allowed to operate on tokens without being their owner.\n     */\n    error ERC1155InvalidOperator(address operator);\n\n    /**\n     * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation.\n     * Used in batch transfers.\n     * @param idsLength Length of the array of token identifiers\n     * @param valuesLength Length of the array of token amounts\n     */\n    error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);\n}\n"},"node_modules/@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.5.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"../IERC20.sol\";\nimport {IERC1363} from \"../../../interfaces/IERC1363.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC-20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n    /**\n     * @dev An operation with an ERC-20 token failed.\n     */\n    error SafeERC20FailedOperation(address token);\n\n    /**\n     * @dev Indicates a failed `decreaseAllowance` request.\n     */\n    error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);\n\n    /**\n     * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful.\n     */\n    function safeTransfer(IERC20 token, address to, uint256 value) internal {\n        if (!_safeTransfer(token, to, value, true)) {\n            revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\n     * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\n     */\n    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n        if (!_safeTransferFrom(token, from, to, value, true)) {\n            revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Variant of {safeTransfer} that returns a bool instead of reverting if the operation is not successful.\n     */\n    function trySafeTransfer(IERC20 token, address to, uint256 value) internal returns (bool) {\n        return _safeTransfer(token, to, value, false);\n    }\n\n    /**\n     * @dev Variant of {safeTransferFrom} that returns a bool instead of reverting if the operation is not successful.\n     */\n    function trySafeTransferFrom(IERC20 token, address from, address to, uint256 value) internal returns (bool) {\n        return _safeTransferFrom(token, from, to, value, false);\n    }\n\n    /**\n     * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful.\n     *\n     * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the \"client\"\n     * smart contract uses ERC-7674 to set temporary allowances, then the \"client\" smart contract should avoid using\n     * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract\n     * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.\n     */\n    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n        uint256 oldAllowance = token.allowance(address(this), spender);\n        forceApprove(token, spender, oldAllowance + value);\n    }\n\n    /**\n     * @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no\n     * value, non-reverting calls are assumed to be successful.\n     *\n     * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the \"client\"\n     * smart contract uses ERC-7674 to set temporary allowances, then the \"client\" smart contract should avoid using\n     * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract\n     * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.\n     */\n    function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal {\n        unchecked {\n            uint256 currentAllowance = token.allowance(address(this), spender);\n            if (currentAllowance < requestedDecrease) {\n                revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);\n            }\n            forceApprove(token, spender, currentAllowance - requestedDecrease);\n        }\n    }\n\n    /**\n     * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\n     * to be set to zero before setting it to a non-zero value, such as USDT.\n     *\n     * NOTE: If the token implements ERC-7674, this function will not modify any temporary allowance. This function\n     * only sets the \"standard\" allowance. Any temporary allowance will remain active, in addition to the value being\n     * set here.\n     */\n    function forceApprove(IERC20 token, address spender, uint256 value) internal {\n        if (!_safeApprove(token, spender, value, false)) {\n            if (!_safeApprove(token, spender, 0, true)) revert SafeERC20FailedOperation(address(token));\n            if (!_safeApprove(token, spender, value, true)) revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Performs an {ERC1363} transferAndCall, with a fallback to the simple {ERC20} transfer if the target has no\n     * code. This can be used to implement an {ERC721}-like safe transfer that relies on {ERC1363} checks when\n     * targeting contracts.\n     *\n     * Reverts if the returned value is other than `true`.\n     */\n    function transferAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {\n        if (to.code.length == 0) {\n            safeTransfer(token, to, value);\n        } else if (!token.transferAndCall(to, value, data)) {\n            revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Performs an {ERC1363} transferFromAndCall, with a fallback to the simple {ERC20} transferFrom if the target\n     * has no code. This can be used to implement an {ERC721}-like safe transfer that relies on {ERC1363} checks when\n     * targeting contracts.\n     *\n     * Reverts if the returned value is other than `true`.\n     */\n    function transferFromAndCallRelaxed(\n        IERC1363 token,\n        address from,\n        address to,\n        uint256 value,\n        bytes memory data\n    ) internal {\n        if (to.code.length == 0) {\n            safeTransferFrom(token, from, to, value);\n        } else if (!token.transferFromAndCall(from, to, value, data)) {\n            revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Performs an {ERC1363} approveAndCall, with a fallback to the simple {ERC20} approve if the target has no\n     * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when\n     * targeting contracts.\n     *\n     * NOTE: When the recipient address (`to`) has no code (i.e. is an EOA), this function behaves as {forceApprove}.\n     * Oppositely, when the recipient address (`to`) has code, this function only attempts to call {ERC1363-approveAndCall}\n     * once without retrying, and relies on the returned value to be true.\n     *\n     * Reverts if the returned value is other than `true`.\n     */\n    function approveAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {\n        if (to.code.length == 0) {\n            forceApprove(token, to, value);\n        } else if (!token.approveAndCall(to, value, data)) {\n            revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Imitates a Solidity `token.transfer(to, value)` call, relaxing the requirement on the return value: the\n     * return value is optional (but if data is returned, it must not be false).\n     *\n     * @param token The token targeted by the call.\n     * @param to The recipient of the tokens\n     * @param value The amount of token to transfer\n     * @param bubble Behavior switch if the transfer call reverts: bubble the revert reason or return a false boolean.\n     */\n    function _safeTransfer(IERC20 token, address to, uint256 value, bool bubble) private returns (bool success) {\n        bytes4 selector = IERC20.transfer.selector;\n\n        assembly (\"memory-safe\") {\n            let fmp := mload(0x40)\n            mstore(0x00, selector)\n            mstore(0x04, and(to, shr(96, not(0))))\n            mstore(0x24, value)\n            success := call(gas(), token, 0, 0x00, 0x44, 0x00, 0x20)\n            // if call success and return is true, all is good.\n            // otherwise (not success or return is not true), we need to perform further checks\n            if iszero(and(success, eq(mload(0x00), 1))) {\n                // if the call was a failure and bubble is enabled, bubble the error\n                if and(iszero(success), bubble) {\n                    returndatacopy(fmp, 0x00, returndatasize())\n                    revert(fmp, returndatasize())\n                }\n                // if the return value is not true, then the call is only successful if:\n                // - the token address has code\n                // - the returndata is empty\n                success := and(success, and(iszero(returndatasize()), gt(extcodesize(token), 0)))\n            }\n            mstore(0x40, fmp)\n        }\n    }\n\n    /**\n     * @dev Imitates a Solidity `token.transferFrom(from, to, value)` call, relaxing the requirement on the return\n     * value: the return value is optional (but if data is returned, it must not be false).\n     *\n     * @param token The token targeted by the call.\n     * @param from The sender of the tokens\n     * @param to The recipient of the tokens\n     * @param value The amount of token to transfer\n     * @param bubble Behavior switch if the transfer call reverts: bubble the revert reason or return a false boolean.\n     */\n    function _safeTransferFrom(\n        IERC20 token,\n        address from,\n        address to,\n        uint256 value,\n        bool bubble\n    ) private returns (bool success) {\n        bytes4 selector = IERC20.transferFrom.selector;\n\n        assembly (\"memory-safe\") {\n            let fmp := mload(0x40)\n            mstore(0x00, selector)\n            mstore(0x04, and(from, shr(96, not(0))))\n            mstore(0x24, and(to, shr(96, not(0))))\n            mstore(0x44, value)\n            success := call(gas(), token, 0, 0x00, 0x64, 0x00, 0x20)\n            // if call success and return is true, all is good.\n            // otherwise (not success or return is not true), we need to perform further checks\n            if iszero(and(success, eq(mload(0x00), 1))) {\n                // if the call was a failure and bubble is enabled, bubble the error\n                if and(iszero(success), bubble) {\n                    returndatacopy(fmp, 0x00, returndatasize())\n                    revert(fmp, returndatasize())\n                }\n                // if the return value is not true, then the call is only successful if:\n                // - the token address has code\n                // - the returndata is empty\n                success := and(success, and(iszero(returndatasize()), gt(extcodesize(token), 0)))\n            }\n            mstore(0x40, fmp)\n            mstore(0x60, 0)\n        }\n    }\n\n    /**\n     * @dev Imitates a Solidity `token.approve(spender, value)` call, relaxing the requirement on the return value:\n     * the return value is optional (but if data is returned, it must not be false).\n     *\n     * @param token The token targeted by the call.\n     * @param spender The spender of the tokens\n     * @param value The amount of token to transfer\n     * @param bubble Behavior switch if the transfer call reverts: bubble the revert reason or return a false boolean.\n     */\n    function _safeApprove(IERC20 token, address spender, uint256 value, bool bubble) private returns (bool success) {\n        bytes4 selector = IERC20.approve.selector;\n\n        assembly (\"memory-safe\") {\n            let fmp := mload(0x40)\n            mstore(0x00, selector)\n            mstore(0x04, and(spender, shr(96, not(0))))\n            mstore(0x24, value)\n            success := call(gas(), token, 0, 0x00, 0x44, 0x00, 0x20)\n            // if call success and return is true, all is good.\n            // otherwise (not success or return is not true), we need to perform further checks\n            if iszero(and(success, eq(mload(0x00), 1))) {\n                // if the call was a failure and bubble is enabled, bubble the error\n                if and(iszero(success), bubble) {\n                    returndatacopy(fmp, 0x00, returndatasize())\n                    revert(fmp, returndatasize())\n                }\n                // if the return value is not true, then the call is only successful if:\n                // - the token address has code\n                // - the returndata is empty\n                success := and(success, and(iszero(returndatasize()), gt(extcodesize(token), 0)))\n            }\n            mstore(0x40, fmp)\n        }\n    }\n}\n"},"node_modules/@openzeppelin/contracts/utils/introspection/IERC165.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (utils/introspection/IERC165.sol)\n\npragma solidity >=0.4.16;\n\n/**\n * @dev Interface of the ERC-165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[ERC].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n    /**\n     * @dev Returns true if this contract implements the interface defined by\n     * `interfaceId`. See the corresponding\n     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section]\n     * to learn more about how these ids are created.\n     *\n     * This function call must use less than 30 000 gas.\n     */\n    function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"},"node_modules/@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity >=0.6.2;\n\nimport {IERC20} from \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC-20 standard.\n */\ninterface IERC20Metadata is IERC20 {\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() external view returns (string memory);\n\n    /**\n     * @dev Returns the symbol of the token.\n     */\n    function symbol() external view returns (string memory);\n\n    /**\n     * @dev Returns the decimals places of the token.\n     */\n    function decimals() external view returns (uint8);\n}\n"}},"language":"Solidity","settings":{"viaIR":false,"metadata":{"appendCBOR":true,"bytecodeHash":"ipfs","useLiteralContent":false},"libraries":{"V3/src/src/libraries/RewardsLogicLibrary.sol":{"RewardsLogicLibrary":"0x2b73DF2e7e957C77F1D8C01e0a71aD1fF38D6720"},"V3/src/src/libraries/LeafAllocationLibrary.sol":{"LeafAllocationLibrary":"0xC7E262e848fCa78C3C66Ee3c9835e4E65E3E0398"},"V3/src/src/libraries/VotingRewardsFactoryLibrary.sol":{"VotingRewardsFactoryLibrary":"0x1C3821772BFAAE08eE2D4ED8E2c29844CA49634e"}},"optimizer":{"runs":10000,"enabled":true},"viaSSACFG":false,"evmVersion":"prague","remappings":["forge-std/=node_modules/forge-std/src/","@hyperlane/contracts/=node_modules/@hyperlane-xyz/core/contracts/","node_modules/@hyperlane-xyz/:@openzeppelin/contracts/=node_modules/@openzeppelin/contracts-v4/","node_modules/@hyperlane-xyz/:@openzeppelin/contracts/=node_modules/@openzeppelin/contracts-v4/","node_modules/@hyperlane-xyz/:@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable-v4/","node_modules/@hyperlane-xyz/:@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable-v4/","@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/","@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/","@openzeppelin4/contracts/=node_modules/@openzeppelin/contracts-v4/","@solady/=node_modules/solady/src/","@nomad-xyz/src/=node_modules/@nomad-xyz/excessively-safe-call/src/","V3/=V3/src/","V3-script/=V3/script/","V3-test/=V3/test/"],"experimental":false}},"stdJsonOutput":{"sources":{"V3/src/pools/Pool.sol":{"id":6},"V3/src/pools/PoolFees.sol":{"id":7},"V3/src/pools/StablePool.sol":{"id":8},"V3/src/libraries/PoolOracle.sol":{"id":5},"V3/src/interfaces/pools/IPool.sol":{"id":1},"V3/src/interfaces/pools/IPoolCallee.sol":{"id":2},"V3/src/interfaces/pools/IStablePool.sol":{"id":3},"V3/src/interfaces/pools/tape/IPoolTape.sol":{"id":4},"V3/src/interfaces/factories/IPoolFactory.sol":{"id":0},"node_modules/@openzeppelin/contracts/utils/Panic.sol":{"id":18},"node_modules/@openzeppelin/contracts/utils/Context.sol":{"id":17},"node_modules/@openzeppelin/contracts/utils/math/Math.sol":{"id":22},"node_modules/@openzeppelin/contracts/interfaces/IERC20.sol":{"id":11},"node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol":{"id":13},"node_modules/@openzeppelin/contracts/utils/StorageSlot.sol":{"id":20},"node_modules/@openzeppelin/contracts/interfaces/IERC165.sol":{"id":10},"node_modules/@openzeppelin/contracts/token/ERC20/IERC20.sol":{"id":14},"node_modules/@openzeppelin/contracts/interfaces/IERC1363.sol":{"id":9},"node_modules/@openzeppelin/contracts/utils/math/SafeCast.sol":{"id":23},"node_modules/@openzeppelin/contracts/utils/ReentrancyGuard.sol":{"id":19},"node_modules/@openzeppelin/contracts/interfaces/draft-IERC6093.sol":{"id":12},"node_modules/@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol":{"id":16},"node_modules/@openzeppelin/contracts/utils/introspection/IERC165.sol":{"id":21},"node_modules/@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol":{"id":15}},"contracts":{"V3/src/pools/StablePool.sol":{"StablePool":{"abi":[{"name":"BelowMinimumK","type":"error","inputs":[]},{"name":"CannotCalculateY","type":"error","inputs":[]},{"name":"DepositsNotEqual","type":"error","inputs":[]},{"name":"ERC20InsufficientAllowance","type":"error","inputs":[{"name":"spender","type":"address","internalType":"address"},{"name":"allowance","type":"uint256","internalType":"uint256"},{"name":"needed","type":"uint256","internalType":"uint256"}]},{"name":"ERC20InsufficientBalance","type":"error","inputs":[{"name":"sender","type":"address","internalType":"address"},{"name":"balance","type":"uint256","internalType":"uint256"},{"name":"needed","type":"uint256","internalType":"uint256"}]},{"name":"ERC20InvalidApprover","type":"error","inputs":[{"name":"approver","type":"address","internalType":"address"}]},{"name":"ERC20InvalidReceiver","type":"error","inputs":[{"name":"receiver","type":"address","internalType":"address"}]},{"name":"ERC20InvalidSender","type":"error","inputs":[{"name":"sender","type":"address","internalType":"address"}]},{"name":"ERC20InvalidSpender","type":"error","inputs":[{"name":"spender","type":"address","internalType":"address"}]},{"name":"FactoryAlreadySet","type":"error","inputs":[]},{"name":"InsufficientInputAmount","type":"error","inputs":[]},{"name":"InsufficientLiquidity","type":"error","inputs":[]},{"name":"InsufficientLiquidityBurned","type":"error","inputs":[]},{"name":"InsufficientLiquidityMinted","type":"error","inputs":[]},{"name":"InsufficientOutputAmount","type":"error","inputs":[]},{"name":"InvalidTo","type":"error","inputs":[]},{"name":"IsPaused","type":"error","inputs":[]},{"name":"K","type":"error","inputs":[]},{"name":"KIsZero","type":"error","inputs":[]},{"name":"NotAuthorized","type":"error","inputs":[]},{"name":"NotPoolAdmin","type":"error","inputs":[]},{"name":"ObservationOld","type":"error","inputs":[]},{"name":"ReentrancyGuardReentrantCall","type":"error","inputs":[]},{"name":"SafeERC20FailedOperation","type":"error","inputs":[{"name":"token","type":"address","internalType":"address"}]},{"name":"ZeroAddress","type":"error","inputs":[]},{"name":"Approval","type":"event","inputs":[{"name":"owner","type":"address","indexed":true,"internalType":"address"},{"name":"spender","type":"address","indexed":true,"internalType":"address"},{"name":"value","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"Burn","type":"event","inputs":[{"name":"sender","type":"address","indexed":true,"internalType":"address"},{"name":"to","type":"address","indexed":true,"internalType":"address"},{"name":"amount0","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"amount1","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"Claim","type":"event","inputs":[{"name":"caller","type":"address","indexed":true,"internalType":"address"},{"name":"account","type":"address","indexed":true,"internalType":"address"},{"name":"recipient","type":"address","indexed":true,"internalType":"address"},{"name":"amount0","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"amount1","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"ClaimApproval","type":"event","inputs":[{"name":"account","type":"address","indexed":true,"internalType":"address"},{"name":"operator","type":"address","indexed":true,"internalType":"address"},{"name":"approved","type":"bool","indexed":false,"internalType":"bool"}],"anonymous":false},{"name":"Fees","type":"event","inputs":[{"name":"sender","type":"address","indexed":true,"internalType":"address"},{"name":"amount0","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"amount1","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"IncreaseObservationCardinalityNext","type":"event","inputs":[{"name":"caller","type":"address","indexed":true,"internalType":"address"},{"name":"observationCardinalityNextOld","type":"uint16","indexed":false,"internalType":"uint16"},{"name":"observationCardinalityNextNew","type":"uint16","indexed":false,"internalType":"uint16"}],"anonymous":false},{"name":"Mint","type":"event","inputs":[{"name":"sender","type":"address","indexed":true,"internalType":"address"},{"name":"to","type":"address","indexed":true,"internalType":"address"},{"name":"amount0","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"amount1","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"Swap","type":"event","inputs":[{"name":"sender","type":"address","indexed":true,"internalType":"address"},{"name":"to","type":"address","indexed":true,"internalType":"address"},{"name":"amount0In","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"amount1In","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"amount0Out","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"amount1Out","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"Sync","type":"event","inputs":[{"name":"reserve0","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"reserve1","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"Transfer","type":"event","inputs":[{"name":"from","type":"address","indexed":true,"internalType":"address"},{"name":"to","type":"address","indexed":true,"internalType":"address"},{"name":"value","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"MINIMUM_K","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"PERIOD_SIZE","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"POOL_TYPE","type":"function","inputs":[],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"name":"allowance","type":"function","inputs":[{"name":"owner","type":"address","internalType":"address"},{"name":"spender","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"approve","type":"function","inputs":[{"name":"spender","type":"address","internalType":"address"},{"name":"value","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"nonpayable"},{"name":"approveForClaim","type":"function","inputs":[{"name":"_operator","type":"address","internalType":"address"},{"name":"_approved","type":"bool","internalType":"bool"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"approvedForClaim","type":"function","inputs":[{"name":"_account","type":"address","internalType":"address"},{"name":"_operator","type":"address","internalType":"address"}],"outputs":[{"name":"_approved","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"balanceOf","type":"function","inputs":[{"name":"account","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"blockTimestampLast","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"burn","type":"function","inputs":[{"name":"to","type":"address","internalType":"address"}],"outputs":[{"name":"amount0","type":"uint256","internalType":"uint256"},{"name":"amount1","type":"uint256","internalType":"uint256"}],"stateMutability":"nonpayable"},{"name":"claimFees","type":"function","inputs":[{"name":"_recipient","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"},{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"nonpayable"},{"name":"claimFees","type":"function","inputs":[{"name":"_account","type":"address","internalType":"address"},{"name":"_recipient","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"},{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"nonpayable"},{"name":"claimable0","type":"function","inputs":[{"name":"","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"claimable1","type":"function","inputs":[{"name":"","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"currentCumulativePrices","type":"function","inputs":[],"outputs":[{"name":"reserve0Cumulative","type":"uint256","internalType":"uint256"},{"name":"reserve1Cumulative","type":"uint256","internalType":"uint256"},{"name":"blockTimestamp","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"decimals","type":"function","inputs":[],"outputs":[{"name":"","type":"uint8","internalType":"uint8"}],"stateMutability":"view"},{"name":"factory","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"getAmountInWithTotalFee","type":"function","inputs":[{"name":"amountOut","type":"uint256","internalType":"uint256"},{"name":"tokenOut","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"getAmountOut","type":"function","inputs":[{"name":"amountIn","type":"uint256","internalType":"uint256"},{"name":"tokenIn","type":"address","internalType":"address"},{"name":"_reserve0","type":"uint256","internalType":"uint256"},{"name":"_reserve1","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"getAmountOut","type":"function","inputs":[{"name":"amountIn","type":"uint256","internalType":"uint256"},{"name":"tokenIn","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"getAmountOutWithTotalFee","type":"function","inputs":[{"name":"amountIn","type":"uint256","internalType":"uint256"},{"name":"tokenIn","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"getK","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"nonpayable"},{"name":"getReserves","type":"function","inputs":[],"outputs":[{"name":"_reserve0","type":"uint256","internalType":"uint256"},{"name":"_reserve1","type":"uint256","internalType":"uint256"},{"name":"_blockTimestampLast","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"increaseObservationCardinalityNext","type":"function","inputs":[{"name":"_observationCardinalityNext","type":"uint16","internalType":"uint16"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"index0","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"index1","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"initialize","type":"function","inputs":[{"name":"_token0","type":"address","internalType":"address"},{"name":"_token1","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"metadata","type":"function","inputs":[],"outputs":[{"name":"dec0","type":"uint256","internalType":"uint256"},{"name":"dec1","type":"uint256","internalType":"uint256"},{"name":"r0","type":"uint256","internalType":"uint256"},{"name":"r1","type":"uint256","internalType":"uint256"},{"name":"t0","type":"address","internalType":"address"},{"name":"t1","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"mint","type":"function","inputs":[{"name":"to","type":"address","internalType":"address"}],"outputs":[{"name":"liquidity","type":"uint256","internalType":"uint256"}],"stateMutability":"nonpayable"},{"name":"name","type":"function","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"name":"observationBuffer","type":"function","inputs":[],"outputs":[{"name":"index","type":"uint16","internalType":"uint16"},{"name":"cardinality","type":"uint16","internalType":"uint16"},{"name":"cardinalityNext","type":"uint16","internalType":"uint16"}],"stateMutability":"view"},{"name":"observations","type":"function","inputs":[{"name":"_index","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"timestamp","type":"uint32","internalType":"uint32"},{"name":"reserve0Cumulative","type":"uint256","internalType":"uint256"},{"name":"reserve1Cumulative","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"observe","type":"function","inputs":[{"name":"_secondsAgos","type":"uint32[]","internalType":"uint32[]"}],"outputs":[{"name":"_reserve0Cumulatives","type":"uint256[]","internalType":"uint256[]"},{"name":"_reserve1Cumulatives","type":"uint256[]","internalType":"uint256[]"}],"stateMutability":"view"},{"name":"pendingFees","type":"function","inputs":[{"name":"_account","type":"address","internalType":"address"}],"outputs":[{"name":"_amount0","type":"uint256","internalType":"uint256"},{"name":"_amount1","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"poolFees","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"reserve0","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"reserve0CumulativeLast","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"reserve1","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"reserve1CumulativeLast","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"setName","type":"function","inputs":[{"name":"__name","type":"string","internalType":"string"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"setSymbol","type":"function","inputs":[{"name":"__symbol","type":"string","internalType":"string"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"skim","type":"function","inputs":[{"name":"to","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"supplyIndex0","type":"function","inputs":[{"name":"","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"supplyIndex1","type":"function","inputs":[{"name":"","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"swap","type":"function","inputs":[{"name":"amount0Out","type":"uint256","internalType":"uint256"},{"name":"amount1Out","type":"uint256","internalType":"uint256"},{"name":"to","type":"address","internalType":"address"},{"name":"data","type":"bytes","internalType":"bytes"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"symbol","type":"function","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"name":"sync","type":"function","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"name":"token0","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"token1","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"tokens","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"},{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"totalSupply","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"transfer","type":"function","inputs":[{"name":"to","type":"address","internalType":"address"},{"name":"value","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"nonpayable"},{"name":"transferFrom","type":"function","inputs":[{"name":"from","type":"address","internalType":"address"},{"name":"to","type":"address","internalType":"address"},{"name":"value","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"nonpayable"}],"metadata":"{\"compiler\":{\"version\":\"0.8.36+commit.8a079791\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"BelowMinimumK\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotCalculateY\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DepositsNotEqual\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"allowance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"needed\",\"type\":\"uint256\"}],\"name\":\"ERC20InsufficientAllowance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"balance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"needed\",\"type\":\"uint256\"}],\"name\":\"ERC20InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"approver\",\"type\":\"address\"}],\"name\":\"ERC20InvalidApprover\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"}],\"name\":\"ERC20InvalidReceiver\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"ERC20InvalidSender\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"ERC20InvalidSpender\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FactoryAlreadySet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientInputAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientLiquidity\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientLiquidityBurned\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientLiquidityMinted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTo\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IsPaused\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"K\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"KIsZero\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotAuthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotPoolAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ObservationOld\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrancyGuardReentrantCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"SafeERC20FailedOperation\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount0\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount1\",\"type\":\"uint256\"}],\"name\":\"Burn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount0\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount1\",\"type\":\"uint256\"}],\"name\":\"Claim\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"ClaimApproval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount0\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount1\",\"type\":\"uint256\"}],\"name\":\"Fees\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"observationCardinalityNextOld\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"observationCardinalityNextNew\",\"type\":\"uint16\"}],\"name\":\"IncreaseObservationCardinalityNext\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount0\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount1\",\"type\":\"uint256\"}],\"name\":\"Mint\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount0In\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount1In\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount0Out\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount1Out\",\"type\":\"uint256\"}],\"name\":\"Swap\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"reserve0\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"reserve1\",\"type\":\"uint256\"}],\"name\":\"Sync\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MINIMUM_K\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"PERIOD_SIZE\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"POOL_TYPE\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_operator\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_approved\",\"type\":\"bool\"}],\"name\":\"approveForClaim\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_account\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_operator\",\"type\":\"address\"}],\"name\":\"approvedForClaim\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"_approved\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"blockTimestampLast\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"burn\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amount0\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount1\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_recipient\",\"type\":\"address\"}],\"name\":\"claimFees\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_account\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_recipient\",\"type\":\"address\"}],\"name\":\"claimFees\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"claimable0\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"claimable1\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentCumulativePrices\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"reserve0Cumulative\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"reserve1Cumulative\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"blockTimestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"factory\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"}],\"name\":\"getAmountInWithTotalFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_reserve0\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_reserve1\",\"type\":\"uint256\"}],\"name\":\"getAmountOut\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"}],\"name\":\"getAmountOut\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"}],\"name\":\"getAmountOutWithTotalFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getK\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getReserves\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_reserve0\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_reserve1\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_blockTimestampLast\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"_observationCardinalityNext\",\"type\":\"uint16\"}],\"name\":\"increaseObservationCardinalityNext\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"index0\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"index1\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token0\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token1\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"metadata\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"dec0\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"dec1\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"r0\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"r1\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"t0\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"t1\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"mint\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"liquidity\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"observationBuffer\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"index\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"cardinality\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"cardinalityNext\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"observations\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"reserve0Cumulative\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"reserve1Cumulative\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32[]\",\"name\":\"_secondsAgos\",\"type\":\"uint32[]\"}],\"name\":\"observe\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"_reserve0Cumulatives\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"_reserve1Cumulatives\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_account\",\"type\":\"address\"}],\"name\":\"pendingFees\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount0\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_amount1\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"poolFees\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"reserve0\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"reserve0CumulativeLast\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"reserve1\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"reserve1CumulativeLast\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"__name\",\"type\":\"string\"}],\"name\":\"setName\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"__symbol\",\"type\":\"string\"}],\"name\":\"setSymbol\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"skim\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"supplyIndex0\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"supplyIndex1\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount0Out\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount1Out\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"swap\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"sync\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"token0\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"token1\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"tokens\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"errors\":{\"ERC20InsufficientAllowance(address,uint256,uint256)\":[{\"details\":\"Indicates a failure with the `spender`’s `allowance`. Used in transfers.\",\"params\":{\"allowance\":\"Amount of tokens a `spender` is allowed to operate with.\",\"needed\":\"Minimum amount required to perform a transfer.\",\"spender\":\"Address that may be allowed to operate on tokens without being their owner.\"}}],\"ERC20InsufficientBalance(address,uint256,uint256)\":[{\"details\":\"Indicates an error related to the current `balance` of a `sender`. Used in transfers.\",\"params\":{\"balance\":\"Current balance for the interacting account.\",\"needed\":\"Minimum amount required to perform a transfer.\",\"sender\":\"Address whose tokens are being transferred.\"}}],\"ERC20InvalidApprover(address)\":[{\"details\":\"Indicates a failure with the `approver` of a token to be approved. Used in approvals.\",\"params\":{\"approver\":\"Address initiating an approval operation.\"}}],\"ERC20InvalidReceiver(address)\":[{\"details\":\"Indicates a failure with the token `receiver`. Used in transfers.\",\"params\":{\"receiver\":\"Address to which tokens are being transferred.\"}}],\"ERC20InvalidSender(address)\":[{\"details\":\"Indicates a failure with the token `sender`. Used in transfers.\",\"params\":{\"sender\":\"Address whose tokens are being transferred.\"}}],\"ERC20InvalidSpender(address)\":[{\"details\":\"Indicates a failure with the `spender` to be approved. Used in approvals.\",\"params\":{\"spender\":\"Address that may be allowed to operate on tokens without being their owner.\"}}],\"ReentrancyGuardReentrantCall()\":[{\"details\":\"Unauthorized reentrant call.\"}],\"SafeERC20FailedOperation(address)\":[{\"details\":\"An operation with an ERC-20 token failed.\"}]},\"events\":{\"Approval(address,address,uint256)\":{\"details\":\"Emitted when the allowance of a `spender` for an `owner` is set by a call to {approve}. `value` is the new allowance.\"},\"Burn(address,address,uint256,uint256)\":{\"params\":{\"amount0\":\"Amount of token0 returned\",\"amount1\":\"Amount of token1 returned\",\"sender\":\"Address that initiated the burn\",\"to\":\"Address that received the underlying tokens\"}},\"Claim(address,address,address,uint256,uint256)\":{\"params\":{\"account\":\"Address whose accumulated fees were claimed\",\"amount0\":\"Amount of token0 claimed\",\"amount1\":\"Amount of token1 claimed\",\"caller\":\"Address that triggered the claim\",\"recipient\":\"Address that received the fee tokens\"}},\"ClaimApproval(address,address,bool)\":{\"params\":{\"account\":\"Account whose approval state changed\",\"approved\":\"New approval state\",\"operator\":\"Operator being approved or revoked\"}},\"Fees(address,uint256,uint256)\":{\"params\":{\"amount0\":\"Amount of token0 fees collected\",\"amount1\":\"Amount of token1 fees collected\",\"sender\":\"Address that triggered the fee claim\"}},\"IncreaseObservationCardinalityNext(address,uint16,uint16)\":{\"params\":{\"caller\":\"Address that triggered the cardinality growth\",\"observationCardinalityNextNew\":\"New value of `observationCardinalityNext`\",\"observationCardinalityNextOld\":\"Previous value of `observationCardinalityNext`\"}},\"Mint(address,address,uint256,uint256)\":{\"params\":{\"amount0\":\"Amount of token0 deposited\",\"amount1\":\"Amount of token1 deposited\",\"sender\":\"Address that initiated the mint\",\"to\":\"Address that received the LP tokens\"}},\"Swap(address,address,uint256,uint256,uint256,uint256)\":{\"params\":{\"amount0In\":\"Amount of token0 provided as input\",\"amount0Out\":\"Amount of token0 sent as output\",\"amount1In\":\"Amount of token1 provided as input\",\"amount1Out\":\"Amount of token1 sent as output\",\"sender\":\"Address that initiated the swap\",\"to\":\"Address that received the output tokens\"}},\"Sync(uint256,uint256)\":{\"params\":{\"reserve0\":\"Updated reserve of token0\",\"reserve1\":\"Updated reserve of token1\"}},\"Transfer(address,address,uint256)\":{\"details\":\"Emitted when `value` tokens are moved from one account (`from`) to another (`to`). Note that `value` may be zero.\"}},\"kind\":\"dev\",\"methods\":{\"allowance(address,address)\":{\"details\":\"Returns the remaining number of tokens that `spender` will be allowed to spend on behalf of `owner` through {transferFrom}. This is zero by default. This value changes when {approve} or {transferFrom} are called.\"},\"approve(address,uint256)\":{\"details\":\"See {IERC20-approve}. NOTE: If `value` is the maximum `uint256`, the allowance is not updated on `transferFrom`. This is semantically equivalent to an infinite approval. Requirements: - `spender` cannot be the zero address.\"},\"approveForClaim(address,bool)\":{\"params\":{\"_approved\":\"Whether the operator is approved\",\"_operator\":\"Operator whose approval is updated\"}},\"balanceOf(address)\":{\"details\":\"Returns the value of tokens owned by `account`.\"},\"burn(address)\":{\"params\":{\"to\":\"Address to receive token0 and token1 from burning the pool token\"},\"returns\":{\"amount0\":\"Amount of token0 returned\",\"amount1\":\"Amount of token1 returned\"}},\"claimFees(address)\":{\"params\":{\"_recipient\":\"Address that receives the claimed fee tokens\"},\"returns\":{\"_0\":\"Amount of token0 claimed\",\"_1\":\"Amount of token1 claimed\"}},\"claimFees(address,address)\":{\"details\":\"The caller must be `_account` or an operator approved by `_account`\",\"params\":{\"_account\":\"Account whose accumulated fees are claimed\",\"_recipient\":\"Address that receives the claimed fee tokens\"},\"returns\":{\"_0\":\"Amount of token0 claimed\",\"_1\":\"Amount of token1 claimed\"}},\"decimals()\":{\"details\":\"Returns the number of decimals used to get its user representation. For example, if `decimals` equals `2`, a balance of `505` tokens should be displayed to a user as `5.05` (`505 / 10 ** 2`). Tokens usually opt for a value of 18, imitating the relationship between Ether and Wei. This is the default value returned by this function, unless it's overridden. NOTE: This information is only used for _display_ purposes: it in no way affects any of the arithmetic of the contract, including {IERC20-balanceOf} and {IERC20-transfer}.\"},\"getAmountInWithTotalFee(uint256,address)\":{\"details\":\"Reverts if the exact output cannot be calculated\",\"params\":{\"amountOut\":\"Amount of token out to receive\",\"tokenOut\":\"Address of token out\"},\"returns\":{\"_0\":\"Amount in, fee included\"}},\"getAmountOut(uint256,address)\":{\"details\":\"Does not charge the MEV tax, so the result can be higher than what `swap` pays out.      Use `getAmountOutWithTotalFee` to quote a swap.\",\"params\":{\"amountIn\":\"Amount of token in\",\"tokenIn\":\"Address of token\"},\"returns\":{\"_0\":\"Amount out\"}},\"getAmountOut(uint256,address,uint256,uint256)\":{\"details\":\"Subtracts the base fee from `amountIn` before applying the curve. Does not charge the MEV      tax, so use `getAmountOutWithTotalFee` to quote a swap.\",\"params\":{\"_reserve0\":\"Reserve of token0 to quote against\",\"_reserve1\":\"Reserve of token1 to quote against\",\"amountIn\":\"Input amount in the smallest unit of `tokenIn`\",\"tokenIn\":\"Address of the input token\"},\"returns\":{\"_0\":\"Output amount the swap would produce against the supplied reserves\"}},\"getAmountOutWithTotalFee(uint256,address)\":{\"params\":{\"amountIn\":\"Amount of token in\",\"tokenIn\":\"Address of token in\"},\"returns\":{\"_0\":\"Amount out\"}},\"getReserves()\":{\"returns\":{\"_blockTimestampLast\":\".\",\"_reserve0\":\".\",\"_reserve1\":\".\"}},\"increaseObservationCardinalityNext(uint16)\":{\"details\":\"Pre-initialises buffer slots so observation writes hit warm storage.\",\"params\":{\"_observationCardinalityNext\":\"New target capacity. At most 65,535.\"}},\"initialize(address,address)\":{\"params\":{\"_token0\":\"Address of token0\",\"_token1\":\"Address of token1\"}},\"mint(address)\":{\"params\":{\"to\":\"Address to receive the minted LP token\"},\"returns\":{\"liquidity\":\"Amount of LP token minted\"}},\"name()\":{\"details\":\"Returns the name of the token.\"},\"observations(uint256)\":{\"params\":{\"index\":\"Index of the observation to return\"},\"returns\":{\"reserve0Cumulative\":\"Cumulative reserve0 of the observation\",\"reserve1Cumulative\":\"Cumulative reserve1 of the observation\",\"timestamp\":\"Timestamp of the observation\"}},\"observe(uint32[])\":{\"details\":\"Offsets between two stored observations are linearly interpolated. Observations are      period-gated, so reserve changes within an interval may go unrecorded, making the      interpolation an approximation. Read from the pool directly when an exact value is required.A point newer than the newest stored observation is estimated from the current cumulative      instead of two stored ones, so a trade after that point can change what it reads. It stops      changing once an observation is stored at or after that point. Points that already fall      between two stored observations read the same on every call.\",\"params\":{\"secondsAgos\":\"Array of seconds offsets from `block.timestamp` to query\"},\"returns\":{\"_reserve0Cumulatives\":\"Cumulative reserve0 values at each requested point\",\"_reserve1Cumulatives\":\"Cumulative reserve1 values at each requested point\"}},\"pendingFees(address)\":{\"params\":{\"_account\":\"Address to query.\"},\"returns\":{\"_amount0\":\"Pending token0 fees.\",\"_amount1\":\"Pending token1 fees.\"}},\"setName(string)\":{\"params\":{\"__name\":\"String of new name\"}},\"setSymbol(string)\":{\"params\":{\"__symbol\":\"String of new symbol\"}},\"skim(address)\":{\"params\":{\"to\":\"Address to receive any skimmed rewards\"}},\"swap(uint256,uint256,address,bytes)\":{\"params\":{\"amount0Out\":\"Amount of token0 to send to `to`\",\"amount1Out\":\"Amount of token1 to send to `to`\",\"data\":\"Additional calldata for flashloans\",\"to\":\"Address to recieve the swapped output\"}},\"symbol()\":{\"details\":\"Returns the symbol of the token, usually a shorter version of the name.\"},\"totalSupply()\":{\"details\":\"Returns the value of tokens in existence.\"},\"transfer(address,uint256)\":{\"details\":\"See {IERC20-transfer}. Requirements: - `to` cannot be the zero address. - the caller must have a balance of at least `value`.\"},\"transferFrom(address,address,uint256)\":{\"details\":\"See {IERC20-transferFrom}. Skips emitting an {Approval} event indicating an allowance update. This is not required by the ERC. See {xref-ERC20-_approve-address-address-uint256-bool-}[_approve]. NOTE: Does not update the allowance if the current allowance is the maximum `uint256`. Requirements: - `from` and `to` cannot be the zero address. - `from` must have a balance of at least `value`. - the caller must have allowance for ``from``'s tokens of at least `value`.\"}},\"stateVariables\":{\"POOL_TYPE\":{\"return\":\"The pool type label to be able to identify the type of pool\",\"returns\":{\"_0\":\"The pool type label to be able to identify the type of pool\"}}},\"title\":\"StablePool\",\"version\":1},\"userdoc\":{\"errors\":{\"BelowMinimumK()\":[{\"notice\":\"Thrown on first mint when `_k(amount0, amount1)` is less than or equal to `MINIMUM_K`\"}],\"CannotCalculateY()\":[{\"notice\":\"Thrown when the Newton-Raphson search cannot solve for `y` within its iteration budget\"}],\"DepositsNotEqual()\":[{\"notice\":\"Thrown when the deposited amounts are not equal\"}],\"FactoryAlreadySet()\":[{\"notice\":\"Thrown when the factory address has already been set and cannot be changed\"}],\"InsufficientInputAmount()\":[{\"notice\":\"Thrown when the input amount provided to a swap is zero or insufficient\"}],\"InsufficientLiquidity()\":[{\"notice\":\"Thrown when the pool does not have enough liquidity to fulfil the operation\"}],\"InsufficientLiquidityBurned()\":[{\"notice\":\"Thrown when burning LP tokens would return zero of at least one underlying token\"}],\"InsufficientLiquidityMinted()\":[{\"notice\":\"Thrown when minting would produce zero LP tokens\"}],\"InsufficientOutputAmount()\":[{\"notice\":\"Thrown when the output amount of a swap is zero or below the requested minimum\"}],\"InvalidTo()\":[{\"notice\":\"Thrown when the `to` address supplied to swap or burn is one of the pool's tokens\"}],\"IsPaused()\":[{\"notice\":\"Thrown when an operation is attempted while the pool is paused\"}],\"K()\":[{\"notice\":\"Thrown when the invariant K check fails after a swap\"}],\"KIsZero()\":[{\"notice\":\"Thrown after burn when remaining reserves cause `_k` to round to zero\"}],\"NotAuthorized()\":[{\"notice\":\"Thrown when the caller is neither the account nor an approved claim operator\"}],\"ObservationOld()\":[{\"notice\":\"Thrown when a requested timestamp predates the oldest stored observation.\"}],\"ZeroAddress()\":[{\"notice\":\"Thrown when a zero address is supplied where a non-zero address is required\"}]},\"events\":{\"Burn(address,address,uint256,uint256)\":{\"notice\":\"Emitted when liquidity is burned\"},\"Claim(address,address,address,uint256,uint256)\":{\"notice\":\"Emitted when accumulated fee tokens are claimed\"},\"ClaimApproval(address,address,bool)\":{\"notice\":\"Emitted when an account grants or revokes claim approval for an operator\"},\"Fees(address,uint256,uint256)\":{\"notice\":\"Emitted when fees are claimed by a liquidity provider\"},\"IncreaseObservationCardinalityNext(address,uint16,uint16)\":{\"notice\":\"Emitted whenever `observationCardinalityNext` is increased\"},\"Mint(address,address,uint256,uint256)\":{\"notice\":\"Emitted when liquidity is minted\"},\"Swap(address,address,uint256,uint256,uint256,uint256)\":{\"notice\":\"Emitted on every swap executed through the pool\"},\"Sync(uint256,uint256)\":{\"notice\":\"Emitted when reserves are synced to the current balances\"}},\"kind\":\"user\",\"methods\":{\"MINIMUM_K()\":{\"notice\":\"Minimum value of the stable-swap invariant\"},\"PERIOD_SIZE()\":{\"notice\":\"Period gate for new observations, in seconds. A new observation is written when more         than `PERIOD_SIZE` seconds have passed since the last one, so the smallest possible         spacing between two stored observations is `PERIOD_SIZE + 1` (i.e. 61 seconds at the         default value of 60).\"},\"POOL_TYPE()\":{\"notice\":\"The pool type identifier\"},\"approveForClaim(address,bool)\":{\"notice\":\"Grants or revokes an operator's permission to claim the caller's accumulated fees\"},\"approvedForClaim(address,address)\":{\"notice\":\"Whether an operator may claim an account's accumulated fees\"},\"blockTimestampLast()\":{\"notice\":\"Timestamp of last update to pool\"},\"burn(address)\":{\"notice\":\"This low-level function should be called from a contract which performs important safety checks         standard uniswap v2 implementation\"},\"claimFees(address)\":{\"notice\":\"Claims the caller's accumulated fees\"},\"claimFees(address,address)\":{\"notice\":\"Claims an account's accumulated fees\"},\"claimable0(address)\":{\"notice\":\"Amount of unclaimed, but claimable tokens from fees of token0 for an LP\"},\"claimable1(address)\":{\"notice\":\"Amount of unclaimed, but claimable tokens from fees of token1 for an LP\"},\"currentCumulativePrices()\":{\"notice\":\"Produces the cumulative price using counterfactuals to save gas and avoid a call to sync.\"},\"factory()\":{\"notice\":\"Address of PoolFactory that created this contract\"},\"getAmountInWithTotalFee(uint256,address)\":{\"notice\":\"Get the amount of tokenIn required to receive the amount of tokenOut, charging the total fees\"},\"getAmountOut(uint256,address)\":{\"notice\":\"Get the amount of tokenOut given the amount of tokenIn, charging only the base fee\"},\"getAmountOut(uint256,address,uint256,uint256)\":{\"notice\":\"Quote `amountIn` of `tokenIn` against a custom reserve snapshot\"},\"getAmountOutWithTotalFee(uint256,address)\":{\"notice\":\"Get the amount of tokenOut given the amount of tokenIn, charging the total fees\"},\"getK()\":{\"notice\":\"Returns the value of K in the Pool, based on its reserves.\"},\"getReserves()\":{\"notice\":\"Update reserves and, on the first call per block, price accumulators\"},\"increaseObservationCardinalityNext(uint16)\":{\"notice\":\"Pre-allocates buffer slots increasing the buffer capacity\"},\"index0()\":{\"notice\":\"Accumulated fees of token0 (global)\"},\"index1()\":{\"notice\":\"Accumulated fees of token1 (global)\"},\"initialize(address,address)\":{\"notice\":\"Called on pool creation by the owning PoolFactory\"},\"metadata()\":{\"notice\":\"Returns the decimal (dec), reserves (r), and tokens (t) of token0 and token1\"},\"mint(address)\":{\"notice\":\"This low-level function should be called by addLiquidity functions in Router.sol, which performs important safety checks         standard uniswap v2 implementation\"},\"observationBuffer()\":{\"notice\":\"Circular buffer of TWAP observations with its write index and cardinality metadata.\"},\"observations(uint256)\":{\"notice\":\"Returns the observation at the given index\"},\"observe(uint32[])\":{\"notice\":\"Returns the cumulative reserves as of each requested `secondsAgo`. Reverts when any         `secondsAgos[i]` predates the oldest stored observation.\"},\"pendingFees(address)\":{\"notice\":\"Returns accumulated but unclaimed fees for an account.\"},\"poolFees()\":{\"notice\":\"Address of linked PoolFees.sol\"},\"reserve0()\":{\"notice\":\"Amount of token0 in pool\"},\"reserve0CumulativeLast()\":{\"notice\":\"Cumulative of reserve0 factoring in time elapsed\"},\"reserve1()\":{\"notice\":\"Amount of token1 in pool\"},\"reserve1CumulativeLast()\":{\"notice\":\"Cumulative of reserve1 factoring in time elapsed\"},\"setName(string)\":{\"notice\":\"Set pool name         Only callable by IPoolFactory(factory).poolAdmin()\"},\"setSymbol(string)\":{\"notice\":\"Set pool symbol         Only callable by IPoolFactory(factory).poolAdmin()\"},\"skim(address)\":{\"notice\":\"Force balances to match reserves\"},\"supplyIndex0(address)\":{\"notice\":\"Get an LP's relative index0 to index0\"},\"supplyIndex1(address)\":{\"notice\":\"Get an LP's relative index1 to index1\"},\"swap(uint256,uint256,address,bytes)\":{\"notice\":\"This low-level function should be called from a contract which performs important safety checks\"},\"sync()\":{\"notice\":\"Force reserves to match balances\"},\"token0()\":{\"notice\":\"Address of token in the pool with the lower address value\"},\"token1()\":{\"notice\":\"Address of token in the pool with the higher address value\"},\"tokens()\":{\"notice\":\"Returns [token0, token1]\"}},\"notice\":\"Aerodrome V2 stable-swap pool.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"V3/src/pools/StablePool.sol\":\"StablePool\"},\"evmVersion\":\"prague\",\"libraries\":{\"V3/src/src/libraries/LeafAllocationLibrary.sol:LeafAllocationLibrary\":\"0xc7e262e848fca78c3c66ee3c9835e4e65e3e0398\",\"V3/src/src/libraries/RewardsLogicLibrary.sol:RewardsLogicLibrary\":\"0x2b73df2e7e957c77f1d8c01e0a71ad1ff38d6720\",\"V3/src/src/libraries/VotingRewardsFactoryLibrary.sol:VotingRewardsFactoryLibrary\":\"0x1c3821772bfaae08ee2d4ed8e2c29844ca49634e\"},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[\":@hyperlane/contracts/=node_modules/@hyperlane-xyz/core/contracts/\",\":@nomad-xyz/src/=node_modules/@nomad-xyz/excessively-safe-call/src/\",\":@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/\",\":@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/\",\":@openzeppelin4/contracts/=node_modules/@openzeppelin/contracts-v4/\",\":@solady/=node_modules/solady/src/\",\":V3-script/=V3/script/\",\":V3-test/=V3/test/\",\":V3/=V3/src/\",\":forge-std/=node_modules/forge-std/src/\",\"node_modules/@hyperlane-xyz/:@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable-v4/\",\"node_modules/@hyperlane-xyz/:@openzeppelin/contracts/=node_modules/@openzeppelin/contracts-v4/\"]},\"sources\":{\"V3/src/interfaces/factories/IPoolFactory.sol\":{\"keccak256\":\"0x1f8dc8eab9ed8c2af9fdc70a79ad87fa32c0b944ad264dbfa0ff73840b1eb5cd\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://210e03abf15c2b019338710a28df9b19da6f34a50e3274a7a3f21d0004d803d5\",\"dweb:/ipfs/QmYcX93yesan7C2BneWPCdqLJV5nqroCrmPRosCgAsmPSZ\"]},\"V3/src/interfaces/pools/IPool.sol\":{\"keccak256\":\"0x4ac3d8b3381f9f0b24516a34f28a25c36a3f11448b72e11155a8fb47e33cf65c\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://5e5fd853c52b861cb4884edfdef7519cdac15a852a59f0047ec8582280fb8a68\",\"dweb:/ipfs/QmbxZcm4BH4Nu4V2rm767AtxHnroZofENMSNQJjg4dknc7\"]},\"V3/src/interfaces/pools/IPoolCallee.sol\":{\"keccak256\":\"0xc1e83c75cb704ca137543fd48127b5f3904d2644d13093d678c4edf6a618cfa9\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://3a03eb17ea6a74081180b3ef1386ccaaa8214c5efdd59bff833385b6c595603d\",\"dweb:/ipfs/QmRr8YmMC3n1mtjFU1Ukh3JphT267KFeBeFSChCik5hfhz\"]},\"V3/src/interfaces/pools/IStablePool.sol\":{\"keccak256\":\"0x2ef11f9e8c2845a0d0e6854db6fad6ad85d5c4dc26e1e61fade770c41691d6bd\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://493275d0ee5e7226644cc127587a8fffa57aa29157289f6fe31648670fc1175c\",\"dweb:/ipfs/QmQr1UKZ22AZYyKvB8XqPVEWrZAaCzXYS65x3QroAD9TB6\"]},\"V3/src/interfaces/pools/tape/IPoolTape.sol\":{\"keccak256\":\"0xbafec7377a6f67eafa045e7395c59cdbab75e2a517207868cb216c69289d1b36\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://9bbb4ad7a82504240c578972aa0cb4c5dbcf64a3cd34d455df2878c37061f0a4\",\"dweb:/ipfs/QmPnZJ1JQXdWBo7mStv4Rcw1C51mmBHZp8eSosFyKfa2WU\"]},\"V3/src/libraries/PoolOracle.sol\":{\"keccak256\":\"0x149aeb7e33e8a25357632ce0dede4c614e377eb3158755954869152f4cbdeffe\",\"license\":\"GPL-3.0-or-later\",\"urls\":[\"bzz-raw://6cb60ad438b8415995b69614859d5a4a6fc1cfe09fc1429a0d67d3dbaa03d394\",\"dweb:/ipfs/QmPmeR5efBLbsUjiAPxFiLi1iKoZa3Qoww5h5X5JVoY28n\"]},\"V3/src/pools/Pool.sol\":{\"keccak256\":\"0xe9f9e84d0714dccf6e244c4deda76b2b1b7520b8758204655c2b3f57c0a33874\",\"license\":\"GPL-3.0-or-later\",\"urls\":[\"bzz-raw://feeea4a1a04ff36ef97cd13bec25105ccb4dc213631ced965545b61a8df44226\",\"dweb:/ipfs/QmVPMEZjQr9kFtcH4ssrgXsjmHyNg2uEPAKXGsW3aUjSpo\"]},\"V3/src/pools/PoolFees.sol\":{\"keccak256\":\"0xcacae30b57729c48c074d85d95be72137b15beb64e52cc85a8f9947b9ca49882\",\"license\":\"GPL-3.0-or-later\",\"urls\":[\"bzz-raw://794663e81644b94ac2b62ece1ea5abbb9ee0415392f8cbcf591e425e32ea7679\",\"dweb:/ipfs/QmYyVAiZeniGrmMyu9SLP94mHFFGR9UsD3ktPePxstLdDG\"]},\"V3/src/pools/StablePool.sol\":{\"keccak256\":\"0xab686a4bdcc2c218119e259a9330ca5d3f7a4d664a5d8d287dedab1bfb2d17f9\",\"license\":\"GPL-3.0-or-later\",\"urls\":[\"bzz-raw://9d73c976a388c68e3450f5ca9c83c3ddab1d0cfdbaac37970b0d0f2773e42a25\",\"dweb:/ipfs/QmfD2FFZDD7BssFoy4db7tVQEvdLB9toN63t76Qw9MRyfv\"]},\"node_modules/@openzeppelin/contracts/interfaces/IERC1363.sol\":{\"keccak256\":\"0xd5ea07362ab630a6a3dee4285a74cf2377044ca2e4be472755ad64d7c5d4b69d\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://da5e832b40fc5c3145d3781e2e5fa60ac2052c9d08af7e300dc8ab80c4343100\",\"dweb:/ipfs/QmTzf7N5ZUdh5raqtzbM11yexiUoLC9z3Ws632MCuycq1d\"]},\"node_modules/@openzeppelin/contracts/interfaces/IERC165.sol\":{\"keccak256\":\"0x0afcb7e740d1537b252cb2676f600465ce6938398569f09ba1b9ca240dde2dfc\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://1c299900ac4ec268d4570ecef0d697a3013cd11a6eb74e295ee3fbc945056037\",\"dweb:/ipfs/Qmab9owJoxcA7vJT5XNayCMaUR1qxqj1NDzzisduwaJMcZ\"]},\"node_modules/@openzeppelin/contracts/interfaces/IERC20.sol\":{\"keccak256\":\"0x1a6221315ce0307746c2c4827c125d821ee796c74a676787762f4778671d4f44\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://1bb2332a7ee26dd0b0de9b7fe266749f54820c99ab6a3bcb6f7e6b751d47ee2d\",\"dweb:/ipfs/QmcRWpaBeCYkhy68PR3B4AgD7asuQk7PwkWxrvJbZcikLF\"]},\"node_modules/@openzeppelin/contracts/interfaces/draft-IERC6093.sol\":{\"keccak256\":\"0x1b88b3fb3d85ba5496d7d5f396f83ee1fddcdd6762059ff65992655b67920998\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://89393bb3212da1c0889601b9706a07b39419ddc4d2faab9eaf6e7f9152cf6a1c\",\"dweb:/ipfs/QmcCfzzxv1Bkdz1c1yF4gQCeYb6Us5BJANnzTFqawfd1HL\"]},\"node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"keccak256\":\"0x669464167428061ee0f8618b73b3ee90aff8405683e7ddde8cd77dadaa1afe29\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://0dda78587a7358b4fdf6b9fca0fde5a5e34930f36d5268a16028627fc0170195\",\"dweb:/ipfs/QmQ1b6cCceDRWNxti9HifsTCzmVP25Haxs1bWugm52vTqH\"]},\"node_modules/@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"keccak256\":\"0x74ed01eb66b923d0d0cfe3be84604ac04b76482a55f9dd655e1ef4d367f95bc2\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://5282825a626cfe924e504274b864a652b0023591fa66f06a067b25b51ba9b303\",\"dweb:/ipfs/QmeCfPykghhMc81VJTrHTC7sF6CRvaA1FXVq2pJhwYp1dV\"]},\"node_modules/@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"keccak256\":\"0xd6fa4088198f04eef10c5bce8a2f4d60554b7ec4b987f684393c01bf79b94d9f\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://f95ee0bbd4dd3ac730d066ba3e785ded4565e890dbec2fa7d3b9fe3bad9d0d6e\",\"dweb:/ipfs/QmSLr6bHkPFWT7ntj34jmwfyskpwo97T9jZUrk5sz3sdtR\"]},\"node_modules/@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"keccak256\":\"0x304d732678032a9781ae85c8f204c8fba3d3a5e31c02616964e75cfdc5049098\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://299ced486011781dc98f638059678323c03079fefae1482abaa2135b22fa92d0\",\"dweb:/ipfs/QmbZNbcPTBxNvwChavN2kkZZs7xHhYL7mv51KrxMhsMs3j\"]},\"node_modules/@openzeppelin/contracts/utils/Context.sol\":{\"keccak256\":\"0x493033a8d1b176a037b2cc6a04dad01a5c157722049bbecf632ca876224dd4b2\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6a708e8a5bdb1011c2c381c9a5cfd8a9a956d7d0a9dc1bd8bcdaf52f76ef2f12\",\"dweb:/ipfs/Qmax9WHBnVsZP46ZxEMNRQpLQnrdE4dK8LehML1Py8FowF\"]},\"node_modules/@openzeppelin/contracts/utils/Panic.sol\":{\"keccak256\":\"0xf7fe324703a64fc51702311dc51562d5cb1497734f074e4f483bfb6717572d7a\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://c6a5ff4f9fd8649b7ee20800b7fa387d3465bd77cf20c2d1068cd5c98e1ed57a\",\"dweb:/ipfs/QmVSaVJf9FXFhdYEYeCEfjMVHrxDh5qL4CGkxdMWpQCrqG\"]},\"node_modules/@openzeppelin/contracts/utils/ReentrancyGuard.sol\":{\"keccak256\":\"0xa516cbf1c7d15d3517c2d668601ce016c54395bf5171918a14e2686977465f53\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://1e1d079e8edfb58efd23a311e315a4807b01b5d1cf153f8fa2d0608b9dec3e99\",\"dweb:/ipfs/QmTBExeX2SDTkn5xbk5ssbYSx7VqRp9H4Ux1CY4uQM4b9N\"]},\"node_modules/@openzeppelin/contracts/utils/StorageSlot.sol\":{\"keccak256\":\"0xcf74f855663ce2ae00ed8352666b7935f6cddea2932fdf2c3ecd30a9b1cd0e97\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://9f660b1f351b757dfe01438e59888f31f33ded3afcf5cb5b0d9bf9aa6f320a8b\",\"dweb:/ipfs/QmarDJ5hZEgBtCmmrVzEZWjub9769eD686jmzb2XpSU1cM\"]},\"node_modules/@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"keccak256\":\"0x8891738ffe910f0cf2da09566928589bf5d63f4524dd734fd9cedbac3274dd5c\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://971f954442df5c2ef5b5ebf1eb245d7105d9fbacc7386ee5c796df1d45b21617\",\"dweb:/ipfs/QmadRjHbkicwqwwh61raUEapaVEtaLMcYbQZWs9gUkgj3u\"]},\"node_modules/@openzeppelin/contracts/utils/math/Math.sol\":{\"keccak256\":\"0x59973a93b1f983f94e10529f46ca46544a9fec2b5f56fb1390bbe9e0dc79f857\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://c55ef8f0b9719790c2ae6f81d80a59ffb89f2f0abe6bc065585bd79edce058c5\",\"dweb:/ipfs/QmNNmCbX9NjPXKqHJN8R1WC2rNeZSQrPZLd6FF6AKLyH5Y\"]},\"node_modules/@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"keccak256\":\"0xc8cae21c9ae4a46e5162ff9bf5b351d6fa6a6eba72d515f3bc1bdfeda7fdf083\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://ce830ebcf28e31643caba318996db3763c36d52cd0f23798ba83c135355d45e9\",\"dweb:/ipfs/QmdGPcvptHN7UBCbUYBbRX3hiRVRFLRwno8b4uga6uFNif\"]}},\"version\":1}","userdoc":{"kind":"user","errors":{"K()":[{"notice":"Thrown when the invariant K check fails after a swap"}],"KIsZero()":[{"notice":"Thrown after burn when remaining reserves cause `_k` to round to zero"}],"IsPaused()":[{"notice":"Thrown when an operation is attempted while the pool is paused"}],"InvalidTo()":[{"notice":"Thrown when the `to` address supplied to swap or burn is one of the pool's tokens"}],"ZeroAddress()":[{"notice":"Thrown when a zero address is supplied where a non-zero address is required"}],"BelowMinimumK()":[{"notice":"Thrown on first mint when `_k(amount0, amount1)` is less than or equal to `MINIMUM_K`"}],"NotAuthorized()":[{"notice":"Thrown when the caller is neither the account nor an approved claim operator"}],"ObservationOld()":[{"notice":"Thrown when a requested timestamp predates the oldest stored observation."}],"CannotCalculateY()":[{"notice":"Thrown when the Newton-Raphson search cannot solve for `y` within its iteration budget"}],"DepositsNotEqual()":[{"notice":"Thrown when the deposited amounts are not equal"}],"FactoryAlreadySet()":[{"notice":"Thrown when the factory address has already been set and cannot be changed"}],"InsufficientLiquidity()":[{"notice":"Thrown when the pool does not have enough liquidity to fulfil the operation"}],"InsufficientInputAmount()":[{"notice":"Thrown when the input amount provided to a swap is zero or insufficient"}],"InsufficientOutputAmount()":[{"notice":"Thrown when the output amount of a swap is zero or below the requested minimum"}],"InsufficientLiquidityBurned()":[{"notice":"Thrown when burning LP tokens would return zero of at least one underlying token"}],"InsufficientLiquidityMinted()":[{"notice":"Thrown when minting would produce zero LP tokens"}]},"events":{"Sync(uint256,uint256)":{"notice":"Emitted when reserves are synced to the current balances"},"Fees(address,uint256,uint256)":{"notice":"Emitted when fees are claimed by a liquidity provider"},"ClaimApproval(address,address,bool)":{"notice":"Emitted when an account grants or revokes claim approval for an operator"},"Burn(address,address,uint256,uint256)":{"notice":"Emitted when liquidity is burned"},"Mint(address,address,uint256,uint256)":{"notice":"Emitted when liquidity is minted"},"Claim(address,address,address,uint256,uint256)":{"notice":"Emitted when accumulated fee tokens are claimed"},"Swap(address,address,uint256,uint256,uint256,uint256)":{"notice":"Emitted on every swap executed through the pool"},"IncreaseObservationCardinalityNext(address,uint16,uint16)":{"notice":"Emitted whenever `observationCardinalityNext` is increased"}},"notice":"Aerodrome V2 stable-swap pool.","methods":{"getK()":{"notice":"Returns the value of K in the Pool, based on its reserves."},"sync()":{"notice":"Force reserves to match balances"},"index0()":{"notice":"Accumulated fees of token0 (global)"},"index1()":{"notice":"Accumulated fees of token1 (global)"},"token0()":{"notice":"Address of token in the pool with the lower address value"},"token1()":{"notice":"Address of token in the pool with the higher address value"},"tokens()":{"notice":"Returns [token0, token1]"},"factory()":{"notice":"Address of PoolFactory that created this contract"},"metadata()":{"notice":"Returns the decimal (dec), reserves (r), and tokens (t) of token0 and token1"},"poolFees()":{"notice":"Address of linked PoolFees.sol"},"reserve0()":{"notice":"Amount of token0 in pool"},"reserve1()":{"notice":"Amount of token1 in pool"},"MINIMUM_K()":{"notice":"Minimum value of the stable-swap invariant"},"POOL_TYPE()":{"notice":"The pool type identifier"},"PERIOD_SIZE()":{"notice":"Period gate for new observations, in seconds. A new observation is written when more         than `PERIOD_SIZE` seconds have passed since the last one, so the smallest possible         spacing between two stored observations is `PERIOD_SIZE + 1` (i.e. 61 seconds at the         default value of 60)."},"burn(address)":{"notice":"This low-level function should be called from a contract which performs important safety checks         standard uniswap v2 implementation"},"getReserves()":{"notice":"Update reserves and, on the first call per block, price accumulators"},"mint(address)":{"notice":"This low-level function should be called by addLiquidity functions in Router.sol, which performs important safety checks         standard uniswap v2 implementation"},"skim(address)":{"notice":"Force balances to match reserves"},"setName(string)":{"notice":"Set pool name         Only callable by IPoolFactory(factory).poolAdmin()"},"observe(uint32[])":{"notice":"Returns the cumulative reserves as of each requested `secondsAgo`. Reverts when any         `secondsAgos[i]` predates the oldest stored observation."},"setSymbol(string)":{"notice":"Set pool symbol         Only callable by IPoolFactory(factory).poolAdmin()"},"claimFees(address)":{"notice":"Claims the caller's accumulated fees"},"claimable0(address)":{"notice":"Amount of unclaimed, but claimable tokens from fees of token0 for an LP"},"claimable1(address)":{"notice":"Amount of unclaimed, but claimable tokens from fees of token1 for an LP"},"observationBuffer()":{"notice":"Circular buffer of TWAP observations with its write index and cardinality metadata."},"blockTimestampLast()":{"notice":"Timestamp of last update to pool"},"pendingFees(address)":{"notice":"Returns accumulated but unclaimed fees for an account."},"observations(uint256)":{"notice":"Returns the observation at the given index"},"supplyIndex0(address)":{"notice":"Get an LP's relative index0 to index0"},"supplyIndex1(address)":{"notice":"Get an LP's relative index1 to index1"},"reserve0CumulativeLast()":{"notice":"Cumulative of reserve0 factoring in time elapsed"},"reserve1CumulativeLast()":{"notice":"Cumulative of reserve1 factoring in time elapsed"},"currentCumulativePrices()":{"notice":"Produces the cumulative price using counterfactuals to save gas and avoid a call to sync."},"claimFees(address,address)":{"notice":"Claims an account's accumulated fees"},"initialize(address,address)":{"notice":"Called on pool creation by the owning PoolFactory"},"approveForClaim(address,bool)":{"notice":"Grants or revokes an operator's permission to claim the caller's accumulated fees"},"getAmountOut(uint256,address)":{"notice":"Get the amount of tokenOut given the amount of tokenIn, charging only the base fee"},"approvedForClaim(address,address)":{"notice":"Whether an operator may claim an account's accumulated fees"},"swap(uint256,uint256,address,bytes)":{"notice":"This low-level function should be called from a contract which performs important safety checks"},"getAmountInWithTotalFee(uint256,address)":{"notice":"Get the amount of tokenIn required to receive the amount of tokenOut, charging the total fees"},"getAmountOutWithTotalFee(uint256,address)":{"notice":"Get the amount of tokenOut given the amount of tokenIn, charging the total fees"},"increaseObservationCardinalityNext(uint16)":{"notice":"Pre-allocates buffer slots increasing the buffer capacity"},"getAmountOut(uint256,address,uint256,uint256)":{"notice":"Quote `amountIn` of `tokenIn` against a custom reserve snapshot"}},"version":1},"devdoc":{"kind":"dev","title":"StablePool","errors":{"ERC20InvalidSender(address)":[{"params":{"sender":"Address whose tokens are being transferred."},"details":"Indicates a failure with the token `sender`. Used in transfers."}],"ERC20InvalidSpender(address)":[{"params":{"spender":"Address that may be allowed to operate on tokens without being their owner."},"details":"Indicates a failure with the `spender` to be approved. Used in approvals."}],"ERC20InvalidApprover(address)":[{"params":{"approver":"Address initiating an approval operation."},"details":"Indicates a failure with the `approver` of a token to be approved. Used in approvals."}],"ERC20InvalidReceiver(address)":[{"params":{"receiver":"Address to which tokens are being transferred."},"details":"Indicates a failure with the token `receiver`. Used in transfers."}],"ReentrancyGuardReentrantCall()":[{"details":"Unauthorized reentrant call."}],"SafeERC20FailedOperation(address)":[{"details":"An operation with an ERC-20 token failed."}],"ERC20InsufficientBalance(address,uint256,uint256)":[{"params":{"needed":"Minimum amount required to perform a transfer.","sender":"Address whose tokens are being transferred.","balance":"Current balance for the interacting account."},"details":"Indicates an error related to the current `balance` of a `sender`. Used in transfers."}],"ERC20InsufficientAllowance(address,uint256,uint256)":[{"params":{"needed":"Minimum amount required to perform a transfer.","spender":"Address that may be allowed to operate on tokens without being their owner.","allowance":"Amount of tokens a `spender` is allowed to operate with."},"details":"Indicates a failure with the `spender`’s `allowance`. Used in transfers."}]},"events":{"Sync(uint256,uint256)":{"params":{"reserve0":"Updated reserve of token0","reserve1":"Updated reserve of token1"}},"Fees(address,uint256,uint256)":{"params":{"sender":"Address that triggered the fee claim","amount0":"Amount of token0 fees collected","amount1":"Amount of token1 fees collected"}},"Approval(address,address,uint256)":{"details":"Emitted when the allowance of a `spender` for an `owner` is set by a call to {approve}. `value` is the new allowance."},"Transfer(address,address,uint256)":{"details":"Emitted when `value` tokens are moved from one account (`from`) to another (`to`). Note that `value` may be zero."},"ClaimApproval(address,address,bool)":{"params":{"account":"Account whose approval state changed","approved":"New approval state","operator":"Operator being approved or revoked"}},"Burn(address,address,uint256,uint256)":{"params":{"to":"Address that received the underlying tokens","sender":"Address that initiated the burn","amount0":"Amount of token0 returned","amount1":"Amount of token1 returned"}},"Mint(address,address,uint256,uint256)":{"params":{"to":"Address that received the LP tokens","sender":"Address that initiated the mint","amount0":"Amount of token0 deposited","amount1":"Amount of token1 deposited"}},"Claim(address,address,address,uint256,uint256)":{"params":{"caller":"Address that triggered the claim","account":"Address whose accumulated fees were claimed","amount0":"Amount of token0 claimed","amount1":"Amount of token1 claimed","recipient":"Address that received the fee tokens"}},"Swap(address,address,uint256,uint256,uint256,uint256)":{"params":{"to":"Address that received the output tokens","sender":"Address that initiated the swap","amount0In":"Amount of token0 provided as input","amount1In":"Amount of token1 provided as input","amount0Out":"Amount of token0 sent as output","amount1Out":"Amount of token1 sent as output"}},"IncreaseObservationCardinalityNext(address,uint16,uint16)":{"params":{"caller":"Address that triggered the cardinality growth","observationCardinalityNextNew":"New value of `observationCardinalityNext`","observationCardinalityNextOld":"Previous value of `observationCardinalityNext`"}}},"methods":{"name()":{"details":"Returns the name of the token."},"symbol()":{"details":"Returns the symbol of the token, usually a shorter version of the name."},"decimals()":{"details":"Returns the number of decimals used to get its user representation. For example, if `decimals` equals `2`, a balance of `505` tokens should be displayed to a user as `5.05` (`505 / 10 ** 2`). Tokens usually opt for a value of 18, imitating the relationship between Ether and Wei. This is the default value returned by this function, unless it's overridden. NOTE: This information is only used for _display_ purposes: it in no way affects any of the arithmetic of the contract, including {IERC20-balanceOf} and {IERC20-transfer}."},"burn(address)":{"params":{"to":"Address to receive token0 and token1 from burning the pool token"},"returns":{"amount0":"Amount of token0 returned","amount1":"Amount of token1 returned"}},"getReserves()":{"returns":{"_reserve0":".","_reserve1":".","_blockTimestampLast":"."}},"mint(address)":{"params":{"to":"Address to receive the minted LP token"},"returns":{"liquidity":"Amount of LP token minted"}},"skim(address)":{"params":{"to":"Address to receive any skimmed rewards"}},"totalSupply()":{"details":"Returns the value of tokens in existence."},"setName(string)":{"params":{"__name":"String of new name"}},"observe(uint32[])":{"params":{"secondsAgos":"Array of seconds offsets from `block.timestamp` to query"},"details":"Offsets between two stored observations are linearly interpolated. Observations are      period-gated, so reserve changes within an interval may go unrecorded, making the      interpolation an approximation. Read from the pool directly when an exact value is required.A point newer than the newest stored observation is estimated from the current cumulative      instead of two stored ones, so a trade after that point can change what it reads. It stops      changing once an observation is stored at or after that point. Points that already fall      between two stored observations read the same on every call.","returns":{"_reserve0Cumulatives":"Cumulative reserve0 values at each requested point","_reserve1Cumulatives":"Cumulative reserve1 values at each requested point"}},"setSymbol(string)":{"params":{"__symbol":"String of new symbol"}},"balanceOf(address)":{"details":"Returns the value of tokens owned by `account`."},"claimFees(address)":{"params":{"_recipient":"Address that receives the claimed fee tokens"},"returns":{"_0":"Amount of token0 claimed","_1":"Amount of token1 claimed"}},"pendingFees(address)":{"params":{"_account":"Address to query."},"returns":{"_amount0":"Pending token0 fees.","_amount1":"Pending token1 fees."}},"observations(uint256)":{"params":{"index":"Index of the observation to return"},"returns":{"timestamp":"Timestamp of the observation","reserve0Cumulative":"Cumulative reserve0 of the observation","reserve1Cumulative":"Cumulative reserve1 of the observation"}},"approve(address,uint256)":{"details":"See {IERC20-approve}. NOTE: If `value` is the maximum `uint256`, the allowance is not updated on `transferFrom`. This is semantically equivalent to an infinite approval. Requirements: - `spender` cannot be the zero address."},"transfer(address,uint256)":{"details":"See {IERC20-transfer}. Requirements: - `to` cannot be the zero address. - the caller must have a balance of at least `value`."},"allowance(address,address)":{"details":"Returns the remaining number of tokens that `spender` will be allowed to spend on behalf of `owner` through {transferFrom}. This is zero by default. This value changes when {approve} or {transferFrom} are called."},"claimFees(address,address)":{"params":{"_account":"Account whose accumulated fees are claimed","_recipient":"Address that receives the claimed fee tokens"},"details":"The caller must be `_account` or an operator approved by `_account`","returns":{"_0":"Amount of token0 claimed","_1":"Amount of token1 claimed"}},"initialize(address,address)":{"params":{"_token0":"Address of token0","_token1":"Address of token1"}},"approveForClaim(address,bool)":{"params":{"_approved":"Whether the operator is approved","_operator":"Operator whose approval is updated"}},"getAmountOut(uint256,address)":{"params":{"tokenIn":"Address of token","amountIn":"Amount of token in"},"details":"Does not charge the MEV tax, so the result can be higher than what `swap` pays out.      Use `getAmountOutWithTotalFee` to quote a swap.","returns":{"_0":"Amount out"}},"swap(uint256,uint256,address,bytes)":{"params":{"to":"Address to recieve the swapped output","data":"Additional calldata for flashloans","amount0Out":"Amount of token0 to send to `to`","amount1Out":"Amount of token1 to send to `to`"}},"transferFrom(address,address,uint256)":{"details":"See {IERC20-transferFrom}. Skips emitting an {Approval} event indicating an allowance update. This is not required by the ERC. See {xref-ERC20-_approve-address-address-uint256-bool-}[_approve]. NOTE: Does not update the allowance if the current allowance is the maximum `uint256`. Requirements: - `from` and `to` cannot be the zero address. - `from` must have a balance of at least `value`. - the caller must have allowance for ``from``'s tokens of at least `value`."},"getAmountInWithTotalFee(uint256,address)":{"params":{"tokenOut":"Address of token out","amountOut":"Amount of token out to receive"},"details":"Reverts if the exact output cannot be calculated","returns":{"_0":"Amount in, fee included"}},"getAmountOutWithTotalFee(uint256,address)":{"params":{"tokenIn":"Address of token in","amountIn":"Amount of token in"},"returns":{"_0":"Amount out"}},"increaseObservationCardinalityNext(uint16)":{"params":{"_observationCardinalityNext":"New target capacity. At most 65,535."},"details":"Pre-initialises buffer slots so observation writes hit warm storage."},"getAmountOut(uint256,address,uint256,uint256)":{"params":{"tokenIn":"Address of the input token","amountIn":"Input amount in the smallest unit of `tokenIn`","_reserve0":"Reserve of token0 to quote against","_reserve1":"Reserve of token1 to quote against"},"details":"Subtracts the base fee from `amountIn` before applying the curve. Does not charge the MEV      tax, so use `getAmountOutWithTotalFee` to quote a swap.","returns":{"_0":"Output amount the swap would produce against the supplied reserves"}}},"version":1,"stateVariables":{"POOL_TYPE":{"return":"The pool type label to be able to identify the type of pool","returns":{"_0":"The pool type label to be able to identify the type of pool"}}}},"storageLayout":{"types":{"t_bool":{"label":"bool","encoding":"inplace","numberOfBytes":"1"},"t_uint16":{"label":"uint16","encoding":"inplace","numberOfBytes":"2"},"t_uint32":{"label":"uint32","encoding":"inplace","numberOfBytes":"4"},"t_address":{"label":"address","encoding":"inplace","numberOfBytes":"20"},"t_uint256":{"label":"uint256","encoding":"inplace","numberOfBytes":"32"},"t_string_storage":{"label":"string","encoding":"bytes","numberOfBytes":"32"},"t_mapping(t_address,t_bool)":{"key":"t_address","label":"mapping(address => bool)","value":"t_bool","encoding":"mapping","numberOfBytes":"32"},"t_mapping(t_address,t_uint256)":{"key":"t_address","label":"mapping(address => uint256)","value":"t_uint256","encoding":"mapping","numberOfBytes":"32"},"t_struct(Observation)1124_storage":{"label":"struct PoolOracle.Observation","members":[{"slot":"0","type":"t_uint32","astId":1119,"label":"timestamp","offset":0,"contract":"V3/src/pools/StablePool.sol:StablePool"},{"slot":"1","type":"t_uint256","astId":1121,"label":"reserve0Cumulative","offset":0,"contract":"V3/src/pools/StablePool.sol:StablePool"},{"slot":"2","type":"t_uint256","astId":1123,"label":"reserve1Cumulative","offset":0,"contract":"V3/src/pools/StablePool.sol:StablePool"}],"encoding":"inplace","numberOfBytes":"96"},"t_struct(ObservationBuffer)1137_storage":{"label":"struct PoolOracle.ObservationBuffer","members":[{"slot":"0","type":"t_array(t_struct(Observation)1124_storage)65535_storage","astId":1130,"label":"observations","offset":0,"contract":"V3/src/pools/StablePool.sol:StablePool"},{"slot":"196605","type":"t_uint16","astId":1132,"label":"index","offset":0,"contract":"V3/src/pools/StablePool.sol:StablePool"},{"slot":"196605","type":"t_uint16","astId":1134,"label":"cardinality","offset":2,"contract":"V3/src/pools/StablePool.sol:StablePool"},{"slot":"196605","type":"t_uint16","astId":1136,"label":"cardinalityNext","offset":4,"contract":"V3/src/pools/StablePool.sol:StablePool"}],"encoding":"inplace","numberOfBytes":"6291392"},"t_mapping(t_address,t_mapping(t_address,t_bool))":{"key":"t_address","label":"mapping(address => mapping(address => bool))","value":"t_mapping(t_address,t_bool)","encoding":"mapping","numberOfBytes":"32"},"t_mapping(t_address,t_mapping(t_address,t_uint256))":{"key":"t_address","label":"mapping(address => mapping(address => uint256))","value":"t_mapping(t_address,t_uint256)","encoding":"mapping","numberOfBytes":"32"},"t_array(t_struct(Observation)1124_storage)65535_storage":{"base":"t_struct(Observation)1124_storage","label":"struct PoolOracle.Observation[65535]","encoding":"inplace","numberOfBytes":"6291360"}},"storage":[{"slot":"0","type":"t_mapping(t_address,t_uint256)","astId":5142,"label":"_balances","offset":0,"contract":"V3/src/pools/StablePool.sol:StablePool"},{"slot":"1","type":"t_mapping(t_address,t_mapping(t_address,t_uint256))","astId":5148,"label":"_allowances","offset":0,"contract":"V3/src/pools/StablePool.sol:StablePool"},{"slot":"2","type":"t_uint256","astId":5150,"label":"_totalSupply","offset":0,"contract":"V3/src/pools/StablePool.sol:StablePool"},{"slot":"3","type":"t_string_storage","astId":5152,"label":"_name","offset":0,"contract":"V3/src/pools/StablePool.sol:StablePool"},{"slot":"4","type":"t_string_storage","astId":5154,"label":"_symbol","offset":0,"contract":"V3/src/pools/StablePool.sol:StablePool"},{"slot":"5","type":"t_string_storage","astId":1936,"label":"_name","offset":0,"contract":"V3/src/pools/StablePool.sol:StablePool"},{"slot":"6","type":"t_string_storage","astId":1939,"label":"_symbol","offset":0,"contract":"V3/src/pools/StablePool.sol:StablePool"},{"slot":"7","type":"t_address","astId":1942,"label":"token0","offset":0,"contract":"V3/src/pools/StablePool.sol:StablePool"},{"slot":"8","type":"t_address","astId":1945,"label":"token1","offset":0,"contract":"V3/src/pools/StablePool.sol:StablePool"},{"slot":"9","type":"t_address","astId":1948,"label":"poolFees","offset":0,"contract":"V3/src/pools/StablePool.sol:StablePool"},{"slot":"10","type":"t_address","astId":1951,"label":"factory","offset":0,"contract":"V3/src/pools/StablePool.sol:StablePool"},{"slot":"11","type":"t_struct(ObservationBuffer)1137_storage","astId":1955,"label":"observationBuffer","offset":0,"contract":"V3/src/pools/StablePool.sol:StablePool"},{"slot":"196617","type":"t_uint256","astId":1958,"label":"_decimals0","offset":0,"contract":"V3/src/pools/StablePool.sol:StablePool"},{"slot":"196618","type":"t_uint256","astId":1961,"label":"_decimals1","offset":0,"contract":"V3/src/pools/StablePool.sol:StablePool"},{"slot":"196619","type":"t_uint256","astId":1964,"label":"reserve0","offset":0,"contract":"V3/src/pools/StablePool.sol:StablePool"},{"slot":"196620","type":"t_uint256","astId":1967,"label":"reserve1","offset":0,"contract":"V3/src/pools/StablePool.sol:StablePool"},{"slot":"196621","type":"t_uint256","astId":1970,"label":"blockTimestampLast","offset":0,"contract":"V3/src/pools/StablePool.sol:StablePool"},{"slot":"196622","type":"t_uint256","astId":1973,"label":"reserve0CumulativeLast","offset":0,"contract":"V3/src/pools/StablePool.sol:StablePool"},{"slot":"196623","type":"t_uint256","astId":1976,"label":"reserve1CumulativeLast","offset":0,"contract":"V3/src/pools/StablePool.sol:StablePool"},{"slot":"196624","type":"t_uint256","astId":1979,"label":"index0","offset":0,"contract":"V3/src/pools/StablePool.sol:StablePool"},{"slot":"196625","type":"t_uint256","astId":1982,"label":"index1","offset":0,"contract":"V3/src/pools/StablePool.sol:StablePool"},{"slot":"196626","type":"t_mapping(t_address,t_uint256)","astId":1987,"label":"supplyIndex0","offset":0,"contract":"V3/src/pools/StablePool.sol:StablePool"},{"slot":"196627","type":"t_mapping(t_address,t_uint256)","astId":1992,"label":"supplyIndex1","offset":0,"contract":"V3/src/pools/StablePool.sol:StablePool"},{"slot":"196628","type":"t_mapping(t_address,t_uint256)","astId":1997,"label":"claimable0","offset":0,"contract":"V3/src/pools/StablePool.sol:StablePool"},{"slot":"196629","type":"t_mapping(t_address,t_uint256)","astId":2002,"label":"claimable1","offset":0,"contract":"V3/src/pools/StablePool.sol:StablePool"},{"slot":"196630","type":"t_mapping(t_address,t_mapping(t_address,t_bool))","astId":2009,"label":"approvedForClaim","offset":0,"contract":"V3/src/pools/StablePool.sol:StablePool"}]},"transientStorageLayout":{"types":null,"storage":[]},"evm":{"bytecode":{"object":"608060405234801561000f575f5ffd5b5060408051602080820183525f8083528351918201909352918252906003610037838261012a565b506004610044828261012a565b505050600161005d61005a61006360201b60201c565b90565b556101e8565b7f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0090565b634e487b7160e01b5f52604160045260245ffd5b600181811c908216806100af57607f821691505b6020821081036100cd57634e487b7160e01b5f52602260045260245ffd5b50919050565b601f821115610125578282111561012557805f5260205f20601f840160051c60208510156100fe57505f5b90810190601f840160051c035f5b81811015610121575f8382015560010161010c565b5050505b505050565b81516001600160401b0381111561014357610143610087565b61015781610151845461009b565b846100d3565b6020601f821160018114610189575f83156101725750848201515b5f19600385901b1c1916600184901b1784556101e1565b5f84815260208120601f198516915b828110156101b85787850151825560209485019460019092019101610198565b50848210156101d557868401515f19600387901b60f8161c191681555b505060018360011b0184555b5050505050565b6153e7806101f55f395ff3fe608060405234801561000f575f5ffd5b5060043610610346575f3560e01c8063648da859116101be578063bc25cf77116100fe578063c5884ad11161009e578063ee39e7a011610079578063ee39e7a014610856578063f140a35a1461085e578063fc9654ab14610871578063fff6cae914610879575f5ffd5b8063c5884ad1146107dc578063d21220a71461080b578063dd62ed3e1461081e575f5ffd5b8063c245febc116100d9578063c245febc146107a0578063c45a0155146107ab578063c47f0027146107be578063c5700a02146107d1575f5ffd5b8063bc25cf7714610777578063bda39cad1461078a578063bf944dbc14610795575f5ffd5b806395d89b4111610169578063a1ac4d1311610144578063a1ac4d131461071d578063a9059cbb1461073e578063b84c824614610751578063b95d88f814610764575f5ffd5b806395d89b41146106ce5780639d63848a146106d65780639f767c88146106fc575f5ffd5b806378273aca1161019957806378273aca14610687578063883bdbfd1461069a57806389afcb44146106bb575f5ffd5b8063648da859146106255780636a6278421461064c57806370a082311461065f575f5ffd5b8063252c09d7116102895780633358095911610234578063485cc9551161020f578063485cc955146105da5780634983f2f5146105ed5780634d5a9f8a146105f95780635a76f25e1461061a575f5ffd5b80633358095914610569578063392f37e91461057c578063443cb4bc146105cf575f5ffd5b8063313ce56711610264578063313ce5671461053c57806332148f671461054b57806332c0defd1461055e575f5ffd5b8063252c09d7146104e157806325d2a3f3146105165780632dbfa73514610529575f5ffd5b8063119c4e9f116102f45780631a4211dc116102cf5780631a4211dc1461045a5780631df8c717146104a5578063205aabf1146104ad57806323b872dd146104ce575f5ffd5b8063119c4e9f1461041757806315a0ea6a1461042a57806318160ddd14610452575f5ffd5b8063095ea7b311610324578063095ea7b3146103a85780630dfe1681146103cb5780630ea099c1146103f6575f5ffd5b8063022c0d9f1461034a57806306fdde031461035f5780630902f1ac1461037d575b5f5ffd5b61035d61035836600461451c565b610881565b005b610367611049565b6040516103749190614581565b60405180910390f35b6203000b546203000c546203000d545b60408051938452602084019290925290820152606001610374565b6103bb6103b63660046145b6565b6110d9565b6040519015158152602001610374565b6007546103de906001600160a01b031681565b6040516001600160a01b039091168152602001610374565b6104096104043660046145e0565b6110f2565b604051908152602001610374565b61040961042536600461460e565b611175565b61043d610438366004614648565b611280565b60408051928352602083019190915201610374565b600254610409565b62030008546104809061ffff808216916201000081048216916401000000009091041683565b6040805161ffff94851681529284166020840152921691810191909152606001610374565b61038d6112d5565b6104096104bb366004614648565b620300136020525f908152604090205481565b6103bb6104dc366004614663565b61134c565b6104f46104ef3660046146a1565b611371565b6040805163ffffffff9094168452602084019290925290820152606001610374565b61043d610524366004614648565b6113ce565b61043d6105373660046146b8565b6114af565b60405160128152602001610374565b61035d6105593660046146e4565b61157c565b610409620300105481565b6009546103de906001600160a01b031681565b62030009546203000a546203000b546203000c546007546008546040805196875260208701959095529385019290925260608401526001600160a01b0390811660808401521660a082015260c001610374565b6104096203000b5481565b61035d6105e83660046146b8565b6115f0565b6104096402540be40081565b610409610607366004614648565b620300146020525f908152604090205481565b6104096203000c5481565b6104097f56325f535441424c45000000000000000000000000000000000000000000000081565b61040961065a366004614648565b611930565b61040961066d366004614648565b6001600160a01b03165f9081526020819052604090205490565b61035d610695366004614712565b611bc2565b6106ad6106a836600461473e565b611c8d565b6040516103749291906147e9565b61043d6106c9366004614648565b611cbb565b610367611fca565b600754600854604080516001600160a01b03938416815292909116602083015201610374565b61040961070a366004614648565b620300126020525f908152604090205481565b61040961072b366004614648565b620300156020525f908152604090205481565b6103bb61074c3660046145b6565b611fd9565b61035d61075f36600461480d565b611fe6565b6104096107723660046145e0565b6120b1565b61035d610785366004614648565b612249565b610409620300115481565b6104096203000e5481565b6104096203000f5481565b600a546103de906001600160a01b031681565b61035d6107cc36600461480d565b6123b6565b6104096203000d5481565b6103bb6107ea3660046146b8565b6203001660209081525f928352604080842090915290825290205460ff1681565b6008546103de906001600160a01b031681565b61040961082c3660046146b8565b6001600160a01b039182165f90815260016020908152604080832093909416825291909152205490565b610409612481565b61040961086c3660046145e0565b6124ca565b610409603c81565b61035d6125d6565b610889612729565b600a5f9054906101000a90046001600160a01b03166001600160a01b031663b187bd266040518163ffffffff1660e01b8152600401602060405180830381865afa1580156108d9573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108fd919061484c565b15610934576040517f1309a56300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84158015610940575083155b15610977576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6203000b546203000c5481871015806109905750808610155b156109c7576040517fbb55fd2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6007546008545f9182916001600160a01b0391821691908116908916821480610a015750806001600160a01b0316896001600160a01b0316145b15610a38576040517f290fa18800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8a15610a5257610a526001600160a01b0383168a8d612757565b8915610a6c57610a6c6001600160a01b0382168a8c612757565b8615610aed576040517f9a7bff790000000000000000000000000000000000000000000000000000000081526001600160a01b038a1690639a7bff7990610abf9033908f908f908e908e90600401614867565b5f604051808303815f87803b158015610ad6575f5ffd5b505af1158015610ae8573d5f5f3e3d5ffd5b505050505b6040516370a0823160e01b81523060048201526001600160a01b038316906370a0823190602401602060405180830381865afa158015610b2f573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b5391906148b3565b6040516370a0823160e01b81523060048201529094506001600160a01b038216906370a0823190602401602060405180830381865afa158015610b98573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610bbc91906148b3565b925050505f8985610bcd91906148f7565b8311610bd9575f610bed565b610be38a866148f7565b610bed90846148f7565b90505f610bfa8a866148f7565b8311610c06575f610c1a565b610c108a866148f7565b610c1a90846148f7565b905081158015610c28575080155b15610c5f576040517f098fb56100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051610100810182525f80825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810191909152610ca98c8461490a565b6fffffffffffffffffffffffffffffffff166040820152610cca8b8361490a565b6fffffffffffffffffffffffffffffffff1660608201526007546008546001600160a01b0391821691165f8080610d0388888e8e6127aa565b919450925090508715610d78575f612710610d1e858b61491d565b610d289190614961565b9050610d3381612863565b6fffffffffffffffffffffffffffffffff81168752612710610d55848b61491d565b610d5f9190614961565b6fffffffffffffffffffffffffffffffff1660c0880152505b8615610de9575f612710610d8c858a61491d565b610d969190614961565b9050610da181612910565b6fffffffffffffffffffffffffffffffff81166020880152612710610dc6848a61491d565b610dd09190614961565b6fffffffffffffffffffffffffffffffff1660e0880152505b8015610e195760408601516fffffffffffffffffffffffffffffffff908116608088015260608701511660a08701525b6040516370a0823160e01b81523060048201526001600160a01b038616906370a0823190602401602060405180830381865afa158015610e5b573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e7f91906148b3565b6040516370a0823160e01b8152306004820152909a506001600160a01b038516906370a0823190602401602060405180830381865afa158015610ec4573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ee891906148b3565b9850610ef48c8c6129b6565b610efe8b8b6129b6565b1015610f36576040517fa932492f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600a546040517f5310a4210000000000000000000000000000000000000000000000000000000081526001600160a01b0390911690635310a42190610f7f908990600401614974565b5f604051808303815f87803b158015610f96575f5ffd5b505af1158015610fa8573d5f5f3e3d5ffd5b50505050505050505050610fbe84848888612a5f565b60408051838152602081018390529081018c9052606081018b90526001600160a01b038a169033907fb3e2773606abfd36b5bd91394b3a54d1398336c65005baf7bf7a05efeffaf75b9060800160405180910390a350505050505061104260017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b5050505050565b60606005805461105890614a84565b80601f016020809104026020016040519081016040528092919081815260200182805461108490614a84565b80156110cf5780601f106110a6576101008083540402835291602001916110cf565b820191905f5260205f20905b8154815290600101906020018083116110b257829003601f168201915b5050505050905090565b5f336110e6818585612b44565b60019150505b92915050565b6203000b546203000c546007545f929190839081906001600160a01b03878116911614611120575f87611123565b865f5b915091505f611134838387876127aa565b505090506127108189611147919061491d565b6111519190614961565b61115b90896148f7565b975061116988888787612b51565b98975050505050505050565b6007545f90819081906001600160a01b03878116911614611197575f8761119a565b865f5b600a546040517fdf29d5bb0000000000000000000000000000000000000000000000000000000081523060048201525f602482015260448101849052606481018390526084810189905260a48101889052929450909250612710916001600160a01b039091169063df29d5bb9060c401602060405180830381865afa158015611225573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061124991906148b3565b611253908961491d565b61125d9190614961565b61126790886148f7565b965061127587878787612b51565b979650505050505050565b5f806001600160a01b0383166112c2576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6112cc3384612c93565b91509150915091565b6203000e546203000f54425f80806112fc6203000b546203000c546203000d549192909190565b925092509250838114611344575f61131482866148f7565b9050611320818561491d565b61132a908861490a565b9650611336818461491d565b611340908761490a565b9550505b505050909192565b5f33611359858285612dd0565b611364858585612e5f565b60019150505b9392505050565b5f808080600b8561ffff811061138957611389614ad5565b6040805160608101825260039290920292909201805463ffffffff16808352600182015460208401819052600290920154929093018290529197919650945092505050565b6001600160a01b0381165f908152620300146020908152604080832054620300158352818420549284905292205480156114a9576001600160a01b0384165f9081526203001260205260409020546203001054670de0b6b3a764000091611434916148f7565b61143e908361491d565b6114489190614961565b611452908461490a565b6001600160a01b0385165f9081526203001360205260409020546203001154919450670de0b6b3a76400009161148891906148f7565b611492908361491d565b61149c9190614961565b6114a6908361490a565b91505b50915091565b5f806001600160a01b0383166114f1576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336001600160a01b0385161480159061152f57506001600160a01b0384165f908152620300166020908152604080832033845290915290205460ff16155b15611566576040517fea8e4eb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6115708484612c93565b915091505b9250929050565b6203000854640100000000900461ffff165f611599600b84612eee565b90508161ffff168161ffff16146115eb576040805161ffff80851682528316602082015233917ff0b7b7d1cdf542f5660a7879f0cac17375fdcf984af4a6d499a9daedacb24c58910160405180910390a25b505050565b600a546001600160a01b031615611633576040517f154c51b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600a8054337fffffffffffffffffffffffff0000000000000000000000000000000000000000918216179091556008805482166001600160a01b03848116919091179091556007805490921690841617905560405182908290611695906144bd565b6001600160a01b03928316815291166020820152604001604051809103905ff0801580156116c5573d5f5f3e3d5ffd5b5060095f6101000a8154816001600160a01b0302191690836001600160a01b031602179055505f826001600160a01b03166395d89b416040518163ffffffff1660e01b81526004015f60405180830381865afa158015611727573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261174e9190810190614b2f565b90505f826001600160a01b03166395d89b416040518163ffffffff1660e01b81526004015f60405180830381865afa15801561178c573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526117b39190810190614b2f565b90506117bf8282613005565b6005906117cc9082614c39565b506117d78282613031565b6006906117e49082614c39565b50836001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611821573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118459190614cf4565b61185090600a614def565b6203000981905550826001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611894573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118b89190614cf4565b6118c390600a614def565b6203000a55600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000164263ffffffff161790556203000880547fffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ffff166401000100001790555b50505050565b5f611939612729565b6203000b546203000c546007546040516370a0823160e01b81523060048201525f916001600160a01b0316906370a0823190602401602060405180830381865afa158015611989573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119ad91906148b3565b6008546040516370a0823160e01b81523060048201529192505f916001600160a01b03909116906370a0823190602401602060405180830381865afa1580156119f8573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611a1c91906148b3565b90505f611a2985846148f7565b90505f611a3685846148f7565b90505f611a4260025490565b9050805f03611ac4576103e8611a60611a5b848661491d565b613046565b611a6a91906148f7565b9750611a7960016103e86131ab565b611a8383836131fc565b6103e8881015611abf576040517fd226f9d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611b31565b611af687611ad2838661491d565b611adc9190614961565b87611ae7848661491d565b611af19190614961565b6132bc565b9750875f03611b31576040517fd226f9d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611b3b89896131ab565b611b4785858989612a5f565b60408051848152602081018490526001600160a01b038b169133917f2f00e3cdd69a77be7ed215ec7b2a36784dd158f921fca79ac29deffa353fe6ee910160405180910390a350505050505050611bbd60017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b919050565b6001600160a01b038216611c02576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b335f81815262030016602090815260408083206001600160a01b0387168085529083529281902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001686151590811790915590519081529192917f63484c3756a6c7d95f131879210268006b60e58057de5db75f3a8c91c7869ebf910160405180910390a35050565b6060805f5f611c9a6112d5565b509092509050611cae600b878785856132cb565b9350935050509250929050565b5f5f611cc5612729565b6203000b546203000c546007546008546040516370a0823160e01b81523060048201526001600160a01b0392831692909116905f9083906370a0823190602401602060405180830381865afa158015611d20573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611d4491906148b3565b6040516370a0823160e01b81523060048201529091505f906001600160a01b038416906370a0823190602401602060405180830381865afa158015611d8b573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611daf91906148b3565b305f908152602081905260409020546002549192509080611dd0858461491d565b611dda9190614961565b995080611de7848461491d565b611df19190614961565b9850891580611dfe575088155b15611e35576040517f749383ad00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611e3f30836133e6565b611e536001600160a01b0387168c8c612757565b611e676001600160a01b0386168c8b612757565b6040516370a0823160e01b81523060048201526001600160a01b038716906370a0823190602401602060405180830381865afa158015611ea9573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611ecd91906148b3565b6040516370a0823160e01b81523060048201529094506001600160a01b038616906370a0823190602401602060405180830381865afa158015611f12573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f3691906148b3565b9250611f428484613433565b611f4e84848a8a612a5f565b604080518b8152602081018b90526001600160a01b038d169133917f5d624aa9c148153ab3446c1b154f660ee7701e549fe9b62dab7171b1c80e6fa2910160405180910390a35050505050505050611fc560017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b915091565b60606006805461105890614a84565b5f336110e6818585612e5f565b600a5f9054906101000a90046001600160a01b03166001600160a01b031663b782cc496040518163ffffffff1660e01b8152600401602060405180830381865afa158015612036573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061205a9190614dfd565b6001600160a01b0316336001600160a01b0316146120a4576040517f058a2da800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60066115eb828483614e18565b5f825f036120c057505f6110ec565b6203000b546203000c546007546001600160a01b038581169116146120e557806120e7565b815b851061211f576040517fbb55fd2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f61212c86868585613475565b9050805f03612140575f93505050506110ec565b6007545f9081906001600160a01b0388811691161461216057825f612163565b5f835b600a546040517f11896ad200000000000000000000000000000000000000000000000000000000815230600482015233602482015260448101849052606481018390526084810189905260a481018890529294509092505f916001600160a01b03909116906311896ad29060c401602060405180830381865afa1580156121ec573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061221091906148b3565b9050612232816122216001876148f7565b61222d846127106148f7565b6135ce565b61223c908561490a565b9998505050505050505050565b612251612729565b6007546008546203000b546040516370a0823160e01b81523060048201526001600160a01b0393841693909216915f919084906370a0823190602401602060405180830381865afa1580156122a8573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906122cc91906148b3565b6122d691906148f7565b905080156122f2576122f26001600160a01b0384168583612757565b6203000c546040516370a0823160e01b81523060048201525f91906001600160a01b038516906370a0823190602401602060405180830381865afa15801561233c573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061236091906148b3565b61236a91906148f7565b90508015612386576123866001600160a01b0384168683612757565b505050506123b360017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b50565b600a5f9054906101000a90046001600160a01b03166001600160a01b031663b782cc496040518163ffffffff1660e01b8152600401602060405180830381865afa158015612406573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061242a9190614dfd565b6001600160a01b0316336001600160a01b031614612474576040517f058a2da800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60056115eb828483614e18565b5f61248a612729565b61249c6203000b546203000c546129b6565b90506124c760017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b90565b6203000b546203000c546007545f929190839081906001600160a01b038781169116146124f8575f876124fb565b865f5b600a546040517fdf29d5bb0000000000000000000000000000000000000000000000000000000081523060048201525f602482015260448101849052606481018390526084810188905260a48101879052929450909250612710916001600160a01b039091169063df29d5bb9060c401602060405180830381865afa158015612586573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906125aa91906148b3565b6125b4908961491d565b6125be9190614961565b6125c890886148f7565b965061127587878686612b51565b6125de612729565b6002545f03612619576040517fbb55fd2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6007546040516370a0823160e01b81523060048201526126fe916001600160a01b0316906370a0823190602401602060405180830381865afa158015612661573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061268591906148b3565b6008546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa1580156126cb573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906126ef91906148b3565b6203000b546203000c54612a5f565b61272760017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b565b61273161367e565b60027f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b61276483838360016136e1565b6115eb576040517f5274afe70000000000000000000000000000000000000000000000000000000081526001600160a01b03841660048201526024015b60405180910390fd5b600a546040517fdb6b39b400000000000000000000000000000000000000000000000000000000815230600482015233602482015260448101869052606481018590526084810184905260a481018390525f91829182916001600160a01b03169063db6b39b49060c401606060405180830381865afa15801561282f573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906128539190614ed2565b9250925092509450945094915050565b805f0361286d5750565b60095460075461288a916001600160a01b03918216911683612757565b5f61289460025490565b6128a683670de0b6b3a764000061491d565b6128b09190614961565b905080156128d15780620300105f8282546128cb919061490a565b90915550505b604080518381525f602082015233917f112c256902bf554b6ed882d2936687aaeb4225e8cd5b51303c90ca6cf43a860291015b60405180910390a25050565b805f0361291a5750565b600954600854612937916001600160a01b03918216911683612757565b5f61294160025490565b61295383670de0b6b3a764000061491d565b61295d9190614961565b9050801561297e5780620300115f828254612978919061490a565b90915550505b604080515f81526020810184905233917f112c256902bf554b6ed882d2936687aaeb4225e8cd5b51303c90ca6cf43a86029101612904565b5f5f620300095484670de0b6b3a76400006129d1919061491d565b6129db9190614961565b90505f6203000a5484670de0b6b3a76400006129f7919061491d565b612a019190614961565b90505f612a178383670de0b6b3a76400006135ce565b90505f612a2d8384670de0b6b3a76400006135ce565b612a408586670de0b6b3a76400006135ce565b612a4a919061490a565b90506112758282670de0b6b3a76400006135ce565b6203000d5442905f90612a7290836148f7565b90505f81118015612a8257508315155b8015612a8d57508215155b15612ad657612a9c818561491d565b6203000e5f828254612aae919061490a565b90915550612abe9050818461491d565b6203000f5f828254612ad0919061490a565b90915550505b6203000e546203000f54612aee91600b91603c61375c565b6203000b8690556203000c8590556203000d82905560408051878152602081018790527fcf2aa50876cdfbb541206f89af0ee78d44a2abf8d328e37fa4917f982149848a910160405180910390a1505050505050565b6115eb838383600161391f565b5f5f612b5d84846129b6565b6203000954909150612b7785670de0b6b3a764000061491d565b612b819190614961565b6203000a54909450612b9b84670de0b6b3a764000061491d565b612ba59190614961565b6007549093505f9081906001600160a01b03888116911614612bc8578486612bcb565b85855b60075491935091506001600160a01b03888116911614612c0b576203000a54612bfc89670de0b6b3a764000061491d565b612c069190614961565b612c2c565b6203000954612c2289670de0b6b3a764000061491d565b612c2c9190614961565b97505f612c43612c3c848b61490a565b8584613a23565b612c4d90836148f7565b600754909150670de0b6b3a7640000906001600160a01b038a8116911614612c79576203000954612c7f565b6203000a545b612c89908361491d565b61223c9190614961565b5f5f612c9e84613b44565b50506001600160a01b0382165f908152620300146020908152604080832054620300159092529091205481151580612cd557505f81115b15611575576001600160a01b038481165f9081526203001460209081526040808320839055620300159091528082209190915560095490517f533cf5ce0000000000000000000000000000000000000000000000000000000081528583166004820152602481018590526044810184905291169063533cf5ce906064015f604051808303815f87803b158015612d69575f5ffd5b505af1158015612d7b573d5f5f3e3d5ffd5b505060408051858152602081018590526001600160a01b0380881694508816925033917fcd5e4f020ddad29434c2200a9edf2f8d7ec30f0d787f03b528ab7279aab0acbe910160405180910390a49250929050565b6001600160a01b038381165f908152600160209081526040808320938616835292905220545f1981101561192a5781811015612e51576040517ffb8f41b20000000000000000000000000000000000000000000000000000000081526001600160a01b038416600482015260248101829052604481018390526064016127a1565b61192a84848484035f61391f565b6001600160a01b038316612ea1576040517f96c6fd1e0000000000000000000000000000000000000000000000000000000081525f60048201526024016127a1565b6001600160a01b038216612ee3576040517fec442f050000000000000000000000000000000000000000000000000000000081525f60048201526024016127a1565b6115eb838383613cb0565b6202fffd8201545f9061ffff64010000000090910481169083168110612f155790506110ec565b805b8361ffff168161ffff161015612fc45760018561ffff808416908110612f3f57612f3f614ad5565b6003020180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff9290921691909117905560018561ffff838116908110612f8e57612f8e614ad5565b60030201600101819055506001855f018261ffff1661ffff8110612fb457612fb4614ad5565b6003020160020155600101612f17565b5050506202fffd9190910180547fffffffffffffffffffffffffffffffffffffffffffffffffffff0000ffffffff1664010000000061ffff84160217905590565b6060828260405160200161301a929190614f20565b604051602081830303815290604052905092915050565b6060828260405160200161301a929190614f81565b5f60018211613053575090565b81600170010000000000000000000000000000000082106130795760809190911c9060401b5b6801000000000000000082106130945760409190911c9060201b5b64010000000082106130ab5760209190911c9060101b5b6201000082106130c05760109190911c9060081b5b61010082106130d45760089190911c9060041b5b601082106130e75760049190911c9060021b5b600482106130f35760011b5b600302600190811c9081858161310b5761310b614934565b048201901c9050600181858161312357613123614934565b048201901c9050600181858161313b5761313b614934565b048201901c9050600181858161315357613153614934565b048201901c9050600181858161316b5761316b614934565b048201901c9050600181858161318357613183614934565b048201901c90506131a281858161319c5761319c614934565b04821190565b90039392505050565b6001600160a01b0382166131ed576040517fec442f050000000000000000000000000000000000000000000000000000000081525f60048201526024016127a1565b6131f85f8383613cb0565b5050565b6203000a5461321382670de0b6b3a764000061491d565b61321d9190614961565b620300095461323484670de0b6b3a764000061491d565b61323e9190614961565b14613275576040517f0a04d7fa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6402540be40061328583836129b6565b116131f8576040517f438d3ade00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f82821882841002821861136a565b60608042858067ffffffffffffffff8111156132e9576132e9614b02565b604051908082528060200260200182016040528015613312578160200160208202803683370190505b5093508067ffffffffffffffff81111561332e5761332e614b02565b604051908082528060200260200182016040528015613357578160200160208202803683370190505b5092505f5b818110156133d9576133978a848b8b8581811061337b5761337b614ad5565b90506020020160208101906133909190614fb2565b8a8a613ceb565b8683815181106133a9576133a9614ad5565b602002602001018684815181106133c2576133c2614ad5565b60209081029190910101919091525260010161335c565b5050509550959350505050565b6001600160a01b038216613428576040517f96c6fd1e0000000000000000000000000000000000000000000000000000000081525f60048201526024016127a1565b6131f8825f83613cb0565b61343d82826129b6565b5f036131f8576040517f7d06c0c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f5f61348184846129b6565b620300095490915061349b85670de0b6b3a764000061491d565b6134a59190614961565b6203000a549094506134bf84670de0b6b3a764000061491d565b6134c99190614961565b6007549093505f9081906001600160a01b038881169116146134ec5784866134ef565b85855b60075491935091505f9081906001600160a01b038a811691161461351c576203000a546203000954613527565b62030009546203000a545b90925090506135476135418b670de0b6b3a764000061491d565b83613d71565b9950838a10613582576040517fbb55fd2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f6135976135908c876148f7565b8786613a23565b90506135bf826135a786846148f7565b6135b1919061491d565b670de0b6b3a7640000613d71565b9b9a5050505050505050505050565b5f5f5f6135db8686613da5565b91509150815f036135ff578381816135f5576135f5614934565b049250505061136a565b818411613616576136166003851502601118613dc1565b5f848688095f868103871696879004966002600389028118808a02820302808a02820302808a02820302808a02820302808a02820302808a02909103029181900381900460010185841190960395909502919093039390930492909217029150509392505050565b6136aa5f60027f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00613dd2565b15612727576040517f3ee5aeb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517fa9059cbb000000000000000000000000000000000000000000000000000000005f8181526001600160a01b038616600452602485905291602083604481808b5af1925060015f51148316613750578383151615613744573d5f823e3d81fd5b5f873b113d1516831692505b60405250949350505050565b6202fffd840154429061ffff908116905f9087908390811061378057613780614ad5565b600302015463ffffffff90811684031690508381116137a15750505061192a565b6202fffd87015461ffff620100008204811691829164010000000090910416811080156137df57506137d4600183614fd5565b61ffff168461ffff16145b156137f2576137ef826001614fef565b90505b5f816137ff866001614fef565b6138099190615009565b905060405180606001604052808763ffffffff1681526020018a8152602001898152508a5f018261ffff1661ffff811061384557613845614ad5565b82516003919091029190910180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff909216919091178155602082015160018201556040909101516002909101556202fffd8a0180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff8381169190911790915583811690831614613913576202fffd8a0180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ffff166201000061ffff8516021790555b50505050505050505050565b6001600160a01b038416613961576040517fe602df050000000000000000000000000000000000000000000000000000000081525f60048201526024016127a1565b6001600160a01b0383166139a3576040517f94280d620000000000000000000000000000000000000000000000000000000081525f60048201526024016127a1565b6001600160a01b038085165f908152600160209081526040808320938716835292905220829055801561192a57826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92584604051613a1591815260200190565b60405180910390a350505050565b5f805b60ff811015613b11575f613a3a8685613dd9565b905084811015613ab4575f613a65613a5283886148f7565b670de0b6b3a764000061222d8a89613e3f565b9050805f03613aa25785613a8388613a7e88600161490a565b613dd9565b1115613a9e57613a9485600161490a565b935050505061136a565b5060015b613aac818661490a565b945050613b08565b5f613ac2613a5287846148f7565b9050805f03613afa5785821480613ae6575085613ae488613a7e6001896148f7565b105b15613af65784935050505061136a565b5060015b613b0481866148f7565b9450505b50600101613a26565b506040517f6eb5c82100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0381165f908152602081905260409020548015613c77576001600160a01b0382165f9081526203001260209081526040808320805462030013808552928520805462030010546203001154948190559490955282905593613bac85846148f7565b90505f613bb985846148f7565b90508115613c14575f670de0b6b3a7640000613bd5848a61491d565b613bdf9190614961565b6001600160a01b038a165f908152620300146020526040812080549293508392909190613c0d90849061490a565b9091555050505b8015613c6d575f670de0b6b3a7640000613c2e838a61491d565b613c389190614961565b6001600160a01b038a165f908152620300156020526040812080549293508392909190613c6690849061490a565b9091555050505b5050505050505050565b62030010546001600160a01b0383165f908152620300126020908152604080832093909355620300115462030013909152919020555050565b6001600160a01b03831615613cc857613cc883613b44565b6001600160a01b03821615613ce057613ce082613b44565b6115eb838383613ea6565b5f5f8463ffffffff165f03613d04575082905081613d67565b8486035f80613d168a8a858a8a613fe5565b915091508263ffffffff16815f015163ffffffff1603613d46578060200151816040015194509450505050613d67565b613d5e82825f015183602001518460400151876141bf565b90955093505050505b9550959350505050565b5f815f03613d8357613d836012613dc1565b816001840381613d9557613d95614934565b046001018315155b029392505050565b5f805f1983850993909202808410938190039390930393915050565b634e487b715f52806020526024601cfd5b5414919050565b5f5f613dee8484670de0b6b3a76400006135ce565b90505f613e048485670de0b6b3a76400006135ce565b613e178687670de0b6b3a76400006135ce565b613e21919061490a565b9050613e368282670de0b6b3a76400006135ce565b95945050505050565b5f5f613e548384670de0b6b3a76400006135ce565b90505f613e6a8586670de0b6b3a76400006135ce565b9050613e7f8186670de0b6b3a76400006135ce565b613e9c613e8d87600361491d565b84670de0b6b3a76400006135ce565b613e36919061490a565b6001600160a01b038316613ed0578060025f828254613ec5919061490a565b90915550613f599050565b6001600160a01b0383165f9081526020819052604090205481811015613f3b576040517fe450d38c0000000000000000000000000000000000000000000000000000000081526001600160a01b038516600482015260248101829052604481018390526064016127a1565b6001600160a01b0384165f9081526020819052604090209082900390555b6001600160a01b038216613f7557600280548290039055613f93565b6001600160a01b0382165f9081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051613fd891815260200190565b60405180910390a3505050565b61400c60405180606001604052805f63ffffffff1681526020015f81526020015f81525090565b61403360405180606001604052805f63ffffffff1681526020015f81526020015f81525090565b6202fffd87015461ffff9081169088908290811061405357614053614ad5565b6040805160608101825260039290920292909201805463ffffffff168083526001820154602084015260029091015492820192909252935061409790889088614240565b156140ee57825163ffffffff8088169116036140b65750819050613d67565b5f5f6140c5858a89898c6141bf565b6040805160608101825263ffffffff8c16815260208101939093528201529350613d6792505050565b6202fffd880154889062010000900461ffff1661410c836001614fef565b6141169190615009565b61ffff1661ffff811061412b5761412b614ad5565b6040805160608101825260039290920292909201805463ffffffff168083526001820154602084015260029091015492820192909252935061416f90889088614240565b6141a5576040517fc02e462000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6141b088888861430e565b92509250509550959350505050565b845160208601515f91829163ffffffff8289038116928603169083906141e590896148f7565b90505f8a60400151886141f891906148f7565b90506142058284866135ce565b8b60200151614214919061490a565b95506142218184866135ce565b8b60400151614230919061490a565b9450505050509550959350505050565b5f8363ffffffff168363ffffffff161115801561426957508363ffffffff168263ffffffff1611155b15614285578163ffffffff168363ffffffff161115905061136a565b5f8463ffffffff168463ffffffff16116142b3576142ae63ffffffff851664010000000061502c565b6142bb565b8363ffffffff165b64ffffffffff1690505f8563ffffffff168463ffffffff16116142f2576142ed63ffffffff851664010000000061502c565b6142fa565b8363ffffffff165b64ffffffffff169091111595945050505050565b61433560405180606001604052805f63ffffffff1681526020015f81526020015f81525090565b61435c60405180606001604052805f63ffffffff1681526020015f81526020015f81525090565b6202fffd85015461ffff62010000820481169187915f918491166001018161438657614386614934565b0690505f1961ffff84168201015b6002818301048361ffff861682816143ae576143ae614934565b0661ffff81106143c0576143c0614ad5565b6040805160608101825260039290920292909201805463ffffffff1682526001808201546020840152600290910154928201929092529750849061ffff87169083018161440f5761440f614934565b0661ffff811061442157614421614ad5565b6040805160608101825260039290920292909201805463ffffffff16825260018101546020830152600201549181019190915287519096505f90614467908b908b614240565b90505f6144788b8b8a5f0151614240565b90508180156144845750805b15614491575050506144b1565b81156144a2578260010194506144a9565b6001830393505b505050614394565b50505050935093915050565b6103688061504a83390190565b6001600160a01b03811681146123b3575f5ffd5b5f5f83601f8401126144ee575f5ffd5b50813567ffffffffffffffff811115614505575f5ffd5b602083019150836020828501011115611575575f5ffd5b5f5f5f5f5f60808688031215614530575f5ffd5b85359450602086013593506040860135614549816144ca565b9250606086013567ffffffffffffffff811115614564575f5ffd5b614570888289016144de565b969995985093965092949392505050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b5f5f604083850312156145c7575f5ffd5b82356145d2816144ca565b946020939093013593505050565b5f5f604083850312156145f1575f5ffd5b823591506020830135614603816144ca565b809150509250929050565b5f5f5f5f60808587031215614621575f5ffd5b843593506020850135614633816144ca565b93969395505050506040820135916060013590565b5f60208284031215614658575f5ffd5b813561136a816144ca565b5f5f5f60608486031215614675575f5ffd5b8335614680816144ca565b92506020840135614690816144ca565b929592945050506040919091013590565b5f602082840312156146b1575f5ffd5b5035919050565b5f5f604083850312156146c9575f5ffd5b82356146d4816144ca565b91506020830135614603816144ca565b5f602082840312156146f4575f5ffd5b813561ffff8116811461136a575f5ffd5b80151581146123b3575f5ffd5b5f5f60408385031215614723575f5ffd5b823561472e816144ca565b9150602083013561460381614705565b5f5f6020838503121561474f575f5ffd5b823567ffffffffffffffff811115614765575f5ffd5b8301601f81018513614775575f5ffd5b803567ffffffffffffffff81111561478b575f5ffd5b8560208260051b840101111561479f575f5ffd5b6020919091019590945092505050565b5f8151808452602084019350602083015f5b828110156147df5781518652602095860195909101906001016147c1565b5093949350505050565b604081525f6147fb60408301856147af565b8281036020840152613e3681856147af565b5f5f6020838503121561481e575f5ffd5b823567ffffffffffffffff811115614834575f5ffd5b614840858286016144de565b90969095509350505050565b5f6020828403121561485c575f5ffd5b815161136a81614705565b6001600160a01b038616815284602082015283604082015260806060820152816080820152818360a08301375f81830160a090810191909152601f909201601f19160101949350505050565b5f602082840312156148c3575f5ffd5b5051919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b818103818111156110ec576110ec6148ca565b808201808211156110ec576110ec6148ca565b80820281158282048414176110ec576110ec6148ca565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f8261496f5761496f614934565b500490565b5f610100820190506fffffffffffffffffffffffffffffffff83511682526fffffffffffffffffffffffffffffffff60208401511660208301526fffffffffffffffffffffffffffffffff604084015116604083015260608301516149ed60608401826fffffffffffffffffffffffffffffffff169052565b506080830151614a1160808401826fffffffffffffffffffffffffffffffff169052565b5060a0830151614a3560a08401826fffffffffffffffffffffffffffffffff169052565b5060c0830151614a5960c08401826fffffffffffffffffffffffffffffffff169052565b5060e0830151614a7d60e08401826fffffffffffffffffffffffffffffffff169052565b5092915050565b600181811c90821680614a9857607f821691505b602082108103614acf577f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b50919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f60208284031215614b3f575f5ffd5b815167ffffffffffffffff811115614b55575f5ffd5b8201601f81018413614b65575f5ffd5b805167ffffffffffffffff811115614b7f57614b7f614b02565b604051601f19603f601f19601f8501160116810181811067ffffffffffffffff82111715614baf57614baf614b02565b604052818152828201602001861015614bc6575f5ffd5b8160208401602083015e5f91810160200191909152949350505050565b601f8211156115eb57828211156115eb57805f5260205f20601f840160051c6020851015614c0e57505f5b90810190601f840160051c035f5b81811015614c31575f83820155600101614c1c565b505050505050565b815167ffffffffffffffff811115614c5357614c53614b02565b614c6781614c618454614a84565b84614be3565b6020601f821160018114614c99575f8315614c825750848201515b5f19600385901b1c1916600184901b178455611042565b5f84815260208120601f198516915b82811015614cc85787850151825560209485019460019092019101614ca8565b5084821015614ce557868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b5f60208284031215614d04575f5ffd5b815160ff8116811461136a575f5ffd5b6001815b6001841115614d4f57808504811115614d3357614d336148ca565b6001841615614d4157908102905b60019390931c928002614d18565b935093915050565b5f82614d65575060016110ec565b81614d7157505f6110ec565b8160018114614d875760028114614d9157614dad565b60019150506110ec565b60ff841115614da257614da26148ca565b50506001821b6110ec565b5060208310610133831016604e8410600b8410161715614dd0575081810a6110ec565b614ddc5f198484614d14565b805f1904821115613d9d57613d9d6148ca565b5f61136a60ff841683614d57565b5f60208284031215614e0d575f5ffd5b815161136a816144ca565b67ffffffffffffffff831115614e3057614e30614b02565b614e4483614e3e8354614a84565b83614be3565b5f601f841160018114614e75575f8515614e5e5750838201355b5f19600387901b1c1916600186901b178355611042565b5f83815260208120601f198716915b82811015614ea45786850135825560209485019460019092019101614e84565b5086821015614ec0575f1960f88860031b161c19848701351681555b505060018560011b0183555050505050565b5f5f5f60608486031215614ee4575f5ffd5b8351602085015160408601519194509250614efe81614705565b809150509250925092565b5f81518060208401855e5f93019283525090919050565b7f537461626c65563220414d4d202d20000000000000000000000000000000000081525f614f51600f830185614f09565b7f2f000000000000000000000000000000000000000000000000000000000000008152613e366001820185614f09565b7f73414d4d56322d0000000000000000000000000000000000000000000000000081525f614f516007830185614f09565b5f60208284031215614fc2575f5ffd5b813563ffffffff8116811461136a575f5ffd5b61ffff82811682821603908111156110ec576110ec6148ca565b61ffff81811683821601908111156110ec576110ec6148ca565b5f61ffff83168061501c5761501c614934565b8061ffff84160691505092915050565b64ffffffffff81811683821601908111156110ec576110ec6148ca56fe60e060405234801561000f575f5ffd5b5060405161036838038061036883398101604081905261002e91610064565b336080526001600160a01b0391821660a0521660c052610095565b80516001600160a01b038116811461005f575f5ffd5b919050565b5f5f60408385031215610075575f5ffd5b61007e83610049565b915061008c60208401610049565b90509250929050565b60805160a05160c0516102ab6100bd5f395f61011801525f60d101525f605a01526102ab5ff3fe608060405234801561000f575f5ffd5b5060043610610029575f3560e01c8063533cf5ce1461002d575b5f5ffd5b61004061003b36600461022b565b610042565b005b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146100b1576040517f6f61f64100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81156100f8576100f873ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168484610144565b801561013f5761013f73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168483610144565b505050565b61015183838360016101a3565b61013f576040517f5274afe700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8416600482015260240160405180910390fd5b6040517fa9059cbb000000000000000000000000000000000000000000000000000000005f81815273ffffffffffffffffffffffffffffffffffffffff8616600452602485905291602083604481808b5af1925060015f5114831661021f578383151615610213573d5f823e3d81fd5b5f873b113d1516831692505b60405250949350505050565b5f5f5f6060848603121561023d575f5ffd5b833573ffffffffffffffffffffffffffffffffffffffff81168114610260575f5ffd5b9560208501359550604090940135939250505056fea2646970667358221220eeabba3bd98e978db119b83233dcf1a15cbc1751f5b6fdcc907308b07b33330264736f6c63430008240033a2646970667358221220aa9bbd0570a5d863052798f5e72b7cb02066916c003643151160fd218424ee5f64736f6c63430008240033","sourceMap":"362:5174:8:-:0;;;;;;;;;;;;-1:-1:-1;1582:113:13;;;;;;;;;-1:-1:-1;1582:113:13;;;;;;;;;;;;;;;1648:5;:13;1582:113;1648:5;:13;:::i;:::-;-1:-1:-1;1671:7:13;:17;1681:7;1671;:17;:::i;:::-;;1582:113;;2365:1:19;2539:46;:29;:27;;;:29;;:::i;:::-;2822:4:20;2679:163;2539:46:19;:66;362:5174:8;;4636:127:19;1505:66;;4636:127::o;14::24:-;75:10;70:3;66:20;63:1;56:31;106:4;103:1;96:15;130:4;127:1;120:15;146:380;225:1;221:12;;;;268;;;289:61;;343:4;335:6;331:17;321:27;;289:61;396:2;388:6;385:14;365:18;362:38;359:161;;442:10;437:3;433:20;430:1;423:31;477:4;474:1;467:15;505:4;502:1;495:15;359:161;;146:380;;;:::o;657:692::-;759:2;754:3;751:11;748:595;;;796:10;791:3;788:19;785:548;;;848:5;845:1;838:16;896:4;893:1;883:18;961:2;949:10;945:19;942:1;938:27;1000:4;988:10;985:20;982:45;;;-1:-1:-1;1024:1:24;982:45;1063:23;;;;1133:2;1124:12;;1121:1;1117:20;1113:39;1178:1;1196:123;1210:2;1207:1;1204:9;1196:123;;;1299:1;1278:19;;;1271:30;1228:1;1221:9;1196:123;;;1200:3;;;785:548;657:692;;;:::o;1525:1299::-;1645:10;;-1:-1:-1;;;;;1667:30:24;;1664:56;;;1700:18;;:::i;:::-;1729:97;1819:6;1779:38;1811:4;1805:11;1779:38;:::i;:::-;1773:4;1729:97;:::i;:::-;1875:4;1906:2;1895:14;;1923:1;1918:649;;;;2611:1;2628:6;2625:89;;;-1:-1:-1;2680:19:24;;;2674:26;2625:89;-1:-1:-1;;1482:1:24;1478:11;;;1474:24;1470:29;1460:40;1506:1;1502:11;;;1457:57;2727:81;;1888:930;;1918:649;604:1;597:14;;;641:4;628:18;;-1:-1:-1;;1954:20:24;;;2072:222;2086:7;2083:1;2080:14;2072:222;;;2168:19;;;2162:26;2147:42;;2275:4;2260:20;;;;2228:1;2216:14;;;;2102:12;2072:222;;;2076:3;2322:6;2313:7;2310:19;2307:201;;;2383:19;;;2377:26;-1:-1:-1;;2466:1:24;2462:14;;;2478:3;2458:24;2454:37;2450:42;2435:58;2420:74;;2307:201;;;2554:1;2545:6;2542:1;2538:14;2534:22;2528:4;2521:36;1888:930;;;;1525:1299;;:::o;:::-;362:5174:8;;;;;;","linkReferences":{}},"deployedBytecode":{"object":"608060405234801561000f575f5ffd5b5060043610610346575f3560e01c8063648da859116101be578063bc25cf77116100fe578063c5884ad11161009e578063ee39e7a011610079578063ee39e7a014610856578063f140a35a1461085e578063fc9654ab14610871578063fff6cae914610879575f5ffd5b8063c5884ad1146107dc578063d21220a71461080b578063dd62ed3e1461081e575f5ffd5b8063c245febc116100d9578063c245febc146107a0578063c45a0155146107ab578063c47f0027146107be578063c5700a02146107d1575f5ffd5b8063bc25cf7714610777578063bda39cad1461078a578063bf944dbc14610795575f5ffd5b806395d89b4111610169578063a1ac4d1311610144578063a1ac4d131461071d578063a9059cbb1461073e578063b84c824614610751578063b95d88f814610764575f5ffd5b806395d89b41146106ce5780639d63848a146106d65780639f767c88146106fc575f5ffd5b806378273aca1161019957806378273aca14610687578063883bdbfd1461069a57806389afcb44146106bb575f5ffd5b8063648da859146106255780636a6278421461064c57806370a082311461065f575f5ffd5b8063252c09d7116102895780633358095911610234578063485cc9551161020f578063485cc955146105da5780634983f2f5146105ed5780634d5a9f8a146105f95780635a76f25e1461061a575f5ffd5b80633358095914610569578063392f37e91461057c578063443cb4bc146105cf575f5ffd5b8063313ce56711610264578063313ce5671461053c57806332148f671461054b57806332c0defd1461055e575f5ffd5b8063252c09d7146104e157806325d2a3f3146105165780632dbfa73514610529575f5ffd5b8063119c4e9f116102f45780631a4211dc116102cf5780631a4211dc1461045a5780631df8c717146104a5578063205aabf1146104ad57806323b872dd146104ce575f5ffd5b8063119c4e9f1461041757806315a0ea6a1461042a57806318160ddd14610452575f5ffd5b8063095ea7b311610324578063095ea7b3146103a85780630dfe1681146103cb5780630ea099c1146103f6575f5ffd5b8063022c0d9f1461034a57806306fdde031461035f5780630902f1ac1461037d575b5f5ffd5b61035d61035836600461451c565b610881565b005b610367611049565b6040516103749190614581565b60405180910390f35b6203000b546203000c546203000d545b60408051938452602084019290925290820152606001610374565b6103bb6103b63660046145b6565b6110d9565b6040519015158152602001610374565b6007546103de906001600160a01b031681565b6040516001600160a01b039091168152602001610374565b6104096104043660046145e0565b6110f2565b604051908152602001610374565b61040961042536600461460e565b611175565b61043d610438366004614648565b611280565b60408051928352602083019190915201610374565b600254610409565b62030008546104809061ffff808216916201000081048216916401000000009091041683565b6040805161ffff94851681529284166020840152921691810191909152606001610374565b61038d6112d5565b6104096104bb366004614648565b620300136020525f908152604090205481565b6103bb6104dc366004614663565b61134c565b6104f46104ef3660046146a1565b611371565b6040805163ffffffff9094168452602084019290925290820152606001610374565b61043d610524366004614648565b6113ce565b61043d6105373660046146b8565b6114af565b60405160128152602001610374565b61035d6105593660046146e4565b61157c565b610409620300105481565b6009546103de906001600160a01b031681565b62030009546203000a546203000b546203000c546007546008546040805196875260208701959095529385019290925260608401526001600160a01b0390811660808401521660a082015260c001610374565b6104096203000b5481565b61035d6105e83660046146b8565b6115f0565b6104096402540be40081565b610409610607366004614648565b620300146020525f908152604090205481565b6104096203000c5481565b6104097f56325f535441424c45000000000000000000000000000000000000000000000081565b61040961065a366004614648565b611930565b61040961066d366004614648565b6001600160a01b03165f9081526020819052604090205490565b61035d610695366004614712565b611bc2565b6106ad6106a836600461473e565b611c8d565b6040516103749291906147e9565b61043d6106c9366004614648565b611cbb565b610367611fca565b600754600854604080516001600160a01b03938416815292909116602083015201610374565b61040961070a366004614648565b620300126020525f908152604090205481565b61040961072b366004614648565b620300156020525f908152604090205481565b6103bb61074c3660046145b6565b611fd9565b61035d61075f36600461480d565b611fe6565b6104096107723660046145e0565b6120b1565b61035d610785366004614648565b612249565b610409620300115481565b6104096203000e5481565b6104096203000f5481565b600a546103de906001600160a01b031681565b61035d6107cc36600461480d565b6123b6565b6104096203000d5481565b6103bb6107ea3660046146b8565b6203001660209081525f928352604080842090915290825290205460ff1681565b6008546103de906001600160a01b031681565b61040961082c3660046146b8565b6001600160a01b039182165f90815260016020908152604080832093909416825291909152205490565b610409612481565b61040961086c3660046145e0565b6124ca565b610409603c81565b61035d6125d6565b610889612729565b600a5f9054906101000a90046001600160a01b03166001600160a01b031663b187bd266040518163ffffffff1660e01b8152600401602060405180830381865afa1580156108d9573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108fd919061484c565b15610934576040517f1309a56300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84158015610940575083155b15610977576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6203000b546203000c5481871015806109905750808610155b156109c7576040517fbb55fd2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6007546008545f9182916001600160a01b0391821691908116908916821480610a015750806001600160a01b0316896001600160a01b0316145b15610a38576040517f290fa18800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8a15610a5257610a526001600160a01b0383168a8d612757565b8915610a6c57610a6c6001600160a01b0382168a8c612757565b8615610aed576040517f9a7bff790000000000000000000000000000000000000000000000000000000081526001600160a01b038a1690639a7bff7990610abf9033908f908f908e908e90600401614867565b5f604051808303815f87803b158015610ad6575f5ffd5b505af1158015610ae8573d5f5f3e3d5ffd5b505050505b6040516370a0823160e01b81523060048201526001600160a01b038316906370a0823190602401602060405180830381865afa158015610b2f573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b5391906148b3565b6040516370a0823160e01b81523060048201529094506001600160a01b038216906370a0823190602401602060405180830381865afa158015610b98573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610bbc91906148b3565b925050505f8985610bcd91906148f7565b8311610bd9575f610bed565b610be38a866148f7565b610bed90846148f7565b90505f610bfa8a866148f7565b8311610c06575f610c1a565b610c108a866148f7565b610c1a90846148f7565b905081158015610c28575080155b15610c5f576040517f098fb56100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051610100810182525f80825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810191909152610ca98c8461490a565b6fffffffffffffffffffffffffffffffff166040820152610cca8b8361490a565b6fffffffffffffffffffffffffffffffff1660608201526007546008546001600160a01b0391821691165f8080610d0388888e8e6127aa565b919450925090508715610d78575f612710610d1e858b61491d565b610d289190614961565b9050610d3381612863565b6fffffffffffffffffffffffffffffffff81168752612710610d55848b61491d565b610d5f9190614961565b6fffffffffffffffffffffffffffffffff1660c0880152505b8615610de9575f612710610d8c858a61491d565b610d969190614961565b9050610da181612910565b6fffffffffffffffffffffffffffffffff81166020880152612710610dc6848a61491d565b610dd09190614961565b6fffffffffffffffffffffffffffffffff1660e0880152505b8015610e195760408601516fffffffffffffffffffffffffffffffff908116608088015260608701511660a08701525b6040516370a0823160e01b81523060048201526001600160a01b038616906370a0823190602401602060405180830381865afa158015610e5b573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e7f91906148b3565b6040516370a0823160e01b8152306004820152909a506001600160a01b038516906370a0823190602401602060405180830381865afa158015610ec4573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ee891906148b3565b9850610ef48c8c6129b6565b610efe8b8b6129b6565b1015610f36576040517fa932492f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600a546040517f5310a4210000000000000000000000000000000000000000000000000000000081526001600160a01b0390911690635310a42190610f7f908990600401614974565b5f604051808303815f87803b158015610f96575f5ffd5b505af1158015610fa8573d5f5f3e3d5ffd5b50505050505050505050610fbe84848888612a5f565b60408051838152602081018390529081018c9052606081018b90526001600160a01b038a169033907fb3e2773606abfd36b5bd91394b3a54d1398336c65005baf7bf7a05efeffaf75b9060800160405180910390a350505050505061104260017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b5050505050565b60606005805461105890614a84565b80601f016020809104026020016040519081016040528092919081815260200182805461108490614a84565b80156110cf5780601f106110a6576101008083540402835291602001916110cf565b820191905f5260205f20905b8154815290600101906020018083116110b257829003601f168201915b5050505050905090565b5f336110e6818585612b44565b60019150505b92915050565b6203000b546203000c546007545f929190839081906001600160a01b03878116911614611120575f87611123565b865f5b915091505f611134838387876127aa565b505090506127108189611147919061491d565b6111519190614961565b61115b90896148f7565b975061116988888787612b51565b98975050505050505050565b6007545f90819081906001600160a01b03878116911614611197575f8761119a565b865f5b600a546040517fdf29d5bb0000000000000000000000000000000000000000000000000000000081523060048201525f602482015260448101849052606481018390526084810189905260a48101889052929450909250612710916001600160a01b039091169063df29d5bb9060c401602060405180830381865afa158015611225573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061124991906148b3565b611253908961491d565b61125d9190614961565b61126790886148f7565b965061127587878787612b51565b979650505050505050565b5f806001600160a01b0383166112c2576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6112cc3384612c93565b91509150915091565b6203000e546203000f54425f80806112fc6203000b546203000c546203000d549192909190565b925092509250838114611344575f61131482866148f7565b9050611320818561491d565b61132a908861490a565b9650611336818461491d565b611340908761490a565b9550505b505050909192565b5f33611359858285612dd0565b611364858585612e5f565b60019150505b9392505050565b5f808080600b8561ffff811061138957611389614ad5565b6040805160608101825260039290920292909201805463ffffffff16808352600182015460208401819052600290920154929093018290529197919650945092505050565b6001600160a01b0381165f908152620300146020908152604080832054620300158352818420549284905292205480156114a9576001600160a01b0384165f9081526203001260205260409020546203001054670de0b6b3a764000091611434916148f7565b61143e908361491d565b6114489190614961565b611452908461490a565b6001600160a01b0385165f9081526203001360205260409020546203001154919450670de0b6b3a76400009161148891906148f7565b611492908361491d565b61149c9190614961565b6114a6908361490a565b91505b50915091565b5f806001600160a01b0383166114f1576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336001600160a01b0385161480159061152f57506001600160a01b0384165f908152620300166020908152604080832033845290915290205460ff16155b15611566576040517fea8e4eb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6115708484612c93565b915091505b9250929050565b6203000854640100000000900461ffff165f611599600b84612eee565b90508161ffff168161ffff16146115eb576040805161ffff80851682528316602082015233917ff0b7b7d1cdf542f5660a7879f0cac17375fdcf984af4a6d499a9daedacb24c58910160405180910390a25b505050565b600a546001600160a01b031615611633576040517f154c51b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600a8054337fffffffffffffffffffffffff0000000000000000000000000000000000000000918216179091556008805482166001600160a01b03848116919091179091556007805490921690841617905560405182908290611695906144bd565b6001600160a01b03928316815291166020820152604001604051809103905ff0801580156116c5573d5f5f3e3d5ffd5b5060095f6101000a8154816001600160a01b0302191690836001600160a01b031602179055505f826001600160a01b03166395d89b416040518163ffffffff1660e01b81526004015f60405180830381865afa158015611727573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261174e9190810190614b2f565b90505f826001600160a01b03166395d89b416040518163ffffffff1660e01b81526004015f60405180830381865afa15801561178c573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526117b39190810190614b2f565b90506117bf8282613005565b6005906117cc9082614c39565b506117d78282613031565b6006906117e49082614c39565b50836001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611821573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118459190614cf4565b61185090600a614def565b6203000981905550826001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611894573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118b89190614cf4565b6118c390600a614def565b6203000a55600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000164263ffffffff161790556203000880547fffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ffff166401000100001790555b50505050565b5f611939612729565b6203000b546203000c546007546040516370a0823160e01b81523060048201525f916001600160a01b0316906370a0823190602401602060405180830381865afa158015611989573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119ad91906148b3565b6008546040516370a0823160e01b81523060048201529192505f916001600160a01b03909116906370a0823190602401602060405180830381865afa1580156119f8573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611a1c91906148b3565b90505f611a2985846148f7565b90505f611a3685846148f7565b90505f611a4260025490565b9050805f03611ac4576103e8611a60611a5b848661491d565b613046565b611a6a91906148f7565b9750611a7960016103e86131ab565b611a8383836131fc565b6103e8881015611abf576040517fd226f9d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611b31565b611af687611ad2838661491d565b611adc9190614961565b87611ae7848661491d565b611af19190614961565b6132bc565b9750875f03611b31576040517fd226f9d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611b3b89896131ab565b611b4785858989612a5f565b60408051848152602081018490526001600160a01b038b169133917f2f00e3cdd69a77be7ed215ec7b2a36784dd158f921fca79ac29deffa353fe6ee910160405180910390a350505050505050611bbd60017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b919050565b6001600160a01b038216611c02576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b335f81815262030016602090815260408083206001600160a01b0387168085529083529281902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001686151590811790915590519081529192917f63484c3756a6c7d95f131879210268006b60e58057de5db75f3a8c91c7869ebf910160405180910390a35050565b6060805f5f611c9a6112d5565b509092509050611cae600b878785856132cb565b9350935050509250929050565b5f5f611cc5612729565b6203000b546203000c546007546008546040516370a0823160e01b81523060048201526001600160a01b0392831692909116905f9083906370a0823190602401602060405180830381865afa158015611d20573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611d4491906148b3565b6040516370a0823160e01b81523060048201529091505f906001600160a01b038416906370a0823190602401602060405180830381865afa158015611d8b573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611daf91906148b3565b305f908152602081905260409020546002549192509080611dd0858461491d565b611dda9190614961565b995080611de7848461491d565b611df19190614961565b9850891580611dfe575088155b15611e35576040517f749383ad00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611e3f30836133e6565b611e536001600160a01b0387168c8c612757565b611e676001600160a01b0386168c8b612757565b6040516370a0823160e01b81523060048201526001600160a01b038716906370a0823190602401602060405180830381865afa158015611ea9573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611ecd91906148b3565b6040516370a0823160e01b81523060048201529094506001600160a01b038616906370a0823190602401602060405180830381865afa158015611f12573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f3691906148b3565b9250611f428484613433565b611f4e84848a8a612a5f565b604080518b8152602081018b90526001600160a01b038d169133917f5d624aa9c148153ab3446c1b154f660ee7701e549fe9b62dab7171b1c80e6fa2910160405180910390a35050505050505050611fc560017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b915091565b60606006805461105890614a84565b5f336110e6818585612e5f565b600a5f9054906101000a90046001600160a01b03166001600160a01b031663b782cc496040518163ffffffff1660e01b8152600401602060405180830381865afa158015612036573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061205a9190614dfd565b6001600160a01b0316336001600160a01b0316146120a4576040517f058a2da800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60066115eb828483614e18565b5f825f036120c057505f6110ec565b6203000b546203000c546007546001600160a01b038581169116146120e557806120e7565b815b851061211f576040517fbb55fd2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f61212c86868585613475565b9050805f03612140575f93505050506110ec565b6007545f9081906001600160a01b0388811691161461216057825f612163565b5f835b600a546040517f11896ad200000000000000000000000000000000000000000000000000000000815230600482015233602482015260448101849052606481018390526084810189905260a481018890529294509092505f916001600160a01b03909116906311896ad29060c401602060405180830381865afa1580156121ec573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061221091906148b3565b9050612232816122216001876148f7565b61222d846127106148f7565b6135ce565b61223c908561490a565b9998505050505050505050565b612251612729565b6007546008546203000b546040516370a0823160e01b81523060048201526001600160a01b0393841693909216915f919084906370a0823190602401602060405180830381865afa1580156122a8573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906122cc91906148b3565b6122d691906148f7565b905080156122f2576122f26001600160a01b0384168583612757565b6203000c546040516370a0823160e01b81523060048201525f91906001600160a01b038516906370a0823190602401602060405180830381865afa15801561233c573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061236091906148b3565b61236a91906148f7565b90508015612386576123866001600160a01b0384168683612757565b505050506123b360017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b50565b600a5f9054906101000a90046001600160a01b03166001600160a01b031663b782cc496040518163ffffffff1660e01b8152600401602060405180830381865afa158015612406573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061242a9190614dfd565b6001600160a01b0316336001600160a01b031614612474576040517f058a2da800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60056115eb828483614e18565b5f61248a612729565b61249c6203000b546203000c546129b6565b90506124c760017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b90565b6203000b546203000c546007545f929190839081906001600160a01b038781169116146124f8575f876124fb565b865f5b600a546040517fdf29d5bb0000000000000000000000000000000000000000000000000000000081523060048201525f602482015260448101849052606481018390526084810188905260a48101879052929450909250612710916001600160a01b039091169063df29d5bb9060c401602060405180830381865afa158015612586573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906125aa91906148b3565b6125b4908961491d565b6125be9190614961565b6125c890886148f7565b965061127587878686612b51565b6125de612729565b6002545f03612619576040517fbb55fd2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6007546040516370a0823160e01b81523060048201526126fe916001600160a01b0316906370a0823190602401602060405180830381865afa158015612661573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061268591906148b3565b6008546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa1580156126cb573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906126ef91906148b3565b6203000b546203000c54612a5f565b61272760017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b565b61273161367e565b60027f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b61276483838360016136e1565b6115eb576040517f5274afe70000000000000000000000000000000000000000000000000000000081526001600160a01b03841660048201526024015b60405180910390fd5b600a546040517fdb6b39b400000000000000000000000000000000000000000000000000000000815230600482015233602482015260448101869052606481018590526084810184905260a481018390525f91829182916001600160a01b03169063db6b39b49060c401606060405180830381865afa15801561282f573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906128539190614ed2565b9250925092509450945094915050565b805f0361286d5750565b60095460075461288a916001600160a01b03918216911683612757565b5f61289460025490565b6128a683670de0b6b3a764000061491d565b6128b09190614961565b905080156128d15780620300105f8282546128cb919061490a565b90915550505b604080518381525f602082015233917f112c256902bf554b6ed882d2936687aaeb4225e8cd5b51303c90ca6cf43a860291015b60405180910390a25050565b805f0361291a5750565b600954600854612937916001600160a01b03918216911683612757565b5f61294160025490565b61295383670de0b6b3a764000061491d565b61295d9190614961565b9050801561297e5780620300115f828254612978919061490a565b90915550505b604080515f81526020810184905233917f112c256902bf554b6ed882d2936687aaeb4225e8cd5b51303c90ca6cf43a86029101612904565b5f5f620300095484670de0b6b3a76400006129d1919061491d565b6129db9190614961565b90505f6203000a5484670de0b6b3a76400006129f7919061491d565b612a019190614961565b90505f612a178383670de0b6b3a76400006135ce565b90505f612a2d8384670de0b6b3a76400006135ce565b612a408586670de0b6b3a76400006135ce565b612a4a919061490a565b90506112758282670de0b6b3a76400006135ce565b6203000d5442905f90612a7290836148f7565b90505f81118015612a8257508315155b8015612a8d57508215155b15612ad657612a9c818561491d565b6203000e5f828254612aae919061490a565b90915550612abe9050818461491d565b6203000f5f828254612ad0919061490a565b90915550505b6203000e546203000f54612aee91600b91603c61375c565b6203000b8690556203000c8590556203000d82905560408051878152602081018790527fcf2aa50876cdfbb541206f89af0ee78d44a2abf8d328e37fa4917f982149848a910160405180910390a1505050505050565b6115eb838383600161391f565b5f5f612b5d84846129b6565b6203000954909150612b7785670de0b6b3a764000061491d565b612b819190614961565b6203000a54909450612b9b84670de0b6b3a764000061491d565b612ba59190614961565b6007549093505f9081906001600160a01b03888116911614612bc8578486612bcb565b85855b60075491935091506001600160a01b03888116911614612c0b576203000a54612bfc89670de0b6b3a764000061491d565b612c069190614961565b612c2c565b6203000954612c2289670de0b6b3a764000061491d565b612c2c9190614961565b97505f612c43612c3c848b61490a565b8584613a23565b612c4d90836148f7565b600754909150670de0b6b3a7640000906001600160a01b038a8116911614612c79576203000954612c7f565b6203000a545b612c89908361491d565b61223c9190614961565b5f5f612c9e84613b44565b50506001600160a01b0382165f908152620300146020908152604080832054620300159092529091205481151580612cd557505f81115b15611575576001600160a01b038481165f9081526203001460209081526040808320839055620300159091528082209190915560095490517f533cf5ce0000000000000000000000000000000000000000000000000000000081528583166004820152602481018590526044810184905291169063533cf5ce906064015f604051808303815f87803b158015612d69575f5ffd5b505af1158015612d7b573d5f5f3e3d5ffd5b505060408051858152602081018590526001600160a01b0380881694508816925033917fcd5e4f020ddad29434c2200a9edf2f8d7ec30f0d787f03b528ab7279aab0acbe910160405180910390a49250929050565b6001600160a01b038381165f908152600160209081526040808320938616835292905220545f1981101561192a5781811015612e51576040517ffb8f41b20000000000000000000000000000000000000000000000000000000081526001600160a01b038416600482015260248101829052604481018390526064016127a1565b61192a84848484035f61391f565b6001600160a01b038316612ea1576040517f96c6fd1e0000000000000000000000000000000000000000000000000000000081525f60048201526024016127a1565b6001600160a01b038216612ee3576040517fec442f050000000000000000000000000000000000000000000000000000000081525f60048201526024016127a1565b6115eb838383613cb0565b6202fffd8201545f9061ffff64010000000090910481169083168110612f155790506110ec565b805b8361ffff168161ffff161015612fc45760018561ffff808416908110612f3f57612f3f614ad5565b6003020180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff9290921691909117905560018561ffff838116908110612f8e57612f8e614ad5565b60030201600101819055506001855f018261ffff1661ffff8110612fb457612fb4614ad5565b6003020160020155600101612f17565b5050506202fffd9190910180547fffffffffffffffffffffffffffffffffffffffffffffffffffff0000ffffffff1664010000000061ffff84160217905590565b6060828260405160200161301a929190614f20565b604051602081830303815290604052905092915050565b6060828260405160200161301a929190614f81565b5f60018211613053575090565b81600170010000000000000000000000000000000082106130795760809190911c9060401b5b6801000000000000000082106130945760409190911c9060201b5b64010000000082106130ab5760209190911c9060101b5b6201000082106130c05760109190911c9060081b5b61010082106130d45760089190911c9060041b5b601082106130e75760049190911c9060021b5b600482106130f35760011b5b600302600190811c9081858161310b5761310b614934565b048201901c9050600181858161312357613123614934565b048201901c9050600181858161313b5761313b614934565b048201901c9050600181858161315357613153614934565b048201901c9050600181858161316b5761316b614934565b048201901c9050600181858161318357613183614934565b048201901c90506131a281858161319c5761319c614934565b04821190565b90039392505050565b6001600160a01b0382166131ed576040517fec442f050000000000000000000000000000000000000000000000000000000081525f60048201526024016127a1565b6131f85f8383613cb0565b5050565b6203000a5461321382670de0b6b3a764000061491d565b61321d9190614961565b620300095461323484670de0b6b3a764000061491d565b61323e9190614961565b14613275576040517f0a04d7fa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6402540be40061328583836129b6565b116131f8576040517f438d3ade00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f82821882841002821861136a565b60608042858067ffffffffffffffff8111156132e9576132e9614b02565b604051908082528060200260200182016040528015613312578160200160208202803683370190505b5093508067ffffffffffffffff81111561332e5761332e614b02565b604051908082528060200260200182016040528015613357578160200160208202803683370190505b5092505f5b818110156133d9576133978a848b8b8581811061337b5761337b614ad5565b90506020020160208101906133909190614fb2565b8a8a613ceb565b8683815181106133a9576133a9614ad5565b602002602001018684815181106133c2576133c2614ad5565b60209081029190910101919091525260010161335c565b5050509550959350505050565b6001600160a01b038216613428576040517f96c6fd1e0000000000000000000000000000000000000000000000000000000081525f60048201526024016127a1565b6131f8825f83613cb0565b61343d82826129b6565b5f036131f8576040517f7d06c0c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f5f61348184846129b6565b620300095490915061349b85670de0b6b3a764000061491d565b6134a59190614961565b6203000a549094506134bf84670de0b6b3a764000061491d565b6134c99190614961565b6007549093505f9081906001600160a01b038881169116146134ec5784866134ef565b85855b60075491935091505f9081906001600160a01b038a811691161461351c576203000a546203000954613527565b62030009546203000a545b90925090506135476135418b670de0b6b3a764000061491d565b83613d71565b9950838a10613582576040517fbb55fd2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f6135976135908c876148f7565b8786613a23565b90506135bf826135a786846148f7565b6135b1919061491d565b670de0b6b3a7640000613d71565b9b9a5050505050505050505050565b5f5f5f6135db8686613da5565b91509150815f036135ff578381816135f5576135f5614934565b049250505061136a565b818411613616576136166003851502601118613dc1565b5f848688095f868103871696879004966002600389028118808a02820302808a02820302808a02820302808a02820302808a02820302808a02909103029181900381900460010185841190960395909502919093039390930492909217029150509392505050565b6136aa5f60027f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00613dd2565b15612727576040517f3ee5aeb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517fa9059cbb000000000000000000000000000000000000000000000000000000005f8181526001600160a01b038616600452602485905291602083604481808b5af1925060015f51148316613750578383151615613744573d5f823e3d81fd5b5f873b113d1516831692505b60405250949350505050565b6202fffd840154429061ffff908116905f9087908390811061378057613780614ad5565b600302015463ffffffff90811684031690508381116137a15750505061192a565b6202fffd87015461ffff620100008204811691829164010000000090910416811080156137df57506137d4600183614fd5565b61ffff168461ffff16145b156137f2576137ef826001614fef565b90505b5f816137ff866001614fef565b6138099190615009565b905060405180606001604052808763ffffffff1681526020018a8152602001898152508a5f018261ffff1661ffff811061384557613845614ad5565b82516003919091029190910180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff909216919091178155602082015160018201556040909101516002909101556202fffd8a0180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff8381169190911790915583811690831614613913576202fffd8a0180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ffff166201000061ffff8516021790555b50505050505050505050565b6001600160a01b038416613961576040517fe602df050000000000000000000000000000000000000000000000000000000081525f60048201526024016127a1565b6001600160a01b0383166139a3576040517f94280d620000000000000000000000000000000000000000000000000000000081525f60048201526024016127a1565b6001600160a01b038085165f908152600160209081526040808320938716835292905220829055801561192a57826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92584604051613a1591815260200190565b60405180910390a350505050565b5f805b60ff811015613b11575f613a3a8685613dd9565b905084811015613ab4575f613a65613a5283886148f7565b670de0b6b3a764000061222d8a89613e3f565b9050805f03613aa25785613a8388613a7e88600161490a565b613dd9565b1115613a9e57613a9485600161490a565b935050505061136a565b5060015b613aac818661490a565b945050613b08565b5f613ac2613a5287846148f7565b9050805f03613afa5785821480613ae6575085613ae488613a7e6001896148f7565b105b15613af65784935050505061136a565b5060015b613b0481866148f7565b9450505b50600101613a26565b506040517f6eb5c82100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0381165f908152602081905260409020548015613c77576001600160a01b0382165f9081526203001260209081526040808320805462030013808552928520805462030010546203001154948190559490955282905593613bac85846148f7565b90505f613bb985846148f7565b90508115613c14575f670de0b6b3a7640000613bd5848a61491d565b613bdf9190614961565b6001600160a01b038a165f908152620300146020526040812080549293508392909190613c0d90849061490a565b9091555050505b8015613c6d575f670de0b6b3a7640000613c2e838a61491d565b613c389190614961565b6001600160a01b038a165f908152620300156020526040812080549293508392909190613c6690849061490a565b9091555050505b5050505050505050565b62030010546001600160a01b0383165f908152620300126020908152604080832093909355620300115462030013909152919020555050565b6001600160a01b03831615613cc857613cc883613b44565b6001600160a01b03821615613ce057613ce082613b44565b6115eb838383613ea6565b5f5f8463ffffffff165f03613d04575082905081613d67565b8486035f80613d168a8a858a8a613fe5565b915091508263ffffffff16815f015163ffffffff1603613d46578060200151816040015194509450505050613d67565b613d5e82825f015183602001518460400151876141bf565b90955093505050505b9550959350505050565b5f815f03613d8357613d836012613dc1565b816001840381613d9557613d95614934565b046001018315155b029392505050565b5f805f1983850993909202808410938190039390930393915050565b634e487b715f52806020526024601cfd5b5414919050565b5f5f613dee8484670de0b6b3a76400006135ce565b90505f613e048485670de0b6b3a76400006135ce565b613e178687670de0b6b3a76400006135ce565b613e21919061490a565b9050613e368282670de0b6b3a76400006135ce565b95945050505050565b5f5f613e548384670de0b6b3a76400006135ce565b90505f613e6a8586670de0b6b3a76400006135ce565b9050613e7f8186670de0b6b3a76400006135ce565b613e9c613e8d87600361491d565b84670de0b6b3a76400006135ce565b613e36919061490a565b6001600160a01b038316613ed0578060025f828254613ec5919061490a565b90915550613f599050565b6001600160a01b0383165f9081526020819052604090205481811015613f3b576040517fe450d38c0000000000000000000000000000000000000000000000000000000081526001600160a01b038516600482015260248101829052604481018390526064016127a1565b6001600160a01b0384165f9081526020819052604090209082900390555b6001600160a01b038216613f7557600280548290039055613f93565b6001600160a01b0382165f9081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051613fd891815260200190565b60405180910390a3505050565b61400c60405180606001604052805f63ffffffff1681526020015f81526020015f81525090565b61403360405180606001604052805f63ffffffff1681526020015f81526020015f81525090565b6202fffd87015461ffff9081169088908290811061405357614053614ad5565b6040805160608101825260039290920292909201805463ffffffff168083526001820154602084015260029091015492820192909252935061409790889088614240565b156140ee57825163ffffffff8088169116036140b65750819050613d67565b5f5f6140c5858a89898c6141bf565b6040805160608101825263ffffffff8c16815260208101939093528201529350613d6792505050565b6202fffd880154889062010000900461ffff1661410c836001614fef565b6141169190615009565b61ffff1661ffff811061412b5761412b614ad5565b6040805160608101825260039290920292909201805463ffffffff168083526001820154602084015260029091015492820192909252935061416f90889088614240565b6141a5576040517fc02e462000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6141b088888861430e565b92509250509550959350505050565b845160208601515f91829163ffffffff8289038116928603169083906141e590896148f7565b90505f8a60400151886141f891906148f7565b90506142058284866135ce565b8b60200151614214919061490a565b95506142218184866135ce565b8b60400151614230919061490a565b9450505050509550959350505050565b5f8363ffffffff168363ffffffff161115801561426957508363ffffffff168263ffffffff1611155b15614285578163ffffffff168363ffffffff161115905061136a565b5f8463ffffffff168463ffffffff16116142b3576142ae63ffffffff851664010000000061502c565b6142bb565b8363ffffffff165b64ffffffffff1690505f8563ffffffff168463ffffffff16116142f2576142ed63ffffffff851664010000000061502c565b6142fa565b8363ffffffff165b64ffffffffff169091111595945050505050565b61433560405180606001604052805f63ffffffff1681526020015f81526020015f81525090565b61435c60405180606001604052805f63ffffffff1681526020015f81526020015f81525090565b6202fffd85015461ffff62010000820481169187915f918491166001018161438657614386614934565b0690505f1961ffff84168201015b6002818301048361ffff861682816143ae576143ae614934565b0661ffff81106143c0576143c0614ad5565b6040805160608101825260039290920292909201805463ffffffff1682526001808201546020840152600290910154928201929092529750849061ffff87169083018161440f5761440f614934565b0661ffff811061442157614421614ad5565b6040805160608101825260039290920292909201805463ffffffff16825260018101546020830152600201549181019190915287519096505f90614467908b908b614240565b90505f6144788b8b8a5f0151614240565b90508180156144845750805b15614491575050506144b1565b81156144a2578260010194506144a9565b6001830393505b505050614394565b50505050935093915050565b6103688061504a83390190565b6001600160a01b03811681146123b3575f5ffd5b5f5f83601f8401126144ee575f5ffd5b50813567ffffffffffffffff811115614505575f5ffd5b602083019150836020828501011115611575575f5ffd5b5f5f5f5f5f60808688031215614530575f5ffd5b85359450602086013593506040860135614549816144ca565b9250606086013567ffffffffffffffff811115614564575f5ffd5b614570888289016144de565b969995985093965092949392505050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b5f5f604083850312156145c7575f5ffd5b82356145d2816144ca565b946020939093013593505050565b5f5f604083850312156145f1575f5ffd5b823591506020830135614603816144ca565b809150509250929050565b5f5f5f5f60808587031215614621575f5ffd5b843593506020850135614633816144ca565b93969395505050506040820135916060013590565b5f60208284031215614658575f5ffd5b813561136a816144ca565b5f5f5f60608486031215614675575f5ffd5b8335614680816144ca565b92506020840135614690816144ca565b929592945050506040919091013590565b5f602082840312156146b1575f5ffd5b5035919050565b5f5f604083850312156146c9575f5ffd5b82356146d4816144ca565b91506020830135614603816144ca565b5f602082840312156146f4575f5ffd5b813561ffff8116811461136a575f5ffd5b80151581146123b3575f5ffd5b5f5f60408385031215614723575f5ffd5b823561472e816144ca565b9150602083013561460381614705565b5f5f6020838503121561474f575f5ffd5b823567ffffffffffffffff811115614765575f5ffd5b8301601f81018513614775575f5ffd5b803567ffffffffffffffff81111561478b575f5ffd5b8560208260051b840101111561479f575f5ffd5b6020919091019590945092505050565b5f8151808452602084019350602083015f5b828110156147df5781518652602095860195909101906001016147c1565b5093949350505050565b604081525f6147fb60408301856147af565b8281036020840152613e3681856147af565b5f5f6020838503121561481e575f5ffd5b823567ffffffffffffffff811115614834575f5ffd5b614840858286016144de565b90969095509350505050565b5f6020828403121561485c575f5ffd5b815161136a81614705565b6001600160a01b038616815284602082015283604082015260806060820152816080820152818360a08301375f81830160a090810191909152601f909201601f19160101949350505050565b5f602082840312156148c3575f5ffd5b5051919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b818103818111156110ec576110ec6148ca565b808201808211156110ec576110ec6148ca565b80820281158282048414176110ec576110ec6148ca565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f8261496f5761496f614934565b500490565b5f610100820190506fffffffffffffffffffffffffffffffff83511682526fffffffffffffffffffffffffffffffff60208401511660208301526fffffffffffffffffffffffffffffffff604084015116604083015260608301516149ed60608401826fffffffffffffffffffffffffffffffff169052565b506080830151614a1160808401826fffffffffffffffffffffffffffffffff169052565b5060a0830151614a3560a08401826fffffffffffffffffffffffffffffffff169052565b5060c0830151614a5960c08401826fffffffffffffffffffffffffffffffff169052565b5060e0830151614a7d60e08401826fffffffffffffffffffffffffffffffff169052565b5092915050565b600181811c90821680614a9857607f821691505b602082108103614acf577f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b50919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f60208284031215614b3f575f5ffd5b815167ffffffffffffffff811115614b55575f5ffd5b8201601f81018413614b65575f5ffd5b805167ffffffffffffffff811115614b7f57614b7f614b02565b604051601f19603f601f19601f8501160116810181811067ffffffffffffffff82111715614baf57614baf614b02565b604052818152828201602001861015614bc6575f5ffd5b8160208401602083015e5f91810160200191909152949350505050565b601f8211156115eb57828211156115eb57805f5260205f20601f840160051c6020851015614c0e57505f5b90810190601f840160051c035f5b81811015614c31575f83820155600101614c1c565b505050505050565b815167ffffffffffffffff811115614c5357614c53614b02565b614c6781614c618454614a84565b84614be3565b6020601f821160018114614c99575f8315614c825750848201515b5f19600385901b1c1916600184901b178455611042565b5f84815260208120601f198516915b82811015614cc85787850151825560209485019460019092019101614ca8565b5084821015614ce557868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b5f60208284031215614d04575f5ffd5b815160ff8116811461136a575f5ffd5b6001815b6001841115614d4f57808504811115614d3357614d336148ca565b6001841615614d4157908102905b60019390931c928002614d18565b935093915050565b5f82614d65575060016110ec565b81614d7157505f6110ec565b8160018114614d875760028114614d9157614dad565b60019150506110ec565b60ff841115614da257614da26148ca565b50506001821b6110ec565b5060208310610133831016604e8410600b8410161715614dd0575081810a6110ec565b614ddc5f198484614d14565b805f1904821115613d9d57613d9d6148ca565b5f61136a60ff841683614d57565b5f60208284031215614e0d575f5ffd5b815161136a816144ca565b67ffffffffffffffff831115614e3057614e30614b02565b614e4483614e3e8354614a84565b83614be3565b5f601f841160018114614e75575f8515614e5e5750838201355b5f19600387901b1c1916600186901b178355611042565b5f83815260208120601f198716915b82811015614ea45786850135825560209485019460019092019101614e84565b5086821015614ec0575f1960f88860031b161c19848701351681555b505060018560011b0183555050505050565b5f5f5f60608486031215614ee4575f5ffd5b8351602085015160408601519194509250614efe81614705565b809150509250925092565b5f81518060208401855e5f93019283525090919050565b7f537461626c65563220414d4d202d20000000000000000000000000000000000081525f614f51600f830185614f09565b7f2f000000000000000000000000000000000000000000000000000000000000008152613e366001820185614f09565b7f73414d4d56322d0000000000000000000000000000000000000000000000000081525f614f516007830185614f09565b5f60208284031215614fc2575f5ffd5b813563ffffffff8116811461136a575f5ffd5b61ffff82811682821603908111156110ec576110ec6148ca565b61ffff81811683821601908111156110ec576110ec6148ca565b5f61ffff83168061501c5761501c614934565b8061ffff84160691505092915050565b64ffffffffff81811683821601908111156110ec576110ec6148ca56fe60e060405234801561000f575f5ffd5b5060405161036838038061036883398101604081905261002e91610064565b336080526001600160a01b0391821660a0521660c052610095565b80516001600160a01b038116811461005f575f5ffd5b919050565b5f5f60408385031215610075575f5ffd5b61007e83610049565b915061008c60208401610049565b90509250929050565b60805160a05160c0516102ab6100bd5f395f61011801525f60d101525f605a01526102ab5ff3fe608060405234801561000f575f5ffd5b5060043610610029575f3560e01c8063533cf5ce1461002d575b5f5ffd5b61004061003b36600461022b565b610042565b005b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146100b1576040517f6f61f64100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81156100f8576100f873ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168484610144565b801561013f5761013f73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168483610144565b505050565b61015183838360016101a3565b61013f576040517f5274afe700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8416600482015260240160405180910390fd5b6040517fa9059cbb000000000000000000000000000000000000000000000000000000005f81815273ffffffffffffffffffffffffffffffffffffffff8616600452602485905291602083604481808b5af1925060015f5114831661021f578383151615610213573d5f823e3d81fd5b5f873b113d1516831692505b60405250949350505050565b5f5f5f6060848603121561023d575f5ffd5b833573ffffffffffffffffffffffffffffffffffffffff81168114610260575f5ffd5b9560208501359550604090940135939250505056fea2646970667358221220eeabba3bd98e978db119b83233dcf1a15cbc1751f5b6fdcc907308b07b33330264736f6c63430008240033a2646970667358221220aa9bbd0570a5d863052798f5e72b7cb02066916c003643151160fd218424ee5f64736f6c63430008240033","sourceMap":"362:5174:8:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5112:3053:6;;;;;;:::i;:::-;;:::i;:::-;;24340:84;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;22002:214;22131:8;;22157;;22193:18;;22002:214;;;;1999:25:24;;;2055:2;2040:18;;2033:34;;;;2083:18;;;2076:34;1987:2;1972:18;22002:214:6;1797:319:24;3902:186:13;;;;;;:::i;:::-;;:::i;:::-;;;2658:14:24;;2651:22;2633:41;;2621:2;2606:18;3902:186:13;2493:187:24;2027:21:6;;;;;-1:-1:-1;;;;;2027:21:6;;;;;;-1:-1:-1;;;;;2849:55:24;;;2831:74;;2819:2;2804:18;2027:21:6;2685:226:24;22816:523:6;;;;;;:::i;:::-;;:::i;:::-;;;3434:25:24;;;3422:2;3407:18;22816:523:6;3288:177:24;20705:496:6;;;;;;:::i;:::-;;:::i;4006:183::-;;;;;;:::i;:::-;;:::i;:::-;;;;4509:25:24;;;4565:2;4550:18;;4543:34;;;;4482:18;4006:183:6;4335:248:24;2803:97:13;2881:12;;2803:97;;2301:53:6;;;;;;;;;;;;;;;;;;;;;;;;;;;4814:6:24;4802:19;;;4784:38;;4858:19;;;4853:2;4838:18;;4831:47;4914:19;;4894:18;;;4887:47;;;;4772:2;4757:18;2301:53:6;4588:352:24;21229:745:6;;;:::i;3009:47::-;;;;;;:::i;:::-;;;;;;;;;;;;;;4680:244:13;;;;;;:::i;:::-;;:::i;20331:346:6:-;;;;;;:::i;:::-;;:::i;:::-;;;;5919:10:24;5907:23;;;5889:42;;5962:2;5947:18;;5940:34;;;;5990:18;;;5983:34;5877:2;5862:18;20331:346:6;5689:334:24;19162:402:6;;;;;;:::i;:::-;;:::i;4217:298::-;;;;;;:::i;:::-;;:::i;2688:82:13:-;;;2761:2;6563:36:24;;6551:2;6536:18;2688:82:13;6421:184:24;12027:433:6;;;;;;:::i;:::-;;:::i;2835:21::-;;;;;;2125:23;;;;;-1:-1:-1;;;;;2125:23:6;;;19592:211;19739:10;;19751;;19763:8;;19773;;19783:6;;19791;;19592:211;;;7174:25:24;;;7230:2;7215:18;;7208:34;;;;7258:18;;;7251:34;;;;7316:2;7301:18;;7294:34;-1:-1:-1;;;;;19783:6:6;;;7359:3:24;7344:19;;7337:84;19791:6:6;7452:3:24;7437:19;;7430:84;7161:3;7146:19;19592:211:6;6887:633:24;2540:23:6;;;;;;11337:582;;;;;;:::i;:::-;;:::i;437:44:8:-;;473:8;437:44;;3085:45:6;;;;;;:::i;:::-;;;;;;;;;;;;;;2591:23;;;;;;510:47:8;;;;;9477:1162:6;;;;;;:::i;:::-;;:::i;2933:116:13:-;;;;;;:::i;:::-;-1:-1:-1;;;;;3024:18:13;2998:7;3024:18;;;;;;;;;;;;2933:116;3734:244:6;;;;;;:::i;:::-;;:::i;19952:351::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;8236:1213::-;;;;;;:::i;:::-;;:::i;24428:88::-;;;:::i;19831:93::-;19904:6;;19912;;19831:93;;;-1:-1:-1;;;;;19904:6:6;;;9900:74:24;;19912:6:6;;;;10005:2:24;9990:18;;9983:83;9873:18;19831:93:6;9726:346:24;2934:47:6;;;;;;:::i;:::-;;;;;;;;;;;;;;3158:45;;;;;;:::i;:::-;;;;;;;;;;;;;;3244:178:13;;;;;;:::i;:::-;;:::i;4863:176:6:-;;;;;;:::i;:::-;;:::i;23367:969::-;;;;;;:::i;:::-;;:::i;10667:396::-;;;;;;:::i;:::-;;:::i;2884:21::-;;;;;;2704:37;;;;;;2769;;;;;;2176:22;;;;;-1:-1:-1;;;;;2176:22:6;;;4667:168;;;;;;:::i;:::-;;:::i;2642:33::-;;;;;;3231:97;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;2076:21;;;;;-1:-1:-1;;;;;2076:21:6;;;3455:140:13;;;;;;:::i;:::-;-1:-1:-1;;;;;3561:18:13;;;3535:7;3561:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;3455:140;4543:96:6;;;:::i;22244:544::-;;;;;;:::i;:::-;;:::i;1345:47::-;;1383:9;1345:47;;11091:218;;;:::i;5112:3053::-;3023:21:19;:19;:21::i;:::-;5244:7:6::1;;;;;;;;;-1:-1:-1::0;;;;;5244:7:6::1;-1:-1:-1::0;;;;;5231:30:6::1;;:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5227:55;;;5272:10;;;;;;;;;;;;;;5227:55;5292:15:::0;;:34;::::1;;;-1:-1:-1::0;5311:15:6;;5292:34:::1;5288:73;;;5335:26;;;;;;;;;;;;;;5288:73;5409:8;::::0;5419::::1;::::0;5438:23;;::::1;;::::0;:50:::1;;;5479:9;5465:10;:23;;5438:50;5434:86;;;5497:23;;;;;;;;;;;;;;5434:86;5680:6;::::0;5688::::1;::::0;5527:17:::1;::::0;;;-1:-1:-1;;;;;5680:6:6;;::::1;::::0;5688;;::::1;::::0;5707:13;::::1;::::0;::::1;::::0;:30:::1;;;5730:7;-1:-1:-1::0;;;;;5724:13:6::1;:2;-1:-1:-1::0;;;;;5724:13:6::1;;5707:30;5703:54;;;5746:11;;;;;;;;;;;;;;5703:54;5769:14:::0;;5765:64:::1;;5785:44;-1:-1:-1::0;;;;;5785:28:6;::::1;5814:2:::0;5818:10;5785:28:::1;:44::i;:::-;5875:14:::0;;5871:64:::1;;5891:44;-1:-1:-1::0;;;;;5891:28:6;::::1;5920:2:::0;5924:10;5891:28:::1;:44::i;:::-;5981:15:::0;;5977:83:::1;;5998:62;::::0;;;;-1:-1:-1;;;;;5998:20:6;::::1;::::0;::::1;::::0;:62:::1;::::0;6019:10:::1;::::0;6031;;6043;;6055:4;;;;5998:62:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5977:83;6114:40;::::0;-1:-1:-1;;;6114:40:6;;6148:4:::1;6114:40;::::0;::::1;2831:74:24::0;-1:-1:-1;;;;;6114:25:6;::::1;::::0;::::1;::::0;2804:18:24;;6114:40:6::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6174;::::0;-1:-1:-1;;;6174:40:6;;6208:4:::1;6174:40;::::0;::::1;2831:74:24::0;6102:52:6;;-1:-1:-1;;;;;;6174:25:6;::::1;::::0;::::1;::::0;2804:18:24;;6174:40:6::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6162:52;;5573:648;;6226:17;6270:10;6258:9;:22;;;;:::i;:::-;6246:9;:34;:77;;6322:1;6246:77;;;6296:22;6308:10:::0;6296:9;:22:::1;:::i;:::-;6283:36;::::0;:9;:36:::1;:::i;:::-;6226:97:::0;-1:-1:-1;6329:17:6::1;6361:22;6373:10:::0;6361:9;:22:::1;:::i;:::-;6349:9;:34;:77;;6425:1;6349:77;;;6399:22;6411:10:::0;6399:9;:22:::1;:::i;:::-;6386:36;::::0;:9;:36:::1;:::i;:::-;6329:97:::0;-1:-1:-1;6436:14:6;;:32;::::1;;;-1:-1:-1::0;6454:14:6;;6436:32:::1;6432:70;;;6477:25;;;;;;;;;;;;;;6432:70;-1:-1:-1::0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6716:22:6::1;6728:10:::0;6716:9;:22:::1;:::i;:::-;6688:51;;:17;::::0;::::1;:51:::0;6775:22:::1;6787:10:::0;6775:9;:22:::1;:::i;:::-;6747:51;;:17;::::0;::::1;:51:::0;6844:6:::1;::::0;6852::::1;::::0;-1:-1:-1;;;;;6844:6:6;;::::1;::::0;6852::::1;6807:15;::::0;;6971:55:::1;6983:9:::0;6994;7005;7016;6971:11:::1;:55::i;:::-;6924:102:::0;;-1:-1:-1;6924:102:6;-1:-1:-1;6924:102:6;-1:-1:-1;7038:13:6;;7034:238:::1;;7063:19;1606:6;7086:16;7098:4:::0;7086:9;:16:::1;:::i;:::-;7085:29;;;;:::i;:::-;7063:51;;7124:21;7133:11;7124:8;:21::i;:::-;7155:37;::::0;::::1;::::0;;1606:6:::1;7231:19;7243:7:::0;7231:9;:19:::1;:::i;:::-;7230:32;;;;:::i;:::-;7202:61;;:17;::::0;::::1;:61:::0;-1:-1:-1;7034:238:6::1;7283:13:::0;;7279:238:::1;;7308:19;1606:6;7331:16;7343:4:::0;7331:9;:16:::1;:::i;:::-;7330:29;;;;:::i;:::-;7308:51;;7369:21;7378:11;7369:8;:21::i;:::-;7400:37;::::0;::::1;:14;::::0;::::1;:37:::0;1606:6:::1;7476:19;7488:7:::0;7476:9;:19:::1;:::i;:::-;7475:32;;;;:::i;:::-;7447:61;;:17;::::0;::::1;:61:::0;-1:-1:-1;7279:238:6::1;7528:6;7524:121;;;7569:17;::::0;::::1;::::0;7546:40:::1;::::0;;::::1;:20;::::0;::::1;:40:::0;7619:17:::1;::::0;::::1;::::0;7596:40:::1;:20;::::0;::::1;:40:::0;7524:121:::1;7728:40;::::0;-1:-1:-1;;;7728:40:6;;7762:4:::1;7728:40;::::0;::::1;2831:74:24::0;-1:-1:-1;;;;;7728:25:6;::::1;::::0;::::1;::::0;2804:18:24;;7728:40:6::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;7788;::::0;-1:-1:-1;;;7788:40:6;;7822:4:::1;7788:40;::::0;::::1;2831:74:24::0;7716:52:6;;-1:-1:-1;;;;;;7788:25:6;::::1;::::0;::::1;::::0;2804:18:24;;7788:40:6::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;7776:52;;7928:24;7931:9;7942;7928:2;:24::i;:::-;7901;7904:9;7915;7901:2;:24::i;:::-;:51;7897:67;;;7961:3;;;;;;;;;;;;;;7897:67;7985:7;::::0;7972:47:::1;::::0;;;;-1:-1:-1;;;;;7985:7:6;;::::1;::::0;7972:36:::1;::::0;:47:::1;::::0;8009:9;;7972:47:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6508:1518;;;;;;8032:51;8040:9;8051;8062;8073;8032:7;:51::i;:::-;8094:66;::::0;;14085:25:24;;;14141:2;14126:18;;14119:34;;;14169:18;;;14162:34;;;14227:2;14212:18;;14205:34;;;-1:-1:-1;;;;;8094:66:6;::::1;::::0;8099:10:::1;::::0;8094:66:::1;::::0;14072:3:24;14057:19;8094:66:6::1;;;;;;;5221:2944;;;;;;3065:20:19::0;2365:1;1505:66;3972:62;3749:292::o;3065:20::-;5112:3053:6;;;;;:::o;24340:84::-;24386:13;24414:5;24407:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24340:84;:::o;3902:186:13:-;3975:4;735:10:17;4029:31:13;735:10:17;4045:7:13;4054:5;4029:8;:31::i;:::-;4077:4;4070:11;;;3902:186;;;;;:::o;22816:523:6:-;22965:8;;22975;;23044:6;;22908:7;;22965:8;22975;22908:7;;;;-1:-1:-1;;;;;23033:17:6;;;23044:6;;23033:17;:67;;23087:1;23091:8;23033:67;;;23054:8;23072:1;23033:67;22990:110;;;;23107:12;23125:57;23137:10;23149;23161:9;23172;23125:11;:57::i;:::-;23106:76;;;;1606:6;23251:4;23240:8;:15;;;;:::i;:::-;23239:28;;;;:::i;:::-;23227:40;;;;:::i;:::-;;;23280:54;23294:8;23304:7;23313:9;23324;23280:13;:54::i;:::-;23273:61;22816:523;-1:-1:-1;;;;;;;;22816:523:6:o;20705:496::-;20912:6;;20843:7;;;;;;-1:-1:-1;;;;;20901:17:6;;;20912:6;;20901:17;:67;;20955:1;20959:8;20901:67;;;20922:8;20940:1;20901:67;21019:7;;21006:105;;;;;21047:4;21006:105;;;14979:74:24;21019:7:6;15069:18:24;;;15062:83;15161:18;;;15154:34;;;15204:18;;;15197:34;;;15247:19;;;15240:35;;;15291:19;;;15284:35;;;20858:110:6;;-1:-1:-1;20858:110:6;;-1:-1:-1;1606:6:6;;-1:-1:-1;;;;;21019:7:6;;;;21006:32;;14951:19:24;;21006:105:6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;20987:124;;:8;:124;:::i;:::-;20986:143;;;;:::i;:::-;20974:155;;;;:::i;:::-;;;21142:54;21156:8;21166:7;21175:9;21186;21142:13;:54::i;:::-;21135:61;20705:496;-1:-1:-1;;;;;;;20705:496:6:o;4006:183::-;4063:7;;-1:-1:-1;;;;;4091:24:6;;4087:50;;4124:13;;;;;;;;;;;;;;4087:50;4150:34;4161:10;4173;4150;:34::i;:::-;4143:41;;;;4006:183;;;:::o;21229:745::-;21444:22;;21493;;21402:15;21297:26;;;21688:13;22131:8;;22157;;22193:18;;22131:8;;22157;;22193:18;22002:214;21688:13;21618:83;;;;;;21734:14;21711:19;:37;21707:263;;21799:19;21821:36;21838:19;21821:14;:36;:::i;:::-;21799:58;-1:-1:-1;21887:23:6;21799:58;21887:9;:23;:::i;:::-;21865:45;;;;:::i;:::-;;-1:-1:-1;21940:23:6;21952:11;21940:9;:23;:::i;:::-;21918:45;;;;:::i;:::-;;;21750:220;21707:263;21379:595;;;21229:745;;;:::o;4680:244:13:-;4767:4;735:10:17;4823:37:13;4839:4;735:10:17;4854:5:13;4823:15;:37::i;:::-;4870:26;4880:4;4886:2;4890:5;4870:9;:26::i;:::-;4913:4;4906:11;;;4680:244;;;;;;:::o;20331:346:6:-;20404:16;;;;20531:17;20562:6;20531:38;;;;;;;:::i;:::-;20486:83;;;;;;;;20531:38;;;;;;;;;20486:83;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;20486:83:6;-1:-1:-1;20331:346:6;-1:-1:-1;;;20331:346:6:o;19162:402::-;-1:-1:-1;;;;;19277:20:6;;19224:16;19277:20;;;:10;:20;;;;;;;;;19314:10;:20;;;;;;3024:18:13;;;;;;;19390:13:6;;19386:174;;-1:-1:-1;;;;;19448:22:6;;;;;;:12;:22;;;;;;19439:6;;19475:4;;19439:31;;;:::i;:::-;19426:45;;:9;:45;:::i;:::-;19425:54;;;;:::i;:::-;19413:66;;;;:::i;:::-;-1:-1:-1;;;;;19522:22:6;;;;;;:12;:22;;;;;;19513:6;;19413:66;;-1:-1:-1;19549:4:6;;19513:31;;19522:22;19513:31;:::i;:::-;19500:45;;:9;:45;:::i;:::-;19499:54;;;;:::i;:::-;19487:66;;;;:::i;:::-;;;19386:174;19260:304;19162:402;;;:::o;4217:298::-;4292:7;;-1:-1:-1;;;;;4320:24:6;;4316:50;;4353:13;;;;;;;;;;;;;;4316:50;4376:10;-1:-1:-1;;;;;4376:22:6;;;;;;:65;;-1:-1:-1;;;;;;4403:26:6;;;;;;:16;:26;;;;;;;;4430:10;4403:38;;;;;;;;;;4402:39;4376:65;4372:93;;;4450:15;;;;;;;;;;;;;;4372:93;4478:32;4489:8;4499:10;4478;:32::i;:::-;4471:39;;;;4217:298;;;;;;:::o;12027:433::-;12155:33;;;;;;;12122:30;12227:51;12155:17;12250:27;12227:22;:51::i;:::-;12194:84;;12315:23;12288:50;;:23;:50;;;12284:172;;12353:96;;;15719:6:24;15707:19;;;15689:38;;15763:19;;15758:2;15743:18;;15736:47;12388:10:6;;12353:96;;15662:18:24;12353:96:6;;;;;;;12284:172;12116:344;;12027:433;:::o;11337:582::-;11410:7;;-1:-1:-1;;;;;11410:7:6;:21;11406:53;;11440:19;;;;;;;;;;;;;;11406:53;11465:7;:20;;11475:10;11465:20;;;;;;;;11500:6;11491:37;;;;-1:-1:-1;;;;;11491:37:6;;;;;;;;;;11492:6;11491:37;;;;;;;;;;;11553:30;;11491:37;;;;11553:30;;;:::i;:::-;-1:-1:-1;;;;;9918:55:24;;;9900:74;;10010:55;;10005:2;9990:18;;9983:83;9888:2;9873:18;11553:30:6;;;;;;;;;;;;;;;;;;;;;;;11534:8;;:50;;;;;-1:-1:-1;;;;;11534:50:6;;;;;-1:-1:-1;;;;;11534:50:6;;;;;;11590:21;11620:7;-1:-1:-1;;;;;11614:21:6;;:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;11614:23:6;;;;;;;;;;;;:::i;:::-;11590:47;;11643:21;11673:7;-1:-1:-1;;;;;11667:21:6;;:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;11667:23:6;;;;;;;;;;;;:::i;:::-;11643:47;;11704:27;11714:7;11723;11704:9;:27::i;:::-;11696:5;;:35;;:5;:35;:::i;:::-;;11747:29;11759:7;11768;11747:11;:29::i;:::-;11737:7;;:39;;:7;:39;:::i;:::-;;11808:7;-1:-1:-1;;;;;11802:23:6;;:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;11796:31;;:2;:31;:::i;:::-;11783:10;:44;;;;11858:7;-1:-1:-1;;;;;11852:23:6;;:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;11846:31;;:2;:31;:::i;:::-;11833:10;:44;11884:17;1908:56:5;;;;1948:15;1908:56;;;;;1970:16;:20;;1996:24;;;;;;11884:30:6;11400:519;;11337:582;;:::o;9477:1162::-;9534:17;3023:21:19;:19;:21::i;:::-;9601:8:6::1;::::0;9611::::1;::::0;9653:6:::1;::::0;9646:39:::1;::::0;-1:-1:-1;;;9646:39:6;;9679:4:::1;9646:39;::::0;::::1;2831:74:24::0;9560:17:6::1;::::0;-1:-1:-1;;;;;9653:6:6::1;::::0;9646:24:::1;::::0;2804:18:24;;9646:39:6::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;9718:6;::::0;9711:39:::1;::::0;-1:-1:-1;;;9711:39:6;;9744:4:::1;9711:39;::::0;::::1;2831:74:24::0;9626:59:6;;-1:-1:-1;9691:17:6::1;::::0;-1:-1:-1;;;;;9718:6:6;;::::1;::::0;9711:24:::1;::::0;2804:18:24;;9711:39:6::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;9691:59:::0;-1:-1:-1;9756:16:6::1;9775:21;9787:9:::0;9775;:21:::1;:::i;:::-;9756:40:::0;-1:-1:-1;9802:16:6::1;9821:21;9833:9:::0;9821;:21:::1;:::i;:::-;9802:40;;9849:20;9872:13;2881:12:13::0;;;2803:97;9872:13:6::1;9849:36;;9973:12;9989:1;9973:17:::0;9969:531:::1;;1490:7;10012:30;10022:19;10033:8:::0;10022;:19:::1;:::i;:::-;10012:9;:30::i;:::-;:51;;;;:::i;:::-;10000:63;;10071:37;10085:1;1490:7;10071:5;:37::i;:::-;10195:35;10211:8;10221;10195:15;:35::i;:::-;1490:7;10242:9;:30;10238:72;;;10281:29;;;;;;;;;;;;;;10238:72;9969:531;;;10343:86;10380:9:::0;10353:23:::1;10364:12:::0;10353:8;:23:::1;:::i;:::-;10352:37;;;;:::i;:::-;10419:9:::0;10392:23:::1;10403:12:::0;10392:8;:23:::1;:::i;:::-;10391:37;;;;:::i;:::-;10343:8;:86::i;:::-;10331:98;;10441:9;10454:1;10441:14:::0;10437:56:::1;;10464:29;;;;;;;;;;;;;;10437:56;10505:20;10511:2;10515:9;10505:5;:20::i;:::-;10532:51;10540:9;10551;10562;10573;10532:7;:51::i;:::-;10594:40;::::0;;4509:25:24;;;4565:2;4550:18;;4543:34;;;-1:-1:-1;;;;;10594:40:6;::::1;::::0;10599:10:::1;::::0;10594:40:::1;::::0;4482:18:24;10594:40:6::1;;;;;;;9553:1086;;;;;;;3065:20:19::0;2365:1;1505:66;3972:62;3749:292::o;3065:20::-;9477:1162:6;;;:::o;3734:244::-;-1:-1:-1;;;;;3813:23:6;;3809:49;;3845:13;;;;;;;;;;;;;;3809:49;3881:10;3864:28;;;;:16;:28;;;;;;;;-1:-1:-1;;;;;3864:39:6;;;;;;;;;;;;:51;;;;;;;;;;;;;3926:47;;2633:41:24;;;3864:39:6;;3881:10;3926:47;;2606:18:24;3926:47:6;;;;;;;3734:244;;:::o;19952:351::-;20036:37;20075;20123:14;20139;20158:25;:23;:25::i;:::-;-1:-1:-1;20122:61:6;;-1:-1:-1;20122:61:6;-1:-1:-1;20243:55:6;:17;20269:12;;20122:61;;20243:25;:55::i;:::-;20236:62;;;;;;19952:351;;;;;:::o;8236:1213::-;8293:15;8310;3023:21:19;:19;:21::i;:::-;8375:8:6::1;::::0;8385::::1;::::0;8438:6:::1;::::0;8446::::1;::::0;8479:40:::1;::::0;-1:-1:-1;;;8479:40:6;;8513:4:::1;8479:40;::::0;::::1;2831:74:24::0;-1:-1:-1;;;;;8438:6:6;;::::1;::::0;8446;;::::1;::::0;8334:17:::1;::::0;8438:6;;8479:25:::1;::::0;2804:18:24;;8479:40:6::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8545;::::0;-1:-1:-1;;;8545:40:6;;8579:4:::1;8545:40;::::0;::::1;2831:74:24::0;8459:60:6;;-1:-1:-1;8525:17:6::1;::::0;-1:-1:-1;;;;;8545:25:6;::::1;::::0;::::1;::::0;2804:18:24;;8545:40:6::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8630:4;8591:18;3024::13::0;;;;;;;;;;;2881:12;;8525:60:6;;-1:-1:-1;3024:18:13;2881:12;8774:22:6::1;8787:9:::0;3024:18:13;8774:22:6::1;:::i;:::-;8773:39;;;;:::i;:::-;8763:49:::0;-1:-1:-1;8903:12:6;8877:22:::1;8890:9:::0;8877:10;:22:::1;:::i;:::-;8876:39;;;;:::i;:::-;8866:49:::0;-1:-1:-1;8973:12:6;;;:28:::1;;-1:-1:-1::0;8989:12:6;;8973:28:::1;8969:70;;;9010:29;;;;;;;;;;;;;;8969:70;9045:32;9059:4;9066:10;9045:5;:32::i;:::-;9083:41;-1:-1:-1::0;;;;;9083:28:6;::::1;9112:2:::0;9116:7;9083:28:::1;:41::i;:::-;9130;-1:-1:-1::0;;;;;9130:28:6;::::1;9159:2:::0;9163:7;9130:28:::1;:41::i;:::-;9189:40;::::0;-1:-1:-1;;;9189:40:6;;9223:4:::1;9189:40;::::0;::::1;2831:74:24::0;-1:-1:-1;;;;;9189:25:6;::::1;::::0;::::1;::::0;2804:18:24;;9189:40:6::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;9247;::::0;-1:-1:-1;;;9247:40:6;;9281:4:::1;9247:40;::::0;::::1;2831:74:24::0;9177:52:6;;-1:-1:-1;;;;;;9247:25:6;::::1;::::0;::::1;::::0;2804:18:24;;9247:40:6::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;9235:52;;9294:43;9316:9;9327;9294:21;:43::i;:::-;9344:51;9352:9;9363;9374;9385;9344:7;:51::i;:::-;9406:38;::::0;;4509:25:24;;;4565:2;4550:18;;4543:34;;;-1:-1:-1;;;;;9406:38:6;::::1;::::0;9411:10:::1;::::0;9406:38:::1;::::0;4482:18:24;9406:38:6::1;;;;;;;8327:1122;;;;;;;;3065:20:19::0;2365:1;1505:66;3972:62;3749:292::o;3065:20::-;8236:1213:6;;;:::o;24428:88::-;24476:13;24504:7;24497:14;;;;;:::i;3244:178:13:-;3313:4;735:10:17;3367:27:13;735:10:17;3384:2:13;3388:5;3367:9;:27::i;4863:176:6:-;4954:7;;;;;;;;;-1:-1:-1;;;;;4954:7:6;-1:-1:-1;;;;;4941:31:6;;:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;4927:47:6;:10;-1:-1:-1;;;;;4927:47:6;;4923:87;;4983:27;;;;;;;;;;;;;;4923:87;5016:7;:18;5026:8;;5016:7;:18;:::i;23367:969::-;23460:7;23479:9;23492:1;23479:14;23475:28;;-1:-1:-1;23502:1:6;23495:8;;23475:28;23551:8;;23561;;23606:6;;-1:-1:-1;;;;;23594:18:6;;;23606:6;;23594:18;:42;;23627:9;23594:42;;;23615:9;23594:42;23580:9;:57;23576:93;;23646:23;;;;;;;;;;;;;;23576:93;23676:25;23704:55;23717:9;23728:8;23738:9;23749;23704:12;:55::i;:::-;23676:83;;23928:17;23949:1;23928:22;23924:36;;23959:1;23952:8;;;;;;;23924:36;24028:6;;23968:18;;;;-1:-1:-1;;;;;24016:18:6;;;24028:6;;24016:18;:86;;24072:17;24099:1;24016:86;;;24046:1;24050:17;24016:86;24142:7;;24129:112;;;;;24177:4;24129:112;;;14979:74:24;24184:10:6;15069:18:24;;;15062:83;15161:18;;;15154:34;;;15204:18;;;15197:34;;;15247:19;;;15240:35;;;15291:19;;;15284:35;;;23967:135:6;;-1:-1:-1;23967:135:6;;-1:-1:-1;24108:12:6;;-1:-1:-1;;;;;24142:7:6;;;;24129:39;;14951:19:24;;24129:112:6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;24108:133;-1:-1:-1;24274:57:6;24108:133;24292:21;24312:1;24292:17;:21;:::i;:::-;24315:15;24326:4;1606:6;24315:15;:::i;:::-;24274:11;:57::i;:::-;24254:77;;:17;:77;:::i;:::-;24247:84;23367:969;-1:-1:-1;;;;;;;;;23367:969:6:o;10667:396::-;3023:21:19;:19;:21::i;:::-;10759:6:6::1;::::0;10767::::1;::::0;10842:8:::1;::::0;10799:40:::1;::::0;-1:-1:-1;;;10799:40:6;;10833:4:::1;10799:40;::::0;::::1;2831:74:24::0;-1:-1:-1;;;;;10759:6:6;;::::1;::::0;10767;;::::1;::::0;10722:15:::1;::::0;10842:8;10759:6;;10799:25:::1;::::0;2804:18:24;;10799:40:6::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:51;;;;:::i;:::-;10780:70:::0;-1:-1:-1;10860:12:6;;10856:60:::1;;10874:42;-1:-1:-1::0;;;;;10874:28:6;::::1;10903:2:::0;10907:8;10874:28:::1;:42::i;:::-;10984:8;::::0;10941:40:::1;::::0;-1:-1:-1;;;10941:40:6;;10975:4:::1;10941:40;::::0;::::1;2831:74:24::0;10922:16:6::1;::::0;10984:8;-1:-1:-1;;;;;10941:25:6;::::1;::::0;::::1;::::0;2804:18:24;;10941:40:6::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:51;;;;:::i;:::-;10922:70:::0;-1:-1:-1;11002:12:6;;10998:60:::1;;11016:42;-1:-1:-1::0;;;;;11016:28:6;::::1;11045:2:::0;11049:8;11016:28:::1;:42::i;:::-;10715:348;;;;3065:20:19::0;2365:1;1505:66;3972:62;3749:292::o;3065:20::-;10667:396:6;:::o;4667:168::-;4754:7;;;;;;;;;-1:-1:-1;;;;;4754:7:6;-1:-1:-1;;;;;4741:31:6;;:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;4727:47:6;:10;-1:-1:-1;;;;;4727:47:6;;4723:87;;4783:27;;;;;;;;;;;;;;4723:87;4816:5;:14;4824:6;;4816:5;:14;:::i;4543:96::-;4590:7;3023:21:19;:19;:21::i;:::-;4612:22:6::1;4615:8;;4625;;4612:2;:22::i;:::-;4605:29;;3065:20:19::0;2365:1;1505:66;3972:62;3749:292::o;3065:20::-;4543:96:6;:::o;22244:544::-;22381:8;;22391;;22460:6;;22324:7;;22381:8;22391;22324:7;;;;-1:-1:-1;;;;;22449:17:6;;;22460:6;;22449:17;:67;;22503:1;22507:8;22449:67;;;22470:8;22488:1;22449:67;22606:7;;22593:105;;;;;22634:4;22593:105;;;14979:74:24;22606:7:6;15069:18:24;;;15062:83;15161:18;;;15154:34;;;15204:18;;;15197:34;;;15247:19;;;15240:35;;;15291:19;;;15284:35;;;22406:110:6;;-1:-1:-1;22406:110:6;;-1:-1:-1;1606:6:6;;-1:-1:-1;;;;;22606:7:6;;;;22593:32;;14951:19:24;;22593:105:6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;22574:124;;:8;:124;:::i;:::-;22573:143;;;;:::i;:::-;22561:155;;;;:::i;:::-;;;22729:54;22743:8;22753:7;22762:9;22773;22729:13;:54::i;11091:218::-;3023:21:19;:19;:21::i;:::-;2881:12:13;;11156:1:6::1;11139:18:::0;11135:54:::1;;11166:23;;;;;;;;;;;;;;11135:54;11210:6;::::0;11203:39:::1;::::0;-1:-1:-1;;;11203:39:6;;11236:4:::1;11203:39;::::0;::::1;2831:74:24::0;11195:109:6::1;::::0;-1:-1:-1;;;;;11210:6:6::1;::::0;11203:24:::1;::::0;2804:18:24;;11203:39:6::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;11251:6;::::0;11244:39:::1;::::0;-1:-1:-1;;;11244:39:6;;11277:4:::1;11244:39;::::0;::::1;2831:74:24::0;-1:-1:-1;;;;;11251:6:6;;::::1;::::0;11244:24:::1;::::0;2804:18:24;;11244:39:6::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;11285:8;;11295;;11195:7;:109::i;:::-;3065:20:19::0;2365:1;1505:66;3972:62;3749:292::o;3065:20::-;11091:218:6:o;3749:292:19:-;3872:25;:23;:25::i;:::-;2407:1;1505:66;3972:62;3749:292::o;1219:204:16:-;1306:37;1320:5;1327:2;1331:5;1338:4;1306:13;:37::i;:::-;1301:116;;1366:40;;;;;-1:-1:-1;;;;;2849:55:24;;1366:40:16;;;2831:74:24;2804:18;;1366:40:16;;;;;;;;16669:352:6;16928:7;;16915:101;;;;;16952:4;16915:101;;;14979:74:24;16959:10:6;15069:18:24;;;15062:83;15161:18;;;15154:34;;;15204:18;;;15197:34;;;15247:19;;;15240:35;;;15291:19;;;15284:35;;;16811:12:6;;;;;;-1:-1:-1;;;;;16928:7:6;;16915:28;;14951:19:24;;16915:101:6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;16908:108;;;;;;16669:352;;;;;;;;:::o;13312:402::-;13415:6;13425:1;13415:11;13411:24;;13312:402;:::o;13411:24::-;13468:8;;13447:6;;13440:45;;-1:-1:-1;;;;;13447:6:6;;;;13468:8;13478:6;13440:27;:45::i;:::-;13528:14;13563:13;2881:12:13;;;2803:97;13563:13:6;13546;:6;13555:4;13546:13;:::i;:::-;13545:31;;;;:::i;:::-;13528:48;-1:-1:-1;13629:10:6;;13625:47;;13659:6;13649;;:16;;;;;;;:::i;:::-;;;;-1:-1:-1;;13625:47:6;13682:27;;;4509:25:24;;;13707:1:6;4565:2:24;4550:18;;4543:34;13687:10:6;;13682:27;;4482:18:24;13682:27:6;;;;;;;;13355:359;13312:402;:::o;13751:322::-;13854:6;13864:1;13854:11;13850:24;;13751:322;:::o;13850:24::-;13907:8;;13886:6;;13879:45;;-1:-1:-1;;;;;13886:6:6;;;;13907:8;13917:6;13879:27;:45::i;:::-;13930:14;13965:13;2881:12:13;;;2803:97;13965:13:6;13948;:6;13957:4;13948:13;:::i;:::-;13947:31;;;;:::i;:::-;13930:48;-1:-1:-1;13988:10:6;;13984:47;;14018:6;14008;;:16;;;;;;;:::i;:::-;;;;-1:-1:-1;;13984:47:6;14041:27;;;14058:1;4509:25:24;;4565:2;4550:18;;4543:34;;;14046:10:6;;14041:27;;4482:18:24;14041:27:6;4335:248:24;2189:387:8;2257:7;2272:16;2305:10;;2292:2;2297:4;2292:9;;;;:::i;:::-;2291:24;;;;:::i;:::-;2272:43;;2321:16;2354:10;;2341:2;2346:4;2341:9;;;;:::i;:::-;2340:24;;;;:::i;:::-;2321:43;;2370:10;2383:37;2395:8;2405;2415:4;2383:11;:37::i;:::-;2370:50;;2426:10;2479:37;2491:8;2501;2511:4;2479:11;:37::i;:::-;2439;2451:8;2461;2471:4;2439:11;:37::i;:::-;:77;;;;:::i;:::-;2426:90;;2529:25;2541:2;2545;2549:4;2529:11;:25::i;16000:615:6:-;16191:18;;16131:15;;16106:22;;16174:35;;16131:15;16174:35;:::i;:::-;16152:57;;16233:1;16219:11;:15;:33;;;;-1:-1:-1;16238:14:6;;;16219:33;:51;;;;-1:-1:-1;16256:14:6;;;16219:51;16215:178;;;16306:23;16318:11;16306:9;:23;:::i;:::-;16280:22;;:49;;;;;;;:::i;:::-;;;;-1:-1:-1;16363:23:6;;-1:-1:-1;16375:11:6;16363:9;:23;:::i;:::-;16337:22;;:49;;;;;;;:::i;:::-;;;;-1:-1:-1;;16215:178:6;16423:22;;16447;;16399:84;;:17;;1383:9;16399:23;:84::i;:::-;16490:8;:19;;;16515:8;:19;;;16540:18;:35;;;16586:24;;;4509:25:24;;;4565:2;4550:18;;4543:34;;;16586:24:6;;4482:18:24;16586:24:6;;;;;;;16100:515;;16000:615;;;;:::o;8630:128:13:-;8714:37;8723:5;8730:7;8739:5;8746:4;8714:8;:37::i;585:699:8:-;735:7;750:16;769:24;772:9;783;769:2;:24::i;:::-;832:10;;750:43;;-1:-1:-1;812:16:8;:9;824:4;812:16;:::i;:::-;811:31;;;;:::i;:::-;881:10;;799:43;;-1:-1:-1;861:16:8;:9;873:4;861:16;:::i;:::-;860:31;;;;:::i;:::-;950:6;;848:43;;-1:-1:-1;898:17:8;;;;-1:-1:-1;;;;;938:18:8;;;950:6;;938:18;:68;;985:9;996;938:68;;;960:9;971;938:68;1036:6;;897:109;;-1:-1:-1;897:109:8;-1:-1:-1;;;;;;1024:18:8;;;1036:6;;1024:18;:86;;1100:10;;1080:16;:9;1092:4;1080:16;:::i;:::-;1079:31;;;;:::i;:::-;1024:86;;;1066:10;;1046:16;:9;1058:4;1046:16;:::i;:::-;1045:31;;;;:::i;:::-;1012:98;-1:-1:-1;1116:18:8;1149:49;1155:21;1167:9;1012:98;1155:21;:::i;:::-;1178:8;1188:9;1149:5;:49::i;:::-;1137:61;;:9;:61;:::i;:::-;1238:6;;1116:82;;-1:-1:-1;1275:4:8;;-1:-1:-1;;;;;1226:18:8;;;1238:6;;1226:18;:44;;1260:10;;1226:44;;;1247:10;;1226:44;1212:59;;:10;:59;:::i;:::-;1211:68;;;;:::i;12703:572:6:-;12779:17;12798;12823:20;12834:8;12823:10;:20::i;:::-;-1:-1:-1;;;;;;;12862:20:6;;;;;;:10;:20;;;;;;;;;12900:10;:20;;;;;;;12931:13;;;;:30;;;12960:1;12948:9;:13;12931:30;12927:344;;;-1:-1:-1;;;;;12978:20:6;;;;;;;:10;:20;;;;;;;;12971:27;;;13013:10;:20;;;;;;13006:27;;;;13051:8;;13042:99;;;;;24144:55:24;;;13042:99:6;;;24126:74:24;24216:18;;;24209:34;;;24259:18;;;24252:34;;;13051:8:6;;;13042:31;;24099:18:24;;13042:99:6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;13155:109:6;;;4509:25:24;;;4565:2;4550:18;;4543:34;;;-1:-1:-1;;;;;13155:109:6;;;;-1:-1:-1;13155:109:6;;;-1:-1:-1;13170:10:6;;13155:109;;4482:18:24;13155:109:6;;;;;;;12703:572;;;;;:::o;10321:476:13:-;-1:-1:-1;;;;;3561:18:13;;;10420:24;3561:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;-1:-1:-1;;10486:36:13;;10482:309;;;10561:5;10542:16;:24;10538:130;;;10593:60;;;;;-1:-1:-1;;;;;24144:55:24;;10593:60:13;;;24126:74:24;24216:18;;;24209:34;;;24259:18;;;24252:34;;;24099:18;;10593:60:13;23924:368:24;10538:130:13;10709:57;10718:5;10725:7;10753:5;10734:16;:24;10760:5;10709:8;:57::i;5297:300::-;-1:-1:-1;;;;;5380:18:13;;5376:86;;5421:30;;;;;5448:1;5421:30;;;2831:74:24;2804:18;;5421:30:13;2685:226:24;5376:86:13;-1:-1:-1;;;;;5475:16:13;;5471:86;;5514:32;;;;;5543:1;5514:32;;;2831:74:24;2804:18;;5514:32:13;2685:226:24;5471:86:13;5566:24;5574:4;5580:2;5584:5;5566:7;:24::i;4026:435:5:-;4136:20;;;;4104:6;;4136:20;;;;;;;;4166:17;;;-1:-1:-1;4162:38:5;;4192:8;-1:-1:-1;4185:15:5;;4162:38;4223:8;4206:199;4238:5;4233:10;;:2;:10;;;4206:199;;;4293:1;4259:4;:21;;;;;;;;;;;:::i;:::-;;;;:35;;;;;;;;;;;;;;;-1:-1:-1;4302:4:5;:21;;;;;;;;;;;:::i;:::-;;;;:40;;:44;;;;4397:1;4354:4;:17;;4372:2;4354:21;;;;;;;;;:::i;:::-;;;;:40;;:44;4245:4;;4206:199;;;-1:-1:-1;;;4410:20:5;;;;;:28;;;;;;;;;;;;;4026:435::o;3042:200:8:-;3141:13;3212:8;3227;3176:60;;;;;;;;;:::i;:::-;;;;;;;;;;;;;3162:75;;3042:200;;;;:::o;3269:194::-;3370:13;3433:8;3448;3405:52;;;;;;;;;:::i;20859:5181:22:-;20907:7;21025:1;21020;:6;21016:53;;-1:-1:-1;21053:1:22;20859:5181::o;21016:53::-;22009:1;22037;22064:8;22057:16;;22053:92;;22100:3;22093:10;;;;;22128:2;22121:9;22053:92;22169:7;22162:2;:15;22158:90;;22204:2;22197:9;;;;;22231:2;22224:9;22158:90;22272:7;22265:2;:15;22261:90;;22307:2;22300:9;;;;;22334:2;22327:9;22261:90;22375:7;22368:2;:15;22364:89;;22410:2;22403:9;;;;;22437:1;22430:8;22364:89;22477:6;22470:2;:14;22466:87;;22511:1;22504:8;;;;;22537:1;22530:8;22466:87;22577:6;22570:2;:14;22566:87;;22611:1;22604:8;;;;;22637:1;22630:8;22566:87;22677:6;22670:2;:14;22666:61;;22711:1;22704:8;22666:61;23153:1;:6;23164:1;23152:13;;;;;25063:1;23152:13;25063:6;;;;:::i;:::-;;25058:2;:11;25057:18;;25052:23;;25183:1;25176:2;25172:1;:6;;;;;:::i;:::-;;25167:2;:11;25166:18;;25161:23;;25294:1;25287:2;25283:1;:6;;;;;:::i;:::-;;25278:2;:11;25277:18;;25272:23;;25403:1;25396:2;25392:1;:6;;;;;:::i;:::-;;25387:2;:11;25386:18;;25381:23;;25513:1;25506:2;25502:1;:6;;;;;:::i;:::-;;25497:2;:11;25496:18;;25491:23;;25623:1;25616:2;25612:1;:6;;;;;:::i;:::-;;25607:2;:11;25606:18;;25601:23;;25995:28;26020:2;26016:1;:6;;;;;:::i;:::-;;26011:11;;;34792:145:23;25995:28:22;25990:33;;;20859:5181;-1:-1:-1;;;20859:5181:22:o;7362:208:13:-;-1:-1:-1;;;;;7432:21:13;;7428:91;;7476:32;;;;;7505:1;7476:32;;;2831:74:24;2804:18;;7476:32:13;2685:226:24;7428:91:13;7528:35;7544:1;7548:7;7557:5;7528:7;:35::i;:::-;7362:208;;:::o;2603:259:8:-;2751:10;;2732:15;:8;2743:4;2732:15;:::i;:::-;2731:30;;;;:::i;:::-;2717:10;;2698:15;:8;2709:4;2698:15;:::i;:::-;2697:30;;;;:::i;:::-;:64;2693:95;;2770:18;;;;;;;;;;;;;;2693:95;473:8;2798:22;2801:8;2811;2798:2;:22::i;:::-;:35;2794:63;;2842:15;;;;;;;;;;;;;;5633:111:22;5691:7;5328:5;;;5725;;;5327:36;5322:42;;5717:20;5087:294;8875:672:5;9063:37;;9169:15;9209:12;;9257:22;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;9257:22:5;;9234:45;;9322:7;9308:22;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;9308:22:5;;9285:45;;9341:10;9336:207;9358:7;9353:2;:12;9336:207;;;9444:92;9458:4;9464:5;9471:12;;9484:2;9471:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;9489:22;9513;9444:13;:92::i;:::-;9382:20;9403:2;9382:24;;;;;;;;:::i;:::-;;;;;;9408:20;9429:2;9408:24;;;;;;;;:::i;:::-;;;;;;;;;;9381:155;;;;;9367:4;;9336:207;;;;9141:406;;8875:672;;;;;;;;:::o;7888:206:13:-;-1:-1:-1;;;;;7958:21:13;;7954:89;;8002:30;;;;;8029:1;8002:30;;;2831:74:24;2804:18;;8002:30:13;2685:226:24;7954:89:13;8052:35;8060:7;8077:1;8081:5;8052:7;:35::i;2889:126:8:-;2977:10;2980:2;2984;2977;:10::i;:::-;2991:1;2977:15;2973:37;;3001:9;;;;;;;;;;;;;;1311:851;1462:7;1477:16;1496:24;1499:9;1510;1496:2;:24::i;:::-;1559:10;;1477:43;;-1:-1:-1;1539:16:8;:9;1551:4;1539:16;:::i;:::-;1538:31;;;;:::i;:::-;1608:10;;1526:43;;-1:-1:-1;1588:16:8;:9;1600:4;1588:16;:::i;:::-;1587:31;;;;:::i;:::-;1681:6;;1575:43;;-1:-1:-1;1625:19:8;;;;-1:-1:-1;;;;;1668:19:8;;;1681:6;;1668:19;:69;;1716:9;1727;1668:69;;;1691:9;1702;1668:69;1808:6;;1624:113;;-1:-1:-1;1624:113:8;-1:-1:-1;1744:20:8;;;;-1:-1:-1;;;;;1795:19:8;;;1808:6;;1795:19;:73;;1845:10;;1857;;1795:73;;;1818:10;;1830;;1795:73;1743:125;;-1:-1:-1;1743:125:8;-1:-1:-1;1887:45:8;1900:17;:10;1913:4;1900:17;:::i;:::-;1919:12;1887;:45::i;:::-;1874:58;;1956:11;1942:10;:25;1938:61;;1976:23;;;;;;;;;;;;;;1938:61;2005:21;2029:53;2035:24;2049:10;2035:11;:24;:::i;:::-;2061:8;2071:10;2029:5;:53::i;:::-;2005:77;-1:-1:-1;2095:62:8;2139:11;2109:26;2125:10;2005:77;2109:26;:::i;:::-;2108:42;;;;:::i;:::-;2152:4;2095:12;:62::i;:::-;2088:69;1311:851;-1:-1:-1;;;;;;;;;;;1311:851:8:o;7296:3683:22:-;7378:14;7429:12;7443:11;7458:12;7465:1;7468;7458:6;:12::i;:::-;7428:42;;;;7552:4;7560:1;7552:9;7548:365;;7887:11;7881:3;:17;;;;;:::i;:::-;;7874:24;;;;;;7548:365;8038:4;8023:11;:19;8019:142;;8062:84;5328:5;8082:16;;5327:36;940:4:18;5322:42:22;8062:11;:84::i;:::-;8413:17;8564:11;8561:1;8558;8551:25;8956:12;8986:15;;;8971:31;;9121:22;;;;;9854:1;9835;:15;;9834:21;;10087;;;10083:25;;10072:36;10157:21;;;10153:25;;10142:36;10229:21;;;10225:25;;10214:36;10300:21;;;10296:25;;10285:36;10373:21;;;10369:25;;10358:36;10447:21;;;10443:25;;;10432:36;9363:12;;;;9359:23;;;9384:1;9355:31;8676:18;;;8666:29;;;9470:11;;;;8719:19;;;;9214:14;;;;9463:18;;;;10922:13;;-1:-1:-1;;7296:3683:22;;;;;:::o;3586:157:19:-;3648:25;4537:4;2407:1;1505:66;4560:46;4543:96:6;3648:25:19;3644:93;;;3696:30;;;;;;;;;;;;;;8373:1244:16;8600:4;8594:11;8509:24;8467:12;8618:22;;;-1:-1:-1;;;;;8666:24:16;;8660:4;8653:38;8711:4;8704:19;;;8467:12;8787:4;8467:12;8775:4;8467:12;;8759:5;8752;8747:45;8736:56;;9004:1;8997:4;8991:11;8988:18;8979:7;8975:32;8965:606;;9136:6;9126:7;9119:15;9115:28;9112:165;;;9192:16;9186:4;9181:3;9166:43;9242:16;9237:3;9230:29;9112:165;9553:1;9545:5;9533:18;9530:25;9511:16;9504:24;9500:56;9491:7;9487:70;9476:81;;8965:606;9591:4;9584:17;-1:-1:-1;8373:1244:16;;-1:-1:-1;;;;8373:1244:16:o;2546:1153:5:-;2785:10;;;;2747:15;;2785:10;;;;;2715:22;;2785:4;;:10;;2878:25;;;;;;:::i;:::-;;;;:35;;;;;2860:53;;2845:68;;-1:-1:-1;2929:27:5;;;2925:40;;2958:7;;;;;2925:40;2992:16;;;;;;;;;;;;;3227:20;;;;;:35;-1:-1:-1;3227:65:5;;;;-1:-1:-1;3276:16:5;3291:1;3276:12;:16;:::i;:::-;3266:26;;:6;:26;;;3227:65;3223:120;;;3320:16;:12;3335:1;3320:16;:::i;:::-;3302:34;;3223:120;3348:16;3382:15;3368:10;:6;3377:1;3368:10;:::i;:::-;3367:30;;;;:::i;:::-;3348:49;;3434:155;;;;;;;;3465:15;3434:155;;;;;;3508:23;3434:155;;;;3559:23;3434:155;;;3403:4;:17;;3421:9;3403:28;;;;;;;;;:::i;:::-;:186;;:28;;;;;;;;;:186;;;;;;;;;;;;;;;;;;-1:-1:-1;3403:186:5;;;;;;;;;;;;;3595:10;;;:22;;;;;;;;;;;;;;;3627:31;;;;;;;3623:71;;3660:16;;;:34;;;;;;;;;;;;3623:71;2709:990;;;;;;2546:1153;;;;:::o;9607:432:13:-;-1:-1:-1;;;;;9719:19:13;;9715:89;;9761:32;;;;;9790:1;9761:32;;;2831:74:24;2804:18;;9761:32:13;2685:226:24;9715:89:13;-1:-1:-1;;;;;9817:21:13;;9813:90;;9861:31;;;;;9889:1;9861:31;;;2831:74:24;2804:18;;9861:31:13;2685:226:24;9813:90:13;-1:-1:-1;;;;;9912:18:13;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;:35;;;9957:76;;;;10007:7;-1:-1:-1;;;;;9991:31:13;10000:5;-1:-1:-1;;;;;9991:31:13;;10016:5;9991:31;;;;3434:25:24;;3422:2;3407:18;;3288:177;9991:31:13;;;;;;;;9607:432;;;;:::o;4072:1462:8:-;4152:7;;4167:1332;4193:3;4188:2;:8;4167:1332;;;4212:17;4232:11;4235:3;4240:2;4232;:11::i;:::-;4212:31;;4267:8;4255:9;:20;4251:1242;;;4458:11;4472:52;4484:20;4495:9;4484:8;:20;:::i;:::-;4506:4;4512:11;4515:3;4520:2;4512;:11::i;4472:52::-;4458:66;;4538:3;4545:1;4538:8;4534:265;;4582:8;4564:15;4567:3;4572:6;:2;4577:1;4572:6;:::i;:::-;4564:2;:15::i;:::-;:26;4560:210;;;4751:6;:2;4756:1;4751:6;:::i;:::-;4744:13;;;;;;;4560:210;-1:-1:-1;4787:1:8;4534:265;4813:8;4818:3;4813:2;:8;:::i;:::-;4808:13;;4277:553;4251:1242;;;4846:11;4860:52;4872:20;4884:8;4872:9;:20;:::i;4860:52::-;4846:66;;4926:3;4933:1;4926:8;4922:540;;4965:8;4952:9;:21;:51;;;-1:-1:-1;4995:8:8;4977:15;4980:3;4985:6;4990:1;4985:2;:6;:::i;4977:15::-;:26;4952:51;4948:485;;;5418:2;5411:9;;;;;;;4948:485;-1:-1:-1;5450:1:8;4922:540;5476:8;5481:3;5476:2;:8;:::i;:::-;5471:13;;4836:657;4251:1242;-1:-1:-1;4198:4:8;;4167:1332;;;;5511:18;;;;;;;;;;;;;;14277:1160:6;-1:-1:-1;;;;;3024:18:13;;14331:17:6;3024:18:13;;;;;;;;;;;14414:13:6;;14410:1023;;-1:-1:-1;;;;;14461:23:6;;14437:21;14461:23;;;:12;:23;;;;;;;;;;14558:12;:23;;;;;;;;14607:6;;14681;;14695:33;;;;14787:23;;;;:33;;;14461:23;14846;14461;14607:6;14846:23;:::i;:::-;14828:41;-1:-1:-1;14935:15:6;14953:23;14963:13;14953:7;:23;:::i;:::-;14935:41;-1:-1:-1;14988:11:6;;14984:172;;15011:14;15052:4;15029:19;15041:7;15029:9;:19;:::i;:::-;15028:28;;;;:::i;:::-;-1:-1:-1;;;;;15116:21:6;;;;;;:10;:21;;;;;:31;;15011:45;;-1:-1:-1;15011:45:6;;15116:21;;;:31;;15011:45;;15116:31;:::i;:::-;;;;-1:-1:-1;;;14984:172:6;15167:11;;15163:122;;15190:14;15231:4;15208:19;15220:7;15208:9;:19;:::i;:::-;15207:28;;;;:::i;:::-;-1:-1:-1;;;;;15245:21:6;;;;;;:10;:21;;;;;:31;;15190:45;;-1:-1:-1;15190:45:6;;15245:21;;;:31;;15190:45;;15245:31;:::i;:::-;;;;-1:-1:-1;;;15163:122:6;14429:862;;;;;;7362:208:13;;:::o;14410:1023:6:-;15331:6;;-1:-1:-1;;;;;15305:23:6;;;;;;:12;:23;;;;;;;;:32;;;;15420:6;;15394:12;:23;;;;;;:32;14325:1112;14277:1160;:::o;18752:207::-;-1:-1:-1;;;;;18839:18:6;;;18835:40;;18859:16;18870:4;18859:10;:16::i;:::-;-1:-1:-1;;;;;18885:16:6;;;18881:36;;18903:14;18914:2;18903:10;:14::i;:::-;18923:31;18937:4;18943:2;18947:6;18923:13;:31::i;7340:921:5:-;7540:27;7569;7608:11;:16;;7623:1;7608:16;7604:92;;-1:-1:-1;7642:22:5;;-1:-1:-1;7666:22:5;7634:55;;7604:92;7749:19;;;7701:14;;7852:97;7880:4;7749:5;:19;7902:22;7926;7852:27;:97::i;:::-;7780:169;;;;7983:7;7959:31;;:10;:20;;;:31;;;7955:121;;8008:10;:29;;;8039:10;:29;;;8000:69;;;;;;;;;7955:121;8126:130;8146:11;8159:10;:20;;;8181:10;:29;;;8212:10;:29;;;8243:7;8126:12;:130::i;:::-;8081:175;;-1:-1:-1;8081:175:5;-1:-1:-1;;;;7340:921:5;;;;;;;;;:::o;6269:704:22:-;6331:7;6354:1;6359;6354:6;6350:150;;6454:35;1035:4:18;6454:11:22;:35::i;:::-;6950:1;6945;6941;:5;6940:11;;;;;:::i;:::-;;6954:1;6940:15;6930:5;;;6914:22;:42;;6269:704;-1:-1:-1;;;6269:704:22:o;1027:550::-;1088:12;;-1:-1:-1;;1471:1:22;1468;1461:20;1501:9;;;;1549:11;;;1535:12;;;;1531:30;;;;;1027:550;-1:-1:-1;;1027:550:22:o;1776:194:18:-;1881:10;1875:4;1868:24;1918:4;1912;1905:18;1949:4;1943;1936:18;4560:46:19;:52;:63;;4479:151;-1:-1:-1;4479:151:19:o;3467:230:8:-;3526:7;3541:10;3554:26;3566:3;3571:2;3575:4;3554:11;:26::i;:::-;3541:39;;3586:10;3629:25;3641:2;3645;3649:4;3629:11;:25::i;:::-;3599:27;3611:3;3616;3621:4;3599:11;:27::i;:::-;:55;;;;:::i;:::-;3586:68;;3667:25;3679:2;3683;3687:4;3667:11;:25::i;:::-;3660:32;3467:230;-1:-1:-1;;;;;3467:230:8:o;3701:284::-;3760:7;3775:17;3795:25;3807:2;3811;3815:4;3795:11;:25::i;:::-;3775:45;;3826:18;3847:27;3859:3;3864;3869:4;3847:11;:27::i;:::-;3826:48;;3927:34;3939:10;3951:3;3956:4;3927:11;:34::i;:::-;3887:37;3899:7;3903:3;3899:1;:7;:::i;:::-;3908:9;3919:4;3887:11;:37::i;:::-;:74;;;;:::i;5912:1107:13:-;-1:-1:-1;;;;;6001:18:13;;5997:540;;6153:5;6137:12;;:21;;;;;;;:::i;:::-;;;;-1:-1:-1;5997:540:13;;-1:-1:-1;5997:540:13;;-1:-1:-1;;;;;6211:15:13;;6189:19;6211:15;;;;;;;;;;;6244:19;;;6240:115;;;6290:50;;;;;-1:-1:-1;;;;;24144:55:24;;6290:50:13;;;24126:74:24;24216:18;;;24209:34;;;24259:18;;;24252:34;;;24099:18;;6290:50:13;23924:368:24;6240:115:13;-1:-1:-1;;;;;6475:15:13;;:9;:15;;;;;;;;;;6493:19;;;;6475:37;;5997:540;-1:-1:-1;;;;;6551:16:13;;6547:425;;6714:12;:21;;;;;;;6547:425;;;-1:-1:-1;;;;;6925:13:13;;:9;:13;;;;;;;;;;:22;;;;;;6547:425;7002:2;-1:-1:-1;;;;;6987:25:13;6996:4;-1:-1:-1;;;;;6987:25:13;;7006:5;6987:25;;;;3434::24;;3422:2;3407:18;;3288:177;6987:25:13;;;;;;;;5912:1107;;;:::o;5242:1164:5:-;5452:30;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;5452:30:5;5484:29;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;5484:29:5;5537:10;;;;;;;;;:4;;:10;;5567:25;;;;;;:::i;:::-;5553:39;;;;;;;;5567:25;;;;;;;;;5553:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;5620:43:5;;5625:5;;5655:7;5620:4;:43::i;:::-;5616:569;;;5777:21;;:32;;;;;;;5773:71;;-1:-1:-1;5819:11:5;;-1:-1:-1;5811:33:5;;5773:71;5853:23;5878;5913:89;5926:11;5939:5;5946:22;5970;5994:7;5913:12;:89::i;:::-;6031:107;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;6146:32:5;;-1:-1:-1;;;6146:32:5;5616:569;6237:16;;;;;;;;;;;6223:10;:6;6232:1;6223:10;:::i;:::-;6222:31;;;;:::i;:::-;6204:50;;;;;;;;;:::i;:::-;6190:64;;;;;;;;6204:50;;;;;;;;;6190:64;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;6285:43:5;;6290:5;;6320:7;6285:4;:43::i;:::-;6280:73;;6337:16;;;;;;;;;;;;;;6280:73;6366:35;6380:4;6386:5;6393:7;6366:13;:35::i;:::-;6359:42;;;;;5242:1164;;;;;;;;:::o;11215:992::-;11633:21;;11794:30;;;;11424:27;;;;11607:48;11615:39;;;11607:48;;;11698:31;;11690:40;;11424:27;;11767:57;;:24;:57;:::i;:::-;11742:82;;11830:22;11882:11;:30;;;11855:24;:57;;;;:::i;:::-;11830:82;;11979:78;11991:14;12007:24;12033:23;11979:11;:78::i;:::-;11946:11;:30;;;:111;;;;:::i;:::-;11918:139;;12124:78;12136:14;12152:24;12178:23;12124:11;:78::i;:::-;12091:11;:30;;;:111;;;;:::i;:::-;12063:139;;11482:725;;;;11215:992;;;;;;;;:::o;9843:290::-;9916:4;9938:5;9932:11;;:2;:11;;;;:26;;;;;9953:5;9947:11;;:2;:11;;;;9932:26;9928:47;;;9973:2;9967:8;;:2;:8;;;;9960:15;;;;9928:47;9982:18;10008:5;10003:10;;:2;:10;;;:30;;10021:12;;;;10026:7;10021:12;:::i;:::-;10003:30;;;10016:2;10003:30;;;9982:51;;;;10039:18;10065:5;10060:10;;:2;:10;;;:30;;10078:12;;;;10083:7;10078:12;:::i;:::-;10060:30;;;10073:2;10060:30;;;10039:51;;10104:24;;;;;9843:290;-1:-1:-1;;;;;9843:290:5:o;12551:963::-;12674:30;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;12674:30:5;12706:29;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;12706:29:5;12765:16;;;;;;;;;;;:4;;12743:19;;12765:16;;12893:10;;12885:23;12765:16;12884:40;;;;:::i;:::-;;;-1:-1:-1;;;12970:17:5;;;;;:21;13022:482;13070:1;13059:7;;;13058:13;13095:12;13108:17;;;13058:13;13108:17;;;;;:::i;:::-;;13095:31;;;;;;;:::i;:::-;13081:45;;;;;;;;13095:31;;;;;;;;;13081:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;13149:12:5;;13162:23;;;;13163:6;;13162:23;;;;;:::i;:::-;;13149:37;;;;;;;:::i;:::-;13136:50;;;;;;;;13149:37;;;;;;;;;13136:50;;;;;;;;;;;;;;;;;;;;;;;;13238:21;;13136:50;;-1:-1:-1;;;13226:43:5;;13231:5;;13261:7;13226:4;:43::i;:::-;13196:73;;13279:27;13309:42;13314:5;13321:7;13330:10;:20;;;13309:4;:42::i;:::-;13279:72;;13365:22;:48;;;;;13391:22;13365:48;13361:59;;;13415:5;;;;;13361:59;13434:22;13430:65;;;13463:2;13468:1;13463:6;13458:11;;13430:65;;;13494:1;13489:2;:6;13484:11;;13430:65;13035:469;;;13022:482;;;12853:657;;12737:777;;12551:963;;;;;;:::o;-1:-1:-1:-;;;;;;;;:::o;14:154:24:-;-1:-1:-1;;;;;93:5:24;89:54;82:5;79:65;69:93;;158:1;155;148:12;173:347;224:8;234:6;288:3;281:4;273:6;269:17;265:27;255:55;;306:1;303;296:12;255:55;-1:-1:-1;329:20:24;;372:18;361:30;;358:50;;;404:1;401;394:12;358:50;441:4;433:6;429:17;417:29;;493:3;486:4;477:6;469;465:19;461:30;458:39;455:59;;;510:1;507;500:12;525:785;622:6;630;638;646;654;707:3;695:9;686:7;682:23;678:33;675:53;;;724:1;721;714:12;675:53;769:23;;;-1:-1:-1;889:2:24;874:18;;861:32;;-1:-1:-1;971:2:24;956:18;;943:32;984:33;943:32;984:33;:::i;:::-;1036:7;-1:-1:-1;1094:2:24;1079:18;;1066:32;1121:18;1110:30;;1107:50;;;1153:1;1150;1143:12;1107:50;1192:58;1242:7;1233:6;1222:9;1218:22;1192:58;:::i;:::-;525:785;;;;-1:-1:-1;525:785:24;;-1:-1:-1;1269:8:24;;1166:84;525:785;-1:-1:-1;;;525:785:24:o;1315:477::-;1464:2;1453:9;1446:21;1427:4;1496:6;1490:13;1539:6;1534:2;1523:9;1519:18;1512:34;1598:6;1593:2;1585:6;1581:15;1576:2;1565:9;1561:18;1555:50;1654:1;1649:2;1640:6;1629:9;1625:22;1621:31;1614:42;1783:2;-1:-1:-1;;1708:2:24;1700:6;1696:15;1692:88;1681:9;1677:104;1673:113;1665:121;;;1315:477;;;;:::o;2121:367::-;2189:6;2197;2250:2;2238:9;2229:7;2225:23;2221:32;2218:52;;;2266:1;2263;2256:12;2218:52;2305:9;2292:23;2324:31;2349:5;2324:31;:::i;:::-;2374:5;2452:2;2437:18;;;;2424:32;;-1:-1:-1;;;2121:367:24:o;2916:::-;2984:6;2992;3045:2;3033:9;3024:7;3020:23;3016:32;3013:52;;;3061:1;3058;3051:12;3013:52;3106:23;;;-1:-1:-1;3205:2:24;3190:18;;3177:32;3218:33;3177:32;3218:33;:::i;:::-;3270:7;3260:17;;;2916:367;;;;;:::o;3470:608::-;3556:6;3564;3572;3580;3633:3;3621:9;3612:7;3608:23;3604:33;3601:53;;;3650:1;3647;3640:12;3601:53;3695:23;;;-1:-1:-1;3794:2:24;3779:18;;3766:32;3807:33;3766:32;3807:33;:::i;:::-;3470:608;;3859:7;;-1:-1:-1;;;;3939:2:24;3924:18;;3911:32;;4042:2;4027:18;4014:32;;3470:608::o;4083:247::-;4142:6;4195:2;4183:9;4174:7;4170:23;4166:32;4163:52;;;4211:1;4208;4201:12;4163:52;4250:9;4237:23;4269:31;4294:5;4269:31;:::i;4945:508::-;5022:6;5030;5038;5091:2;5079:9;5070:7;5066:23;5062:32;5059:52;;;5107:1;5104;5097:12;5059:52;5146:9;5133:23;5165:31;5190:5;5165:31;:::i;:::-;5215:5;-1:-1:-1;5272:2:24;5257:18;;5244:32;5285:33;5244:32;5285:33;:::i;:::-;4945:508;;5337:7;;-1:-1:-1;;;5417:2:24;5402:18;;;;5389:32;;4945:508::o;5458:226::-;5517:6;5570:2;5558:9;5549:7;5545:23;5541:32;5538:52;;;5586:1;5583;5576:12;5538:52;-1:-1:-1;5631:23:24;;5458:226;-1:-1:-1;5458:226:24:o;6028:388::-;6096:6;6104;6157:2;6145:9;6136:7;6132:23;6128:32;6125:52;;;6173:1;6170;6163:12;6125:52;6212:9;6199:23;6231:31;6256:5;6231:31;:::i;:::-;6281:5;-1:-1:-1;6338:2:24;6323:18;;6310:32;6351:33;6310:32;6351:33;:::i;6610:272::-;6668:6;6721:2;6709:9;6700:7;6696:23;6692:32;6689:52;;;6737:1;6734;6727:12;6689:52;6776:9;6763:23;6826:6;6819:5;6815:18;6808:5;6805:29;6795:57;;6848:1;6845;6838:12;7707:118;7793:5;7786:13;7779:21;7772:5;7769:32;7759:60;;7815:1;7812;7805:12;7830:382;7895:6;7903;7956:2;7944:9;7935:7;7931:23;7927:32;7924:52;;;7972:1;7969;7962:12;7924:52;8011:9;7998:23;8030:31;8055:5;8030:31;:::i;:::-;8080:5;-1:-1:-1;8137:2:24;8122:18;;8109:32;8150:30;8109:32;8150:30;:::i;8217:609::-;8302:6;8310;8363:2;8351:9;8342:7;8338:23;8334:32;8331:52;;;8379:1;8376;8369:12;8331:52;8419:9;8406:23;8452:18;8444:6;8441:30;8438:50;;;8484:1;8481;8474:12;8438:50;8507:22;;8560:4;8552:13;;8548:27;-1:-1:-1;8538:55:24;;8589:1;8586;8579:12;8538:55;8629:2;8616:16;8655:18;8647:6;8644:30;8641:50;;;8687:1;8684;8677:12;8641:50;8740:7;8735:2;8725:6;8722:1;8718:14;8714:2;8710:23;8706:32;8703:45;8700:65;;;8761:1;8758;8751:12;8700:65;8792:2;8784:11;;;;;8814:6;;-1:-1:-1;8217:609:24;-1:-1:-1;;;8217:609:24:o;8831:420::-;8884:3;8922:5;8916:12;8949:6;8944:3;8937:19;8981:4;8976:3;8972:14;8965:21;;9020:4;9013:5;9009:16;9043:1;9053:173;9067:6;9064:1;9061:13;9053:173;;;9128:13;;9116:26;;9171:4;9162:14;;;;9199:17;;;;9089:1;9082:9;9053:173;;;-1:-1:-1;9242:3:24;;8831:420;-1:-1:-1;;;;8831:420:24:o;9256:465::-;9513:2;9502:9;9495:21;9476:4;9539:56;9591:2;9580:9;9576:18;9568:6;9539:56;:::i;:::-;9643:9;9635:6;9631:22;9626:2;9615:9;9611:18;9604:50;9671:44;9708:6;9700;9671:44;:::i;10077:410::-;10148:6;10156;10209:2;10197:9;10188:7;10184:23;10180:32;10177:52;;;10225:1;10222;10215:12;10177:52;10265:9;10252:23;10298:18;10290:6;10287:30;10284:50;;;10330:1;10327;10320:12;10284:50;10369:58;10419:7;10410:6;10399:9;10395:22;10369:58;:::i;:::-;10446:8;;10343:84;;-1:-1:-1;10077:410:24;-1:-1:-1;;;;10077:410:24:o;10492:245::-;10559:6;10612:2;10600:9;10591:7;10587:23;10583:32;10580:52;;;10628:1;10625;10618:12;10580:52;10660:9;10654:16;10679:28;10701:5;10679:28;:::i;10742:714::-;-1:-1:-1;;;;;10987:6:24;10983:55;10972:9;10965:74;11075:6;11070:2;11059:9;11055:18;11048:34;11118:6;11113:2;11102:9;11098:18;11091:34;11161:3;11156:2;11145:9;11141:18;11134:31;11202:6;11196:3;11185:9;11181:19;11174:35;11260:6;11252;11246:3;11235:9;11231:19;11218:49;11317:1;11287:22;;;11311:3;11283:32;;;11276:43;;;;11371:2;11359:15;;;-1:-1:-1;;11355:88:24;11340:104;11336:114;;10742:714;-1:-1:-1;;;;10742:714:24:o;11461:230::-;11531:6;11584:2;11572:9;11563:7;11559:23;11555:32;11552:52;;;11600:1;11597;11590:12;11552:52;-1:-1:-1;11645:16:24;;11461:230;-1:-1:-1;11461:230:24:o;11696:184::-;11748:77;11745:1;11738:88;11845:4;11842:1;11835:15;11869:4;11866:1;11859:15;11885:128;11952:9;;;11973:11;;;11970:37;;;11987:18;;:::i;12018:125::-;12083:9;;;12104:10;;;12101:36;;;12117:18;;:::i;12148:168::-;12221:9;;;12252;;12269:15;;;12263:22;;12249:37;12239:71;;12290:18;;:::i;12321:184::-;12373:77;12370:1;12363:88;12470:4;12467:1;12460:15;12494:4;12491:1;12484:15;12510:120;12550:1;12576;12566:35;;12581:18;;:::i;:::-;-1:-1:-1;12615:9:24;;12510:120::o;12759:1090::-;12911:4;12953:3;12942:9;12938:19;12930:27;;13003:34;12994:6;12988:13;12984:54;12973:9;12966:73;13107:34;13099:4;13091:6;13087:17;13081:24;13077:65;13070:4;13059:9;13055:20;13048:95;13211:34;13203:4;13195:6;13191:17;13185:24;13181:65;13174:4;13163:9;13159:20;13152:95;13294:4;13286:6;13282:17;13276:24;13309:54;13357:4;13346:9;13342:20;13328:12;12712:34;12701:46;12689:59;;12635:119;13309:54;;13412:4;13404:6;13400:17;13394:24;13427:56;13477:4;13466:9;13462:20;13446:14;12712:34;12701:46;12689:59;;12635:119;13427:56;;13532:4;13524:6;13520:17;13514:24;13547:56;13597:4;13586:9;13582:20;13566:14;12712:34;12701:46;12689:59;;12635:119;13547:56;;13652:4;13644:6;13640:17;13634:24;13667:56;13717:4;13706:9;13702:20;13686:14;12712:34;12701:46;12689:59;;12635:119;13667:56;;13772:4;13764:6;13760:17;13754:24;13787:56;13837:4;13826:9;13822:20;13806:14;12712:34;12701:46;12689:59;;12635:119;13787:56;;12759:1090;;;;:::o;14250:437::-;14329:1;14325:12;;;;14372;;;14393:61;;14447:4;14439:6;14435:17;14425:27;;14393:61;14500:2;14492:6;14489:14;14469:18;14466:38;14463:218;;14537:77;14534:1;14527:88;14638:4;14635:1;14628:15;14666:4;14663:1;14656:15;14463:218;;14250:437;;;:::o;15330:184::-;15382:77;15379:1;15372:88;15479:4;15476:1;15469:15;15503:4;15500:1;15493:15;15794:184;15846:77;15843:1;15836:88;15943:4;15940:1;15933:15;15967:4;15964:1;15957:15;15983:1053;16063:6;16116:2;16104:9;16095:7;16091:23;16087:32;16084:52;;;16132:1;16129;16122:12;16084:52;16165:9;16159:16;16198:18;16190:6;16187:30;16184:50;;;16230:1;16227;16220:12;16184:50;16253:22;;16306:4;16298:13;;16294:27;-1:-1:-1;16284:55:24;;16335:1;16332;16325:12;16284:55;16368:2;16362:9;16394:18;16386:6;16383:30;16380:56;;;16416:18;;:::i;:::-;16465:2;16459:9;-1:-1:-1;;16607:2:24;-1:-1:-1;;16531:4:24;16523:6;16519:17;16515:90;16511:99;16507:172;16499:6;16495:185;16746:6;16734:10;16731:22;16710:18;16698:10;16695:34;16692:62;16689:88;;;16757:18;;:::i;:::-;16793:2;16786:22;16817;;;16858:15;;;16875:2;16854:24;16851:37;-1:-1:-1;16848:57:24;;;16901:1;16898;16891:12;16848:57;16950:6;16945:2;16941;16937:11;16932:2;16924:6;16920:15;16914:43;17003:1;16977:19;;;16998:2;16973:28;16966:39;;;;16981:6;15983:1053;-1:-1:-1;;;;15983:1053:24:o;17167:692::-;17269:2;17264:3;17261:11;17258:595;;;17306:10;17301:3;17298:19;17295:548;;;17358:5;17355:1;17348:16;17406:4;17403:1;17393:18;17471:2;17459:10;17455:19;17452:1;17448:27;17510:4;17498:10;17495:20;17492:45;;;-1:-1:-1;17534:1:24;17492:45;17573:23;;;;17643:2;17634:12;;17631:1;17627:20;17623:39;17688:1;17706:123;17720:2;17717:1;17714:9;17706:123;;;17809:1;17788:19;;;17781:30;17738:1;17731:9;17706:123;;;17710:3;;;17167:692;;;:::o;18095:1418::-;18221:3;18215:10;18248:18;18240:6;18237:30;18234:56;;;18270:18;;:::i;:::-;18299:97;18389:6;18349:38;18381:4;18375:11;18349:38;:::i;:::-;18343:4;18299:97;:::i;:::-;18445:4;18476:2;18465:14;;18493:1;18488:768;;;;19300:1;19317:6;19314:89;;;-1:-1:-1;19369:19:24;;;19363:26;19314:89;-1:-1:-1;;17992:1:24;17988:11;;;17984:84;17980:89;17970:100;18076:1;18072:11;;;17967:117;19416:81;;18458:1049;;18488:768;17114:1;17107:14;;;17151:4;17138:18;;-1:-1:-1;;18524:79:24;;;18701:222;18715:7;18712:1;18709:14;18701:222;;;18797:19;;;18791:26;18776:42;;18904:4;18889:20;;;;18857:1;18845:14;;;;18731:12;18701:222;;;18705:3;18951:6;18942:7;18939:19;18936:261;;;19012:19;;;19006:26;-1:-1:-1;;19095:1:24;19091:14;;;19107:3;19087:24;19083:97;19079:102;19064:118;19049:134;;18936:261;-1:-1:-1;;;;19243:1:24;19227:14;;;19223:22;19210:36;;-1:-1:-1;18095:1418:24:o;19518:273::-;19586:6;19639:2;19627:9;19618:7;19614:23;19610:32;19607:52;;;19655:1;19652;19645:12;19607:52;19687:9;19681:16;19737:4;19730:5;19726:16;19719:5;19716:27;19706:55;;19757:1;19754;19747:12;19796:375;19884:1;19902:5;19916:249;19937:1;19927:8;19924:15;19916:249;;;19987:4;19982:3;19978:14;19972:4;19969:24;19966:50;;;19996:18;;:::i;:::-;20046:1;20036:8;20032:16;20029:49;;;20060:16;;;;20029:49;20143:1;20139:16;;;;;20099:15;;19916:249;;;19796:375;;;;;;:::o;20176:1022::-;20225:5;20255:8;20245:80;;-1:-1:-1;20296:1:24;20310:5;;20245:80;20344:4;20334:76;;-1:-1:-1;20381:1:24;20395:5;;20334:76;20426:4;20444:1;20439:59;;;;20512:1;20507:174;;;;20419:262;;20439:59;20469:1;20460:10;;20483:5;;;20507:174;20544:3;20534:8;20531:17;20528:43;;;20551:18;;:::i;:::-;-1:-1:-1;;20607:1:24;20593:16;;20666:5;;20419:262;;20765:2;20755:8;20752:16;20746:3;20740:4;20737:13;20733:36;20727:2;20717:8;20714:16;20709:2;20703:4;20700:12;20696:35;20693:77;20690:203;;;-1:-1:-1;20802:19:24;;;20878:5;;20690:203;20925:102;-1:-1:-1;;20950:8:24;20944:4;20925:102;:::i;:::-;21123:6;-1:-1:-1;;21051:79:24;21042:7;21039:92;21036:118;;;21134:18;;:::i;21203:140::-;21261:5;21290:47;21331:4;21321:8;21317:19;21311:4;21290:47;:::i;21348:251::-;21418:6;21471:2;21459:9;21450:7;21446:23;21442:32;21439:52;;;21487:1;21484;21477:12;21439:52;21519:9;21513:16;21538:31;21563:5;21538:31;:::i;21604:1317::-;21728:18;21723:3;21720:27;21717:53;;;21750:18;;:::i;:::-;21779:94;21869:3;21829:38;21861:4;21855:11;21829:38;:::i;:::-;21823:4;21779:94;:::i;:::-;21899:1;21924:2;21919:3;21916:11;21941:1;21936:727;;;;22707:1;22724:3;22721:93;;;-1:-1:-1;22780:19:24;;;22767:33;22721:93;-1:-1:-1;;17992:1:24;17988:11;;;17984:84;17980:89;17970:100;18076:1;18072:11;;;17967:117;22827:78;;21909:1006;;21936:727;17114:1;17107:14;;;17151:4;17138:18;;-1:-1:-1;;21972:76:24;;;22146:229;22160:7;22157:1;22154:14;22146:229;;;22249:19;;;22236:33;22221:49;;22356:4;22341:20;;;;22309:1;22297:14;;;;22176:12;22146:229;;;22150:3;22403;22394:7;22391:16;22388:219;;;-1:-1:-1;;22517:3:24;22511;22508:1;22504:11;22500:21;22496:94;22492:99;22479:9;22474:3;22470:19;22457:33;22453:139;22445:6;22438:155;22388:219;;;22650:1;22644:3;22641:1;22637:11;22633:19;22627:4;22620:33;21909:1006;;21604:1317;;;:::o;22926:471::-;23011:6;23019;23027;23080:2;23068:9;23059:7;23055:23;23051:32;23048:52;;;23096:1;23093;23086:12;23048:52;23141:16;;23247:2;23232:18;;23226:25;23322:2;23307:18;;23301:25;23141:16;;-1:-1:-1;23226:25:24;-1:-1:-1;23335:30:24;23301:25;23335:30;:::i;:::-;23384:7;23374:17;;;22926:471;;;;;:::o;24297:212::-;24339:3;24377:5;24371:12;24421:6;24414:4;24407:5;24403:16;24398:3;24392:36;24483:1;24447:16;;24472:13;;;-1:-1:-1;24447:16:24;;24297:212;-1:-1:-1;24297:212:24:o;24514:570::-;24925:17;24920:3;24913:30;24895:3;24962:39;24997:2;24992:3;24988:12;24980:6;24962:39;:::i;:::-;25021:3;25017:2;25010:15;25041:37;25075:1;25071:2;25067:10;25059:6;25041:37;:::i;25089:561::-;25500:9;25495:3;25488:22;25470:3;25529:38;25564:1;25559:3;25555:11;25547:6;25529:38;:::i;25655:276::-;25713:6;25766:2;25754:9;25745:7;25741:23;25737:32;25734:52;;;25782:1;25779;25772:12;25734:52;25821:9;25808:23;25871:10;25864:5;25860:22;25853:5;25850:33;25840:61;;25897:1;25894;25887:12;25936:158;26029:6;26022:14;;;26006;;;26002:35;;26049:16;;26046:42;;;26068:18;;:::i;26099:155::-;26190:6;26167:14;;;26183;;;26163:35;;26210:15;;26207:41;;;26228:18;;:::i;26259:162::-;26290:1;26324:6;26321:1;26317:14;26350:3;26340:37;;26357:18;;:::i;:::-;26411:3;26402:6;26399:1;26395:14;26391:24;26386:29;;;26259:162;;;;:::o;26426:173::-;26523:12;26494:20;;;26516;;;26490:47;;26549:21;;26546:47;;;26573:18;;:::i","linkReferences":{},"immutableReferences":{}}}}}}},"signatures":{"function":[{"signature":"allowance(address,address)","signatureHash4":"0xdd62ed3e","signatureHash32":"0xdd62ed3e90e97b3d417db9c0c7522647811bafca5afc6694f143588d255fdfb4"},{"signature":"approve(address,uint256)","signatureHash4":"0x095ea7b3","signatureHash32":"0x095ea7b334ae44009aa867bfb386f5c3b4b443ac6f0ee573fa91c4608fbadfba"},{"signature":"approvedForClaim(address,address)","signatureHash4":"0xc5884ad1","signatureHash32":"0xc5884ad16c426960c185fb73f85e33b22988fa120bf37ed55b83ee93877d67d2"},{"signature":"approveForClaim(address,bool)","signatureHash4":"0x78273aca","signatureHash32":"0x78273aca980a51a9cc33edca4b16df195d0143a79dc8a8ae799ede245bab76b7"},{"signature":"balanceOf(address)","signatureHash4":"0x70a08231","signatureHash32":"0x70a08231b98ef4ca268c9cc3f6b4590e4bfec28280db06bb5d45e689f2a360be"},{"signature":"blockTimestampLast()","signatureHash4":"0xc5700a02","signatureHash32":"0xc5700a029faa7c8846d8bba21d75747c2e4b2db9878df5007177d48163cb9ef6"},{"signature":"burn(address)","signatureHash4":"0x89afcb44","signatureHash32":"0x89afcb44fd79f61b5bbd470c26d7036838c13afd3c4b3014433636cfd3b48a0c"},{"signature":"claimable0(address)","signatureHash4":"0x4d5a9f8a","signatureHash32":"0x4d5a9f8a1b07cd76d17b394ee33cd6e9a542526047e2b5e6be9cac6f5592d31f"},{"signature":"claimable1(address)","signatureHash4":"0xa1ac4d13","signatureHash32":"0xa1ac4d13f8017900959cc5e6825d453f2646d1d594d94d7565c84cd5eb423d63"},{"signature":"claimFees(address)","signatureHash4":"0x15a0ea6a","signatureHash32":"0x15a0ea6a3bf9fc498aec511f8a33f1ce6d0f02891e1880269ad1da6401501e39"},{"signature":"claimFees(address,address)","signatureHash4":"0x2dbfa735","signatureHash32":"0x2dbfa7355cffc9d85befbbfc05b781f5a7ef02be6b0d30bbd3d479c24233030e"},{"signature":"currentCumulativePrices()","signatureHash4":"0x1df8c717","signatureHash32":"0x1df8c717051e274777e529c27989a88ab9729cf96dea4db0772aa173a3dc0dfc"},{"signature":"decimals()","signatureHash4":"0x313ce567","signatureHash32":"0x313ce567add4d438edf58b94ff345d7d38c45b17dfc0f947988d7819dca364f9"},{"signature":"factory()","signatureHash4":"0xc45a0155","signatureHash32":"0xc45a01550ceb4bc5c6b2e6f722b5033a03078f9bd6673457375ba94c26ac1cf0"},{"signature":"getAmountInWithTotalFee(uint256,address)","signatureHash4":"0xb95d88f8","signatureHash32":"0xb95d88f8f06431c29adc5f200222fb607838c71f165db5095d83dca65d6c9ba4"},{"signature":"getAmountOut(uint256,address)","signatureHash4":"0xf140a35a","signatureHash32":"0xf140a35a6d9518634ecb89dbe7509bcb112bd7ae0dae35c149dc9d22631e3fd9"},{"signature":"getAmountOut(uint256,address,uint256,uint256)","signatureHash4":"0x119c4e9f","signatureHash32":"0x119c4e9fba8eb5341ceafd0accbe18cfc88e0c0f7828483663603a2872269946"},{"signature":"getAmountOutWithTotalFee(uint256,address)","signatureHash4":"0x0ea099c1","signatureHash32":"0x0ea099c134568ff843970bbdfb56b4cdeadbc57c55b92dc0a9054a70f48a073a"},{"signature":"getK()","signatureHash4":"0xee39e7a0","signatureHash32":"0xee39e7a0224021702e64d3eb21830f9f116b65bba7e66103db70cea7e33f1e3b"},{"signature":"getReserves()","signatureHash4":"0x0902f1ac","signatureHash32":"0x0902f1ac5dbaeedd3217f11b3cbaf929216c9c5abc2d69da89d54964bead575d"},{"signature":"increaseObservationCardinalityNext(uint16)","signatureHash4":"0x32148f67","signatureHash32":"0x32148f671b2ccdd41d0d5958b5bc633b423588268b03b67e35bf29e1a6510a68"},{"signature":"index0()","signatureHash4":"0x32c0defd","signatureHash32":"0x32c0defd0e1b284782cd556c1efeaa098672ce575d027f567e0bfc1af587e63c"},{"signature":"index1()","signatureHash4":"0xbda39cad","signatureHash32":"0xbda39caddc312ecdc6ded4fa47b9e368fe3d7fb757153c1b5b4bcb8844979bcd"},{"signature":"initialize(address,address)","signatureHash4":"0x485cc955","signatureHash32":"0x485cc955cd05f29985ce37d87ac35dcf2fdbc60b9106f66a532e31a2f1d5743b"},{"signature":"metadata()","signatureHash4":"0x392f37e9","signatureHash32":"0x392f37e93152325794bd2e375ac5c76c3ecccfb36c545686fa3edc1f67f10039"},{"signature":"MINIMUM_K()","signatureHash4":"0x4983f2f5","signatureHash32":"0x4983f2f54c2e0a4f5b42b0d26adc2a7a481de1c242b8b3e73d8f4418b22b8103"},{"signature":"mint(address)","signatureHash4":"0x6a627842","signatureHash32":"0x6a627842f752de95745ef8f3ca67858982b5f585d752f8163e5855050041cb3c"},{"signature":"name()","signatureHash4":"0x06fdde03","signatureHash32":"0x06fdde0383f15d582d1a74511486c9ddf862a882fb7904b3d9fe9b8b8e58a796"},{"signature":"observationBuffer()","signatureHash4":"0x1a4211dc","signatureHash32":"0x1a4211dc2e72528ec2337fc1616e9abb0861916e550f329e2fc7e342faf32c16"},{"signature":"observations(uint256)","signatureHash4":"0x252c09d7","signatureHash32":"0x252c09d726f244607e932f457f571ce303b1ef613256cfc3e2645a4508bcc067"},{"signature":"observe(uint32[])","signatureHash4":"0x883bdbfd","signatureHash32":"0x883bdbfdafb581e01e12cfe744d865ab15ff96e60e0558a3b991333a957b1131"},{"signature":"pendingFees(address)","signatureHash4":"0x25d2a3f3","signatureHash32":"0x25d2a3f3c960121f21a07be1f064c89ffdab67eb59e06530ac5938e678059788"},{"signature":"PERIOD_SIZE()","signatureHash4":"0xfc9654ab","signatureHash32":"0xfc9654abae0fccc5dc65cce8e2a33b1c1e8a2797f9561b2656f4fa6d399906a2"},{"signature":"poolFees()","signatureHash4":"0x33580959","signatureHash32":"0x3358095954151ed378b6e6f225741939e9b33cb0a59d0d04520c1124003d1729"},{"signature":"POOL_TYPE()","signatureHash4":"0x648da859","signatureHash32":"0x648da8595eee84ab49d9a49183f8f1f920f299e55027e28f78044d05ec3354eb"},{"signature":"reserve0()","signatureHash4":"0x443cb4bc","signatureHash32":"0x443cb4bc0f66b6ace06e11c30bcb560724e93ab593ef3719a913bf01c2ffc09d"},{"signature":"reserve0CumulativeLast()","signatureHash4":"0xbf944dbc","signatureHash32":"0xbf944dbc6d4acf8975f11c541e9d114fb344d5174d922a1c481ecdb91240bb2e"},{"signature":"reserve1()","signatureHash4":"0x5a76f25e","signatureHash32":"0x5a76f25ed222c5bcfe18b4cccb45d4e760f53976e7aeeae4e4be47a2eb541ccb"},{"signature":"reserve1CumulativeLast()","signatureHash4":"0xc245febc","signatureHash32":"0xc245febc2046909609ac8693e8824f30ec4563fd7ab2411dc07b6eb7e3d8ba74"},{"signature":"setName(string)","signatureHash4":"0xc47f0027","signatureHash32":"0xc47f00276f2f257a0d6e08fde7692b09d811f0ee9b5a09ef0807a6ba46c7db94"},{"signature":"setSymbol(string)","signatureHash4":"0xb84c8246","signatureHash32":"0xb84c82465850ce875c6133a6ebc7b108e7c2670c154ab13675a3c664385c3e34"},{"signature":"skim(address)","signatureHash4":"0xbc25cf77","signatureHash32":"0xbc25cf77f209a4796fa892acd45be15fa2a2d91b60348de52e18e4098606ba6d"},{"signature":"supplyIndex0(address)","signatureHash4":"0x9f767c88","signatureHash32":"0x9f767c88d5509961513c57106276eb0acf9e64c2f0927d2859e918d04940e333"},{"signature":"supplyIndex1(address)","signatureHash4":"0x205aabf1","signatureHash32":"0x205aabf119c36aa2d9f73ed446f22f994f698f58202c60ba7ea37e5225c67fa4"},{"signature":"swap(uint256,uint256,address,bytes)","signatureHash4":"0x022c0d9f","signatureHash32":"0x022c0d9f14a579d1d17baf9fddaebffc4a661f18e5dbcdf9b78b0e655ef26681"},{"signature":"symbol()","signatureHash4":"0x95d89b41","signatureHash32":"0x95d89b41e2f5f391a79ec54e9d87c79d6e777c63e32c28da95b4e9e4a79250ec"},{"signature":"sync()","signatureHash4":"0xfff6cae9","signatureHash32":"0xfff6cae917b7a8768ced5ece158885f4009776adc00606f01315420108ff9e10"},{"signature":"token0()","signatureHash4":"0x0dfe1681","signatureHash32":"0x0dfe16819b2523f68151ea44c4f107305bfeb85c4b18e7e63ac6f999d8cf9a0e"},{"signature":"token1()","signatureHash4":"0xd21220a7","signatureHash32":"0xd21220a7b5fcd6706feb17ecf897df81a823584a161e849e09b1ff66574ed2cb"},{"signature":"tokens()","signatureHash4":"0x9d63848a","signatureHash32":"0x9d63848a0387e91c68d7f251e05c3b3fd0dcac11d64543681901e7ce8e0a4788"},{"signature":"totalSupply()","signatureHash4":"0x18160ddd","signatureHash32":"0x18160ddd7f15c72528c2f94fd8dfe3c8d5aa26e2c50c7d81f4bc7bee8d4b7932"},{"signature":"transfer(address,uint256)","signatureHash4":"0xa9059cbb","signatureHash32":"0xa9059cbb2ab09eb219583f4a59a5d0623ade346d962bcd4e46b11da047c9049b"},{"signature":"transferFrom(address,address,uint256)","signatureHash4":"0x23b872dd","signatureHash32":"0x23b872dd7302113369cda2901243429419bec145408fa8b352b3dd92b66c680b"}],"event":[{"signature":"Approval(address,address,uint256)","signatureHash4":"0x8c5be1e5","signatureHash32":"0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"},{"signature":"Burn(address,address,uint256,uint256)","signatureHash4":"0x5d624aa9","signatureHash32":"0x5d624aa9c148153ab3446c1b154f660ee7701e549fe9b62dab7171b1c80e6fa2"},{"signature":"Claim(address,address,address,uint256,uint256)","signatureHash4":"0xcd5e4f02","signatureHash32":"0xcd5e4f020ddad29434c2200a9edf2f8d7ec30f0d787f03b528ab7279aab0acbe"},{"signature":"ClaimApproval(address,address,bool)","signatureHash4":"0x63484c37","signatureHash32":"0x63484c3756a6c7d95f131879210268006b60e58057de5db75f3a8c91c7869ebf"},{"signature":"Fees(address,uint256,uint256)","signatureHash4":"0x112c2569","signatureHash32":"0x112c256902bf554b6ed882d2936687aaeb4225e8cd5b51303c90ca6cf43a8602"},{"signature":"IncreaseObservationCardinalityNext(address,uint16,uint16)","signatureHash4":"0xf0b7b7d1","signatureHash32":"0xf0b7b7d1cdf542f5660a7879f0cac17375fdcf984af4a6d499a9daedacb24c58"},{"signature":"Mint(address,address,uint256,uint256)","signatureHash4":"0x2f00e3cd","signatureHash32":"0x2f00e3cdd69a77be7ed215ec7b2a36784dd158f921fca79ac29deffa353fe6ee"},{"signature":"Swap(address,address,uint256,uint256,uint256,uint256)","signatureHash4":"0xb3e27736","signatureHash32":"0xb3e2773606abfd36b5bd91394b3a54d1398336c65005baf7bf7a05efeffaf75b"},{"signature":"Sync(uint256,uint256)","signatureHash4":"0xcf2aa508","signatureHash32":"0xcf2aa50876cdfbb541206f89af0ee78d44a2abf8d328e37fa4917f982149848a"},{"signature":"Transfer(address,address,uint256)","signatureHash4":"0xddf252ad","signatureHash32":"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"}],"error":[{"signature":"BelowMinimumK()","signatureHash4":"0x438d3ade","signatureHash32":"0x438d3ade0428461543f2306df1cfff6ff0dbfd4fb0027ea621e88263cae1b39d"},{"signature":"CannotCalculateY()","signatureHash4":"0x6eb5c821","signatureHash32":"0x6eb5c8214609c61c75071982472ae0da1fa64a3d8b137714524558beb7e65900"},{"signature":"DepositsNotEqual()","signatureHash4":"0x0a04d7fa","signatureHash32":"0x0a04d7fa68d22d29ca6a0c9189811a31460aec5d07d795cc10d45ad27e1d02d6"},{"signature":"ERC20InsufficientAllowance(address,uint256,uint256)","signatureHash4":"0xfb8f41b2","signatureHash32":"0xfb8f41b23e99d2101d86da76cdfa87dd51c82ed07d3cb62cbc473e469dbc75c3"},{"signature":"ERC20InsufficientBalance(address,uint256,uint256)","signatureHash4":"0xe450d38c","signatureHash32":"0xe450d38cd8d9f7d95077d567d60ed49c7254716e6ad08fc9872816c97e0ffec6"},{"signature":"ERC20InvalidApprover(address)","signatureHash4":"0xe602df05","signatureHash32":"0xe602df05cc75712490294c6c104ab7c17f4030363910a7a2626411c6d3118847"},{"signature":"ERC20InvalidReceiver(address)","signatureHash4":"0xec442f05","signatureHash32":"0xec442f055133b72f3b2f9f0bb351c406b178527de2040a7d1feb4e058771f613"},{"signature":"ERC20InvalidSender(address)","signatureHash4":"0x96c6fd1e","signatureHash32":"0x96c6fd1edd0cd6ef7ff0ecc0facdf53148dc0048b57fe58af65755250a7a96bd"},{"signature":"ERC20InvalidSpender(address)","signatureHash4":"0x94280d62","signatureHash32":"0x94280d62c347d8d9f4d59a76ea321452406db88df38e0c9da304f58b57b373a2"},{"signature":"FactoryAlreadySet()","signatureHash4":"0x154c51b8","signatureHash32":"0x154c51b849b6be602ef31acb0a6b13b7fae60eb6aa7e2391439a07eac9a1fe38"},{"signature":"InsufficientInputAmount()","signatureHash4":"0x098fb561","signatureHash32":"0x098fb561b214e40e1e2f3f75a32a74ad8612ca9e387347a879ac04251bbf57f8"},{"signature":"InsufficientLiquidity()","signatureHash4":"0xbb55fd27","signatureHash32":"0xbb55fd27c46b5ba9f88ff2cb2222216afeb0f193423b26615497b3020ab61f8e"},{"signature":"InsufficientLiquidityBurned()","signatureHash4":"0x749383ad","signatureHash32":"0x749383ad43fea31adee1a470f5c83825ffb89a6eebe5d77d035a631ddf22e2e9"},{"signature":"InsufficientLiquidityMinted()","signatureHash4":"0xd226f9d4","signatureHash32":"0xd226f9d4fb66d83c9e784a8629bffaacb8e895718029d32e323c8ba88c74f78c"},{"signature":"InsufficientOutputAmount()","signatureHash4":"0x42301c23","signatureHash32":"0x42301c237a29c3e090da1b147e7b504f08db56c9600985b34af188477d350fa7"},{"signature":"InvalidTo()","signatureHash4":"0x290fa188","signatureHash32":"0x290fa188e5368e85375d6fb66e1dd75bc9927c3d95b2732244780d06ce682068"},{"signature":"IsPaused()","signatureHash4":"0x1309a563","signatureHash32":"0x1309a5639731e6b91c4aa19095f23eee07602ba240a393e2b5ccbf71a8e2952f"},{"signature":"K()","signatureHash4":"0xa932492f","signatureHash32":"0xa932492ffc2a9734a61b160a9a2115b493b6255b918466d8b76981e516fb337d"},{"signature":"KIsZero()","signatureHash4":"0x7d06c0c8","signatureHash32":"0x7d06c0c809b1ad01dcbb602774632ceb43283fcd0b052302353625cc844f1bc9"},{"signature":"NotAuthorized()","signatureHash4":"0xea8e4eb5","signatureHash32":"0xea8e4eb51685727b38a21cb154eb3ebd023f607c62908e0f6f0b645d782af2a4"},{"signature":"NotPoolAdmin()","signatureHash4":"0x058a2da8","signatureHash32":"0x058a2da832f549c7f6805d858d1a8944234eaad3148985bd0aefe04215c8100d"},{"signature":"ObservationOld()","signatureHash4":"0xc02e4620","signatureHash32":"0xc02e462096d703e02a6698bb38e0a5c43ad449ce667c4db3278417cecd76e7ae"},{"signature":"ReentrancyGuardReentrantCall()","signatureHash4":"0x3ee5aeb5","signatureHash32":"0x3ee5aeb571de7fc460830b4d0017439a1ca56fb0bc39062227ade4fe4a24c1ca"},{"signature":"SafeERC20FailedOperation(address)","signatureHash4":"0x5274afe7","signatureHash32":"0x5274afe73c98b4749fc91ffae6b7b574e7842cb2144a159e9377a5f20b32edf9"},{"signature":"ZeroAddress()","signatureHash4":"0xd92e233d","signatureHash32":"0xd92e233df2717d4a40030e20904abd27b68fcbeede117eaaccbbdac9618c8c73"}]},"proxyResolution":{"isProxy":false,"proxyType":null,"implementations":[]},"match":"match","chainId":"8453","address":"0xf525988f88B7D8b64631D86070FEC5BFDc50C174"}