mirror of
https://github.com/oceanprotocol/ocean.js.git
synced 2024-11-26 20:39:05 +01:00
Issue-#1485: Remove imports of ABIs in the tests and use utility tranfer(), mint(), balance() functions (#1486)
* remove imports of ABIs in NftFactory test * fix error with data token amount * remove imports of ABIs in FixedRateExchange test * remove imports of ABIs in SideStaking test * remove imports of ABIs in SideStaking test * remove imports of ABIs in Router test
This commit is contained in:
parent
c322b28c27
commit
282cd4e865
@ -1,7 +1,5 @@
|
|||||||
import { assert, expect } from 'chai'
|
import { assert, expect } from 'chai'
|
||||||
import { AbiItem } from 'web3-utils/types'
|
|
||||||
import { deployContracts, Addresses } from '../../TestContractHandler'
|
import { deployContracts, Addresses } from '../../TestContractHandler'
|
||||||
import ERC20Template from '@oceanprotocol/contracts/artifacts/contracts/templates/ERC20Template.sol/ERC20Template.json'
|
|
||||||
import { web3 } from '../../config'
|
import { web3 } from '../../config'
|
||||||
import {
|
import {
|
||||||
NftFactory,
|
NftFactory,
|
||||||
@ -11,7 +9,9 @@ import {
|
|||||||
signHash,
|
signHash,
|
||||||
Nft,
|
Nft,
|
||||||
transfer,
|
transfer,
|
||||||
approve
|
approve,
|
||||||
|
balance,
|
||||||
|
Datatoken
|
||||||
} from '../../../src'
|
} from '../../../src'
|
||||||
import {
|
import {
|
||||||
ProviderFees,
|
ProviderFees,
|
||||||
@ -31,7 +31,7 @@ describe('Nft Factory test', () => {
|
|||||||
let dtAddress2: string
|
let dtAddress2: string
|
||||||
let nftAddress: string
|
let nftAddress: string
|
||||||
|
|
||||||
const DATA_TOKEN_AMOUNT = web3.utils.toWei('1')
|
const DATA_TOKEN_AMOUNT = '1'
|
||||||
const FEE = '0.001'
|
const FEE = '0.001'
|
||||||
|
|
||||||
const nftData: NftCreateData = {
|
const nftData: NftCreateData = {
|
||||||
@ -238,31 +238,38 @@ describe('Nft Factory test', () => {
|
|||||||
const consumeFeeToken = contracts.daiAddress // token address for the feeAmount, in this case DAI
|
const consumeFeeToken = contracts.daiAddress // token address for the feeAmount, in this case DAI
|
||||||
|
|
||||||
// we reuse a DT created in a previous test
|
// we reuse a DT created in a previous test
|
||||||
const dtContract = new web3.eth.Contract(ERC20Template.abi as AbiItem[], dtAddress)
|
expect(await balance(web3, dtAddress, user1)).to.equal('0')
|
||||||
expect(await dtContract.methods.balanceOf(user1).call()).to.equal('0')
|
|
||||||
|
|
||||||
// dt owner mint DATA_TOKEN_AMOUNT to user1
|
// dt owner mint DATA_TOKEN_AMOUNT to user1
|
||||||
await dtContract.methods.mint(user1, DATA_TOKEN_AMOUNT).send({ from: nftOwner })
|
const datatoken = new Datatoken(web3)
|
||||||
|
datatoken.mint(dtAddress, nftOwner, DATA_TOKEN_AMOUNT, user1)
|
||||||
|
|
||||||
// user1 approves NFTFactory to move his DATA_TOKEN_AMOUNT
|
// user1 approves NFTFactory to move his DATA_TOKEN_AMOUNT
|
||||||
await dtContract.methods
|
await approve(
|
||||||
.approve(contracts.erc721FactoryAddress, DATA_TOKEN_AMOUNT)
|
web3,
|
||||||
.send({ from: user1 })
|
user1,
|
||||||
|
dtAddress,
|
||||||
|
contracts.erc721FactoryAddress,
|
||||||
|
DATA_TOKEN_AMOUNT
|
||||||
|
)
|
||||||
|
|
||||||
// we reuse another DT created in a previous test
|
// we reuse another DT created in a previous test
|
||||||
const dtContract2 = new web3.eth.Contract(ERC20Template.abi as AbiItem[], dtAddress2)
|
expect(await balance(web3, dtAddress2, user1)).to.equal('0')
|
||||||
expect(await dtContract2.methods.balanceOf(user1).call()).to.equal('0')
|
|
||||||
|
|
||||||
// dt owner mint DATA_TOKEN_AMOUNT to user1
|
// dt owner mint DATA_TOKEN_AMOUNT to user1
|
||||||
await dtContract2.methods.mint(user1, DATA_TOKEN_AMOUNT).send({ from: nftOwner })
|
datatoken.mint(dtAddress2, nftOwner, DATA_TOKEN_AMOUNT, user1)
|
||||||
// user1 approves NFTFactory to move his DATA_TOKEN_AMOUNT
|
// user1 approves NFTFactory to move his DATA_TOKEN_AMOUNT
|
||||||
await dtContract2.methods
|
await approve(
|
||||||
.approve(contracts.erc721FactoryAddress, DATA_TOKEN_AMOUNT)
|
web3,
|
||||||
.send({ from: user1 })
|
user1,
|
||||||
|
dtAddress2,
|
||||||
|
contracts.erc721FactoryAddress,
|
||||||
|
DATA_TOKEN_AMOUNT
|
||||||
|
)
|
||||||
|
|
||||||
// we check user1 has enought DTs
|
// we check user1 has enought DTs
|
||||||
expect(await dtContract.methods.balanceOf(user1).call()).to.equal(DATA_TOKEN_AMOUNT)
|
expect(await balance(web3, dtAddress, user1)).to.equal(DATA_TOKEN_AMOUNT)
|
||||||
expect(await dtContract2.methods.balanceOf(user1).call()).to.equal(DATA_TOKEN_AMOUNT)
|
expect(await balance(web3, dtAddress2, user1)).to.equal(DATA_TOKEN_AMOUNT)
|
||||||
|
|
||||||
const providerData = JSON.stringify({ timeout: 0 })
|
const providerData = JSON.stringify({ timeout: 0 })
|
||||||
const providerValidUntil = '0'
|
const providerValidUntil = '0'
|
||||||
@ -309,8 +316,8 @@ describe('Nft Factory test', () => {
|
|||||||
]
|
]
|
||||||
await nftFactory.startMultipleTokenOrder(user1, orders)
|
await nftFactory.startMultipleTokenOrder(user1, orders)
|
||||||
// we check user1 has no more DTs
|
// we check user1 has no more DTs
|
||||||
expect(await dtContract.methods.balanceOf(user1).call()).to.equal('0')
|
expect(await balance(web3, dtAddress, user1)).to.equal('0')
|
||||||
expect(await dtContract2.methods.balanceOf(user1).call()).to.equal('0')
|
expect(await balance(web3, dtAddress2, user1)).to.equal('0')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('#checkDatatoken - should confirm if DT is from the factory', async () => {
|
it('#checkDatatoken - should confirm if DT is from the factory', async () => {
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
import { assert, expect } from 'chai'
|
import { assert, expect } from 'chai'
|
||||||
import { AbiItem } from 'web3-utils/types'
|
|
||||||
import { deployContracts, Addresses } from '../../TestContractHandler'
|
import { deployContracts, Addresses } from '../../TestContractHandler'
|
||||||
import MockERC20 from '@oceanprotocol/contracts/artifacts/contracts/utils/mock/MockERC20Decimals.sol/MockERC20Decimals.json'
|
|
||||||
import { web3 } from '../../config'
|
import { web3 } from '../../config'
|
||||||
import {
|
import {
|
||||||
NftFactory,
|
NftFactory,
|
||||||
@ -9,7 +7,8 @@ import {
|
|||||||
Router,
|
Router,
|
||||||
balance,
|
balance,
|
||||||
approve,
|
approve,
|
||||||
ZERO_ADDRESS
|
ZERO_ADDRESS,
|
||||||
|
transfer
|
||||||
} from '../../../src'
|
} from '../../../src'
|
||||||
import { Erc20CreateParams, PoolCreationParams, Operation } from '../../../src/@types'
|
import { Erc20CreateParams, PoolCreationParams, Operation } from '../../../src/@types'
|
||||||
|
|
||||||
@ -123,14 +122,7 @@ describe('Router unit test', () => {
|
|||||||
|
|
||||||
it('#buyDTBatch - should buy multiple DT in one call', async () => {
|
it('#buyDTBatch - should buy multiple DT in one call', async () => {
|
||||||
// APPROVE DAI
|
// APPROVE DAI
|
||||||
const daiContract = new web3.eth.Contract(
|
await transfer(web3, factoryOwner, contracts.daiAddress, user1, DAI_AMOUNT)
|
||||||
MockERC20.abi as AbiItem[],
|
|
||||||
contracts.daiAddress
|
|
||||||
)
|
|
||||||
|
|
||||||
await daiContract.methods
|
|
||||||
.transfer(user1, web3.utils.toWei(DAI_AMOUNT))
|
|
||||||
.send({ from: factoryOwner })
|
|
||||||
|
|
||||||
await approve(web3, user1, contracts.daiAddress, contracts.routerAddress, DAI_AMOUNT)
|
await approve(web3, user1, contracts.daiAddress, contracts.routerAddress, DAI_AMOUNT)
|
||||||
|
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
import { assert, expect } from 'chai'
|
import { assert, expect } from 'chai'
|
||||||
import { AbiItem } from 'web3-utils/types'
|
|
||||||
import { Contract } from 'web3-eth-contract'
|
|
||||||
import BigNumber from 'bignumber.js'
|
import BigNumber from 'bignumber.js'
|
||||||
import ERC20Template from '@oceanprotocol/contracts/artifacts/contracts/templates/ERC20Template.sol/ERC20Template.json'
|
|
||||||
import { deployContracts, Addresses } from '../../../TestContractHandler'
|
import { deployContracts, Addresses } from '../../../TestContractHandler'
|
||||||
import { web3 } from '../../../config'
|
import { web3 } from '../../../config'
|
||||||
import {
|
import {
|
||||||
@ -13,7 +10,8 @@ import {
|
|||||||
approve,
|
approve,
|
||||||
transfer,
|
transfer,
|
||||||
balance,
|
balance,
|
||||||
unitsToAmount
|
unitsToAmount,
|
||||||
|
Datatoken
|
||||||
} from '../../../../src'
|
} from '../../../../src'
|
||||||
import { FreCreationParams, Erc20CreateParams } from '../../../../src/@types'
|
import { FreCreationParams, Erc20CreateParams } from '../../../../src/@types'
|
||||||
|
|
||||||
@ -26,7 +24,6 @@ describe('Fixed Rate unit test', () => {
|
|||||||
let contracts: Addresses
|
let contracts: Addresses
|
||||||
let fixedRate: FixedRateExchange
|
let fixedRate: FixedRateExchange
|
||||||
let dtAddress: string
|
let dtAddress: string
|
||||||
let dtContract: Contract
|
|
||||||
|
|
||||||
const nftData: NftCreateData = {
|
const nftData: NftCreateData = {
|
||||||
name: '72120Bundle',
|
name: '72120Bundle',
|
||||||
@ -96,7 +93,6 @@ describe('Fixed Rate unit test', () => {
|
|||||||
dtAddress = txReceipt.events.TokenCreated.returnValues.newTokenAddress
|
dtAddress = txReceipt.events.TokenCreated.returnValues.newTokenAddress
|
||||||
exchangeId = txReceipt.events.NewFixedRate.returnValues.exchangeId
|
exchangeId = txReceipt.events.NewFixedRate.returnValues.exchangeId
|
||||||
|
|
||||||
dtContract = new web3.eth.Contract(ERC20Template.abi as AbiItem[], dtAddress)
|
|
||||||
// user1 has no dt1
|
// user1 has no dt1
|
||||||
expect(await balance(web3, dtAddress, user1)).to.equal('0')
|
expect(await balance(web3, dtAddress, user1)).to.equal('0')
|
||||||
|
|
||||||
@ -200,9 +196,8 @@ describe('Fixed Rate unit test', () => {
|
|||||||
|
|
||||||
it('#buyDT - user1 should buy some dt', async () => {
|
it('#buyDT - user1 should buy some dt', async () => {
|
||||||
// total supply is ZERO right now so dt owner mints 1000 DT and approves the fixed rate contract
|
// total supply is ZERO right now so dt owner mints 1000 DT and approves the fixed rate contract
|
||||||
await dtContract.methods
|
const datatoken = new Datatoken(web3)
|
||||||
.mint(exchangeOwner, web3.utils.toWei('1000'))
|
await datatoken.mint(dtAddress, exchangeOwner, '1000', exchangeOwner)
|
||||||
.send({ from: exchangeOwner })
|
|
||||||
await approve(web3, exchangeOwner, dtAddress, contracts.fixedRateAddress, '1000')
|
await approve(web3, exchangeOwner, dtAddress, contracts.fixedRateAddress, '1000')
|
||||||
// user1 gets 100 DAI so he can buy DTs
|
// user1 gets 100 DAI so he can buy DTs
|
||||||
await transfer(web3, exchangeOwner, contracts.daiAddress, user1, '100')
|
await transfer(web3, exchangeOwner, contracts.daiAddress, user1, '100')
|
||||||
@ -411,7 +406,6 @@ describe('Fixed Rate unit test', () => {
|
|||||||
dtAddress = txReceipt.events.TokenCreated.returnValues.newTokenAddress
|
dtAddress = txReceipt.events.TokenCreated.returnValues.newTokenAddress
|
||||||
exchangeId = txReceipt.events.NewFixedRate.returnValues.exchangeId
|
exchangeId = txReceipt.events.NewFixedRate.returnValues.exchangeId
|
||||||
|
|
||||||
dtContract = new web3.eth.Contract(ERC20Template.abi as AbiItem[], dtAddress)
|
|
||||||
// user1 has no dt1
|
// user1 has no dt1
|
||||||
expect(await balance(web3, dtAddress, user1)).to.equal('0')
|
expect(await balance(web3, dtAddress, user1)).to.equal('0')
|
||||||
|
|
||||||
@ -511,9 +505,8 @@ describe('Fixed Rate unit test', () => {
|
|||||||
|
|
||||||
it('#buyDT - user1 should buy some dt', async () => {
|
it('#buyDT - user1 should buy some dt', async () => {
|
||||||
// total supply is ZERO right now so dt owner mints 1000 DT and approves the fixed rate contract
|
// total supply is ZERO right now so dt owner mints 1000 DT and approves the fixed rate contract
|
||||||
await dtContract.methods
|
const datatoken = new Datatoken(web3)
|
||||||
.mint(exchangeOwner, web3.utils.toWei('1000'))
|
await datatoken.mint(dtAddress, exchangeOwner, '1000', exchangeOwner)
|
||||||
.send({ from: exchangeOwner })
|
|
||||||
await approve(web3, exchangeOwner, dtAddress, contracts.fixedRateAddress, '1000')
|
await approve(web3, exchangeOwner, dtAddress, contracts.fixedRateAddress, '1000')
|
||||||
// user1 gets 100 USDC so he can buy DTs
|
// user1 gets 100 USDC so he can buy DTs
|
||||||
await transfer(web3, exchangeOwner, contracts.usdcAddress, user1, '100')
|
await transfer(web3, exchangeOwner, contracts.usdcAddress, user1, '100')
|
||||||
|
@ -1,9 +1,5 @@
|
|||||||
import { assert, expect } from 'chai'
|
import { assert, expect } from 'chai'
|
||||||
import { AbiItem } from 'web3-utils/types'
|
|
||||||
import { Contract } from 'web3-eth-contract'
|
|
||||||
import BigNumber from 'bignumber.js'
|
import BigNumber from 'bignumber.js'
|
||||||
import ERC20Template from '@oceanprotocol/contracts/artifacts/contracts/templates/ERC20Template.sol/ERC20Template.json'
|
|
||||||
import MockERC20 from '@oceanprotocol/contracts/artifacts/contracts/utils/mock/MockERC20Decimals.sol/MockERC20Decimals.json'
|
|
||||||
import { deployContracts, Addresses } from '../../../TestContractHandler'
|
import { deployContracts, Addresses } from '../../../TestContractHandler'
|
||||||
import { web3 } from '../../../config'
|
import { web3 } from '../../../config'
|
||||||
import {
|
import {
|
||||||
@ -15,7 +11,10 @@ import {
|
|||||||
Pool,
|
Pool,
|
||||||
SideStaking,
|
SideStaking,
|
||||||
unitsToAmount,
|
unitsToAmount,
|
||||||
ZERO_ADDRESS
|
ZERO_ADDRESS,
|
||||||
|
balance,
|
||||||
|
transfer,
|
||||||
|
decimals
|
||||||
} from '../../../../src'
|
} from '../../../../src'
|
||||||
import {
|
import {
|
||||||
Erc20CreateParams,
|
Erc20CreateParams,
|
||||||
@ -35,9 +34,6 @@ describe('SideStaking unit test', () => {
|
|||||||
let sideStaking: SideStaking
|
let sideStaking: SideStaking
|
||||||
let poolAddress: string
|
let poolAddress: string
|
||||||
let erc20Token: string
|
let erc20Token: string
|
||||||
let erc20Contract: Contract
|
|
||||||
let daiContract: Contract
|
|
||||||
let usdcContract: Contract
|
|
||||||
|
|
||||||
const VESTED_BLOCKS = 2500000
|
const VESTED_BLOCKS = 2500000
|
||||||
const VESTING_AMOUNT = '10000'
|
const VESTING_AMOUNT = '10000'
|
||||||
@ -86,12 +82,6 @@ describe('SideStaking unit test', () => {
|
|||||||
sideStaking = new SideStaking(web3, 8996)
|
sideStaking = new SideStaking(web3, 8996)
|
||||||
assert(sideStaking != null)
|
assert(sideStaking != null)
|
||||||
|
|
||||||
daiContract = new web3.eth.Contract(MockERC20.abi as AbiItem[], contracts.daiAddress)
|
|
||||||
usdcContract = new web3.eth.Contract(
|
|
||||||
MockERC20.abi as AbiItem[],
|
|
||||||
contracts.usdcAddress
|
|
||||||
)
|
|
||||||
|
|
||||||
await approve(
|
await approve(
|
||||||
web3,
|
web3,
|
||||||
factoryOwner,
|
factoryOwner,
|
||||||
@ -164,9 +154,8 @@ describe('SideStaking unit test', () => {
|
|||||||
erc20Token = txReceipt.events.TokenCreated.returnValues.newTokenAddress
|
erc20Token = txReceipt.events.TokenCreated.returnValues.newTokenAddress
|
||||||
poolAddress = txReceipt.events.NewPool.returnValues.poolAddress
|
poolAddress = txReceipt.events.NewPool.returnValues.poolAddress
|
||||||
|
|
||||||
erc20Contract = new web3.eth.Contract(ERC20Template.abi as AbiItem[], erc20Token)
|
|
||||||
// user1 has no dt1
|
// user1 has no dt1
|
||||||
expect(await erc20Contract.methods.balanceOf(user1).call()).to.equal('0')
|
expect(await balance(web3, erc20Token, user1)).to.equal('0')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('#getRouter - should get Router address', async () => {
|
it('#getRouter - should get Router address', async () => {
|
||||||
@ -251,9 +240,7 @@ describe('SideStaking unit test', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it('#swapExactAmountIn - should swap', async () => {
|
it('#swapExactAmountIn - should swap', async () => {
|
||||||
await daiContract.methods
|
await transfer(web3, factoryOwner, contracts.daiAddress, user1, '1000')
|
||||||
.transfer(user1, web3.utils.toWei('1000'))
|
|
||||||
.send({ from: factoryOwner })
|
|
||||||
await approve(web3, user1, contracts.daiAddress, poolAddress, '10')
|
await approve(web3, user1, contracts.daiAddress, poolAddress, '10')
|
||||||
|
|
||||||
const tokenInOutMarket: TokenInOutMarket = {
|
const tokenInOutMarket: TokenInOutMarket = {
|
||||||
@ -275,8 +262,12 @@ describe('SideStaking unit test', () => {
|
|||||||
amountsInOutMaxFee
|
amountsInOutMaxFee
|
||||||
)
|
)
|
||||||
|
|
||||||
expect(await erc20Contract.methods.balanceOf(user1).call()).to.equal(
|
expect(await balance(web3, erc20Token, user1)).to.equal(
|
||||||
tx.events.LOG_SWAP.returnValues.tokenAmountOut
|
await unitsToAmount(
|
||||||
|
web3,
|
||||||
|
erc20Token,
|
||||||
|
tx.events.LOG_SWAP.returnValues.tokenAmountOut
|
||||||
|
)
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -359,7 +350,7 @@ describe('SideStaking unit test', () => {
|
|||||||
marketFeeCollector: factoryOwner,
|
marketFeeCollector: factoryOwner,
|
||||||
poolTemplateAddress: contracts.poolTemplateAddress,
|
poolTemplateAddress: contracts.poolTemplateAddress,
|
||||||
rate: '1',
|
rate: '1',
|
||||||
baseTokenDecimals: await usdcContract.methods.decimals().call(),
|
baseTokenDecimals: await decimals(web3, contracts.usdcAddress),
|
||||||
vestingAmount: VESTING_AMOUNT,
|
vestingAmount: VESTING_AMOUNT,
|
||||||
vestedBlocks: VESTED_BLOCKS,
|
vestedBlocks: VESTED_BLOCKS,
|
||||||
initialBaseTokenLiquidity: await unitsToAmount(
|
initialBaseTokenLiquidity: await unitsToAmount(
|
||||||
@ -386,9 +377,8 @@ describe('SideStaking unit test', () => {
|
|||||||
erc20Token = txReceipt.events.TokenCreated.returnValues.newTokenAddress
|
erc20Token = txReceipt.events.TokenCreated.returnValues.newTokenAddress
|
||||||
poolAddress = txReceipt.events.NewPool.returnValues.poolAddress
|
poolAddress = txReceipt.events.NewPool.returnValues.poolAddress
|
||||||
|
|
||||||
erc20Contract = new web3.eth.Contract(ERC20Template.abi as AbiItem[], erc20Token)
|
|
||||||
// user1 has no dt1
|
// user1 has no dt1
|
||||||
expect(await erc20Contract.methods.balanceOf(user1).call()).to.equal('0')
|
expect(await balance(web3, erc20Token, user1)).to.equal('0')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('#getBaseTokenBalance ', async () => {
|
it('#getBaseTokenBalance ', async () => {
|
||||||
@ -431,12 +421,9 @@ describe('SideStaking unit test', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it('#swapExactAmountIn - should swap', async () => {
|
it('#swapExactAmountIn - should swap', async () => {
|
||||||
const transferAmount = await amountToUnits(web3, contracts.usdcAddress, '1000') // 1000 USDC
|
await transfer(web3, factoryOwner, contracts.usdcAddress, user1, '1000') // 1000 USDC
|
||||||
await usdcContract.methods
|
|
||||||
.transfer(user1, transferAmount)
|
|
||||||
.send({ from: factoryOwner })
|
|
||||||
|
|
||||||
await approve(web3, user1, contracts.usdcAddress, poolAddress, '10')
|
await approve(web3, user1, contracts.usdcAddress, poolAddress, '10')
|
||||||
|
|
||||||
const tokenInOutMarket: TokenInOutMarket = {
|
const tokenInOutMarket: TokenInOutMarket = {
|
||||||
tokenIn: contracts.usdcAddress,
|
tokenIn: contracts.usdcAddress,
|
||||||
tokenOut: erc20Token,
|
tokenOut: erc20Token,
|
||||||
@ -453,8 +440,12 @@ describe('SideStaking unit test', () => {
|
|||||||
tokenInOutMarket,
|
tokenInOutMarket,
|
||||||
amountsInOutMaxFee
|
amountsInOutMaxFee
|
||||||
)
|
)
|
||||||
expect(await erc20Contract.methods.balanceOf(user1).call()).to.equal(
|
expect(await balance(web3, erc20Token, user1)).to.equal(
|
||||||
tx.events.LOG_SWAP.returnValues.tokenAmountOut
|
await unitsToAmount(
|
||||||
|
web3,
|
||||||
|
erc20Token,
|
||||||
|
tx.events.LOG_SWAP.returnValues.tokenAmountOut
|
||||||
|
)
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user