Reformat repo with nightly rustfmt (#25)
This commit is contained in:
parent
aa438c0d62
commit
703b47ab1e
19 changed files with 131 additions and 94 deletions
24
bisenzone-cw-mvp/.github/workflows/Basic.yml
vendored
24
bisenzone-cw-mvp/.github/workflows/Basic.yml
vendored
|
@ -1,6 +1,6 @@
|
||||||
# Based on https://github.com/actions-rs/example/blob/master/.github/workflows/quickstart.yml
|
# Based on https://github.com/actions-rs/example/blob/master/.github/workflows/quickstart.yml
|
||||||
|
|
||||||
on: [push, pull_request]
|
on: [ push, pull_request ]
|
||||||
|
|
||||||
name: Basic
|
name: Basic
|
||||||
|
|
||||||
|
@ -48,16 +48,10 @@ jobs:
|
||||||
uses: actions-rs/toolchain@v1
|
uses: actions-rs/toolchain@v1
|
||||||
with:
|
with:
|
||||||
profile: minimal
|
profile: minimal
|
||||||
toolchain: 1.73.0
|
toolchain: stable
|
||||||
override: true
|
override: true
|
||||||
components: rustfmt, clippy
|
components: rustfmt, clippy
|
||||||
|
|
||||||
- name: Run cargo fmt
|
|
||||||
uses: actions-rs/cargo@v1
|
|
||||||
with:
|
|
||||||
command: fmt
|
|
||||||
args: --all -- --check
|
|
||||||
|
|
||||||
- name: Run cargo clippy
|
- name: Run cargo clippy
|
||||||
uses: actions-rs/cargo@v1
|
uses: actions-rs/cargo@v1
|
||||||
with:
|
with:
|
||||||
|
@ -79,3 +73,17 @@ jobs:
|
||||||
- name: Schema Changes
|
- name: Schema Changes
|
||||||
# fails if any changes not committed
|
# fails if any changes not committed
|
||||||
run: git diff --exit-code schema
|
run: git diff --exit-code schema
|
||||||
|
|
||||||
|
- name: Install nighly toolchain
|
||||||
|
uses: actions-rs/toolchain@v1
|
||||||
|
with:
|
||||||
|
profile: minimal
|
||||||
|
toolchain: nightly
|
||||||
|
override: true
|
||||||
|
components: rustfmt
|
||||||
|
|
||||||
|
- name: Run cargo nightly fmt
|
||||||
|
uses: actions-rs/cargo@v1
|
||||||
|
with:
|
||||||
|
command: fmt
|
||||||
|
args: --all -- --check
|
|
@ -1,5 +1,4 @@
|
||||||
use cosmwasm_schema::write_api;
|
use cosmwasm_schema::write_api;
|
||||||
|
|
||||||
use cw_tee_mtcs::msg::{ExecuteMsg, InstantiateMsg, QueryMsg};
|
use cw_tee_mtcs::msg::{ExecuteMsg, InstantiateMsg, QueryMsg};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
|
@ -3,17 +3,20 @@ use cosmwasm_std::{
|
||||||
Uint128,
|
Uint128,
|
||||||
};
|
};
|
||||||
use cw2::set_contract_version;
|
use cw2::set_contract_version;
|
||||||
use cw20_base::contract::execute_mint;
|
use cw20_base::{
|
||||||
use cw20_base::contract::query_balance as cw20_query_balance;
|
contract::{execute_mint, query_balance as cw20_query_balance},
|
||||||
use cw20_base::state::{MinterData, TokenInfo, TOKEN_INFO};
|
state::{MinterData, TokenInfo, TOKEN_INFO},
|
||||||
use quartz_cw::handler::RawHandler;
|
};
|
||||||
use quartz_cw::state::EPOCH_COUNTER;
|
use quartz_cw::{handler::RawHandler, state::EPOCH_COUNTER};
|
||||||
|
|
||||||
use crate::error::ContractError;
|
use crate::{
|
||||||
use crate::msg::execute::{SubmitObligationMsg, SubmitObligationsMsg, SubmitSetoffsMsg};
|
error::ContractError,
|
||||||
use crate::msg::QueryMsg;
|
msg::{
|
||||||
use crate::msg::{ExecuteMsg, InstantiateMsg};
|
execute::{SubmitObligationMsg, SubmitObligationsMsg, SubmitSetoffsMsg},
|
||||||
use crate::state::{current_epoch_key, ObligationsItem, State, OBLIGATIONS_KEY, STATE};
|
ExecuteMsg, InstantiateMsg, QueryMsg,
|
||||||
|
},
|
||||||
|
state::{current_epoch_key, ObligationsItem, State, OBLIGATIONS_KEY, STATE},
|
||||||
|
};
|
||||||
|
|
||||||
// version info for migration info
|
// version info for migration info
|
||||||
const CONTRACT_NAME: &str = "crates.io:cw-tee-mtcs";
|
const CONTRACT_NAME: &str = "crates.io:cw-tee-mtcs";
|
||||||
|
@ -118,14 +121,15 @@ pub mod execute {
|
||||||
|
|
||||||
use cosmwasm_std::{DepsMut, Env, HexBinary, MessageInfo, Response, StdResult};
|
use cosmwasm_std::{DepsMut, Env, HexBinary, MessageInfo, Response, StdResult};
|
||||||
use cw20_base::contract::{execute_burn, execute_mint};
|
use cw20_base::contract::{execute_burn, execute_mint};
|
||||||
use quartz_cw::state::Hash;
|
use quartz_cw::state::{Hash, EPOCH_COUNTER};
|
||||||
use quartz_cw::state::EPOCH_COUNTER;
|
|
||||||
|
|
||||||
use crate::state::{
|
use crate::{
|
||||||
current_epoch_key, previous_epoch_key, ObligationsItem, RawHash, SetoffsItem, SettleOff,
|
state::{
|
||||||
OBLIGATIONS_KEY, SETOFFS_KEY,
|
current_epoch_key, previous_epoch_key, ObligationsItem, RawHash, SetoffsItem,
|
||||||
|
SettleOff, OBLIGATIONS_KEY, SETOFFS_KEY,
|
||||||
|
},
|
||||||
|
ContractError,
|
||||||
};
|
};
|
||||||
use crate::ContractError;
|
|
||||||
|
|
||||||
pub fn submit_obligation(
|
pub fn submit_obligation(
|
||||||
deps: DepsMut,
|
deps: DepsMut,
|
||||||
|
@ -207,13 +211,12 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult<Binary> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod query {
|
pub mod query {
|
||||||
use cosmwasm_std::Deps;
|
use cosmwasm_std::{Deps, StdResult};
|
||||||
use cosmwasm_std::StdResult;
|
|
||||||
|
|
||||||
use crate::msg::GetAllSetoffsResponse;
|
use crate::{
|
||||||
use crate::state::previous_epoch_key;
|
msg::GetAllSetoffsResponse,
|
||||||
use crate::state::SetoffsItem;
|
state::{previous_epoch_key, SetoffsItem, SETOFFS_KEY},
|
||||||
use crate::state::SETOFFS_KEY;
|
};
|
||||||
|
|
||||||
pub fn get_all_setoffs(deps: Deps) -> StdResult<GetAllSetoffsResponse> {
|
pub fn get_all_setoffs(deps: Deps) -> StdResult<GetAllSetoffsResponse> {
|
||||||
let setoffs = SetoffsItem::new(&previous_epoch_key(SETOFFS_KEY, deps.storage)?)
|
let setoffs = SetoffsItem::new(&previous_epoch_key(SETOFFS_KEY, deps.storage)?)
|
||||||
|
|
|
@ -4,8 +4,7 @@ use cosmwasm_schema::{cw_serde, QueryResponses};
|
||||||
use cosmwasm_std::HexBinary;
|
use cosmwasm_std::HexBinary;
|
||||||
use quartz_cw::prelude::*;
|
use quartz_cw::prelude::*;
|
||||||
|
|
||||||
use crate::state::RawHash;
|
use crate::state::{RawHash, SettleOff};
|
||||||
use crate::state::SettleOff;
|
|
||||||
|
|
||||||
#[cw_serde]
|
#[cw_serde]
|
||||||
pub struct InstantiateMsg(pub QuartzInstantiateMsg);
|
pub struct InstantiateMsg(pub QuartzInstantiateMsg);
|
||||||
|
|
|
@ -3,8 +3,7 @@ pub mod instantiate;
|
||||||
|
|
||||||
use cosmwasm_std::{DepsMut, Env, MessageInfo, Response};
|
use cosmwasm_std::{DepsMut, Env, MessageInfo, Response};
|
||||||
|
|
||||||
use crate::error::Error;
|
use crate::{error::Error, msg::HasDomainType};
|
||||||
use crate::msg::HasDomainType;
|
|
||||||
|
|
||||||
pub trait Handler {
|
pub trait Handler {
|
||||||
fn handle(self, deps: DepsMut<'_>, env: &Env, info: &MessageInfo) -> Result<Response, Error>;
|
fn handle(self, deps: DepsMut<'_>, env: &Env, info: &MessageInfo) -> Result<Response, Error>;
|
||||||
|
@ -37,13 +36,17 @@ where
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info};
|
use cosmwasm_std::{
|
||||||
use cosmwasm_std::DepsMut;
|
testing::{mock_dependencies, mock_env, mock_info},
|
||||||
|
DepsMut,
|
||||||
|
};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
use crate::handler::Handler;
|
use crate::{
|
||||||
use crate::msg::{HasDomainType, RawExecuteMsg, RawInstantiateMsg};
|
handler::Handler,
|
||||||
use crate::state::SESSION;
|
msg::{HasDomainType, RawExecuteMsg, RawInstantiateMsg},
|
||||||
|
state::SESSION,
|
||||||
|
};
|
||||||
|
|
||||||
fn parse_msg<'a, R>(msg_str: &'a str) -> R::DomainType
|
fn parse_msg<'a, R>(msg_str: &'a str) -> R::DomainType
|
||||||
where
|
where
|
||||||
|
|
|
@ -4,11 +4,14 @@ pub mod session_set_pub_key;
|
||||||
|
|
||||||
use cosmwasm_std::{DepsMut, Env, MessageInfo, Response};
|
use cosmwasm_std::{DepsMut, Env, MessageInfo, Response};
|
||||||
|
|
||||||
use crate::error::Error;
|
use crate::{
|
||||||
use crate::handler::Handler;
|
error::Error,
|
||||||
use crate::msg::execute::attested::Attestation;
|
handler::Handler,
|
||||||
use crate::msg::execute::attested::HasUserData;
|
msg::execute::{
|
||||||
use crate::msg::execute::Execute;
|
attested::{Attestation, HasUserData},
|
||||||
|
Execute,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
impl<A> Handler for Execute<A>
|
impl<A> Handler for Execute<A>
|
||||||
where
|
where
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
use cosmwasm_std::{DepsMut, Env, MessageInfo, Response};
|
use cosmwasm_std::{DepsMut, Env, MessageInfo, Response};
|
||||||
use quartz_tee_ra::{verify_epid_attestation, Error as RaVerificationError};
|
use quartz_tee_ra::{verify_epid_attestation, Error as RaVerificationError};
|
||||||
|
|
||||||
use crate::error::Error;
|
use crate::{
|
||||||
use crate::handler::Handler;
|
error::Error,
|
||||||
use crate::msg::execute::attested::{
|
handler::Handler,
|
||||||
Attestation, Attested, EpidAttestation, HasUserData, MockAttestation,
|
msg::execute::attested::{
|
||||||
|
Attestation, Attested, EpidAttestation, HasUserData, MockAttestation,
|
||||||
|
},
|
||||||
|
state::CONFIG,
|
||||||
};
|
};
|
||||||
use crate::state::CONFIG;
|
|
||||||
|
|
||||||
impl Handler for EpidAttestation {
|
impl Handler for EpidAttestation {
|
||||||
fn handle(
|
fn handle(
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
use cosmwasm_std::{DepsMut, Env, MessageInfo, Response};
|
use cosmwasm_std::{DepsMut, Env, MessageInfo, Response};
|
||||||
|
|
||||||
use crate::error::Error;
|
use crate::{
|
||||||
use crate::handler::Handler;
|
error::Error,
|
||||||
use crate::msg::execute::session_create::SessionCreate;
|
handler::Handler,
|
||||||
use crate::state::{Session, SESSION};
|
msg::execute::session_create::SessionCreate,
|
||||||
|
state::{Session, SESSION},
|
||||||
|
};
|
||||||
|
|
||||||
impl Handler for SessionCreate {
|
impl Handler for SessionCreate {
|
||||||
fn handle(self, deps: DepsMut<'_>, _env: &Env, _info: &MessageInfo) -> Result<Response, Error> {
|
fn handle(self, deps: DepsMut<'_>, _env: &Env, _info: &MessageInfo) -> Result<Response, Error> {
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
use cosmwasm_std::{DepsMut, Env, HexBinary, MessageInfo, Response};
|
use cosmwasm_std::{DepsMut, Env, HexBinary, MessageInfo, Response};
|
||||||
|
|
||||||
use crate::error::Error;
|
use crate::{
|
||||||
use crate::handler::Handler;
|
error::Error, handler::Handler, msg::execute::session_set_pub_key::SessionSetPubKey,
|
||||||
use crate::msg::execute::session_set_pub_key::SessionSetPubKey;
|
state::SESSION,
|
||||||
use crate::state::SESSION;
|
};
|
||||||
|
|
||||||
impl Handler for SessionSetPubKey {
|
impl Handler for SessionSetPubKey {
|
||||||
fn handle(self, deps: DepsMut<'_>, _env: &Env, _info: &MessageInfo) -> Result<Response, Error> {
|
fn handle(self, deps: DepsMut<'_>, _env: &Env, _info: &MessageInfo) -> Result<Response, Error> {
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
use cosmwasm_std::{DepsMut, Env, MessageInfo, Response};
|
use cosmwasm_std::{DepsMut, Env, MessageInfo, Response};
|
||||||
use quartz_tee_ra::Error as RaVerificationError;
|
use quartz_tee_ra::Error as RaVerificationError;
|
||||||
|
|
||||||
use crate::error::Error;
|
use crate::{
|
||||||
use crate::handler::Handler;
|
error::Error,
|
||||||
use crate::msg::execute::attested::{Attestation, EpidAttestation, MockAttestation};
|
handler::Handler,
|
||||||
use crate::msg::instantiate::{CoreInstantiate, Instantiate};
|
msg::{
|
||||||
use crate::state::CONFIG;
|
execute::attested::{Attestation, EpidAttestation, MockAttestation},
|
||||||
use crate::state::{RawConfig, EPOCH_COUNTER};
|
instantiate::{CoreInstantiate, Instantiate},
|
||||||
|
},
|
||||||
|
state::{RawConfig, CONFIG, EPOCH_COUNTER},
|
||||||
|
};
|
||||||
|
|
||||||
impl Handler for Instantiate<EpidAttestation> {
|
impl Handler for Instantiate<EpidAttestation> {
|
||||||
fn handle(self, deps: DepsMut<'_>, env: &Env, info: &MessageInfo) -> Result<Response, Error> {
|
fn handle(self, deps: DepsMut<'_>, env: &Env, info: &MessageInfo) -> Result<Response, Error> {
|
||||||
|
|
|
@ -2,11 +2,10 @@ pub mod execute;
|
||||||
pub mod instantiate;
|
pub mod instantiate;
|
||||||
pub mod query;
|
pub mod query;
|
||||||
|
|
||||||
|
use cosmwasm_std::StdError;
|
||||||
pub use execute::{Execute as ExecuteMsg, RawExecute as RawExecuteMsg};
|
pub use execute::{Execute as ExecuteMsg, RawExecute as RawExecuteMsg};
|
||||||
pub use instantiate::{Instantiate as InstantiateMsg, RawInstantiate as RawInstantiateMsg};
|
pub use instantiate::{Instantiate as InstantiateMsg, RawInstantiate as RawInstantiateMsg};
|
||||||
|
|
||||||
use cosmwasm_std::StdError;
|
|
||||||
|
|
||||||
pub trait HasDomainType: From<Self::DomainType> {
|
pub trait HasDomainType: From<Self::DomainType> {
|
||||||
type DomainType: TryFrom<Self, Error = StdError>;
|
type DomainType: TryFrom<Self, Error = StdError>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,11 +5,14 @@ pub mod session_set_pub_key;
|
||||||
use cosmwasm_schema::cw_serde;
|
use cosmwasm_schema::cw_serde;
|
||||||
use cosmwasm_std::StdError;
|
use cosmwasm_std::StdError;
|
||||||
|
|
||||||
use crate::msg::execute::attested::{Attested, EpidAttestation};
|
use crate::msg::{
|
||||||
use crate::msg::execute::attested::{RawAttested, RawEpidAttestation};
|
execute::{
|
||||||
use crate::msg::execute::session_create::{RawSessionCreate, SessionCreate};
|
attested::{Attested, EpidAttestation, RawAttested, RawEpidAttestation},
|
||||||
use crate::msg::execute::session_set_pub_key::{RawSessionSetPubKey, SessionSetPubKey};
|
session_create::{RawSessionCreate, SessionCreate},
|
||||||
use crate::msg::HasDomainType;
|
session_set_pub_key::{RawSessionSetPubKey, SessionSetPubKey},
|
||||||
|
},
|
||||||
|
HasDomainType,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub enum Execute<Attestation = EpidAttestation> {
|
pub enum Execute<Attestation = EpidAttestation> {
|
||||||
|
|
|
@ -2,8 +2,10 @@ use cosmwasm_schema::cw_serde;
|
||||||
use cosmwasm_std::StdError;
|
use cosmwasm_std::StdError;
|
||||||
use quartz_tee_ra::IASReport;
|
use quartz_tee_ra::IASReport;
|
||||||
|
|
||||||
use crate::msg::HasDomainType;
|
use crate::{
|
||||||
use crate::state::{MrEnclave, UserData};
|
msg::HasDomainType,
|
||||||
|
state::{MrEnclave, UserData},
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct Attested<M, A> {
|
pub struct Attested<M, A> {
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
use cosmwasm_schema::cw_serde;
|
use cosmwasm_schema::cw_serde;
|
||||||
use cosmwasm_std::{HexBinary, StdError};
|
use cosmwasm_std::{HexBinary, StdError};
|
||||||
|
|
||||||
use crate::msg::execute::attested::HasUserData;
|
use crate::{
|
||||||
use crate::msg::HasDomainType;
|
msg::{execute::attested::HasUserData, HasDomainType},
|
||||||
use crate::state::{Nonce, UserData};
|
state::{Nonce, UserData},
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct SessionCreate {
|
pub struct SessionCreate {
|
||||||
|
|
|
@ -3,10 +3,11 @@ use cosmwasm_std::{HexBinary, StdError};
|
||||||
use k256::ecdsa::VerifyingKey;
|
use k256::ecdsa::VerifyingKey;
|
||||||
use sha2::{Digest, Sha256};
|
use sha2::{Digest, Sha256};
|
||||||
|
|
||||||
use crate::error::Error;
|
use crate::{
|
||||||
use crate::msg::execute::attested::HasUserData;
|
error::Error,
|
||||||
use crate::msg::HasDomainType;
|
msg::{execute::attested::HasUserData, HasDomainType},
|
||||||
use crate::state::{Nonce, UserData};
|
state::{Nonce, UserData},
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct SessionSetPubKey {
|
pub struct SessionSetPubKey {
|
||||||
|
|
|
@ -2,11 +2,15 @@ use cosmwasm_schema::cw_serde;
|
||||||
use cosmwasm_std::StdError;
|
use cosmwasm_std::StdError;
|
||||||
use sha2::{Digest, Sha256};
|
use sha2::{Digest, Sha256};
|
||||||
|
|
||||||
use crate::msg::execute::attested::{
|
use crate::{
|
||||||
Attested, EpidAttestation, HasUserData, RawAttested, RawEpidAttestation,
|
msg::{
|
||||||
|
execute::attested::{
|
||||||
|
Attested, EpidAttestation, HasUserData, RawAttested, RawEpidAttestation,
|
||||||
|
},
|
||||||
|
HasDomainType,
|
||||||
|
},
|
||||||
|
state::{Config, RawConfig, UserData},
|
||||||
};
|
};
|
||||||
use crate::msg::HasDomainType;
|
|
||||||
use crate::state::{Config, RawConfig, UserData};
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct Instantiate<A = EpidAttestation>(pub Attested<CoreInstantiate, A>);
|
pub struct Instantiate<A = EpidAttestation>(pub Attested<CoreInstantiate, A>);
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
pub use crate::handler::RawHandler;
|
pub use crate::{
|
||||||
pub use crate::msg::execute::RawExecute as QuartzExecuteMsg;
|
handler::RawHandler,
|
||||||
pub use crate::msg::instantiate::RawInstantiate as QuartzInstantiateMsg;
|
msg::{
|
||||||
|
execute::RawExecute as QuartzExecuteMsg,
|
||||||
|
instantiate::RawInstantiate as QuartzInstantiateMsg,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
|
@ -2,10 +2,10 @@ use cosmwasm_std::ensure_eq;
|
||||||
use num_bigint::BigUint;
|
use num_bigint::BigUint;
|
||||||
use sha2::{Digest, Sha256};
|
use sha2::{Digest, Sha256};
|
||||||
|
|
||||||
use crate::intel_sgx::epid::types::IASReport;
|
use crate::intel_sgx::{
|
||||||
use crate::intel_sgx::epid::Error as EpidError;
|
epid::{types::IASReport, Error as EpidError, INTEL_ROOT_EXPONENT, INTEL_ROOT_MODULUS},
|
||||||
use crate::intel_sgx::epid::{INTEL_ROOT_EXPONENT, INTEL_ROOT_MODULUS};
|
Error,
|
||||||
use crate::intel_sgx::Error;
|
};
|
||||||
|
|
||||||
/// Given an RSA signature and the signer's exponent + modulus we recover the digest that was signed by the signature.
|
/// Given an RSA signature and the signer's exponent + modulus we recover the digest that was signed by the signature.
|
||||||
pub fn recover_signature_digest(signature: &[u8], exponent: &[u8], modulus: &[u8]) -> Vec<u8> {
|
pub fn recover_signature_digest(signature: &[u8], exponent: &[u8], modulus: &[u8]) -> Vec<u8> {
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
pub mod intel_sgx;
|
pub mod intel_sgx;
|
||||||
|
|
||||||
pub use intel_sgx::epid::types::IASReport;
|
pub use intel_sgx::{
|
||||||
pub use intel_sgx::epid::verifier::verify as verify_epid_attestation;
|
epid::{types::IASReport, verifier::verify as verify_epid_attestation},
|
||||||
pub use intel_sgx::Error;
|
Error,
|
||||||
|
};
|
||||||
|
|
Loading…
Reference in a new issue