use std::fs;
use std::path::PathBuf;
use tempfile::TempDir;
/// Creates a temporary directory with the incredible-squaring blueprint
///
/// This function creates a temporary directory and populates it with the files needed
/// for the incredible-squaring blueprint. It returns the temporary directory and the path
/// to the blueprint directory.
///
/// # Panics
///
/// - Uses expects for all errors, failing with a panic on any error when generating the blueprint files
#[must_use]
pub fn create_test_blueprint() -> (TempDir, PathBuf) {
let temp_dir = TempDir::new().expect("Failed to create temporary directory");
let blueprint_dir = temp_dir.path().join("test-blueprint");
let current_dir = std::env::current_dir().expect("Failed to get current directory");
let crates_dir = current_dir
.parent()
.expect("Failed to go back one directory");
// Create directory structure
fs::create_dir(&blueprint_dir).expect("Failed to create blueprint directory");
fs::create_dir(blueprint_dir.join("src")).expect("Failed to create src directory");
// Create contracts directory and subdirectories
fs::create_dir(blueprint_dir.join("contracts")).expect("Failed to create contracts directory");
fs::create_dir_all(
blueprint_dir
.join("contracts")
.join("out")
.join("ExperimentalBlueprint.sol"),
)
.expect("Failed to create contract output directories");
// Create a mock contract JSON file
fs::write(
blueprint_dir.join("contracts").join("out").join("ExperimentalBlueprint.sol").join("ExperimentalBlueprint.json"),
r#"{"abi":[{"type":"function","name":"REWARDS_PALLET","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"ROOT_CHAIN","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"blueprintOwner","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"canJoin","inputs":[{"name":"serviceId","type":"uint64","internalType":"uint64"},{"name":"operator","type":"tuple","internalType":"struct ServiceOperators.OperatorPreferences","components":[{"name":"ecdsaPublicKey","type":"bytes","internalType":"bytes"},{"name":"rpcAddress","type":"string","internalType":"string"}]}],"outputs":[{"name":"allowed","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"canLeave","inputs":[{"name":"serviceId","type":"uint64","internalType":"uint64"},{"name":"operator","type":"tuple","internalType":"struct ServiceOperators.OperatorPreferences","components":[{"name":"ecdsaPublicKey","type":"bytes","internalType":"bytes"},{"name":"rpcAddress","type":"string","internalType":"string"}]}],"outputs":[{"name":"allowed","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"currentBlueprintId","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"getHeartbeatInterval","inputs":[{"name":"serviceId","type":"uint64","internalType":"uint64"}],"outputs":[{"name":"useDefault","type":"bool","internalType":"bool"},{"name":"interval","type":"uint64","internalType":"uint64"}],"stateMutability":"view"},{"type":"function","name":"getHeartbeatThreshold","inputs":[{"name":"serviceId","type":"uint64","internalType":"uint64"}],"outputs":[{"name":"useDefault","type":"bool","internalType":"bool"},{"name":"threshold","type":"uint8","internalType":"uint8"}],"stateMutability":"view"},{"type":"function","name":"getSlashingWindow","inputs":[{"name":"serviceId","type":"uint64","internalType":"uint64"}],"outputs":[{"name":"useDefault","type":"bool","internalType":"bool"},{"name":"window","type":"uint64","internalType":"uint64"}],"stateMutability":"view"},{"type":"function","name":"masterBlueprintServiceManager","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"masterBlueprintServiceManagerAddress","inputs":[],"outputs":[{"name":"mbsm","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"onApprove","inputs":[{"name":"operator","type":"tuple","internalType":"struct ServiceOperators.OperatorPreferences","components":[{"name":"ecdsaPublicKey","type":"bytes","internalType":"bytes"},{"name":"rpcAddress","type":"string","internalType":"string"}]},{"name":"requestId","type":"uint64","internalType":"uint64"},{"name":"restakingPercent","type":"uint8","internalType":"uint8"}],"outputs":[],"stateMutability":"payable"},{"type":"function","name":"onBlueprintCreated","inputs":[{"name":"blueprintId","type":"uint64","internalType":"uint64"},{"name":"owner","type":"address","internalType":"address"},{"name":"mbsm","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"onJobCall","inputs":[{"name":"serviceId","type":"uint64","internalType":"uint64"},{"name":"job","type":"uint8","internalType":"uint8"},{"name":"jobCallId","type":"uint64","internalType":"uint64"},{"name":"inputs","type":"bytes","internalType":"bytes"}],"outputs":[],"stateMutability":"payable"},{"type":"function","name":"onJobResult","inputs":[{"name":"serviceId","type":"uint64","internalType":"uint64"},{"name":"job","type":"uint8","internalType":"uint8"},{"name":"jobCallId","type":"uint64","internalType":"uint64"},{"name":"operator","type":"tuple","internalType":"struct ServiceOperators.OperatorPreferences","components":[{"name":"ecdsaPublicKey","type":"bytes","internalType":"bytes"},{"name":"rpcAddress","type":"string","internalType":"string"}]},{"name":"inputs","type":"bytes","internalType":"bytes"},{"name":"outputs","type":"bytes","internalType":"bytes"}],"outputs":[],"stateMutability":"payable"},{"type":"function","name":"onOperatorJoined","inputs":[{"name":"serviceId","type":"uint64","internalType":"uint64"},{"name":"operator","type":"tuple","internalType":"struct ServiceOperators.OperatorPreferences","components":[{"name":"ecdsaPublicKey","type":"bytes","internalType":"bytes"},{"name":"rpcAddress","type":"string","internalType":"string"}]}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"onOperatorLeft","inputs":[{"name":"serviceId","type":"uint64","internalType":"uint64"},{"name":"operator","type":"tuple","internalType":"struct ServiceOperators.OperatorPreferences","components":[{"name":"ecdsaPublicKey","type":"bytes","internalType":"bytes"},{"name":"rpcAddress","type":"string","internalType":"string"}]}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"onRegister","inputs":[{"name":"operator","type":"tuple","internalType":"struct ServiceOperators.OperatorPreferences","components":[{"name":"ecdsaPublicKey","type":"bytes","internalType":"bytes"},{"name":"rpcAddress","type":"string","internalType":"string"}]},{"name":"registrationInputs","type":"bytes","internalType":"bytes"}],"outputs":[],"stateMutability":"payable"},{"type":"function","name":"onReject","inputs":[{"name":"operator","type":"tuple","internalType":"struct ServiceOperators.OperatorPreferences","components":[{"name":"ecdsaPublicKey","type":"bytes","internalType":"bytes"},{"name":"rpcAddress","type":"string","internalType":"string"}]},{"name":"requestId","type":"uint64","internalType":"uint64"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"onRequest","inputs":[{"name":"params","type":"tuple","internalType":"struct ServiceOperators.RequestParams","components":[{"name":"requestId","type":"uint64","internalType":"uint64"},{"name":"requester","type":"address","internalType":"address"},{"name":"operators","type":"tuple[]","internalType":"struct ServiceOperators.OperatorPreferences[]","components":[{"name":"ecdsaPublicKey","type":"bytes","internalType":"bytes"},{"name":"rpcAddress","type":"string","internalType":"string"}]},{"name":"requestInputs","type":"bytes","internalType":"bytes"},{"name":"permittedCallers","type":"address[]","internalType":"address[]"},{"name":"ttl","type":"uint64","internalType":"uint64"},{"name":"paymentAsset","type":"tuple","internalType":"struct Assets.Asset","components":[{"name":"kind","type":"uint8","internalType":"enum Assets.Kind"},{"name":"data","type":"bytes32","internalType":"bytes32"}]},{"name":"amount","type":"uint256","internalType":"uint256"}]}],"outputs":[],"stateMutability":"payable"},{"type":"function","name":"onServiceInitialized","inputs":[{"name":"requestId","type":"uint64","internalType":"uint64"},{"name":"serviceId","type":"uint64","internalType":"uint64"},{"name":"owner","type":"address","internalType":"address"},{"name":"permittedCallers","type":"address[]","internalType":"address[]"},{"name":"ttl","type":"uint64","internalType":"uint64"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"onServiceTermination","inputs":[{"name":"serviceId","type":"uint64","internalType":"uint64"},{"name":"owner","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"onSlash","inputs":[{"name":"serviceId","type":"uint64","internalType":"uint64"},{"name":"offender","type":"bytes","internalType":"bytes"},{"name":"slashPercent","type":"uint8","internalType":"uint8"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"onUnappliedSlash","inputs":[{"name":"serviceId","type":"uint64","internalType":"uint64"},{"name":"offender","type":"bytes","internalType":"bytes"},{"name":"slashPercent","type":"uint8","internalType":"uint8"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"onUnregister","inputs":[{"name":"operator","type":"tuple","internalType":"struct ServiceOperators.OperatorPreferences","components":[{"name":"ecdsaPublicKey","type":"bytes","internalType":"bytes"},{"name":"rpcAddress","type":"string","internalType":"string"}]}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"onUpdateRpcAddress","inputs":[{"name":"operator","type":"tuple","internalType":"struct ServiceOperators.OperatorPreferences","components":[{"name":"ecdsaPublicKey","type":"bytes","internalType":"bytes"},{"name":"rpcAddress","type":"string","internalType":"string"}]}],"outputs":[],"stateMutability":"payable"},{"type":"function","name":"queryDeveloperPaymentAddress","inputs":[{"name":"","type":"uint64","internalType":"uint64"}],"outputs":[{"name":"developerPaymentAddress","type":"address","internalType":"address payable"}],"stateMutability":"view"},{"type":"function","name":"queryDisputeOrigin","inputs":[{"name":"","type":"uint64","internalType":"uint64"}],"outputs":[{"name":"disputeOrigin","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"queryIsPaymentAssetAllowed","inputs":[{"name":"serviceId","type":"uint64","internalType":"uint64"},{"name":"asset","type":"tuple","internalType":"struct Assets.Asset","components":[{"name":"kind","type":"uint8","internalType":"enum Assets.Kind"},{"name":"data","type":"bytes32","internalType":"bytes32"}]}],"outputs":[{"name":"isAllowed","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"querySlashingOrigin","inputs":[{"name":"","type":"uint64","internalType":"uint64"}],"outputs":[{"name":"slashingOrigin","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"rewardsPallet","inputs":[],"outputs":[{"name":"rewardsPalletAddress","type":"address","internalType":"address"}],"stateMutability":"pure"},{"type":"function","name":"rootChain","inputs":[],"outputs":[{"name":"rootChainAddress","type":"address","internalType":"address"}],"stateMutability":"pure"},{"type":"error","name":"OnlyMasterBlueprintServiceManagerAllowed","inputs":[{"name":"caller","type":"address","internalType":"address"},{"name":"masterBlueprintServiceManager","type":"address","internalType":"address"}]},{"type":"error","name":"OnlyRootChainAllowed","inputs":[{"name":"caller","type":"address","internalType":"address"},{"name":"rootChain","type":"address","internalType":"address"}]},{"type":"error","name":"UnsupportedAssetKind","inputs":[{"name":"kind","type":"uint256","internalType":"uint256"}]}],"bytecode":{"object":"0x6080604052348015600e575f5ffd5b506122428061001c5f395ff3fe6080604052600436106101e1575f3560e01c8063760c379f11610101578063a40a952711610094578063d7deb48211610063578063d7deb482146106ce578063dcfee99a146106f6578063e0503b7114610712578063f84076621461073a576101e1565b8063a40a952714610644578063a4d91fe914610660578063a9c380e11461068a578063c4b44839146106b2576101e1565b806392cbb78e116100d057806392cbb78e146105995780639838caa3146105d6578063987ab9db146105f2578063a24e8a901461061c576101e1565b8063760c379f146104e35780637e14b9191461051f578063884673ac146105475780638927061614610571576101e1565b8063216e8042116101795780633fdadfcc116101485780633fdadfcc146104245780635287cd5f146104615780635d79ea291461047d57806374ceeb55146104a7576101e1565b8063216e804214610366578063254891461461039057806329b98dc7146103cc5780633c3aa64c146103e8576101e1565b80630d0dd399116101b55780630d0dd399146102ae57806310f772b8146102d857806314b4df4c146103005780631948fdbc1461033c576101e1565b806268080b146101e557806308179f35146102225780630881898f1461025e5780630b6535d714610286575b5f5ffd5b3480156101f0575f5ffd5b5061020b600480360381019061020691906117f9565b610764565b60405161021992919061184d565b60405180910390f35b34801561022d575f5ffd5b50610248600480360381019061024391906117f9565b610772565b60405161025591906118b3565b60405180910390f35b348015610269575f5ffd5b50610284600480360381019061027f9190611963565b61079c565b005b348015610291575f5ffd5b506102ac60048036038101906102a79190611a0f565b610854565b005b3480156102b9575f5ffd5b506102c2610983565b6040516102cf9190611a6e565b60405180910390f35b3480156102e3575f5ffd5b506102fe60048036038101906102f99190611aa9565b6109a7565b005b34801561030b575f5ffd5b50610326600480360381019061032191906117f9565b610a5d565b6040516103339190611a6e565b60405180910390f35b348015610347575f5ffd5b50610350610a66565b60405161035d9190611a6e565b60405180910390f35b348015610371575f5ffd5b5061037a610a6d565b6040516103879190611a6e565b60405180910390f35b34801561039b575f5ffd5b506103b660048036038101906103b19190611aa9565b610a77565b6040516103c39190611b03565b60405180910390f35b6103e660048036038101906103e19190611b1c565b610b33565b005b3480156103f3575f5ffd5b5061040e60048036038101906104099190611c20565b610bef565b60405161041b9190611b03565b60405180910390f35b34801561042f575f5ffd5b5061044a600480360381019061044591906117f9565b610c02565b60405161045892919061184d565b60405180910390f35b61047b60048036038101906104769190611c5e565b610c10565b005b348015610488575f5ffd5b50610491610cc7565b60405161049e9190611ce2565b60405180910390f35b3480156104b2575f5ffd5b506104cd60048036038101906104c891906117f9565b610ccd565b6040516104da9190611a6e565b60405180910390f35b3480156104ee575f5ffd5b5061050960048036038101906105049190611aa9565b610cd6565b6040516105169190611b03565b60405180910390f35b34801561052a575f5ffd5b5061054560048036038101906105409190611963565b610d92565b005b348015610552575f5ffd5b5061055b610e4a565b6040516105689190611a6e565b60405180910390f35b34801561057c575f5ffd5b5061059760048036038101906105929190611aa9565b610e62565b005b3480156105a4575f5ffd5b506105bf60048036038101906105ba91906117f9565b610f18565b6040516105cd929190611d0a565b60405180910390f35b6105f060048036038101906105eb9190611d31565b610f26565b005b3480156105fd575f5ffd5b50610606610fdf565b6040516106139190611a6e565b60405180910390f35b348015610627575f5ffd5b50610642600480360381019061063d9190611db5565b610ffa565b005b61065e60048036038101906106599190611e12565b6110b0565b005b34801561066b575f5ffd5b50610674611165565b6040516106819190611a6e565b60405180910390f35b348015610695575f5ffd5b506106b060048036038101906106ab9190611e59565b61118c565b005b6106cc60048036038101906106c79190611eb3565b611242565b005b3480156106d9575f5ffd5b506106f460048036038101906106ef9190611f81565b6112f9565b005b610710600480360381019061070b9190612017565b6113b3565b005b34801561071d575f5ffd5b5061073860048036038101906107339190612017565b611468565b005b348015610745575f5ffd5b5061074e61151d565b60405161075b9190611a6e565b60405180910390f35b5f5f60015f91509150915091565b5f60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461084e57335f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040517f0c423fcf00000000000000000000000000000000000000000000000000000000815260040161084592919061205e565b60405180910390fd5b50505050565b7309df6a941ee03b1e632904e382e10862fa9cc0e373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146108ee57337309df6a941ee03b1e632904e382e10862fa9cc0e36040517fb35fd15e0000000000000000000000000000000000000000000000000000000081526004016108e592919061205e565b60405180910390fd5b8267ffffffffffffffff166001819055508160025f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550805f5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505050565b5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a5957335f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040517f0c423fcf000000000000000000000000000000000000000000000000000000008152600401610a5092919061205e565b60405180910390fd5b5050565b5f309050919050565b627e87d581565b5f627e87d5905090565b5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610b2a57335f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040517f0c423fcf000000000000000000000000000000000000000000000000000000008152600401610b2192919061205e565b60405180910390fd5b5f905092915050565b5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610be557335f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040517f0c423fcf000000000000000000000000000000000000000000000000000000008152600401610bdc92919061205e565b60405180910390fd5b5050505050505050565b5f610bfa8383611542565b905092915050565b5f5f60015f91509150915091565b5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610cc257335f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040517f0c423fcf000000000000000000000000000000000000000000000000000000008152600401610cb992919061205e565b60405180910390fd5b505050565b60015481565b5f309050919050565b5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610d8957335f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040517f0c423fcf000000000000000000000000000000000000000000000000000000008152600401610d8092919061205e565b60405180910390fd5b5f905092915050565b5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610e4457335f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040517f0c423fcf000000000000000000000000000000000000000000000000000000008152600401610e3b92919061205e565b60405180910390fd5b50505050565b7309df6a941ee03b1e632904e382e10862fa9cc0e381565b5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610f1457335f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040517f0c423fcf000000000000000000000000000000000000000000000000000000008152600401610f0b92919061205e565b60405180910390fd5b5050565b5f5f60015f91509150915091565b5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610fd857335f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040517f0c423fcf000000000000000000000000000000000000000000000000000000008152600401610fcf92919061205e565b60405180910390fd5b5050505050565b5f7309df6a941ee03b1e632904e382e10862fa9cc0e3905090565b5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146110ac57335f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040517f0c423fcf0000000000000000000000000000000000000000000000000000000081526004016110a392919061205e565b60405180910390fd5b5050565b5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461116257335f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040517f0c423fcf00000000000000000000000000000000000000000000000000000000815260040161115992919061205e565b60405180910390fd5b50565b5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461123e57335f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040517f0c423fcf00000000000000000000000000000000000000000000000000000000815260040161123592919061205e565b60405180910390fd5b5050565b5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146112f457335f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040517f0c423fcf0000000000000000000000000000000000000000000000000000000081526004016112eb92919061205e565b60405180910390fd5b505050565b5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146113ab57335f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040517f0c423fcf0000000000000000000000000000000000000000000000000000000081526004016113a292919061205e565b60405180910390fd5b505050505050565b5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461146557335f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040517f0c423fcf00000000000000000000000000000000000000000000000000000000815260040161145c92919061205e565b60405180910390fd5b50565b5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461151a57335f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040517f0c423fcf00000000000000000000000000000000000000000000000000000000815260040161151192919061205e565b60405180910390fd5b50565b60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f61155c8280360381019061155791906121b4565b6115c7565b1561156a57600190506115c1565b5f6115848380360381019061157f91906121b4565b611643565b90506115bd8160035f8767ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f206116d990919063ffffffff16565b9150505b92915050565b5f6115d182611706565b15611617575f82602001515f1c90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161491505061163e565b61162082611738565b1561163a575f82602001515f1c90505f811491505061163e565b5f90505b919050565b5f61164d82611706565b156116605781602001515f1c90506116d4565b61166982611738565b156116825761167b826020015161176a565b90506116d4565b815f01516001811115611698576116976121df565b5b6040517fea8b16ba0000000000000000000000000000000000000000000000000000000081526004016116cb9190611ce2565b60405180910390fd5b919050565b5f6116fe835f018373ffffffffffffffffffffffffffffffffffffffff165f1b61178b565b905092915050565b5f60018081111561171a576117196121df565b5b825f015160018111156117305761172f6121df565b5b149050919050565b5f5f600181111561174c5761174b6121df565b5b825f01516001811115611762576117616121df565b5b149050919050565b5f815f1c73ffffffff00000000000000000000000000000000179050919050565b5f5f836001015f8481526020019081526020015f20541415905092915050565b5f604051905090565b5f5ffd5b5f5ffd5b5f67ffffffffffffffff82169050919050565b6117d8816117bc565b81146117e2575f5ffd5b50565b5f813590506117f3816117cf565b92915050565b5f6020828403121561180e5761180d6117b4565b5b5f61181b848285016117e5565b91505092915050565b5f8115159050919050565b61183881611824565b82525050565b611847816117bc565b82525050565b5f6040820190506118605f83018561182f565b61186d602083018461183e565b9392505050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61189d82611874565b9050919050565b6118ad81611893565b82525050565b5f6020820190506118c65f8301846118a4565b92915050565b5f5ffd5b5f5ffd5b5f5ffd5b5f5f83601f8401126118ed576118ec6118cc565b5b8235905067ffffffffffffffff81111561190a576119096118d0565b5b602083019150836001820283011115611926576119256118d4565b5b9250929050565b5f60ff82169050919050565b6119428161192d565b811461194c575f5ffd5b50565b5f8135905061195d81611939565b92915050565b5f5f5f5f6060858703121561197b5761197a6117b4565b5b5f611988878288016117e5565b945050602085013567ffffffffffffffff8111156119a9576119a86117b8565b5b6119b5878288016118d8565b935093505060406119c88782880161194f565b91505092959194509250565b5f6119de82611874565b9050919050565b6119ee816119d4565b81146119f8575f5ffd5b50565b5f81359050611a09816119e5565b92915050565b5f5f5f60608486031215611a2657611a256117b4565b5b5f611a33868287016117e5565b9350506020611a44868287016119fb565b9250506040611a55868287016119fb565b9150509250925092565b611a68816119d4565b82525050565b5f602082019050611a815f830184611a5f565b92915050565b5f5ffd5b5f60408284031215611aa057611a9f611a87565b5b81905092915050565b5f5f60408385031215611abf57611abe6117b4565b5b5f611acc858286016117e5565b925050602083013567ffffffffffffffff811115611aed57611aec6117b8565b5b611af985828601611a8b565b9150509250929050565b5f602082019050611b165f83018461182f565b92915050565b5f5f5f5f5f5f5f5f60c0898b031215611b3857611b376117b4565b5b5f611b458b828c016117e5565b9850506020611b568b828c0161194f565b9750506040611b678b828c016117e5565b965050606089013567ffffffffffffffff811115611b8857611b876117b8565b5b611b948b828c01611a8b565b955050608089013567ffffffffffffffff811115611bb557611bb46117b8565b5b611bc18b828c016118d8565b945094505060a089013567ffffffffffffffff811115611be457611be36117b8565b5b611bf08b828c016118d8565b92509250509295985092959890939650565b5f60408284031215611c1757611c16611a87565b5b81905092915050565b5f5f60608385031215611c3657611c356117b4565b5b5f611c43858286016117e5565b9250506020611c5485828601611c02565b9150509250929050565b5f5f5f60608486031215611c7557611c746117b4565b5b5f84013567ffffffffffffffff811115611c9257611c916117b8565b5b611c9e86828701611a8b565b9350506020611caf868287016117e5565b9250506040611cc08682870161194f565b9150509250925092565b5f819050919050565b611cdc81611cca565b82525050565b5f602082019050611cf55f830184611cd3565b92915050565b611d048161192d565b82525050565b5f604082019050611d1d5f83018561182f565b611d2a6020830184611cfb565b9392505050565b5f5f5f5f5f60808688031215611d4a57611d496117b4565b5b5f611d57888289016117e5565b9550506020611d688882890161194f565b9450506040611d79888289016117e5565b935050606086013567ffffffffffffffff811115611d9a57611d996117b8565b5b611da6888289016118d8565b92509250509295509295909350565b5f5f60408385031215611dcb57611dca6117b4565b5b5f611dd8858286016117e5565b9250506020611de9858286016119fb565b9150509250929050565b5f6101208284031215611e0957611e08611a87565b5b81905092915050565b5f60208284031215611e2757611e266117b4565b5b5f82013567ffffffffffffffff811115611e4457611e436117b8565b5b611e5084828501611df3565b91505092915050565b5f5f60408385031215611e6f57611e6e6117b4565b5b5f83013567ffffffffffffffff811115611e8c57611e8b6117b8565b5b611e9885828601611a8b565b9250506020611ea9858286016117e5565b9150509250929050565b5f5f5f60408486031215611eca57611ec96117b4565b5b5f84013567ffffffffffffffff811115611ee757611ee66117b8565b5b611ef386828701611a8b565b935050602084013567ffffffffffffffff811115611f1457611f136117b8565b5b611f20868287016118d8565b92509250509250925092565b5f5f83601f840112611f4157611f406118cc565b5b8235905067ffffffffffffffff811115611f5e57611f5d6118d0565b5b602083019150836020820283011115611f7a57611f796118d4565b5b9250929050565b5f5f5f5f5f5f60a08789031215611f9b57611f9a6117b4565b5b5f611fa889828a016117e5565b9650506020611fb989828a016117e5565b9550506040611fca89828a016119fb565b945050606087013567ffffffffffffffff811115611feb57611fea6117b8565b5b611ff789828a01611f2c565b9350935050608061200a89828a016117e5565b9150509295509295509295565b5f6020828403121561202c5761202b6117b4565b5b5f82013567ffffffffffffffff811115612049576120486117b8565b5b61205584828501611a8b565b91505092915050565b5f6040820190506120715f830185611a5f565b61207e6020830184611a5f565b9392505050565b5f5ffd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6120cf82612089565b810181811067ffffffffffffffff821117156120ee576120ed612099565b5b80604052505050565b5f6121006117ab565b905061210c82826120c6565b919050565b6002811061211d575f5ffd5b50565b5f8135905061212e81612111565b92915050565b5f819050919050565b61214681612134565b8114612150575f5ffd5b50565b5f813590506121618161213d565b92915050565b5f6040828403121561217c5761217b612085565b5b61218660406120f7565b90505f61219584828501612120565b5f8301525060206121a884828501612153565b60208301525092915050565b5f604082840312156121c9576121c86117b4565b5b5f6121d684828501612167565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffdfea2646970667358221220efe83d57b98fd6b4823962803c08507d94a4eb16bbdbab49ff187f2034718f0e64736f6c634300081b0033","sourceMap":"331:66:0:-:0;;;;;;;;;;;;;;;;;;;","linkReferences":{}},"deployedBytecode":{"object":"0x6080604052600436106101e1575f3560e01c8063760c379f11610101578063a40a952711610094578063d7deb48211610063578063d7deb482146106ce578063dcfee99a146106f6578063e0503b7114610712578063f84076621461073a576101e1565b8063a40a952714610644578063a4d91fe914610660578063a9c380e11461068a578063c4b44839146106b2576101e1565b806392cbb78e116100d057806392cbb78e146105995780639838caa3146105d6578063987ab9db146105f2578063a24e8a901461061c576101e1565b8063760c379f146104e35780637e14b9191461051f578063884673ac146105475780638927061614610571576101e1565b8063216e8042116101795780633fdadfcc116101485780633fdadfcc146104245780635287cd5f146104615780635d79ea291461047d57806374ceeb55146104a7576101e1565b8063216e804214610366578063254891461461039057806329b98dc7146103cc5780633c3aa64c146103e8576101e1565b80630d0dd399116101b55780630d0dd399146102ae57806310f772b8146102d857806314b4df4c146103005780631948fdbc1461033c576101e1565b806268080b146101e557806308179f35146102225780630881898f1461025e5780630b6535d714610286575b5f5ffd5b3480156101f0575f5ffd5b5061020b600480360381019061020691906117f9565b610764565b60405161021992919061184d565b60405180910390f35b34801561022d575f5ffd5b50610248600480360381019061024391906117f9565b610772565b60405161025591906118b3565b60405180910390f35b348015610269575f5ffd5b50610284600480360381019061027f9190611963565b61079c565b005b348015610291575f5ffd5b506102ac60048036038101906102a79190611a0f565b610854565b005b3480156102b9575f5ffd5b506102c2610983565b6040516102cf9190611a6e565b60405180910390f35b3480156102e3575f5ffd5b506102fe60048036038101906102f99190611aa9565b6109a7565b005b34801561030b575f5ffd5b50610326600480360381019061032191906117f9565b610a5d565b6040516103339190611a6e565b60405180910390f35b348015610347575f5ffd5b50610350610a66565b60405161035d9190611a6e565b60405180910390f35b348015610371575f5ffd5b5061037a610a6d565b6040516103879190611a6e565b60405180910390f35b34801561039b575f5ffd5b506103b660048036038101906103b19190611aa9565b610a77565b6040516103c39190611b03565b60405180910390f35b6103e660048036038101906103e19190611b1c565b610b33565b005b3480156103f3575f5ffd5b5061040e60048036038101906104099190611c20565b610bef565b60405161041b9190611b03565b60405180910390f35b34801561042f575f5ffd5b5061044a600480360381019061044591906117f9565b610c02565b60405161045892919061184d565b60405180910390f35b61047b60048036038101906104769190611c5e565b610c10565b005b348015610488575f5ffd5b50610491610cc7565b60405161049e9190611ce2565b60405180910390f35b3480156104b2575f5ffd5b506104cd60048036038101906104c891906117f9565b610ccd565b6040516104da9190611a6e565b60405180910390f35b3480156104ee575f5ffd5b5061050960048036038101906105049190611aa9565b610cd6565b6040516105169190611b03565b60405180910390f35b34801561052a575f5ffd5b5061054560048036038101906105409190611963565b610d92565b005b348015610552575f5ffd5b5061055b610e4a565b6040516105689190611a6e565b60405180910390f35b34801561057c575f5ffd5b5061059760048036038101906105929190611aa9565b610e62565b005b3480156105a4575f5ffd5b506105bf60048036038101906105ba91906117f9565b610f18565b6040516105cd929190611d0a565b60405180910390f35b6105f060048036038101906105eb9190611d31565b610f26565b005b3480156105fd575f5ffd5b50610606610fdf565b6040516106139190611a6e565b60405180910390f35b348015610627575f5ffd5b50610642600480360381019061063d9190611db5565b610ffa565b005b61065e60048036038101906106599190611e12565b6110b0565b005b34801561066b575f5ffd5b50610674611165565b6040516106819190611a6e565b60405180910390f35b348015610695575f5ffd5b506106b060048036038101906106ab9190611e59565b61118c565b005b6106cc60048036038101906106c79190611eb3565b611242565b005b3480156106d9575f5ffd5b506106f460048036038101906106ef9190611f81565b6112f9565b005b610710600480360381019061070b9190612017565b6113b3565b005b34801561071d575f5ffd5b5061073860048036038101906107339190612017565b611468565b005b348015610745575f5ffd5b5061074e61151d565b60405161075b9190611a6e565b60405180910390f35b5f5f60015f91509150915091565b5f60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461084e57335f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040517f0c423fcf00000000000000000000000000000000000000000000000000000000815260040161084592919061205e565b60405180910390fd5b50505050565b7309df6a941ee03b1e632904e382e10862fa9cc0e373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146108ee57337309df6a941ee03b1e632904e382e10862fa9cc0e36040517fb35fd15e0000000000000000000000000000000000000000000000000000000081526004016108e592919061205e565b60405180910390fd5b8267ffffffffffffffff166001819055508160025f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550805f5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505050565b5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a5957335f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040517f0c423fcf000000000000000000000000000000000000000000000000000000008152600401610a5092919061205e565b60405180910390fd5b5050565b5f309050919050565b627e87d581565b5f627e87d5905090565b5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610b2a57335f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040517f0c423fcf000000000000000000000000000000000000000000000000000000008152600401610b2192919061205e565b60405180910390fd5b5f905092915050565b5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610be557335f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040517f0c423fcf000000000000000000000000000000000000000000000000000000008152600401610bdc92919061205e565b60405180910390fd5b5050505050505050565b5f610bfa8383611542565b905092915050565b5f5f60015f91509150915091565b5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610cc257335f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040517f0c423fcf000000000000000000000000000000000000000000000000000000008152600401610cb992919061205e565b60405180910390fd5b505050565b60015481565b5f309050919050565b5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610d8957335f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040517f0c423fcf000000000000000000000000000000000000000000000000000000008152600401610d8092919061205e565b60405180910390fd5b5f905092915050565b5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610e4457335f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040517f0c423fcf000000000000000000000000000000000000000000000000000000008152600401610e3b92919061205e565b60405180910390fd5b50505050565b7309df6a941ee03b1e632904e382e10862fa9cc0e381565b5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610f1457335f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040517f0c423fcf000000000000000000000000000000000000000000000000000000008152600401610f0b92919061205e565b60405180910390fd5b5050565b5f5f60015f91509150915091565b5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610fd857335f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040517f0c423fcf000000000000000000000000000000000000000000000000000000008152600401610fcf92919061205e565b60405180910390fd5b5050505050565b5f7309df6a941ee03b1e632904e382e10862fa9cc0e3905090565b5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146110ac57335f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040517f0c423fcf0000000000000000000000000000000000000000000000000000000081526004016110a392919061205e565b60405180910390fd5b5050565b5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461116257335f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040517f0c423fcf00000000000000000000000000000000000000000000000000000000815260040161115992919061205e565b60405180910390fd5b50565b5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461123e57335f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040517f0c423fcf00000000000000000000000000000000000000000000000000000000815260040161123592919061205e565b60405180910390fd5b5050565b5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146112f457335f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040517f0c423fcf0000000000000000000000000000000000000000000000000000000081526004016112eb92919061205e565b60405180910390fd5b505050565b5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146113ab57335f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040517f0c423fcf0000000000000000000000000000000000000000000000000000000081526004016113a292919061205e565b60405180910390fd5b505050505050565b5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461146557335f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040517f0c423fcf00000000000000000000000000000000000000000000000000000000815260040161145c92919061205e565b60405180910390fd5b50565b5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461151a57335f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040517f0c423fcf00000000000000000000000000000000000000000000000000000000815260040161151192919061205e565b60405180910390fd5b50565b60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f61155c8280360381019061155791906121b4565b6115c7565b1561156a57600190506115c1565b5f6115848380360381019061157f91906121b4565b611643565b90506115bd8160035f8767ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f206116d990919063ffffffff16565b9150505b92915050565b5f6115d182611706565b15611617575f82602001515f1c90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161491505061163e565b61162082611738565b1561163a575f82602001515f1c90505f811491505061163e565b5f90505b919050565b5f61164d82611706565b156116605781602001515f1c90506116d4565b61166982611738565b156116825761167b826020015161176a565b90506116d4565b815f01516001811115611698576116976121df565b5b6040517fea8b16ba0000000000000000000000000000000000000000000000000000000081526004016116cb9190611ce2565b60405180910390fd5b919050565b5f6116fe835f018373ffffffffffffffffffffffffffffffffffffffff165f1b61178b565b905092915050565b5f60018081111561171a576117196121df565b5b825f015160018111156117305761172f6121df565b5b149050919050565b5f5f600181111561174c5761174b6121df565b5b825f01516001811115611762576117616121df565b5b149050919050565b5f815f1c73ffffffff00000000000000000000000000000000179050919050565b5f5f836001015f8481526020019081526020015f20541415905092915050565b5f604051905090565b5f5ffd5b5f5ffd5b5f67ffffffffffffffff82169050919050565b6117d8816117bc565b81146117e2575f5ffd5b50565b5f813590506117f3816117cf565b92915050565b5f6020828403121561180e5761180d6117b4565b5b5f61181b848285016117e5565b91505092915050565b5f8115159050919050565b61183881611824565b82525050565b611847816117bc565b82525050565b5f6040820190506118605f83018561182f565b61186d602083018461183e565b9392505050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61189d82611874565b9050919050565b6118ad81611893565b82525050565b5f6020820190506118c65f8301846118a4565b92915050565b5f5ffd5b5f5ffd5b5f5ffd5b5f5f83601f8401126118ed576118ec6118cc565b5b8235905067ffffffffffffffff81111561190a576119096118d0565b5b602083019150836001820283011115611926576119256118d4565b5b9250929050565b5f60ff82169050919050565b6119428161192d565b811461194c575f5ffd5b50565b5f8135905061195d81611939565b92915050565b5f5f5f5f6060858703121561197b5761197a6117b4565b5b5f611988878288016117e5565b945050602085013567ffffffffffffffff8111156119a9576119a86117b8565b5b6119b5878288016118d8565b935093505060406119c88782880161194f565b91505092959194509250565b5f6119de82611874565b9050919050565b6119ee816119d4565b81146119f8575f5ffd5b50565b5f81359050611a09816119e5565b92915050565b5f5f5f60608486031215611a2657611a256117b4565b5b5f611a33868287016117e5565b9350506020611a44868287016119fb565b9250506040611a55868287016119fb565b9150509250925092565b611a68816119d4565b82525050565b5f602082019050611a815f830184611a5f565b92915050565b5f5ffd5b5f60408284031215611aa057611a9f611a87565b5b81905092915050565b5f5f60408385031215611abf57611abe6117b4565b5b5f611acc858286016117e5565b925050602083013567ffffffffffffffff811115611aed57611aec6117b8565b5b611af985828601611a8b565b9150509250929050565b5f602082019050611b165f83018461182f565b92915050565b5f5f5f5f5f5f5f5f60c0898b031215611b3857611b376117b4565b5b5f611b458b828c016117e5565b9850506020611b568b828c0161194f565b9750506040611b678b828c016117e5565b965050606089013567ffffffffffffffff811115611b8857611b876117b8565b5b611b948b828c01611a8b565b955050608089013567ffffffffffffffff811115611bb557611bb46117b8565b5b611bc18b828c016118d8565b945094505060a089013567ffffffffffffffff811115611be457611be36117b8565b5b611bf08b828c016118d8565b92509250509295985092959890939650565b5f60408284031215611c1757611c16611a87565b5b81905092915050565b5f5f60608385031215611c3657611c356117b4565b5b5f611c43858286016117e5565b9250506020611c5485828601611c02565b9150509250929050565b5f5f5f60608486031215611c7557611c746117b4565b5b5f84013567ffffffffffffffff811115611c9257611c916117b8565b5b611c9e86828701611a8b565b9350506020611caf868287016117e5565b9250506040611cc08682870161194f565b9150509250925092565b5f819050919050565b611cdc81611cca565b82525050565b5f602082019050611cf55f830184611cd3565b92915050565b611d048161192d565b82525050565b5f604082019050611d1d5f83018561182f565b611d2a6020830184611cfb565b9392505050565b5f5f5f5f5f60808688031215611d4a57611d496117b4565b5b5f611d57888289016117e5565b9550506020611d688882890161194f565b9450506040611d79888289016117e5565b935050606086013567ffffffffffffffff811115611d9a57611d996117b8565b5b611da6888289016118d8565b92509250509295509295909350565b5f5f60408385031215611dcb57611dca6117b4565b5b5f611dd8858286016117e5565b9250506020611de9858286016119fb565b9150509250929050565b5f6101208284031215611e0957611e08611a87565b5b81905092915050565b5f60208284031215611e2757611e266117b4565b5b5f82013567ffffffffffffffff811115611e4457611e436117b8565b5b611e5084828501611df3565b91505092915050565b5f5f60408385031215611e6f57611e6e6117b4565b5b5f83013567ffffffffffffffff811115611e8c57611e8b6117b8565b5b611e9885828601611a8b565b9250506020611ea9858286016117e5565b9150509250929050565b5f5f5f60408486031215611eca57611ec96117b4565b5b5f84013567ffffffffffffffff811115611ee757611ee66117b8565b5b611ef386828701611a8b565b935050602084013567ffffffffffffffff811115611f1457611f136117b8565b5b611f20868287016118d8565b92509250509250925092565b5f5f83601f840112611f4157611f406118cc565b5b8235905067ffffffffffffffff811115611f5e57611f5d6118d0565b5b602083019150836020820283011115611f7a57611f796118d4565b5b9250929050565b5f5f5f5f5f5f60a08789031215611f9b57611f9a6117b4565b5b5f611fa889828a016117e5565b9650506020611fb989828a016117e5565b9550506040611fca89828a016119fb565b945050606087013567ffffffffffffffff811115611feb57611fea6117b8565b5b611ff789828a01611f2c565b9350935050608061200a89828a016117e5565b9150509295509295509295565b5f6020828403121561202c5761202b6117b4565b5b5f82013567ffffffffffffffff811115612049576120486117b8565b5b61205584828501611a8b565b91505092915050565b5f6040820190506120715f830185611a5f565b61207e6020830184611a5f565b9392505050565b5f5ffd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6120cf82612089565b810181811067ffffffffffffffff821117156120ee576120ed612099565b5b80604052505050565b5f6121006117ab565b905061210c82826120c6565b919050565b6002811061211d575f5ffd5b50565b5f8135905061212e81612111565b92915050565b5f819050919050565b61214681612134565b8114612150575f5ffd5b50565b5f813590506121618161213d565b92915050565b5f6040828403121561217c5761217b612085565b5b61218660406120f7565b90505f61219584828501612120565b5f8301525060206121a884828501612153565b60208301525092915050565b5f604082840312156121c9576121c86117b4565b5b5f6121d684828501612167565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffdfea2646970667358221220efe83d57b98fd6b4823962803c08507d94a4eb16bbdbab49ff187f2034718f0e64736f6c634300081b0033","sourceMap":"331:66:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2464:203:3;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;6826:201;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;4946:182;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;1529:239;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;586:44:9;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;6234:183:3;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;6648:127;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;521:58:9;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1249:116;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;5936:247:3;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;4442:304;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;7078:247;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2982:196;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;3390:226;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;1037:33;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;6468:129;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;5403:246;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;5179:173;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;386:79:9;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;5700:185:3;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;2722:205;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;4185:206;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;1024:104:9;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;4797:98:3;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;3229:110;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;1506:138:9;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3667:177:3;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;1819:212;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;3895:239;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;2246:163;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;2082:113;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;1132:29;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2464:203;2543:15;2560;2652:4;2658:1;2644:16;;;;2464:203;;;:::o;6826:201::-;6935:39;7005:14;;;;;;;;;;;6990:30;;6826:201;;;:::o;4946:182::-;2154:29:9;;;;;;;;;;;2140:43;;:10;:43;;;2136:164;;2247:10;2259:29;;;;;;;;;;;2206:83;;;;;;;;;;;;:::i;:::-;;;;;;;;2136:164;4946:182:3;;;;:::o;1529:239::-;423:42:9;1812:24;;:10;:24;;;1808:106;;1880:10;423:42;1859:44;;;;;;;;;;;;:::i;:::-;;;;;;;;1808:106;1672:11:3::1;1651:32;;:18;:32;;;;1710:5;1693:14;;:22;;;;;;;;;;;;;;;;;;1757:4;1725:29;;:36;;;;;;;;;;;;;;;;;;1529:239:::0;;;:::o;586:44:9:-;;;;;;;;;;;;;:::o;6234:183:3:-;2154:29:9;;;;;;;;;;;2140:43;;:10;:43;;;2136:164;;2247:10;2259:29;;;;;;;;;;;2206:83;;;;;;;;;;;;:::i;:::-;;;;;;;;2136:164;6234:183:3;;:::o;6648:127::-;6715:21;6763:4;6748:20;;6648:127;;;:::o;521:58:9:-;570:8;521:58;:::o;1249:116::-;1297:28;570:8;1337:21;;1249:116;:::o;5936:247:3:-;6136:12;2154:29:9;;;;;;;;;;;2140:43;;:10;:43;;;2136:164;;2247:10;2259:29;;;;;;;;;;;2206:83;;;;;;;;;;;;:::i;:::-;;;;;;;;2136:164;6171:5:3::1;6164:12;;5936:247:::0;;;;:::o;4442:304::-;2154:29:9;;;;;;;;;;;2140:43;;:10;:43;;;2136:164;;2247:10;2259:29;;;;;;;;;;;2206:83;;;;;;;;;;;;:::i;:::-;;;;;;;;2136:164;4442:304:3;;;;;;;;:::o;7078:247::-;7246:14;7283:35;7301:9;7312:5;7283:17;:35::i;:::-;7276:42;;7078:247;;;;:::o;2982:196::-;3058:15;3075:13;3163:4;3169:1;3155:16;;;;2982:196;;;:::o;3390:226::-;2154:29:9;;;;;;;;;;;2140:43;;:10;:43;;;2136:164;;2247:10;2259:29;;;;;;;;;;;2206:83;;;;;;;;;;;;:::i;:::-;;;;;;;;2136:164;3390:226:3;;;:::o;1037:33::-;;;;:::o;6468:129::-;6536:22;6585:4;6570:20;;6468:129;;;:::o;5403:246::-;5602:12;2154:29:9;;;;;;;;;;;2140:43;;:10;:43;;;2136:164;;2247:10;2259:29;;;;;;;;;;;2206:83;;;;;;;;;;;;:::i;:::-;;;;;;;;2136:164;5637:5:3::1;5630:12;;5403:246:::0;;;;:::o;5179:173::-;2154:29:9;;;;;;;;;;;2140:43;;:10;:43;;;2136:164;;2247:10;2259:29;;;;;;;;;;;2206:83;;;;;;;;;;;;:::i;:::-;;;;;;;;2136:164;5179:173:3;;;;:::o;386:79:9:-;423:42;386:79;:::o;5700:185:3:-;2154:29:9;;;;;;;;;;;2140:43;;:10;:43;;;2136:164;;2247:10;2259:29;;;;;;;;;;;2206:83;;;;;;;;;;;;:::i;:::-;;;;;;;;2136:164;5700:185:3;;:::o;2722:205::-;2802:15;2819;2912:4;2918:1;2904:16;;;;2722:205;;;:::o;4185:206::-;2154:29:9;;;;;;;;;;;2140:43;;:10;:43;;;2136:164;;2247:10;2259:29;;;;;;;;;;;2206:83;;;;;;;;;;;;:::i;:::-;;;;;;;;2136:164;4185:206:3;;;;;:::o;1024:104:9:-;1068:24;423:42;1104:17;;1024:104;:::o;4797:98:3:-;2154:29:9;;;;;;;;;;;2140:43;;:10;:43;;;2136:164;;2247:10;2259:29;;;;;;;;;;;2206:83;;;;;;;;;;;;:::i;:::-;;;;;;;;2136:164;4797:98:3;;:::o;3229:110::-;2154:29:9;;;;;;;;;;;2140:43;;:10;:43;;;2136:164;;2247:10;2259:29;;;;;;;;;;;2206:83;;;;;;;;;;;;:::i;:::-;;;;;;;;2136:164;3229:110:3;:::o;1506:138:9:-;1577:12;1608:29;;;;;;;;;;;1601:36;;1506:138;:::o;3667:177:3:-;2154:29:9;;;;;;;;;;;2140:43;;:10;:43;;;2136:164;;2247:10;2259:29;;;;;;;;;;;2206:83;;;;;;;;;;;;:::i;:::-;;;;;;;;2136:164;3667:177:3;;:::o;1819:212::-;2154:29:9;;;;;;;;;;;2140:43;;:10;:43;;;2136:164;;2247:10;2259:29;;;;;;;;;;;2206:83;;;;;;;;;;;;:::i;:::-;;;;;;;;2136:164;1819:212:3;;;:::o;3895:239::-;2154:29:9;;;;;;;;;;;2140:43;;:10;:43;;;2136:164;;2247:10;2259:29;;;;;;;;;;;2206:83;;;;;;;;;;;;:::i;:::-;;;;;;;;2136:164;3895:239:3;;;;;;:::o;2246:163::-;2154:29:9;;;;;;;;;;;2140:43;;:10;:43;;;2136:164;;2247:10;2259:29;;;;;;;;;;;2206:83;;;;;;;;;;;;:::i;:::-;;;;;;;;2136:164;2246:163:3;:::o;2082:113::-;2154:29:9;;;;;;;;;;;2140:43;;:10;:43;;;2136:164;;2247:10;2259:29;;;;;;;;;;;2206:83;;;;;;;;;;;;:::i;:::-;;;;;;;;2136:164;2082:113:3;:::o;1132:29::-;;;;;;;;;;;;;:::o;11561:381::-;11666:4;11733:16;:5;:14;;;;;;;;;;:::i;:::-;;:16::i;:::-;11729:207;;;11772:4;11765:11;;;;11729:207;11807:20;11830:17;:5;:15;;;;;;;;;;:::i;:::-;;:17::i;:::-;11807:40;;11868:57;11912:12;11868:23;:34;11892:9;11868:34;;;;;;;;;;;;;;;:43;;:57;;;;:::i;:::-;11861:64;;;11561:381;;;;;:::o;6143:404:7:-;6204:4;6224:14;6232:5;6224:7;:14::i;:::-;6220:321;;;6254:20;6301:5;:10;;;6293:19;;6254:60;;6360:1;6336:26;;:12;:26;;;6328:35;;;;;6220:321;6384:15;6393:5;6384:8;:15::i;:::-;6380:161;;;6415:15;6441:5;:10;;;6433:19;;6415:37;;6485:1;6474:7;:12;6466:21;;;;;6380:161;6525:5;6518:12;;6143:404;;;;:::o;1620:335::-;1682:7;1705:14;1713:5;1705:7;:14::i;:::-;1701:248;;;1766:5;:10;;;1758:19;;1735:44;;;;1701:248;1800:15;1809:5;1800:8;:15::i;:::-;1796:153;;;1838:21;1848:5;:10;;;1838:9;:21::i;:::-;1831:28;;;;1796:153;1926:5;:10;;;1918:19;;;;;;;;:::i;:::-;;1897:41;;;;;;;;;;;:::i;:::-;;;;;;;;1620:335;;;;:::o;8844:165:1:-;8924:4;8947:55;8957:3;:10;;8993:5;8977:23;;8969:32;;8947:9;:55::i;:::-;8940:62;;8844:165;;;;:::o;4496:114:7:-;4556:4;4593:10;4579:24;;;;;;;;:::i;:::-;;:5;:10;;;:24;;;;;;;;:::i;:::-;;;4572:31;;4496:114;;;:::o;4892:116::-;4953:4;4990:11;4976:25;;;;;;;;:::i;:::-;;:5;:10;;;:25;;;;;;;;:::i;:::-;;;4969:32;;4892:116;;;:::o;2271:387::-;2330:7;2641;2633:16;;2612:17;2604:45;2581:70;;2271:387;;;:::o;4264:129:1:-;4337:4;4385:1;4360:3;:14;;:21;4375:5;4360:21;;;;;;;;;;;;:26;;4353:33;;4264:129;;;;:::o;7:75:11:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:101;370:7;410:18;403:5;399:30;388:41;;334:101;;;:::o;441:120::-;513:23;530:5;513:23;:::i;:::-;506:5;503:34;493:62;;551:1;548;541:12;493:62;441:120;:::o;567:137::-;612:5;650:6;637:20;628:29;;666:32;692:5;666:32;:::i;:::-;567:137;;;;:::o;710:327::-;768:6;817:2;805:9;796:7;792:23;788:32;785:119;;;823:79;;:::i;:::-;785:119;943:1;968:52;1012:7;1003:6;992:9;988:22;968:52;:::i;:::-;958:62;;914:116;710:327;;;;:::o;1043:90::-;1077:7;1120:5;1113:13;1106:21;1095:32;;1043:90;;;:::o;1139:109::-;1220:21;1235:5;1220:21;:::i;:::-;1215:3;1208:34;1139:109;;:::o;1254:115::-;1339:23;1356:5;1339:23;:::i;:::-;1334:3;1327:36;1254:115;;:::o;1375:316::-;1488:4;1526:2;1515:9;1511:18;1503:26;;1539:65;1601:1;1590:9;1586:17;1577:6;1539:65;:::i;:::-;1614:70;1680:2;1669:9;1665:18;1656:6;1614:70;:::i;:::-;1375:316;;;;;:::o;1697:126::-;1734:7;1774:42;1767:5;1763:54;1752:65;;1697:126;;;:::o;1829:104::-;1874:7;1903:24;1921:5;1903:24;:::i;:::-;1892:35;;1829:104;;;:::o;1939:142::-;2042:32;2068:5;2042:32;:::i;:::-;2037:3;2030:45;1939:142;;:::o;2087:254::-;2196:4;2234:2;2223:9;2219:18;2211:26;;2247:87;2331:1;2320:9;2316:17;2307:6;2247:87;:::i;:::-;2087:254;;;;:::o;2347:117::-;2456:1;2453;2446:12;2470:117;2579:1;2576;2569:12;2593:117;2702:1;2699;2692:12;2729:552;2786:8;2796:6;2846:3;2839:4;2831:6;2827:17;2823:27;2813:122;;2854:79;;:::i;:::-;2813:122;2967:6;2954:20;2944:30;;2997:18;2989:6;2986:30;2983:117;;;3019:79;;:::i;:::-;2983:117;3133:4;3125:6;3121:17;3109:29;;3187:3;3179:4;3171:6;3167:17;3157:8;3153:32;3150:41;3147:128;;;3194:79;;:::i;:::-;3147:128;2729:552;;;;;:::o;3287:86::-;3322:7;3362:4;3355:5;3351:16;3340:27;;3287:86;;;:::o;3379:118::-;3450:22;3466:5;3450:22;:::i;:::-;3443:5;3440:33;3430:61;;3487:1;3484;3477:12;3430:61;3379:118;:::o;3503:135::-;3547:5;3585:6;3572:20;3563:29;;3601:31;3626:5;3601:31;:::i;:::-;3503:135;;;;:::o;3644:811::-;3729:6;3737;3745;3753;3802:2;3790:9;3781:7;3777:23;3773:32;3770:119;;;3808:79;;:::i;:::-;3770:119;3928:1;3953:52;3997:7;3988:6;3977:9;3973:22;3953:52;:::i;:::-;3943:62;;3899:116;4082:2;4071:9;4067:18;4054:32;4113:18;4105:6;4102:30;4099:117;;;4135:79;;:::i;:::-;4099:117;4248:64;4304:7;4295:6;4284:9;4280:22;4248:64;:::i;:::-;4230:82;;;;4025:297;4361:2;4387:51;4430:7;4421:6;4410:9;4406:22;4387:51;:::i;:::-;4377:61;;4332:116;3644:811;;;;;;;:::o;4461:96::-;4498:7;4527:24;4545:5;4527:24;:::i;:::-;4516:35;;4461:96;;;:::o;4563:122::-;4636:24;4654:5;4636:24;:::i;:::-;4629:5;4626:35;4616:63;;4675:1;4672;4665:12;4616:63;4563:122;:::o;4691:139::-;4737:5;4775:6;4762:20;4753:29;;4791:33;4818:5;4791:33;:::i;:::-;4691:139;;;;:::o;4836:617::-;4912:6;4920;4928;4977:2;4965:9;4956:7;4952:23;4948:32;4945:119;;;4983:79;;:::i;:::-;4945:119;5103:1;5128:52;5172:7;5163:6;5152:9;5148:22;5128:52;:::i;:::-;5118:62;;5074:116;5229:2;5255:53;5300:7;5291:6;5280:9;5276:22;5255:53;:::i;:::-;5245:63;;5200:118;5357:2;5383:53;5428:7;5419:6;5408:9;5404:22;5383:53;:::i;:::-;5373:63;;5328:118;4836:617;;;;;:::o;5459:118::-;5546:24;5564:5;5546:24;:::i;:::-;5541:3;5534:37;5459:118;;:::o;5583:222::-;5676:4;5714:2;5703:9;5699:18;5691:26;;5727:71;5795:1;5784:9;5780:17;5771:6;5727:71;:::i;:::-;5583:222;;;;:::o;5811:117::-;5920:1;5917;5910:12;5985:243;6070:5;6111:2;6102:6;6097:3;6093:16;6089:25;6086:112;;;6117:79;;:::i;:::-;6086:112;6216:6;6207:15;;5985:243;;;;:::o;6234:710::-;6340:6;6348;6397:2;6385:9;6376:7;6372:23;6368:32;6365:119;;;6403:79;;:::i;:::-;6365:119;6523:1;6548:52;6592:7;6583:6;6572:9;6568:22;6548:52;:::i;:::-;6538:62;;6494:116;6677:2;6666:9;6662:18;6649:32;6708:18;6700:6;6697:30;6694:117;;;6730:79;;:::i;:::-;6694:117;6835:92;6919:7;6910:6;6899:9;6895:22;6835:92;:::i;:::-;6825:102;;6620:317;6234:710;;;;;:::o;6950:210::-;7037:4;7075:2;7064:9;7060:18;7052:26;;7088:65;7150:1;7139:9;7135:17;7126:6;7088:65;:::i;:::-;6950:210;;;;:::o;7166:1683::-;7327:6;7335;7343;7351;7359;7367;7375;7383;7432:3;7420:9;7411:7;7407:23;7403:33;7400:120;;;7439:79;;:::i;:::-;7400:120;7559:1;7584:52;7628:7;7619:6;7608:9;7604:22;7584:52;:::i;:::-;7574:62;;7530:116;7685:2;7711:51;7754:7;7745:6;7734:9;7730:22;7711:51;:::i;:::-;7701:61;;7656:116;7811:2;7837:52;7881:7;7872:6;7861:9;7857:22;7837:52;:::i;:::-;7827:62;;7782:117;7966:2;7955:9;7951:18;7938:32;7997:18;7989:6;7986:30;7983:117;;;8019:79;;:::i;:::-;7983:117;8124:92;8208:7;8199:6;8188:9;8184:22;8124:92;:::i;:::-;8114:102;;7909:317;8293:3;8282:9;8278:19;8265:33;8325:18;8317:6;8314:30;8311:117;;;8347:79;;:::i;:::-;8311:117;8460:64;8516:7;8507:6;8496:9;8492:22;8460:64;:::i;:::-;8442:82;;;;8236:298;8601:3;8590:9;8586:19;8573:33;8633:18;8625:6;8622:30;8619:117;;;8655:79;;:::i;:::-;8619:117;8768:64;8824:7;8815:6;8804:9;8800:22;8768:64;:::i;:::-;8750:82;;;;8544:298;7166:1683;;;;;;;;;;;:::o;8882:229::-;8953:5;8994:2;8985:6;8980:3;8976:16;8972:25;8969:112;;;9000:79;;:::i;:::-;8969:112;9099:6;9090:15;;8882:229;;;;:::o;9117:522::-;9209:6;9217;9266:2;9254:9;9245:7;9241:23;9237:32;9234:119;;;9272:79;;:::i;:::-;9234:119;9392:1;9417:52;9461:7;9452:6;9441:9;9437:22;9417:52;:::i;:::-;9407:62;;9363:116;9518:2;9544:78;9614:7;9605:6;9594:9;9590:22;9544:78;:::i;:::-;9534:88;;9489:143;9117:522;;;;;:::o;9645:851::-;9758:6;9766;9774;9823:2;9811:9;9802:7;9798:23;9794:32;9791:119;;;9829:79;;:::i;:::-;9791:119;9977:1;9966:9;9962:17;9949:31;10007:18;9999:6;9996:30;9993:117;;;10029:79;;:::i;:::-;9993:117;10134:92;10218:7;10209:6;10198:9;10194:22;10134:92;:::i;:::-;10124:102;;9920:316;10275:2;10301:52;10345:7;10336:6;10325:9;10321:22;10301:52;:::i;:::-;10291:62;;10246:117;10402:2;10428:51;10471:7;10462:6;10451:9;10447:22;10428:51;:::i;:::-;10418:61;;10373:116;9645:851;;;;;:::o;10502:77::-;10539:7;10568:5;10557:16;;10502:77;;;:::o;10585:118::-;10672:24;10690:5;10672:24;:::i;:::-;10667:3;10660:37;10585:118;;:::o;10709:222::-;10802:4;10840:2;10829:9;10825:18;10817:26;;10853:71;10921:1;10910:9;10906:17;10897:6;10853:71;:::i;:::-;10709:222;;;;:::o;10937:112::-;11020:22;11036:5;11020:22;:::i;:::-;11015:3;11008:35;10937:112;;:::o;11055:312::-;11166:4;11204:2;11193:9;11189:18;11181:26;;11217:65;11279:1;11268:9;11264:17;11255:6;11217:65;:::i;:::-;11292:68;11356:2;11345:9;11341:18;11332:6;11292:68;:::i;:::-;11055:312;;;;;:::o;11373:955::-;11466:6;11474;11482;11490;11498;11547:3;11535:9;11526:7;11522:23;11518:33;11515:120;;;11554:79;;:::i;:::-;11515:120;11674:1;11699:52;11743:7;11734:6;11723:9;11719:22;11699:52;:::i;:::-;11689:62;;11645:116;11800:2;11826:51;11869:7;11860:6;11849:9;11845:22;11826:51;:::i;:::-;11816:61;;11771:116;11926:2;11952:52;11996:7;11987:6;11976:9;11972:22;11952:52;:::i;:::-;11942:62;;11897:117;12081:2;12070:9;12066:18;12053:32;12112:18;12104:6;12101:30;12098:117;;;12134:79;;:::i;:::-;12098:117;12247:64;12303:7;12294:6;12283:9;12279:22;12247:64;:::i;:::-;12229:82;;;;12024:297;11373:955;;;;;;;;:::o;12334:472::-;12401:6;12409;12458:2;12446:9;12437:7;12433:23;12429:32;12426:119;;;12464:79;;:::i;:::-;12426:119;12584:1;12609:52;12653:7;12644:6;12633:9;12629:22;12609:52;:::i;:::-;12599:62;;12555:116;12710:2;12736:53;12781:7;12772:6;12761:9;12757:22;12736:53;:::i;:::-;12726:63;;12681:118;12334:472;;;;;:::o;12857:238::-;12936:5;12977:3;12968:6;12963:3;12959:16;12955:26;12952:113;;;12984:79;;:::i;:::-;12952:113;13083:6;13074:15;;12857:238;;;;:::o;13101:555::-;13193:6;13242:2;13230:9;13221:7;13217:23;13213:32;13210:119;;;13248:79;;:::i;:::-;13210:119;13396:1;13385:9;13381:17;13368:31;13426:18;13418:6;13415:30;13412:117;;;13448:79;;:::i;:::-;13412:117;13553:86;13631:7;13622:6;13611:9;13607:22;13553:86;:::i;:::-;13543:96;;13339:310;13101:555;;;;:::o;13662:710::-;13768:6;13776;13825:2;13813:9;13804:7;13800:23;13796:32;13793:119;;;13831:79;;:::i;:::-;13793:119;13979:1;13968:9;13964:17;13951:31;14009:18;14001:6;13998:30;13995:117;;;14031:79;;:::i;:::-;13995:117;14136:92;14220:7;14211:6;14200:9;14196:22;14136:92;:::i;:::-;14126:102;;13922:316;14277:2;14303:52;14347:7;14338:6;14327:9;14323:22;14303:52;:::i;:::-;14293:62;;14248:117;13662:710;;;;;:::o;14378:910::-;14496:6;14504;14512;14561:2;14549:9;14540:7;14536:23;14532:32;14529:119;;;14567:79;;:::i;:::-;14529:119;14715:1;14704:9;14700:17;14687:31;14745:18;14737:6;14734:30;14731:117;;;14767:79;;:::i;:::-;14731:117;14872:92;14956:7;14947:6;14936:9;14932:22;14872:92;:::i;:::-;14862:102;;14658:316;15041:2;15030:9;15026:18;15013:32;15072:18;15064:6;15061:30;15058:117;;;15094:79;;:::i;:::-;15058:117;15207:64;15263:7;15254:6;15243:9;15239:22;15207:64;:::i;:::-;15189:82;;;;14984:297;14378:910;;;;;:::o;15311:568::-;15384:8;15394:6;15444:3;15437:4;15429:6;15425:17;15421:27;15411:122;;15452:79;;:::i;:::-;15411:122;15565:6;15552:20;15542:30;;15595:18;15587:6;15584:30;15581:117;;;15617:79;;:::i;:::-;15581:117;15731:4;15723:6;15719:17;15707:29;;15785:3;15777:4;15769:6;15765:17;15755:8;15751:32;15748:41;15745:128;;;15792:79;;:::i;:::-;15745:128;15311:568;;;;;:::o;15885:1135::-;16004:6;16012;16020;16028;16036;16044;16093:3;16081:9;16072:7;16068:23;16064:33;16061:120;;;16100:79;;:::i;:::-;16061:120;16220:1;16245:52;16289:7;16280:6;16269:9;16265:22;16245:52;:::i;:::-;16235:62;;16191:116;16346:2;16372:52;16416:7;16407:6;16396:9;16392:22;16372:52;:::i;:::-;16362:62;;16317:117;16473:2;16499:53;16544:7;16535:6;16524:9;16520:22;16499:53;:::i;:::-;16489:63;;16444:118;16629:2;16618:9;16614:18;16601:32;16660:18;16652:6;16649:30;16646:117;;;16682:79;;:::i;:::-;16646:117;16795:80;16867:7;16858:6;16847:9;16843:22;16795:80;:::i;:::-;16777:98;;;;16572:313;16924:3;16951:52;16995:7;16986:6;16975:9;16971:22;16951:52;:::i;:::-;16941:62;;16895:118;15885:1135;;;;;;;;:::o;17026:567::-;17124:6;17173:2;17161:9;17152:7;17148:23;17144:32;17141:119;;;17179:79;;:::i;:::-;17141:119;17327:1;17316:9;17312:17;17299:31;17357:18;17349:6;17346:30;17343:117;;;17379:79;;:::i;:::-;17343:117;17484:92;17568:7;17559:6;17548:9;17544:22;17484:92;:::i;:::-;17474:102;;17270:316;17026:567;;;;:::o;17599:332::-;17720:4;17758:2;17747:9;17743:18;17735:26;;17771:71;17839:1;17828:9;17824:17;17815:6;17771:71;:::i;:::-;17852:72;17920:2;17909:9;17905:18;17896:6;17852:72;:::i;:::-;17599:332;;;;;:::o;17937:117::-;18046:1;18043;18036:12;18060:102;18101:6;18152:2;18148:7;18143:2;18136:5;18132:14;18128:28;18118:38;;18060:102;;;:::o;18168:180::-;18216:77;18213:1;18206:88;18313:4;18310:1;18303:15;18337:4;18334:1;18327:15;18354:281;18437:27;18459:4;18437:27;:::i;:::-;18429:6;18425:40;18567:6;18555:10;18552:22;18531:18;18519:10;18516:34;18513:62;18510:88;;;18578:18;;:::i;:::-;18510:88;18618:10;18614:2;18607:22;18397:238;18354:281;;:::o;18641:129::-;18675:6;18702:20;;:::i;:::-;18692:30;;18731:33;18759:4;18751:6;18731:33;:::i;:::-;18641:129;;;:::o;18899:108::-;18981:1;18974:5;18971:12;18961:40;;18997:1;18994;18987:12;18961:40;18899:108;:::o;19013:157::-;19068:5;19106:6;19093:20;19084:29;;19122:42;19158:5;19122:42;:::i;:::-;19013:157;;;;:::o;19176:77::-;19213:7;19242:5;19231:16;;19176:77;;;:::o;19259:122::-;19332:24;19350:5;19332:24;:::i;:::-;19325:5;19322:35;19312:63;;19371:1;19368;19361:12;19312:63;19259:122;:::o;19387:139::-;19433:5;19471:6;19458:20;19449:29;;19487:33;19514:5;19487:33;:::i;:::-;19387:139;;;;:::o;19559:581::-;19631:5;19675:4;19663:9;19658:3;19654:19;19650:30;19647:117;;;19683:79;;:::i;:::-;19647:117;19782:21;19798:4;19782:21;:::i;:::-;19773:30;;19862:1;19902:58;19956:3;19947:6;19936:9;19932:22;19902:58;:::i;:::-;19895:4;19888:5;19884:16;19877:84;19813:159;20031:2;20072:49;20117:3;20108:6;20097:9;20093:22;20072:49;:::i;:::-;20065:4;20058:5;20054:16;20047:75;19982:151;19559:581;;;;:::o;20146:375::-;20228:6;20277:2;20265:9;20256:7;20252:23;20248:32;20245:119;;;20283:79;;:::i;:::-;20245:119;20403:1;20428:76;20496:7;20487:6;20476:9;20472:22;20428:76;:::i;:::-;20418:86;;20374:140;20146:375;;;;:::o;20527:180::-;20575:77;20572:1;20565:88;20672:4;20669:1;20662:15;20696:4;20693:1;20686:15","linkReferences":{}},"methodIdentifiers":{"REWARDS_PALLET()":"1948fdbc","ROOT_CHAIN()":"884673ac","blueprintOwner()":"f8407662","canJoin(uint64,(bytes,string))":"760c379f","canLeave(uint64,(bytes,string))":"25489146","currentBlueprintId()":"5d79ea29","getHeartbeatInterval(uint64)":"0068080b","getHeartbeatThreshold(uint64)":"92cbb78e","getSlashingWindow(uint64)":"3fdadfcc","masterBlueprintServiceManager()":"0d0dd399","masterBlueprintServiceManagerAddress()":"a4d91fe9","onApprove((bytes,string),uint64,uint8)":"5287cd5f","onBlueprintCreated(uint64,address,address)":"0b6535d7","onJobCall(uint64,uint8,uint64,bytes)":"9838caa3","onJobResult(uint64,uint8,uint64,(bytes,string),bytes,bytes)":"29b98dc7","onOperatorJoined(uint64,(bytes,string))":"89270616","onOperatorLeft(uint64,(bytes,string))":"10f772b8","onRegister((bytes,string),bytes)":"c4b44839","onReject((bytes,string),uint64)":"a9c380e1","onRequest((uint64,address,(bytes,string)[],bytes,address[],uint64,(uint8,bytes32),uint256))":"a40a9527","onServiceInitialized(uint64,uint64,address,address[],uint64)":"d7deb482","onServiceTermination(uint64,address)":"a24e8a90","onSlash(uint64,bytes,uint8)":"7e14b919","onUnappliedSlash(uint64,bytes,uint8)":"0881898f","onUnregister((bytes,string))":"e0503b71","onUpdateRpcAddress((bytes,string))":"dcfee99a","queryDeveloperPaymentAddress(uint64)":"08179f35","queryDisputeOrigin(uint64)":"14b4df4c","queryIsPaymentAssetAllowed(uint64,(uint8,bytes32))":"3c3aa64c","querySlashingOrigin(uint64)":"74ceeb55","rewardsPallet()":"216e8042","rootChain()":"987ab9db"},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.27+commit.40a35a09\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"masterBlueprintServiceManager\",\"type\":\"address\"}],\"name\":\"OnlyMasterBlueprintServiceManagerAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rootChain\",\"type\":\"address\"}],\"name\":\"OnlyRootChainAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"kind\",\"type\":\"uint256\"}],\"name\":\"UnsupportedAssetKind\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"REWARDS_PALLET\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"ROOT_CHAIN\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"blueprintOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"serviceId\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"ecdsaPublicKey\",\"type\":\"bytes\"},{\"internalType\":\"string\",\"name\":\"rpcAddress\",\"type\":\"string\"}],\"internalType\":\"struct ServiceOperators.OperatorPreferences\",\"name\":\"operator\",\"type\":\"tuple\"}],\"name\":\"canJoin\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"serviceId\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"ecdsaPublicKey\",\"type\":\"bytes\"},{\"internalType\":\"string\",\"name\":\"rpcAddress\",\"type\":\"string\"}],\"internalType\":\"struct ServiceOperators.OperatorPreferences\",\"name\":\"operator\",\"type\":\"tuple\"}],\"name\":\"canLeave\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentBlueprintId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"serviceId\",\"type\":\"uint64\"}],\"name\":\"getHeartbeatInterval\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"useDefault\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"interval\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"serviceId\",\"type\":\"uint64\"}],\"name\":\"getHeartbeatThreshold\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"useDefault\",\"type\":\"bool\"},{\"internalType\":\"uint8\",\"name\":\"threshold\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"serviceId\",\"type\":\"uint64\"}],\"name\":\"getSlashingWindow\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"useDefault\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"window\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"masterBlueprintServiceManager\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"masterBlueprintServiceManagerAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"mbsm\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"ecdsaPublicKey\",\"type\":\"bytes\"},{\"internalType\":\"string\",\"name\":\"rpcAddress\",\"type\":\"string\"}],\"internalType\":\"struct ServiceOperators.OperatorPreferences\",\"name\":\"operator\",\"type\":\"tuple\"},{\"internalType\":\"uint64\",\"name\":\"requestId\",\"type\":\"uint64\"},{\"internalType\":\"uint8\",\"name\":\"restakingPercent\",\"type\":\"uint8\"}],\"name\":\"onApprove\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"blueprintId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"mbsm\",\"type\":\"address\"}],\"name\":\"onBlueprintCreated\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"serviceId\",\"type\":\"uint64\"},{\"internalType\":\"uint8\",\"name\":\"job\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"jobCallId\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"inputs\",\"type\":\"bytes\"}],\"name\":\"onJobCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"serviceId\",\"type\":\"uint64\"},{\"internalType\":\"uint8\",\"name\":\"job\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"jobCallId\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"ecdsaPublicKey\",\"type\":\"bytes\"},{\"internalType\":\"string\",\"name\":\"rpcAddress\",\"type\":\"string\"}],\"internalType\":\"struct ServiceOperators.OperatorPreferences\",\"name\":\"operator\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"inputs\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"outputs\",\"type\":\"bytes\"}],\"name\":\"onJobResult\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"serviceId\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"ecdsaPublicKey\",\"type\":\"bytes\"},{\"internalType\":\"string\",\"name\":\"rpcAddress\",\"type\":\"string\"}],\"internalType\":\"struct ServiceOperators.OperatorPreferences\",\"name\":\"operator\",\"type\":\"tuple\"}],\"name\":\"onOperatorJoined\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"serviceId\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"ecdsaPublicKey\",\"type\":\"bytes\"},{\"internalType\":\"string\",\"name\":\"rpcAddress\",\"type\":\"string\"}],\"internalType\":\"struct ServiceOperators.OperatorPreferences\",\"name\":\"operator\",\"type\":\"tuple\"}],\"name\":\"onOperatorLeft\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"ecdsaPublicKey\",\"type\":\"bytes\"},{\"internalType\":\"string\",\"name\":\"rpcAddress\",\"type\":\"string\"}],\"internalType\":\"struct ServiceOperators.OperatorPreferences\",\"name\":\"operator\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"registrationInputs\",\"type\":\"bytes\"}],\"name\":\"onRegister\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"ecdsaPublicKey\",\"type\":\"bytes\"},{\"internalType\":\"string\",\"name\":\"rpcAddress\",\"type\":\"string\"}],\"internalType\":\"struct ServiceOperators.OperatorPreferences\",\"name\":\"operator\",\"type\":\"tuple\"},{\"internalType\":\"uint64\",\"name\":\"requestId\",\"type\":\"uint64\"}],\"name\":\"onReject\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"requestId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"requester\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"ecdsaPublicKey\",\"type\":\"bytes\"},{\"internalType\":\"string\",\"name\":\"rpcAddress\",\"type\":\"string\"}],\"internalType\":\"struct ServiceOperators.OperatorPreferences[]\",\"name\":\"operators\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes\",\"name\":\"requestInputs\",\"type\":\"bytes\"},{\"internalType\":\"address[]\",\"name\":\"permittedCallers\",\"type\":\"address[]\"},{\"internalType\":\"uint64\",\"name\":\"ttl\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"enum Assets.Kind\",\"name\":\"kind\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"data\",\"type\":\"bytes32\"}],\"internalType\":\"struct Assets.Asset\",\"name\":\"paymentAsset\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"struct ServiceOperators.RequestParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"onRequest\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"requestId\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"serviceId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"permittedCallers\",\"type\":\"address[]\"},{\"internalType\":\"uint64\",\"name\":\"ttl\",\"type\":\"uint64\"}],\"name\":\"onServiceInitialized\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"serviceId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"onServiceTermination\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"serviceId\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offender\",\"type\":\"bytes\"},{\"internalType\":\"uint8\",\"name\":\"slashPercent\",\"type\":\"uint8\"}],\"name\":\"onSlash\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"serviceId\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offender\",\"type\":\"bytes\"},{\"internalType\":\"uint8\",\"name\":\"slashPercent\",\"type\":\"uint8\"}],\"name\":\"onUnappliedSlash\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"ecdsaPublicKey\",\"type\":\"bytes\"},{\"internalType\":\"string\",\"name\":\"rpcAddress\",\"type\":\"string\"}],\"internalType\":\"struct ServiceOperators.OperatorPreferences\",\"name\":\"operator\",\"type\":\"tuple\"}],\"name\":\"onUnregister\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"ecdsaPublicKey\",\"type\":\"bytes\"},{\"internalType\":\"string\",\"name\":\"rpcAddress\",\"type\":\"string\"}],\"internalType\":\"struct ServiceOperators.OperatorPreferences\",\"name\":\"operator\",\"type\":\"tuple\"}],\"name\":\"onUpdateRpcAddress\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"name\":\"queryDeveloperPaymentAddress\",\"outputs\":[{\"internalType\":\"address payable\",\"name\":\"developerPaymentAddress\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"name\":\"queryDisputeOrigin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"disputeOrigin\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"serviceId\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"enum Assets.Kind\",\"name\":\"kind\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"data\",\"type\":\"bytes32\"}],\"internalType\":\"struct Assets.Asset\",\"name\":\"asset\",\"type\":\"tuple\"}],\"name\":\"queryIsPaymentAssetAllowed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isAllowed\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"name\":\"querySlashingOrigin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"slashingOrigin\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"rewardsPallet\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rewardsPalletAddress\",\"type\":\"address\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"rootChain\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rootChainAddress\",\"type\":\"address\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"This contract is an example of a service blueprint that provides a single service.For all supported hooks, check the `BlueprintServiceManagerBase` contract.\",\"errors\":{\"UnsupportedAssetKind(uint256)\":[{\"details\":\"The asset kind is not supported by the library.\"}]},\"kind\":\"dev\",\"methods\":{\"canJoin(uint64,(bytes,string))\":{\"details\":\"Hook to check if an operator can join a service instance\",\"params\":{\"operator\":\"The operator's preferences and details\",\"serviceId\":\"The ID of the service instance\"},\"returns\":{\"allowed\":\"Returns true if the operator is allowed to join\"}},\"canLeave(uint64,(bytes,string))\":{\"details\":\"Hook to check if an operator can leave a service instance\",\"params\":{\"operator\":\"The operator's preferences and details\",\"serviceId\":\"The ID of the service instance\"},\"returns\":{\"allowed\":\"Returns true if the operator is allowed to leave\"}},\"getHeartbeatInterval(uint64)\":{\"details\":\"Get the heartbeat interval for a service.\",\"params\":{\"serviceId\":\"The ID of the service.\"},\"returns\":{\"interval\":\"The heartbeat interval in blocks. 0 means heartbeats are disabled.\",\"useDefault\":\"Whether to use the default value.\"}},\"getHeartbeatThreshold(uint64)\":{\"details\":\"Get the heartbeat threshold for a service.\",\"params\":{\"serviceId\":\"The ID of the service.\"},\"returns\":{\"threshold\":\"The heartbeat threshold percentage (0-100).\",\"useDefault\":\"Whether to use the default value.\"}},\"getSlashingWindow(uint64)\":{\"details\":\"Get the slashing window for a service.\",\"params\":{\"serviceId\":\"The ID of the service.\"},\"returns\":{\"useDefault\":\"Whether to use the default value.\",\"window\":\"The slashing window in blocks.\"}},\"masterBlueprintServiceManagerAddress()\":{\"details\":\"Get the master blueprint service manager address\",\"returns\":{\"mbsm\":\"The address of the master blueprint service manager\"}},\"onApprove((bytes,string),uint64,uint8)\":{\"details\":\"Hook for service request approval. Called when a service request is approved by an operator.\",\"params\":{\"operator\":\"The operator's details.\",\"requestId\":\"The ID of the request.\",\"restakingPercent\":\"The percentage of the restaking amount (0-100).\"}},\"onBlueprintCreated(uint64,address,address)\":{\"details\":\"Hook to handle blueprint creation. Gets called by the root chain when a new blueprint is created. Could be a good place to store the master blueprint service manager address or any other blueprint related data.\",\"params\":{\"blueprintId\":\"The unique identifier for the blueprint.\",\"mbsm\":\"The address of the master blueprint service manager.\",\"owner\":\"The address of the blueprint owner.\"}},\"onJobCall(uint64,uint8,uint64,bytes)\":{\"details\":\"Hook for job calls on the service. Called when a job is called within the service context.\",\"params\":{\"inputs\":\"Inputs required for the job execution in bytes format.\",\"job\":\"The job identifier.\",\"jobCallId\":\"A unique ID for the job call.\",\"serviceId\":\"The ID of the service where the job is called.\"}},\"onJobResult(uint64,uint8,uint64,(bytes,string),bytes,bytes)\":{\"details\":\"Hook for handling job result. Called when operators send the result of a job execution.\",\"params\":{\"inputs\":\"Inputs used for the job execution in bytes format.\",\"job\":\"The job identifier.\",\"jobCallId\":\"The unique ID for the job call.\",\"operator\":\"The operator sending the result in bytes format.\",\"outputs\":\"Outputs resulting from the job execution in bytes format.\",\"serviceId\":\"The ID of the service related to the job.\"}},\"onOperatorJoined(uint64,(bytes,string))\":{\"details\":\"Hook called after an operator has joined a service instance\",\"params\":{\"operator\":\"The operator's preferences and details\",\"serviceId\":\"The ID of the service instance\"}},\"onOperatorLeft(uint64,(bytes,string))\":{\"details\":\"Hook called after an operator has left a service instance\",\"params\":{\"operator\":\"The operator's preferences and details\",\"serviceId\":\"The ID of the service instance\"}},\"onRegister((bytes,string),bytes)\":{\"details\":\"Hook for service operator registration. Called when a service operator attempts to register with the blueprint.\",\"params\":{\"operator\":\"The operator's details.\",\"registrationInputs\":\"Inputs required for registration in bytes format.\"}},\"onReject((bytes,string),uint64)\":{\"details\":\"Hook for service request rejection. Called when a service request is rejected by an operator.\",\"params\":{\"operator\":\"The operator's details.\",\"requestId\":\"The ID of the request.\"}},\"onRequest((uint64,address,(bytes,string)[],bytes,address[],uint64,(uint8,bytes32),uint256))\":{\"details\":\"Hook for service instance requests. Called when a user requests a service instance from the blueprint but this does not mean the service is initiated yet. To get notified when the service is initiated, implement the `onServiceInitialized` hook.\",\"params\":{\"params\":\"The parameters for the service request.\"}},\"onServiceInitialized(uint64,uint64,address,address[],uint64)\":{\"details\":\"Hook for service initialization. Called when a service is initialized. This hook is called after the service is approved from all of the operators.\",\"params\":{\"owner\":\"The owner of the service.\",\"permittedCallers\":\"The list of permitted callers for the service.\",\"requestId\":\"The ID of the request.\",\"serviceId\":\"The ID of the service.\",\"ttl\":\"The time-to-live for the service.\"}},\"onServiceTermination(uint64,address)\":{\"details\":\"Hook for service termination. Called when a service is terminated.\",\"params\":{\"owner\":\"The owner of the service.\",\"serviceId\":\"The ID of the service to be terminated.\"}},\"onSlash(uint64,bytes,uint8)\":{\"details\":\"Hook for handling applied slashes. Called when a slash is applied to an offender.\",\"params\":{\"offender\":\"The offender's details in bytes format.\",\"serviceId\":\"The ID of the service related to the slash.\",\"slashPercent\":\"The percentage of the slash.\"}},\"onUnappliedSlash(uint64,bytes,uint8)\":{\"details\":\"Hook for handling unapplied slashes. Called when a slash is queued and still not yet applied to an offender.\",\"params\":{\"offender\":\"The offender's details in bytes format.\",\"serviceId\":\"The ID of the service related to the slash.\",\"slashPercent\":\"The percentage of the slash.\"}},\"onUnregister((bytes,string))\":{\"details\":\"Hook for service operator unregistration. Called when a service operator attempts to unregister from the blueprint.\",\"params\":{\"operator\":\"The operator's details.\"}},\"onUpdateRpcAddress((bytes,string))\":{\"details\":\"Hook for updating RPC address. Called when an operator updates their RPC address.\",\"params\":{\"operator\":\"The operator's details with the updated RPC address.\"}},\"queryDeveloperPaymentAddress(uint64)\":{\"details\":\"Query the developer payment address for a service. This mainly used by the runtime or the Master Blueprint Service Manager to determine the developer payment address for a service.\",\"params\":{\"serviceId\":\"The ID of the service.\"},\"returns\":{\"developerPaymentAddress\":\"The address of the developer payment address for that service\"}},\"queryDisputeOrigin(uint64)\":{\"details\":\"Query the dispute origin for a service. This mainly used by the runtime to determine the allowed account that can dispute an unapplied slash and remove it. by default, the service manager is the only account that can dispute a service. override this function to allow other accounts to dispute a service.\",\"params\":{\"serviceId\":\"The ID of the service.\"},\"returns\":{\"disputeOrigin\":\"The account that can dispute the unapplied slash for that service\"}},\"queryIsPaymentAssetAllowed(uint64,(uint8,bytes32))\":{\"details\":\"Determines if a specified payment asset is permitted for a given service.\",\"params\":{\"asset\":\"The asset to verify for allowance.\",\"serviceId\":\"The ID of the service to check against.\"},\"returns\":{\"isAllowed\":\"Returns true if the asset is allowed, false otherwise.\"}},\"querySlashingOrigin(uint64)\":{\"details\":\"Query the slashing origin for a service. This mainly used by the runtime to determine the allowed account that can slash a service. by default, the service manager is the only account that can slash a service. override this function to allow other accounts to slash a service.\",\"params\":{\"serviceId\":\"The ID of the service.\"},\"returns\":{\"slashingOrigin\":\"The account that can slash the offender.\"}},\"rewardsPallet()\":{\"details\":\"Get the rewards pallet address\",\"returns\":{\"rewardsPalletAddress\":\"The address of the rewards pallet\"}},\"rootChain()\":{\"details\":\"Get the root chain address\",\"returns\":{\"rootChainAddress\":\"The address of the root chain\"}}},\"title\":\"ExperimentalBlueprint\",\"version\":1},\"userdoc\":{\"errors\":{\"OnlyMasterBlueprintServiceManagerAllowed(address,address)\":[{\"notice\":\"Error message for unauthorized access\"}],\"OnlyRootChainAllowed(address,address)\":[{\"notice\":\"Error message for unauthorized access\"}]},\"kind\":\"user\",\"methods\":{\"REWARDS_PALLET()\":{\"notice\":\"The address of the rewards pallet\"},\"ROOT_CHAIN()\":{\"notice\":\"The address of the root chain\"},\"queryDeveloperPaymentAddress(uint64)\":{\"notice\":\"This function should be implemented by the Blueprint Service Manager contract.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/src/ExperimentalBlueprint.sol\":\"ExperimentalBlueprint\"},\"evmVersion\":\"shanghai\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[\":@openzeppelin-contracts-5.1.0/=dependencies/tnt-core-0.5.0/dependencies/@openzeppelin-contracts-5.1.0/\",\":@openzeppelin/contracts/=dependencies/tnt-core-0.5.0/dependencies/@openzeppelin-contracts-5.1.0/\",\":forge-std-1.9.4/=dependencies/tnt-core-0.5.0/dependencies/forge-std-1.9.4/src/\",\":forge-std/=dependencies/tnt-core-0.5.0/dependencies/forge-std-1.9.4/src/\",\":tnt-core-0.5.0/=dependencies/tnt-core-0.5.0/\",\":tnt-core/=dependencies/tnt-core-0.5.0/src/\"]},\"sources\":{\"contracts/src/ExperimentalBlueprint.sol\":{\"keccak256\":\"0x2e82123c72245a469f19c4f98dc0f6ac77f4ce3aaae3695af97742ca8fe7b9c4\",\"license\":\"UNLICENSE\",\"urls\":[\"bzz-raw://2bc3ad66c3f384a310fde9397c3ae053a584bb551c061950eb6a9eae28958ebf\",\"dweb:/ipfs/QmTcN5FbRf3GMocBYowqkWYmbGKLV4PMkQCehSL12sfViy\"]},\"dependencies/tnt-core-0.5.0/dependencies/@openzeppelin-contracts-5.1.0/utils/structs/EnumerableSet.sol\":{\"keccak256\":\"0x9b161e97b8967d4bc0c08d25741889a30692cdda4b71910bf1b0e315f1962212\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://821500c39d095eaa25b06f46e65f1d0e97c4c96b39227f79077dee7d9e84051f\",\"dweb:/ipfs/QmSTeGorKzSWF6HAmxo32uCZiEuKNvreQdUiX1AaYtUMTz\"]},\"dependencies/tnt-core-0.5.0/src/BlueprintServiceManagerBase.sol\":{\"keccak256\":\"0x06712ada8ea5523132c1d893ecdb8d24120522ab94b103d2a0e1fe81a08b8ff6\",\"license\":\"UNLICENSED\",\"urls\":[\"bzz-raw://e588cea1834136427a0621ce7505d9ae590ebc84c2eec88ee3c0c2a28080ddee\",\"dweb:/ipfs/QmbfhUxmYKSfu5NRRqy5How2PpMriuAjzWCufodWnPspgV\"]},\"src/AssetsLib.sol\":{\"keccak256\":\"0xed4ff5cfdc3c07601ccb4424befd7cf9f9a66288dbec113b5c061eb9df848c9b\",\"license\":\"UNLICENSED\",\"urls\":[\"bzz-raw://69bb3aece25285b93753630bf1501118c418f6f2e3c9245907bd17b10c307f49\",\"dweb:/ipfs/Qmcn5EtQbwRpgJw8pfFh1Ji7d3K4wLCvM4fsZdtdui5zLh\"]},\"src/IBlueprintServiceManager.sol\":{\"keccak256\":\"0x1249d3bd773cc2dcff97ceae075aa21cf61f13bf0939eeb0e21c8ecf10182338\",\"license\":\"UNLICENSED\",\"urls\":[\"bzz-raw://4a1a5731a399f3e427490f981471ad5fa00343f4979b54a0486c7a0587d910b3\",\"dweb:/ipfs/QmXVk2hnkcbWrKbh44vXSh4rRsmFqLs2ea9EgcCjBt36ZM\"]},\"src/Permissions.sol\":{\"keccak256\":\"0xcb9b4d6badf8849f22a03d466fde3ed53fe491dbefbc1f578dd09b3a7b2c8b96\",\"license\":\"UNLICENSED\",\"urls\":[\"bzz-raw://0bf4bfc91efbd465b09a37241acc19ac0f4fee5e2807e5598f787ba5c2368e2a\",\"dweb:/ipfs/QmbSK9adP3axpecxHgTCc57zLi8cDKsjrMFosRmxTYTZue\"]},\"src/ServiceOperatorsLib.sol\":{\"keccak256\":\"0x3ff42db82165bb146f646f1fa901058bfa972ae6eb1488afeb0b3ebedda74666\",\"license\":\"UNLICENSED\",\"urls\":[\"bzz-raw://546d82b1619217587a3490d3e4156c6c9affde9f214defd9f3a6c97f4bc65f93\",\"dweb:/ipfs/QmdpRSCz2cikRzWFbtiqP1kXYA1A2HKCeHE6bp2Nxo938r\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.27+commit.40a35a09"},"language":"Solidity","output":{"abi":[{"inputs":[{"internalType":"address","name":"caller","type":"address"},{"internalType":"address","name":"masterBlueprintServiceManager","type":"address"}],"type":"error","name":"OnlyMasterBlueprintServiceManagerAllowed"},{"inputs":[{"internalType":"address","name":"caller","type":"address"},{"internalType":"address","name":"rootChain","type":"address"}],"type":"error","name":"OnlyRootChainAllowed"},{"inputs":[{"internalType":"uint256","name":"kind","type":"uint256"}],"type":"error","name":"UnsupportedAssetKind"},{"inputs":[],"stateMutability":"view","type":"function","name":"REWARDS_PALLET","outputs":[{"internalType":"address","name":"","type":"address"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"ROOT_CHAIN","outputs":[{"internalType":"address","name":"","type":"address"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"blueprintOwner","outputs":[{"internalType":"address","name":"","type":"address"}]},{"inputs":[{"internalType":"uint64","name":"serviceId","type":"uint64"},{"internalType":"struct ServiceOperators.OperatorPreferences","name":"operator","type":"tuple","components":[{"internalType":"bytes","name":"ecdsaPublicKey","type":"bytes"},{"internalType":"string","name":"rpcAddress","type":"string"}]}],"stateMutability":"view","type":"function","name":"canJoin","outputs":[{"internalType":"bool","name":"allowed","type":"bool"}]},{"inputs":[{"internalType":"uint64","name":"serviceId","type":"uint64"},{"internalType":"struct ServiceOperators.OperatorPreferences","name":"operator","type":"tuple","components":[{"internalType":"bytes","name":"ecdsaPublicKey","type":"bytes"},{"internalType":"string","name":"rpcAddress","type":"string"}]}],"stateMutability":"view","type":"function","name":"canLeave","outputs":[{"internalType":"bool","name":"allowed","type":"bool"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"currentBlueprintId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}]},{"inputs":[{"internalType":"uint64","name":"serviceId","type":"uint64"}],"stateMutability":"view","type":"function","name":"getHeartbeatInterval","outputs":[{"internalType":"bool","name":"useDefault","type":"bool"},{"internalType":"uint64","name":"interval","type":"uint64"}]},{"inputs":[{"internalType":"uint64","name":"serviceId","type":"uint64"}],"stateMutability":"view","type":"function","name":"getHeartbeatThreshold","outputs":[{"internalType":"bool","name":"useDefault","type":"bool"},{"internalType":"uint8","name":"threshold","type":"uint8"}]},{"inputs":[{"internalType":"uint64","name":"serviceId","type":"uint64"}],"stateMutability":"view","type":"function","name":"getSlashingWindow","outputs":[{"internalType":"bool","name":"useDefault","type":"bool"},{"internalType":"uint64","name":"window","type":"uint64"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"masterBlueprintServiceManager","outputs":[{"internalType":"address","name":"","type":"address"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"masterBlueprintServiceManagerAddress","outputs":[{"internalType":"address","name":"mbsm","type":"address"}]},{"inputs":[{"internalType":"struct ServiceOperators.OperatorPreferences","name":"operator","type":"tuple","components":[{"internalType":"bytes","name":"ecdsaPublicKey","type":"bytes"},{"internalType":"string","name":"rpcAddress","type":"string"}]},{"internalType":"uint64","name":"requestId","type":"uint64"},{"internalType":"uint8","name":"restakingPercent","type":"uint8"}],"stateMutability":"payable","type":"function","name":"onApprove"},{"inputs":[{"internalType":"uint64","name":"blueprintId","type":"uint64"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"mbsm","type":"address"}],"stateMutability":"nonpayable","type":"function","name":"onBlueprintCreated"},{"inputs":[{"internalType":"uint64","name":"serviceId","type":"uint64"},{"internalType":"uint8","name":"job","type":"uint8"},{"internalType":"uint64","name":"jobCallId","type":"uint64"},{"internalType":"bytes","name":"inputs","type":"bytes"}],"stateMutability":"payable","type":"function","name":"onJobCall"},{"inputs":[{"internalType":"uint64","name":"serviceId","type":"uint64"},{"internalType":"uint8","name":"job","type":"uint8"},{"internalType":"uint64","name":"jobCallId","type":"uint64"},{"internalType":"struct ServiceOperators.OperatorPreferences","name":"operator","type":"tuple","components":[{"internalType":"bytes","name":"ecdsaPublicKey","type":"bytes"},{"internalType":"string","name":"rpcAddress","type":"string"}]},{"internalType":"bytes","name":"inputs","type":"bytes"},{"internalType":"bytes","name":"outputs","type":"bytes"}],"stateMutability":"payable","type":"function","name":"onJobResult"},{"inputs":[{"internalType":"uint64","name":"serviceId","type":"uint64"},{"internalType":"struct ServiceOperators.OperatorPreferences","name":"operator","type":"tuple","components":[{"internalType":"bytes","name":"ecdsaPublicKey","type":"bytes"},{"internalType":"string","name":"rpcAddress","type":"string"}]}],"stateMutability":"nonpayable","type":"function","name":"onOperatorJoined"},{"inputs":[{"internalType":"uint64","name":"serviceId","type":"uint64"},{"internalType":"struct ServiceOperators.OperatorPreferences","name":"operator","type":"tuple","components":[{"internalType":"bytes","name":"ecdsaPublicKey","type":"bytes"},{"internalType":"string","name":"rpcAddress","type":"string"}]}],"stateMutability":"nonpayable","type":"function","name":"onOperatorLeft"},{"inputs":[{"internalType":"struct ServiceOperators.OperatorPreferences","name":"operator","type":"tuple","components":[{"internalType":"bytes","name":"ecdsaPublicKey","type":"bytes"},{"internalType":"string","name":"rpcAddress","type":"string"}]},{"internalType":"bytes","name":"registrationInputs","type":"bytes"}],"stateMutability":"payable","type":"function","name":"onRegister"},{"inputs":[{"internalType":"struct ServiceOperators.OperatorPreferences","name":"operator","type":"tuple","components":[{"internalType":"bytes","name":"ecdsaPublicKey","type":"bytes"},{"internalType":"string","name":"rpcAddress","type":"string"}]},{"internalType":"uint64","name":"requestId","type":"uint64"}],"stateMutability":"nonpayable","type":"function","name":"onReject"},{"inputs":[{"internalType":"struct ServiceOperators.RequestParams","name":"params","type":"tuple","components":[{"internalType":"uint64","name":"requestId","type":"uint64"},{"internalType":"address","name":"requester","type":"address"},{"internalType":"struct ServiceOperators.OperatorPreferences[]","name":"operators","type":"tuple[]","components":[{"internalType":"bytes","name":"ecdsaPublicKey","type":"bytes"},{"internalType":"string","name":"rpcAddress","type":"string"}]},{"internalType":"bytes","name":"requestInputs","type":"bytes"},{"internalType":"address[]","name":"permittedCallers","type":"address[]"},{"internalType":"uint64","name":"ttl","type":"uint64"},{"internalType":"struct Assets.Asset","name":"paymentAsset","type":"tuple","components":[{"internalType":"enum Assets.Kind","name":"kind","type":"uint8"},{"internalType":"bytes32","name":"data","type":"bytes32"}]},{"internalType":"uint256","name":"amount","type":"uint256"}]}],"stateMutability":"payable","type":"function","name":"onRequest"},{"inputs":[{"internalType":"uint64","name":"requestId","type":"uint64"},{"internalType":"uint64","name":"serviceId","type":"uint64"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"address[]","name":"permittedCallers","type":"address[]"},{"internalType":"uint64","name":"ttl","type":"uint64"}],"stateMutability":"nonpayable","type":"function","name":"onServiceInitialized"},{"inputs":[{"internalType":"uint64","name":"serviceId","type":"uint64"},{"internalType":"address","name":"owner","type":"address"}],"stateMutability":"nonpayable","type":"function","name":"onServiceTermination"},{"inputs":[{"internalType":"uint64","name":"serviceId","type":"uint64"},{"internalType":"bytes","name":"offender","type":"bytes"},{"internalType":"uint8","name":"slashPercent","type":"uint8"}],"stateMutability":"nonpayable","type":"function","name":"onSlash"},{"inputs":[{"internalType":"uint64","name":"serviceId","type":"uint64"},{"internalType":"bytes","name":"offender","type":"bytes"},{"internalType":"uint8","name":"slashPercent","type":"uint8"}],"stateMutability":"nonpayable","type":"function","name":"onUnappliedSlash"},{"inputs":[{"internalType":"struct ServiceOperators.OperatorPreferences","name":"operator","type":"tuple","components":[{"internalType":"bytes","name":"ecdsaPublicKey","type":"bytes"},{"internalType":"string","name":"rpcAddress","type":"string"}]}],"stateMutability":"nonpayable","type":"function","name":"onUnregister"},{"inputs":[{"internalType":"struct ServiceOperators.OperatorPreferences","name":"operator","type":"tuple","components":[{"internalType":"bytes","name":"ecdsaPublicKey","type":"bytes"},{"internalType":"string","name":"rpcAddress","type":"string"}]}],"stateMutability":"payable","type":"function","name":"onUpdateRpcAddress"},{"inputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function","name":"queryDeveloperPaymentAddress","outputs":[{"internalType":"address payable","name":"developerPaymentAddress","type":"address"}]},{"inputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function","name":"queryDisputeOrigin","outputs":[{"internalType":"address","name":"disputeOrigin","type":"address"}]},{"inputs":[{"internalType":"uint64","name":"serviceId","type":"uint64"},{"internalType":"struct Assets.Asset","name":"asset","type":"tuple","components":[{"internalType":"enum Assets.Kind","name":"kind","type":"uint8"},{"internalType":"bytes32","name":"data","type":"bytes32"}]}],"stateMutability":"view","type":"function","name":"queryIsPaymentAssetAllowed","outputs":[{"internalType":"bool","name":"isAllowed","type":"bool"}]},{"inputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function","name":"querySlashingOrigin","outputs":[{"internalType":"address","name":"slashingOrigin","type":"address"}]},{"inputs":[],"stateMutability":"pure","type":"function","name":"rewardsPallet","outputs":[{"internalType":"address","name":"rewardsPalletAddress","type":"address"}]},{"inputs":[],"stateMutability":"pure","type":"function","name":"rootChain","outputs":[{"internalType":"address","name":"rootChainAddress","type":"address"}]}],"devdoc":{"kind":"dev","methods":{"canJoin(uint64,(bytes,string))":{"details":"Hook to check if an operator can join a service instance","params":{"operator":"The operator's preferences and details","serviceId":"The ID of the service instance"},"returns":{"allowed":"Returns true if the operator is allowed to join"}},"canLeave(uint64,(bytes,string))":{"details":"Hook to check if an operator can leave a service instance","params":{"operator":"The operator's preferences and details","serviceId":"The ID of the service instance"},"returns":{"allowed":"Returns true if the operator is allowed to leave"}},"getHeartbeatInterval(uint64)":{"details":"Get the heartbeat interval for a service.","params":{"serviceId":"The ID of the service."},"returns":{"interval":"The heartbeat interval in blocks. 0 means heartbeats are disabled.","useDefault":"Whether to use the default value."}},"getHeartbeatThreshold(uint64)":{"details":"Get the heartbeat threshold for a service.","params":{"serviceId":"The ID of the service."},"returns":{"threshold":"The heartbeat threshold percentage (0-100).","useDefault":"Whether to use the default value."}},"getSlashingWindow(uint64)":{"details":"Get the slashing window for a service.","params":{"serviceId":"The ID of the service."},"returns":{"useDefault":"Whether to use the default value.","window":"The slashing window in blocks."}},"masterBlueprintServiceManagerAddress()":{"details":"Get the master blueprint service manager address","returns":{"mbsm":"The address of the master blueprint service manager"}},"onApprove((bytes,string),uint64,uint8)":{"details":"Hook for service request approval. Called when a service request is approved by an operator.","params":{"operator":"The operator's details.","requestId":"The ID of the request.","restakingPercent":"The percentage of the restaking amount (0-100)."}},"onBlueprintCreated(uint64,address,address)":{"details":"Hook to handle blueprint creation. Gets called by the root chain when a new blueprint is created. Could be a good place to store the master blueprint service manager address or any other blueprint related data.","params":{"blueprintId":"The unique identifier for the blueprint.","mbsm":"The address of the master blueprint service manager.","owner":"The address of the blueprint owner."}},"onJobCall(uint64,uint8,uint64,bytes)":{"details":"Hook for job calls on the service. Called when a job is called within the service context.","params":{"inputs":"Inputs required for the job execution in bytes format.","job":"The job identifier.","jobCallId":"A unique ID for the job call.","serviceId":"The ID of the service where the job is called."}},"onJobResult(uint64,uint8,uint64,(bytes,string),bytes,bytes)":{"details":"Hook for handling job result. Called when operators send the result of a job execution.","params":{"inputs":"Inputs used for the job execution in bytes format.","job":"The job identifier.","jobCallId":"The unique ID for the job call.","operator":"The operator sending the result in bytes format.","outputs":"Outputs resulting from the job execution in bytes format.","serviceId":"The ID of the service related to the job."}},"onOperatorJoined(uint64,(bytes,string))":{"details":"Hook called after an operator has joined a service instance","params":{"operator":"The operator's preferences and details","serviceId":"The ID of the service instance"}},"onOperatorLeft(uint64,(bytes,string))":{"details":"Hook called after an operator has left a service instance","params":{"operator":"The operator's preferences and details","serviceId":"The ID of the service instance"}},"onRegister((bytes,string),bytes)":{"details":"Hook for service operator registration. Called when a service operator attempts to register with the blueprint.","params":{"operator":"The operator's details.","registrationInputs":"Inputs required for registration in bytes format."}},"onReject((bytes,string),uint64)":{"details":"Hook for service request rejection. Called when a service request is rejected by an operator.","params":{"operator":"The operator's details.","requestId":"The ID of the request."}},"onRequest((uint64,address,(bytes,string)[],bytes,address[],uint64,(uint8,bytes32),uint256))":{"details":"Hook for service instance requests. Called when a user requests a service instance from the blueprint but this does not mean the service is initiated yet. To get notified when the service is initiated, implement the `onServiceInitialized` hook.","params":{"params":"The parameters for the service request."}},"onServiceInitialized(uint64,uint64,address,address[],uint64)":{"details":"Hook for service initialization. Called when a service is initialized. This hook is called after the service is approved from all of the operators.","params":{"owner":"The owner of the service.","permittedCallers":"The list of permitted callers for the service.","requestId":"The ID of the request.","serviceId":"The ID of the service.","ttl":"The time-to-live for the service."}},"onServiceTermination(uint64,address)":{"details":"Hook for service termination. Called when a service is terminated.","params":{"owner":"The owner of the service.","serviceId":"The ID of the service to be terminated."}},"onSlash(uint64,bytes,uint8)":{"details":"Hook for handling applied slashes. Called when a slash is applied to an offender.","params":{"offender":"The offender's details in bytes format.","serviceId":"The ID of the service related to the slash.","slashPercent":"The percentage of the slash."}},"onUnappliedSlash(uint64,bytes,uint8)":{"details":"Hook for handling unapplied slashes. Called when a slash is queued and still not yet applied to an offender.","params":{"offender":"The offender's details in bytes format.","serviceId":"The ID of the service related to the slash.","slashPercent":"The percentage of the slash."}},"onUnregister((bytes,string))":{"details":"Hook for service operator unregistration. Called when a service operator attempts to unregister from the blueprint.","params":{"operator":"The operator's details."}},"onUpdateRpcAddress((bytes,string))":{"details":"Hook for updating RPC address. Called when an operator updates their RPC address.","params":{"operator":"The operator's details with the updated RPC address."}},"queryDeveloperPaymentAddress(uint64)":{"details":"Query the developer payment address for a service. This mainly used by the runtime or the Master Blueprint Service Manager to determine the developer payment address for a service.","params":{"serviceId":"The ID of the service."},"returns":{"developerPaymentAddress":"The address of the developer payment address for that service"}},"queryDisputeOrigin(uint64)":{"details":"Query the dispute origin for a service. This mainly used by the runtime to determine the allowed account that can dispute an unapplied slash and remove it. by default, the service manager is the only account that can dispute a service. override this function to allow other accounts to dispute a service.","params":{"serviceId":"The ID of the service."},"returns":{"disputeOrigin":"The account that can dispute the unapplied slash for that service"}},"queryIsPaymentAssetAllowed(uint64,(uint8,bytes32))":{"details":"Determines if a specified payment asset is permitted for a given service.","params":{"asset":"The asset to verify for allowance.","serviceId":"The ID of the service to check against."},"returns":{"isAllowed":"Returns true if the asset is allowed, false otherwise."}},"querySlashingOrigin(uint64)":{"details":"Query the slashing origin for a service. This mainly used by the runtime to determine the allowed account that can slash a service. by default, the service manager is the only account that can slash a service. override this function to allow other accounts to slash a service.","params":{"serviceId":"The ID of the service."},"returns":{"slashingOrigin":"The account that can slash the offender."}},"rewardsPallet()":{"details":"Get the rewards pallet address","returns":{"rewardsPalletAddress":"The address of the rewards pallet"}},"rootChain()":{"details":"Get the root chain address","returns":{"rootChainAddress":"The address of the root chain"}}},"version":1},"userdoc":{"kind":"user","methods":{"REWARDS_PALLET()":{"notice":"The address of the rewards pallet"},"ROOT_CHAIN()":{"notice":"The address of the root chain"},"queryDeveloperPaymentAddress(uint64)":{"notice":"This function should be implemented by the Blueprint Service Manager contract."}},"version":1}},"settings":{"remappings":["@openzeppelin-contracts-5.1.0/=dependencies/tnt-core-0.5.0/dependencies/@openzeppelin-contracts-5.1.0/","@openzeppelin/contracts/=dependencies/tnt-core-0.5.0/dependencies/@openzeppelin-contracts-5.1.0/","forge-std-1.9.4/=dependencies/tnt-core-0.5.0/dependencies/forge-std-1.9.4/src/","forge-std/=dependencies/tnt-core-0.5.0/dependencies/forge-std-1.9.4/src/","tnt-core-0.5.0/=dependencies/tnt-core-0.5.0/","tnt-core/=dependencies/tnt-core-0.5.0/src/"],"optimizer":{"enabled":false,"runs":200},"metadata":{"bytecodeHash":"ipfs"},"compilationTarget":{"contracts/src/ExperimentalBlueprint.sol":"ExperimentalBlueprint"},"evmVersion":"shanghai","libraries":{}},"sources":{"contracts/src/ExperimentalBlueprint.sol":{"keccak256":"0x2e82123c72245a469f19c4f98dc0f6ac77f4ce3aaae3695af97742ca8fe7b9c4","urls":["bzz-raw://2bc3ad66c3f384a310fde9397c3ae053a584bb551c061950eb6a9eae28958ebf","dweb:/ipfs/QmTcN5FbRf3GMocBYowqkWYmbGKLV4PMkQCehSL12sfViy"],"license":"UNLICENSE"},"dependencies/tnt-core-0.5.0/dependencies/@openzeppelin-contracts-5.1.0/utils/structs/EnumerableSet.sol":{"keccak256":"0x9b161e97b8967d4bc0c08d25741889a30692cdda4b71910bf1b0e315f1962212","urls":["bzz-raw://821500c39d095eaa25b06f46e65f1d0e97c4c96b39227f79077dee7d9e84051f","dweb:/ipfs/QmSTeGorKzSWF6HAmxo32uCZiEuKNvreQdUiX1AaYtUMTz"],"license":"MIT"},"dependencies/tnt-core-0.5.0/src/BlueprintServiceManagerBase.sol":{"keccak256":"0x06712ada8ea5523132c1d893ecdb8d24120522ab94b103d2a0e1fe81a08b8ff6","urls":["bzz-raw://e588cea1834136427a0621ce7505d9ae590ebc84c2eec88ee3c0c2a28080ddee","dweb:/ipfs/QmbfhUxmYKSfu5NRRqy5How2PpMriuAjzWCufodWnPspgV"],"license":"UNLICENSED"},"src/AssetsLib.sol":{"keccak256":"0xed4ff5cfdc3c07601ccb4424befd7cf9f9a66288dbec113b5c061eb9df848c9b","urls":["bzz-raw://69bb3aece25285b93753630bf1501118c418f6f2e3c9245907bd17b10c307f49","dweb:/ipfs/Qmcn5EtQbwRpgJw8pfFh1Ji7d3K4wLCvM4fsZdtdui5zLh"],"license":"UNLICENSED"},"src/IBlueprintServiceManager.sol":{"keccak256":"0x1249d3bd773cc2dcff97ceae075aa21cf61f13bf0939eeb0e21c8ecf10182338","urls":["bzz-raw://4a1a5731a399f3e427490f981471ad5fa00343f4979b54a0486c7a0587d910b3","dweb:/ipfs/QmXVk2hnkcbWrKbh44vXSh4rRsmFqLs2ea9EgcCjBt36ZM"],"license":"UNLICENSED"},"src/Permissions.sol":{"keccak256":"0xcb9b4d6badf8849f22a03d466fde3ed53fe491dbefbc1f578dd09b3a7b2c8b96","urls":["bzz-raw://0bf4bfc91efbd465b09a37241acc19ac0f4fee5e2807e5598f787ba5c2368e2a","dweb:/ipfs/QmbSK9adP3axpecxHgTCc57zLi8cDKsjrMFosRmxTYTZue"],"license":"UNLICENSED"},"src/ServiceOperatorsLib.sol":{"keccak256":"0x3ff42db82165bb146f646f1fa901058bfa972ae6eb1488afeb0b3ebedda74666","urls":["bzz-raw://546d82b1619217587a3490d3e4156c6c9affde9f214defd9f3a6c97f4bc65f93","dweb:/ipfs/QmdpRSCz2cikRzWFbtiqP1kXYA1A2HKCeHE6bp2Nxo938r"],"license":"UNLICENSED"}},"version":1},"id":0}"#,
).expect("Failed to create mock contract JSON file");
// Create a simple forge.toml file to avoid Foundry trying to build anything
fs::write(
blueprint_dir.join("foundry.toml"),
r#"[profile.default]
src = "contracts"
out = "contracts/out"
libs = ["lib"]
"#,
)
.expect("Failed to write foundry.toml");
// Create Cargo.toml
fs::write(
blueprint_dir.join("Cargo.toml"),
format!(
r#"[package]
name = "incredible-squaring-blueprint"
version = "0.1.0"
edition = "2024"
[dependencies]
blueprint-sdk = {{ path = "{}/crates/sdk", features = ["std", "tangle", "macros"] }}
tokio = {{ version = "1.43.0", features = ["rt-multi-thread", "sync", "macros"] }}
tracing-subscriber = {{ version = "0.3.19", features = ["env-filter"] }}
tower = {{ version = "0.5.2", default-features = false }}
[package.metadata.blueprint]
manager = {{ Evm = "ExperimentalBlueprint" }}
master_revision = "Latest"
[profile.dev]
opt-level = 0
debug = false
"#,
crates_dir.display(),
),
)
.expect("Failed to write Cargo.toml");
// Create blueprint.json
fs::write(
blueprint_dir.join("blueprint.json"),
format!(
r#"{{
"metadata": {{
"name": "experiment",
"description": "",
"author": "",
"category": null,
"code_repository": "",
"logo": null,
"website": "",
"license": ""
}},
"manager": {{
"Evm": "contracts/out/ExperimentalBlueprint.sol/ExperimentalBlueprint.json"
}},
"master_manager_revision": "Latest",
"jobs": [
{{
"job_id": 0,
"metadata": {{
"name": "incredible_squaring_blueprint_lib::square",
"description": null
}},
"params": [
"Uint64"
],
"result": [
"Uint64"
],
"pricing_model": {{
"PayOnce": {{
"amount": 0
}}
}}
}}
],
"registration_params": [],
"request_params": [],
"sources": [
{{
"type": "Testing",
"cargo_package": "incredible-squaring-blueprint",
"cargo_bin": "main",
"base_path": "{}"
}}
]
}}"#,
blueprint_dir.display()
),
)
.expect("Failed to write blueprint.json");
// Create main.rs (combined lib.rs and main.rs)
fs::write(
blueprint_dir.join("src").join("main.rs"),
r#"use blueprint_sdk::Job;
use blueprint_sdk::Router;
use blueprint_sdk::contexts::tangle::TangleClientContext;
use blueprint_core::crypto::keypair::sp_runtime::traits::Verify;
use blueprint_core::crypto::sp::sp_core::ed25519::Signature;
use blueprint_core::extract::Context;
use blueprint_runner::config::BlueprintEnvironment;
use blueprint_runner::error::RunnerError;
use blueprint_runner::ext::BackgroundService;
use blueprint_runner::BlueprintRunner;
use blueprint_sdk::prelude::*;
use blueprint_sdk::tangle::config::TangleConfig;
use blueprint_sdk::tangle::consumer::TangleConsumer;
use blueprint_sdk::tangle::extract::{TangleArg, TangleResult};
use blueprint_sdk::tangle::filters::MatchesServiceId;
use blueprint_sdk::tangle::layers::TangleLayer;
use blueprint_sdk::tangle::producer::TangleProducer;
use tokio::sync::oneshot;
use tokio::sync::oneshot::Receiver;
use tower::filter::FilterLayer;
use blueprint_core::{error, info};
use blueprint_core::level_filters::LevelFilter;
// QoS imports
use blueprint_qos::default_qos_config;
use blueprint_qos::error::Error as QosError;
use blueprint_qos::heartbeat::{HeartbeatConfig, HeartbeatConsumer, HeartbeatStatus};
use blueprint_qos::servers::prometheus::PrometheusServerConfig;
use blueprint_qos::unified_service::QoSServiceBuilder;
use std::sync::Arc;
use std::fs;
// The job ID
pub const XSQUARE_JOB_ID: u32 = 0;
// The job function
pub async fn square(TangleArg(x): TangleArg<u64>) -> TangleResult<u64> {
let result = x * x;
// The result is then converted into a `JobResult` to be sent back to the caller.
TangleResult(result)
}
/// Mock heartbeat consumer for testing
#[derive(Clone, Debug)]
pub struct MockHeartbeatConsumer {
heartbeat_count: Arc<tokio::sync::Mutex<usize>>,
last_status: Arc<tokio::sync::Mutex<Option<HeartbeatStatus>>>,
}
impl MockHeartbeatConsumer {
pub fn new() -> Self {
Self {
heartbeat_count: Arc::new(tokio::sync::Mutex::new(0)),
last_status: Arc::new(tokio::sync::Mutex::new(None)),
}
}
pub async fn heartbeat_count(&self) -> usize {
*self.heartbeat_count.lock().await
}
}
impl HeartbeatConsumer for MockHeartbeatConsumer {
async fn send_heartbeat(&self, status: &HeartbeatStatus) -> std::result::Result<(), QosError> {
let mut count = self.heartbeat_count.lock().await;
*count += 1;
let mut last = self.last_status.lock().await;
*last = Some(status.clone());
// Log basic heartbeat information
info!("Heartbeat #{} sent for service {} blueprint {}",
*count, status.service_id, status.blueprint_id);
// Note: The on-chain heartbeat will be sent by the HeartbeatService
// based on the chain's expectations
Ok(())
}
}
#[derive(Clone)]
pub struct FooBackgroundService;
impl FooBackgroundService {
pub fn new() -> Self {
Self
}
}
impl BackgroundService for FooBackgroundService {
async fn start(&self) -> Result<Receiver<Result<(), RunnerError>>, RunnerError> {
let (tx, rx) = oneshot::channel();
tokio::spawn(async move {
let _ = tx.send(Ok(()));
});
Ok(rx)
}
}
#[tokio::main]
async fn main() -> Result<(), blueprint_sdk::Error> {
setup_log();
let env = BlueprintEnvironment::load()?;
let sr25519_signer = env.keystore().first_local::<SpSr25519>()?;
let sr25519_pair = env.keystore().get_secret::<SpSr25519>(&sr25519_signer)?;
let st25519_signer = TanglePairSigner::new(sr25519_pair.0);
let tangle_client = env.tangle_client().await?;
let tangle_producer = TangleProducer::finalized_blocks(tangle_client.rpc_client.clone()).await?;
let tangle_consumer = TangleConsumer::new(tangle_client.rpc_client.clone(), st25519_signer);
let tangle_config = TangleConfig::default();
let service_id = env.protocol_settings.tangle()?.service_id.unwrap();
// Initialize QoS services
// Configure the heartbeat service
let mut qos_config = default_qos_config();
qos_config.heartbeat = Some(HeartbeatConfig {
interval_secs: 5, // Send heartbeats every 5 seconds
jitter_percent: 5,
service_id,
blueprint_id: 1, // Use a default blueprint ID for testing
max_missed_heartbeats: 3,
});
// Configure Prometheus metrics server
qos_config.prometheus_server = Some(PrometheusServerConfig::default());
qos_config.manage_servers = true;
// Configure the metrics gRPC server with production-like settings
// Following Windsurf Guidelines for minimal, sufficient configuration
qos_config.metrics_grpc_port = Some(8085); // Must match QOS_PORT in the test
qos_config.metrics_grpc_address = Some("127.0.0.1".to_string());
// Explicitly enable all metrics subsystems for test reliability
qos_config.metrics_enabled = true;
qos_config.enable_metrics_server = true;
qos_config.start_metrics_server = true; // Critical: Actually start the server
// Set a short interval to ensure metrics are collected quickly during tests
qos_config.metrics_collection_interval_secs = Some(1);
// Create the heartbeat consumer
let heartbeat_consumer = Arc::new(MockHeartbeatConsumer::new());
// Build the QoS service
let qos_service = match QoSServiceBuilder::new(env.clone())
.with_config(qos_config)
.with_heartbeat_consumer(heartbeat_consumer.clone())
.build()
.await
{
Ok(service) => service,
Err(e) => {
error!("Failed to initialize QoS service: {}", e);
return Err(blueprint_sdk::Error::GenericError(format!("QoS initialization failed: {}", e)));
}
};
// Get the heartbeat service if available
let heartbeat_service = match qos_service.heartbeat_service() {
Some(service) => {
info!("Heartbeat service initialized successfully");
service.clone()
},
None => {
error!("Failed to initialize heartbeat service");
return Err(blueprint_sdk::Error::GenericError("Heartbeat service initialization failed".to_string()));
}
};
// Start the heartbeat service
if let Err(e) = heartbeat_service.start_heartbeat().await {
error!("Failed to start heartbeat service: {}", e);
return Err(blueprint_sdk::Error::GenericError(format!("Failed to start heartbeat service: {}", e)));
}
// Create builder and add router and background service
let mut builder = BlueprintRunner::builder(tangle_config, env)
.router(
Router::new()
// Add the square job with the TangleLayer
.route(XSQUARE_JOB_ID, square.layer(TangleLayer))
// Add the FilterLayer to filter out job calls that don't match the service ID
.layer(FilterLayer::new(MatchesServiceId(service_id)))
)
.background_service(FooBackgroundService::new());
// Add the heartbeat service to the BlueprintRunner
builder = builder.heartbeat_service(heartbeat_service);
// Add QoS service to builder
// This ensures the metrics gRPC server is properly registered and started
info!("Registering QoS service with metrics gRPC server enabled");
builder = builder.qos_service(qos_service);
// Check if prometheus metrics server is available and add it if so
if qos_service.prometheus_server_url().is_some() {
// We need to use the PrometheusServer directly from the QoS crate
// The metrics_server method expects an Arc<PrometheusServer>
info!("Prometheus metrics server initialized");
// Create a new PrometheusServer with the same config
let prometheus_config = PrometheusServerConfig::default();
let prometheus_server = Arc::new(blueprint_qos::servers::prometheus::PrometheusServer::new(prometheus_config));
builder = builder.metrics_server(prometheus_server);
}
// Complete the builder chain
let result = builder
// Add potentially many producers
//
// A producer is simply a `Stream` that outputs `JobCall`s, which are passed down to the intended
// job functions.
.producer(tangle_producer)
// Add potentially many consumers
//
// A consumer is simply a `Sink` that consumes `JobResult`s, which are the output of the job functions.
// Every result will be passed to every consumer. It is the responsibility of the consumer
// to determine whether or not to process a result.
.consumer(tangle_consumer)
// Custom shutdown handlers
//
// Now users can specify what to do when an error occurs and the runner is shutting down.
// That can be cleanup logic, finalizing database transactions, etc.
.with_shutdown_handler(async { println!("Shutting down!") })
.run()
.await;
if let Err(e) = result {
error!("Runner failed! {e:?}");
}
Ok(())
}
pub fn setup_log() {
use tracing_subscriber::util::SubscriberInitExt;
let _ = tracing_subscriber::fmt::SubscriberBuilder::default()
.without_time()
.with_span_events(tracing_subscriber::fmt::format::FmtSpan::NONE)
.with_env_filter(
tracing_subscriber::EnvFilter::builder()
.with_default_directive(LevelFilter::INFO.into())
.from_env_lossy(),
)
.finish()
.try_init();
}"#,
).expect("Failed to write main.rs");
(temp_dir, blueprint_dir)
}