@meshsdk/contracts
Advanced tools
Comparing version
@@ -1,40 +0,11 @@ | ||
import { IInitiator, ISubmitter, IFetcher, Network, ISigner, MeshTxBuilder, BrowserWallet, UTxO, Asset } from '@meshsdk/core'; | ||
import * as _meshsdk_mesh_csl from '@meshsdk/mesh-csl'; | ||
import { ConStr0, PubKeyAddress, Integer, CurrencySymbol, TokenName, BuiltinByteString, Value, ConStr1 } from '@meshsdk/mesh-csl'; | ||
import { MeshTxBuilder, IFetcher, BrowserWallet, MeshWallet, UTxO, Asset } from '@meshsdk/core'; | ||
import * as _meshsdk_common from '@meshsdk/common'; | ||
import { ConStr0, PubKeyAddress, Integer, CurrencySymbol, TokenName, BuiltinByteString, Value, ConStr1, Asset as Asset$1, UTxO as UTxO$1 } from '@meshsdk/common'; | ||
declare type OwnerAddress = string; | ||
declare class BasicMarketplace { | ||
private _fetcher; | ||
private _initiator; | ||
private _network; | ||
private _owner; | ||
private _percentage; | ||
private _script; | ||
private _signer; | ||
private _submitter; | ||
constructor(options?: CreateMarketplaceOptions); | ||
delistAsset(address: string, asset: string, price: number): Promise<string>; | ||
listAsset(address: string, asset: string, price: number): Promise<string>; | ||
purchaseAsset(address: string, asset: string, price: number): Promise<string>; | ||
relistAsset(address: string, asset: string, oldPrice: number, newPrice: number): Promise<string>; | ||
private buildTx; | ||
private findUTxO; | ||
private splitAmount; | ||
} | ||
declare type CreateMarketplaceOptions = { | ||
percentage: number; | ||
initiator: IInitiator; | ||
submitter: ISubmitter; | ||
owner: OwnerAddress; | ||
fetcher: IFetcher; | ||
network: Network; | ||
signer: ISigner; | ||
}; | ||
declare type MeshTxInitiatorInput = { | ||
mesh: MeshTxBuilder; | ||
fetcher?: IFetcher; | ||
wallet?: BrowserWallet; | ||
wallet?: BrowserWallet | MeshWallet; | ||
networkId?: number; | ||
stakeCredential?: string; | ||
}; | ||
@@ -44,5 +15,6 @@ declare class MeshTxInitiator { | ||
fetcher?: IFetcher; | ||
wallet?: BrowserWallet; | ||
wallet?: BrowserWallet | MeshWallet; | ||
stakeCredential?: string; | ||
networkId: number; | ||
constructor({ mesh, fetcher, wallet, networkId }: MeshTxInitiatorInput); | ||
constructor({ mesh, fetcher, wallet, networkId, stakeCredential, }: MeshTxInitiatorInput); | ||
protected signSubmitReset: () => Promise<string | undefined>; | ||
@@ -130,3 +102,3 @@ protected queryUtxos: (walletAddress: string) => Promise<UTxO[]>; | ||
declare class MeshPaymentSplitterContract extends MeshTxInitiator { | ||
wrapPayees: (payees: string[]) => _meshsdk_mesh_csl.List; | ||
wrapPayees: (payees: string[]) => _meshsdk_common.List; | ||
scriptCbor: () => string; | ||
@@ -139,2 +111,13 @@ payees: string[]; | ||
export { ActiveEscrowDatum, BasicMarketplace, InitiationDatum, MarketplaceDatum, MeshEscrowContract, MeshGiftCardContract, MeshMarketplaceContract, MeshPaymentSplitterContract, MeshVestingContract, RecipientDepositRedeemer, VestingDatum, activeEscrowDatum, initiateEscrowDatum, marketplaceDatum, recipientDepositRedeemer }; | ||
declare type SwapDatum = ConStr0<[PubKeyAddress, Value, Value]>; | ||
declare class MeshSwapContract extends MeshTxInitiator { | ||
scriptCbor: string; | ||
scriptAddress: string; | ||
constructor(inputs: MeshTxInitiatorInput); | ||
initiateSwap: (toProvide: Asset$1[], toReceive: Asset$1[]) => Promise<string>; | ||
acceptSwap: (swapUtxo: UTxO$1) => Promise<string>; | ||
cancelSwap: (swapUtxo: UTxO$1) => Promise<string>; | ||
getUtxoByTxHash: (txHash: string) => Promise<UTxO$1 | undefined>; | ||
} | ||
export { ActiveEscrowDatum, InitiationDatum, MarketplaceDatum, MeshEscrowContract, MeshGiftCardContract, MeshMarketplaceContract, MeshPaymentSplitterContract, MeshSwapContract, MeshVestingContract, RecipientDepositRedeemer, SwapDatum, VestingDatum, activeEscrowDatum, initiateEscrowDatum, marketplaceDatum, recipientDepositRedeemer }; |
@@ -6,3 +6,3 @@ { | ||
"author": "MeshJS", | ||
"version": "1.0.0-beta.5", | ||
"version": "1.0.1", | ||
"license": "Apache-2.0", | ||
@@ -38,8 +38,8 @@ "type": "module", | ||
"peerDependencies": { | ||
"@meshsdk/core": "1.5.16" | ||
"@meshsdk/core": "^1.0.0" | ||
}, | ||
"dependencies": { | ||
"@harmoniclabs/plu-ts": "0.2.2", | ||
"@meshsdk/mesh-csl": "^0.0.4" | ||
"@meshsdk/common": "^1.0.0-alpha.9", | ||
"@meshsdk/core-csl": "^1.6.0-alpha.7" | ||
} | ||
} | ||
} |
@@ -1,3 +0,9 @@ | ||
import { MeshTxBuilder, IFetcher, UTxO, BrowserWallet } from '@meshsdk/core'; | ||
import { v2ScriptToBech32 } from '@meshsdk/mesh-csl'; | ||
import { | ||
MeshTxBuilder, | ||
IFetcher, | ||
UTxO, | ||
BrowserWallet, | ||
MeshWallet, | ||
} from '@meshsdk/core'; | ||
import { v2ScriptToBech32 } from '@meshsdk/core-csl'; | ||
@@ -7,4 +13,5 @@ export type MeshTxInitiatorInput = { | ||
fetcher?: IFetcher; | ||
wallet?: BrowserWallet; | ||
wallet?: BrowserWallet | MeshWallet; | ||
networkId?: number; | ||
stakeCredential?: string; | ||
}; | ||
@@ -15,6 +22,13 @@ | ||
fetcher?: IFetcher; | ||
wallet?: BrowserWallet; | ||
wallet?: BrowserWallet | MeshWallet; | ||
stakeCredential?: string; | ||
networkId = 0; | ||
constructor({ mesh, fetcher, wallet, networkId }: MeshTxInitiatorInput) { | ||
constructor({ | ||
mesh, | ||
fetcher, | ||
wallet, | ||
networkId, | ||
stakeCredential, | ||
}: MeshTxInitiatorInput) { | ||
this.mesh = mesh; | ||
@@ -30,2 +44,5 @@ if (fetcher) { | ||
} | ||
if (stakeCredential) { | ||
this.stakeCredential = this.stakeCredential; | ||
} | ||
} | ||
@@ -32,0 +49,0 @@ |
@@ -6,4 +6,7 @@ import { MeshTxInitiator, MeshTxInitiatorInput } from '@mesh/common'; | ||
v2ScriptToBech32, | ||
parseDatumCbor, | ||
parsePlutusAddressObjToBech32, | ||
} from '@meshsdk/core-csl'; | ||
import { | ||
ConStr0, | ||
parseDatumCbor, | ||
PubKeyAddress, | ||
@@ -17,6 +20,5 @@ Value, | ||
conStr1, | ||
parsePlutusAddressObjToBech32, | ||
parsePlutusValueToAssets, | ||
mConStr2, | ||
} from '@meshsdk/mesh-csl'; | ||
} from '@meshsdk/common'; | ||
import blueprint from './aiken-workspace/plutus.json'; | ||
@@ -23,0 +25,0 @@ import { Asset, UTxO, mergeAssets } from '@meshsdk/core'; |
@@ -5,2 +5,4 @@ # Escrow contract | ||
[Demo](https://meshjs.dev/smart-contracts/escrow) | ||
The escrow smart contract allows two parties to exchange assets securely. The contract holds the assets until both parties agree and sign off on the transaction. | ||
@@ -7,0 +9,0 @@ |
import { MeshTxInitiator, MeshTxInitiatorInput } from '@mesh/common'; | ||
import { | ||
v2ScriptToBech32, | ||
getV2ScriptHash, | ||
parseDatumCbor, | ||
applyParamsToScript, | ||
} from '@meshsdk/core-csl'; | ||
import { | ||
mConStr0, | ||
applyObjParamsToScript, | ||
builtinByteString, | ||
txOutRef, | ||
stringToHex, | ||
getV2ScriptHash, | ||
parseDatumCbor, | ||
BuiltinByteString, | ||
@@ -15,3 +17,3 @@ List, | ||
mConStr1, | ||
} from '@meshsdk/mesh-csl'; | ||
} from '@meshsdk/common'; | ||
import blueprint from './aiken-workspace/plutus.json'; | ||
@@ -25,3 +27,3 @@ import { Asset, UTxO } from '@meshsdk/core'; | ||
giftCardCbor = (tokenNameHex: string, utxoTxHash: string, utxoTxId: number) => | ||
applyObjParamsToScript(blueprint.validators[0].compiledCode, [ | ||
applyParamsToScript(blueprint.validators[0].compiledCode, [ | ||
builtinByteString(tokenNameHex), | ||
@@ -32,5 +34,5 @@ txOutRef(utxoTxHash, utxoTxId), | ||
redeemCbor = (tokenNameHex: string, policyId: string) => | ||
applyObjParamsToScript(blueprint.validators[1].compiledCode, [ | ||
builtinByteString(tokenNameHex), | ||
builtinByteString(policyId), | ||
applyParamsToScript(blueprint.validators[1].compiledCode, [ | ||
tokenNameHex, | ||
policyId, | ||
]); | ||
@@ -37,0 +39,0 @@ |
@@ -5,2 +5,4 @@ # Giftcard contract | ||
[Demo](https://meshjs.dev/smart-contracts/giftcard) | ||
Creating a giftcard will mint a token and send the assets to the contract. While redeeming will burn the token and send the assets to the redeemer. | ||
@@ -7,0 +9,0 @@ |
@@ -6,1 +6,2 @@ export * from './marketplace'; | ||
export * from './payment-splitter'; | ||
export * from './swap'; |
@@ -1,2 +0,1 @@ | ||
export * from './basic.service'; | ||
export * from './offchain'; |
import { MeshTxInitiator, MeshTxInitiatorInput } from '@mesh/common'; | ||
import { | ||
serializeBech32Address, | ||
v2ScriptToBech32, | ||
parseDatumCbor, | ||
parsePlutusAddressObjToBech32, | ||
applyParamsToScript, | ||
} from '@meshsdk/core-csl'; | ||
import { | ||
ConStr0, | ||
@@ -14,9 +20,5 @@ PubKeyAddress, | ||
integer, | ||
applyObjParamsToScript, | ||
v2ScriptToBech32, | ||
mConStr1, | ||
parseDatumCbor, | ||
parsePlutusAddressObjToBech32, | ||
mConStr0, | ||
} from '@meshsdk/mesh-csl'; | ||
} from '@meshsdk/common'; | ||
import blueprint from './aiken-workspace/plutus.json'; | ||
@@ -65,3 +67,3 @@ import { | ||
serializeBech32Address(ownerAddress); | ||
this.scriptCbor = applyObjParamsToScript( | ||
this.scriptCbor = applyParamsToScript( | ||
blueprint.validators[0].compiledCode, | ||
@@ -71,3 +73,4 @@ [ | ||
integer(feePercentageBasisPoint), | ||
] | ||
], | ||
'JSON' | ||
); | ||
@@ -142,5 +145,5 @@ } | ||
// const inputLovelace = marketplaceUtxo.output.amount.find( | ||
// (a) => a.unit === 'lovelace' | ||
// )!.quantity; | ||
const inputLovelace = marketplaceUtxo.output.amount.find( | ||
(a) => a.unit === 'lovelace' | ||
)!.quantity; | ||
@@ -174,3 +177,2 @@ const tx = this.mesh | ||
if (ownerToReceiveLovelace > 0) { | ||
console.log(7, 'ownerToReceiveLovelace', ownerToReceiveLovelace); | ||
const ownerAddress = this.ownerAddress; | ||
@@ -187,6 +189,5 @@ const ownerToReceive = [ | ||
const sellerToReceiveLovelace = | ||
inputDatum.fields[1].int - ownerToReceiveLovelace; | ||
inputDatum.fields[1].int + Number(inputLovelace); | ||
if (sellerToReceiveLovelace > 0) { | ||
console.log(8, 'sellerToReceiveLovelace', sellerToReceiveLovelace); | ||
const sellerAddress = parsePlutusAddressObjToBech32(inputDatum.fields[0]); | ||
@@ -193,0 +194,0 @@ const sellerToReceive = [ |
@@ -5,2 +5,4 @@ # Marketplace Contract | ||
[Demo](https://meshjs.dev/smart-contracts/marketplace) | ||
The marketplace smart contract allows users to buy and sell NFTs. A seller list an NFT for sales by specifying a certain price, and anyone can buy it by paying the demanded price. | ||
@@ -7,0 +9,0 @@ |
@@ -7,8 +7,4 @@ import { MeshTxInitiator, MeshTxInitiatorInput } from '@mesh/common'; | ||
} from '@meshsdk/core'; | ||
import { | ||
serializeBech32Address, | ||
applyObjParamsToScript, | ||
builtinByteString, | ||
list, | ||
} from '@meshsdk/mesh-csl'; | ||
import { serializeBech32Address, applyParamsToScript } from '@meshsdk/core-csl'; | ||
import { builtinByteString, list } from '@meshsdk/common'; | ||
import blueprint from './aiken-workspace/plutus.json'; | ||
@@ -25,5 +21,7 @@ | ||
scriptCbor = () => | ||
applyObjParamsToScript(blueprint.validators[0].compiledCode, [ | ||
this.wrapPayees(this.payees), | ||
]); | ||
applyParamsToScript( | ||
blueprint.validators[0].compiledCode, | ||
[this.wrapPayees(this.payees)], | ||
'JSON' | ||
); | ||
payees: string[] = []; | ||
@@ -30,0 +28,0 @@ |
@@ -5,2 +5,40 @@ # 💸 Aiken Payment Splitter | ||
[Demo](https://meshjs.dev/smart-contracts/payment-splitter) | ||
There are 2 actions (or endpoints) available to interact with this smart contract: | ||
- Send Lovelace to Payment Splitter | ||
- Trigger Payout | ||
To initialize the payment splitter, we need to initialize a provider, MeshTxBuilder and MeshPaymentSplitterContract. | ||
```typescript | ||
import { BlockfrostProvider, MeshTxBuilder } from '@meshsdk/core'; | ||
import { MeshPaymentSplitterContract } from '@meshsdk/contracts'; | ||
import { useWallet } from '@meshsdk/react'; | ||
const { connected, wallet } = useWallet(); | ||
const blockchainProvider = new BlockfrostProvider(APIKEY); | ||
const meshTxBuilder = new MeshTxBuilder({ | ||
fetcher: blockchainProvider, | ||
submitter: blockchainProvider, | ||
}); | ||
const contract = new MeshPaymentSplitterContract( | ||
{ | ||
mesh: meshTxBuilder, | ||
fetcher: blockchainProvider, | ||
wallet: wallet, | ||
networkId: 0, | ||
}, | ||
[ | ||
'addr_test1vpg334d6skwu6xxq0r4lqrnsjd5293n8s3d80em60kf6guc7afx8k', | ||
'addr_test1vp4l2kk0encl7t7972ngepgm0044fu8695prkgh5vjj5l6sxu0l3p', | ||
'addr_test1vqqnfs2vt42nq4htq460wd6gjxaj05jg9vzg76ur6ws4sngs55pwr', | ||
'addr_test1vqv2qhqddxmf87pzky2nkd9wm4y5599mhp62mu4atuss5dgdja5pw', | ||
]); | ||
``` | ||
## ⛓ On-chain | ||
@@ -7,0 +45,0 @@ |
# Swap | ||
Swap (deposit, cancel) | ||
Swap contract facilitates the exchange of assets between two parties. This contract is designed to be used in a peer-to-peer exchange scenario where two parties agree to exchange assets. The contract ensures that the assets are locked up until it is accepted by the other party. At any point before it is accepted, one can cancel the swap to retrieve the assets. | ||
[Demo](https://meshjs.dev/smart-contracts/swap) | ||
There are 2 actions (or endpoints) available to interact with this smart contract: | ||
- initiate swap | ||
- accept asset | ||
- cancel swap | ||
To initialize the swap, we need to initialize a provider, MeshTxBuilder and MeshSwapContract. | ||
```typescript | ||
import { BlockfrostProvider, MeshTxBuilder } from '@meshsdk/core'; | ||
import { MeshSwapContract } from '@meshsdk/contracts'; | ||
import { useWallet } from '@meshsdk/react'; | ||
const { connected, wallet } = useWallet(); | ||
const blockchainProvider = new BlockfrostProvider(APIKEY); | ||
const meshTxBuilder = new MeshTxBuilder({ | ||
fetcher: blockchainProvider, | ||
submitter: blockchainProvider, | ||
}); | ||
const contract = new MeshSwapContract({ | ||
mesh: meshTxBuilder, | ||
fetcher: blockchainProvider, | ||
wallet: wallet, | ||
networkId: 0, | ||
}); | ||
``` |
import { MeshTxInitiator, MeshTxInitiatorInput } from '@mesh/common'; | ||
import { | ||
mConStr0, | ||
serializeBech32Address, | ||
applyParamsToScript, | ||
v2ScriptToBech32, | ||
parseDatumCbor, | ||
} from '@meshsdk/core-csl'; | ||
import { | ||
mConStr0, | ||
unixTimeToEnclosingSlot, | ||
@@ -12,4 +15,3 @@ SLOT_CONFIG_NETWORK, | ||
BuiltinByteString, | ||
parseDatumCbor, | ||
} from '@meshsdk/mesh-csl'; | ||
} from '@meshsdk/common'; | ||
import blueprint from './aiken-workspace/plutus.json'; | ||
@@ -73,4 +75,4 @@ import { Asset, UTxO } from '@meshsdk/core'; | ||
this.networkId === 0 | ||
? SLOT_CONFIG_NETWORK.Preprod | ||
: SLOT_CONFIG_NETWORK.Mainnet | ||
? SLOT_CONFIG_NETWORK.preprod | ||
: SLOT_CONFIG_NETWORK.mainnet | ||
) + 1; | ||
@@ -77,0 +79,0 @@ |
@@ -5,2 +5,4 @@ # Vesting Contract | ||
[Demo](https://meshjs.dev/smart-contracts/vesting) | ||
When a new employee joins an organization, they typically receive a promise of compensation to be disbursed after a specified duration of employment. This arrangement often involves the organization depositing the funds into a vesting contract, with the employee gaining access to the funds upon the completion of a predetermined lockup period. Through the utilization of vesting contracts, organizations establish a mechanism to encourage employee retention by linking financial rewards to tenure. | ||
@@ -7,0 +9,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
326141
5.77%66
3.13%0
-100%36
800%0
-100%6049
-0.48%9
28.57%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed